mantis-report
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReporter (/mantis-report)
报告生成器(/mantis-report)
System Goal
系统目标
Security Reporting Expert. Synthesizes complex, technical finding logs into a
high-quality, human-readable review packet for developers and stakeholders.
安全报告专家。将复杂的技术漏洞发现日志整合为高质量、易读的审查报告包,供开发人员和利益相关者使用。
Command Definition
命令定义
- Command:
/mantis-report - Description: Generates a human-readable security review packet containing confirmed findings and exploit chains.
- 命令:
/mantis-report - 描述: 生成包含已确认漏洞发现和利用链的易读性安全审查报告包。
Input/Output Contract
输入/输出约定
- Reads:
- (all active finding files for this pass).
workspace/findings/*.json - (archived findings from prior passes) and legacy
workspace/archive/findings_pass_*/*.json. The report is a campaign-wide view: this pass's full findings plus carried-forward findings that prior passes stopped retrying (e.g. hit the retry cap) so they do not vanish from the report.workspace/archive/loop*_findings/*.json - (to track current loop pass, and to read
workspace/.mantis_state.jsonandvcs_info{active_snapshot,root,snapshot_id} for provenance).snapshot_pinned - Per-finding snapshot provenance fields, all OPTIONAL: ,
discovery_commit,repro_snapshot_id. When any is absent/empty it is rendered as "(not recorded)" — never a reason to drop a finding.patch_base_snapshot
- Writes:
- (pass- and snapshot-tagged markdown report). Falls back to the unsuffixed
workspace/report/review_packet_pass_<N>_<snapshot_tag>.mdon a legacy pass with no recorded snapshot.review_packet_pass_<N>.md - Updates copy/symlink at .
workspace/report/review_packet-latest.md
- Preconditions:
- Calibrated and reproduced findings exist in or
workspace/findings/. The report is a campaign-wide view: it reports the current state of every unresolved finding discovered in this or any prior pass, de-duplicated to each finding's latest state. A confirmed-but-unfixed finding that plan stopped carrying back (e.g. it hit the 2-attempt retry cap) does NOT vanish — it appears here at its most recent archived state.workspace/archive/
- Calibrated and reproduced findings exist in
- Idempotency Guarantee:
- Writes to pass-and-snapshot-tagged files. In-place overwrite of
. Re-running the SAME pass on the SAME snapshot updates the same tagged file. Re-running the same pass number on a DIFFERENT snapshot writes a DISTINCT file (the
review_packet-latest.mdsuffix prevents cross-snapshot overwrite). Legacy passes with no recorded snapshot keep the unsuffixed<snapshot_tag>name and overwrite in place, exactly as before.review_packet_pass_<N>.md
- Writes to pass-and-snapshot-tagged files. In-place overwrite of
- 读取:
- (本次审查的所有活跃漏洞发现文件)。
workspace/findings/*.json - (过往审查的归档漏洞发现)以及旧版
workspace/archive/findings_pass_*/*.json。报告覆盖整个审查周期:包含本次审查的完整漏洞发现,以及过往审查中因达到重试上限而停止重试、但未被修复的遗留漏洞发现,确保这些内容不会从报告中消失。workspace/archive/loop*_findings/*.json - (用于跟踪当前循环审查次数,读取
workspace/.mantis_state.json和vcs_info{active_snapshot,root,snapshot_id} 以记录溯源信息)。snapshot_pinned - 每个漏洞发现的快照溯源字段(均为可选):、
discovery_commit、repro_snapshot_id。若任何字段缺失/为空,则显示为“(未记录)”——绝不能因此丢弃漏洞发现。patch_base_snapshot
- 写入:
- (带有审查次数和快照标签的Markdown报告)。若为无快照记录的旧版审查,则回退使用无后缀的
workspace/report/review_packet_pass_<N>_<snapshot_tag>.md。review_packet_pass_<N>.md - 更新 的副本或符号链接。
workspace/report/review_packet-latest.md
- 前置条件:
- 或
workspace/findings/中存在已校准和复现的漏洞发现。报告覆盖整个审查周期:展示本次或过往审查中发现的所有未解决漏洞发现的当前状态,并按每个漏洞发现的最新状态去重。已确认但未修复、且审查计划停止重试的漏洞发现(例如达到2次重试上限)不会消失——将以其最新的归档状态呈现在报告中。workspace/archive/
- 幂等性保证:
- 写入带有审查次数和快照标签的文件。原地覆盖 。针对同一快照重新运行同一审查次数时,会更新同一标签文件。针对不同快照重新运行同一审查次数时,会写入一个独立文件(
review_packet-latest.md后缀可防止跨快照覆盖)。无快照记录的旧版审查保留无后缀的<snapshot_tag>名称,并原地覆盖,与之前的行为完全一致。review_packet_pass_<N>.md
- 写入带有审查次数和快照标签的文件。原地覆盖
Instructions
操作说明
Step 0 — Locator Resolution.
LOCATOR RESOLUTION (before reading ANY target code or artifact):
0. ROLE: If this skill NEVER reads target source (report, calibrate, reflect),
you are a FINDINGS-ONLY stage: skip steps 2-6; still read active_snapshot from
state for provenance/annotation; NEVER stop merely because a code root is unset.
1. Determine CODE_ROOT, in this priority order:
a. If --target_root is passed on THIS invocation, CODE_ROOT = --target_root.
It is AUTHORITATIVE and OVERRIDES SNAPSHOT_ROOT and the state fallback
(used when a caller hands you a prepared tree, e.g. a patched shadow).
b. Else if --snapshot_root (or SNAPSHOT_ROOT) is passed, use it.
c. Else read state_root/workspace/.mantis_state.json (state_root from
--state_root if passed, else ./workspace/... relative to the current dir)
-> active_snapshot.root / .snapshot_id / .snapshot_pinned.
d. Else (no arg AND no readable active_snapshot): CODE_ROOT = current directory,
treat snapshot_pinned = false (MODE-OFF). Do NOT stop.
2. SENTINEL CHECK (only if snapshot_pinned is true AND you did NOT take path 1a):
verify CODE_ROOT/.mantis_snapshot_id exists and equals SNAPSHOT_ID. If missing
or different -> STOP "snapshot sentinel mismatch". (A --target_root tree (1a) is
deliberately mutated and is sentinel-EXEMPT.)
3. PATH FIELDS:
- SNAPSHOT-RELATIVE (read under CODE_ROOT): code_paths entries; plan target_files
that are file paths. Strip ONLY a trailing ":<digits>". A code_paths entry
containing "://" is a URL/endpoint, NOT a file read. A code_paths entry that is
NOT of the form <existing-path>:<integer> is a non-source LOCATOR
(symbol/offset/endpoint): only check that the artifact/symbol exists; skip ALL
line-range and line-existence logic.
- STATE-RELATIVE (read/write under state_root/workspace, NEVER prefix CODE_ROOT):
kb_references, repro_file_path, reattack_file_path, helper scripts, report
files, and all state/findings JSON.
4. Never WRITE under CODE_ROOT when snapshot_pinned is true. Any command that
compiles, generates, or writes artifacts MUST run in a PRIVATE SHADOW copy
(mktemp -d from CODE_ROOT), never with cwd=CODE_ROOT. Read-only inspection may
cd into CODE_ROOT.
5. VCS-METADATA CARVE-OUT: history-log extraction and any VCS diff/blame command
run in the LIVE repository root (which still has .git/.hg/.repo), NOT CODE_ROOT
(the snapshot copy strips VCS metadata). Do NOT stop merely because CODE_ROOT
lacks .git/.hg/.repo.
6. Every shell command uses ABSOLUTE paths and sets its own working directory on
that call. Do NOT assume the working directory persists between calls.Then the following FINDINGS-ONLY notes apply to the Reporter:
- The Reporter is a FINDINGS-ONLY stage (Block A, ROLE step 0): it SKIPS locator steps 2–6, does NOT require or resolve a CODE_ROOT, and NEVER stops because a code root or sentinel is unset.
- It STILL reads (
active_snapshot,root,snapshot_id) andsnapshot_pinnedfromvcs_infofor provenance — used to build the header, the top banners, and the output file name.workspace/.mantis_state.json - Every path the Reporter touches (,
workspace/findings/*.json,workspace/.mantis_state.json,workspace/report/*) is STATE-RELATIVE and is NEVER prefixed with CODE_ROOT.workspace/archive/*
Compile a professional Markdown report detailing the verified/reproduced
vulnerabilities and exploit chains.
Execute the reporting stage as follows:
-
Load findings — this pass in full, plus carried-forward open findings (newest-first fold; no script). Build a working set keyed by finding identity, each finding once at its most-recent state:SAME-BUG PREDICATE (used for ALL current↔archived dedup, fold, and suppression in this stage; over-reporting is always safe here, hiding a real finding is never acceptable): two findings are the SAME BUG only if EITHER (i) they have the exact same(UUID); OR (ii) ALL THREE hold — they share a non-empty
id, they share a non-emptylineage_id, AND at least onesignatureentry compared WITH its trailingcode_paths(line-inclusive) is identical between them. Otherwise they are DISTINCT — render BOTH. NEVER treat two findings as the same bug on:linealone orlineage_idalone: both are coarser than a bug's true identity (basename-derived lineage can link two distinct same-named files; asignaturestrips the line number so it collides between distinct same-file bugs), and collapsing on either alone can silently drop a real finding.signatureDesign note (re-anchoring vs fold):'s re-anchoring (Phase 2) only provides a line hint that steers RE-DISCOVER — it does NOT rewrite the carried finding'smantis-plan. A re-discovered finding surfaces at its NEW line on the current snapshot. Because the fold predicate requires a line-inclusivecode_pathsmatch, the re-discovered finding will NOT fold with its ancestor (the line numbers differ). This is SAFE over-reporting — both entries render, the current one shows the new location. A future phase could relax the predicate to path-only matching when BOTH findings carry the samecode_pathsANDsignatureAND the ancestor's line is confirmed absent on the current snapshot, but the conservative line-inclusive match is used today to prevent any silent-drop risk.lineage_id- Read all active and add every active finding to the working set, keyed by its
workspace/findings/*.json(UUID) — all remediation statuses, so this pass'sid/VERIFIED_SECUREfixes still render with their patches in Categories 1/2. NEVER collapse two ACTIVE findings, even if they share aMITIGATION_PROPOSEDorlineage_id— keep each activesignatureas its own entry.id - Scan (and legacy
workspace/archive/findings_pass_<N>/) in descending pass order. Add an archived finding only if it is still OPEN (see 4) AND NO finding already in the working set is the SAME BUG as it (per the predicate above) AND no earlier (higher-pass) archived copy of the SAME BUG was already added. First copy met = latest state; ignore later same-bug copies in lower dirs. (An archived finding is suppressed ONLY when a genuine same-bug supersedes it; a mereloop<N>_findings/orlineage_idcoincidence does NOT suppress it.)signature - Supersession fold (Phase 3): When an archived finding IS the SAME BUG
(predicate ii) as a current finding, the current finding supersedes it —
show a single entry at the current (most-recent) state; do not also render
the archived copy. When the predicate is NOT satisfied (different
, e.g. a file rename, or
signatureabsent), render both as separate entries (safe over-reporting, never hiding).lineage_id- Under-reporting safeguard: If the current (superseding) finding
FAILS the actionable predicate (step 4 below) but the archived ancestor
would have PASSED it (e.g., the ancestor was and OPEN, but the current pass's reproduce resulted in
reproduceddue to a transient build/environment failure on the new snapshot), do NOT let the transient downgrade suppress the confirmed-open bug. Instead, keep the ancestor's last confirmed state visible in the report (render it with a note "Open — repro pending on new snapshot") so a previously-confirmed bug can never silently disappear from the report. The current finding's newer metadata (e.g., updatednot_attemptedline numbers) may still be attached as an annotation, but the verdict/status shown must be the ancestor's last confirmed state, never the transient downgrade.code_paths
- Under-reporting safeguard: If the current (superseding) finding
FAILS the actionable predicate (step 4 below) but the archived ancestor
would have PASSED it (e.g., the ancestor was
- Actionable / quality predicate (applies to active AND archived):
include a finding only if it is an exploit chain (present, or "Exploit Chain" in title/history) OR
constituent_findingsisrepro_statusOR (reproducedisrepro_statusAND it carries empirical execution evidence — an external stack trace, sanitizer trace (ASan/UBSan/MSan/TSan), or crash log). Do not include false positives,statically_confirmed,NON_VIABLE,DUPLICATE, or ordinaryfailed_to_reproducefindings lacking empirical traces.statically_confirmed - Open predicate (archived carry-forward in step 2 only): an archived
finding is "still open" if it satisfies (4) AND is NOT
patch_status/VERIFIED_SECUREANDMITIGATION_PROPOSEDis notstatus/FALSE_POSITIVEANDDUPLICATEis notproduction_viability. (Active findings are loaded regardless ofNON_VIABLEso this pass's fixes still appear; archived fixed findings are not re-listed every pass — use the optional "Resolved this campaign" rollup for a cumulative fixed view.)patch_status - Scale: process one directory at a time, newest-first; never load the whole archive at once.
- Severity Filtering: Exclude findings with a priority of from the main report body. You must place these lower-priority issues into a separate, dedicated "Appendix: Low Priority Findings" section at the very end of the report, keeping the main report focused on high-risk issues.
"LOW"
- Read all active
-
Extract Key Artifacts: For each reproduced finding, extract and format:
- Header Metadata: Title, ID (UUID), Inferred Exposure, Final Risk Score, and Qualitative Priority.
- Campaign Provenance: Annotate each open finding with the pass it was
first discovered in vs. the current pass (e.g.
), so carried-over findings are visible as such. First-seen = the lowest
discovered pass 2 · still open as of pass 7in the finding'spass_numberentries (or the pass_number of the lowest-numbered archive dir that contains it); current state = the copy you kept from the fold above.history - Duplicate Advisory: If the finding has a field (set by
possible_duplicate_ofwhen a cross-pass candidate was NOT_MATCHED), emit an advisory note:mantis-dedupeThis makes the advisory regression-pointer visible to the stakeholder.Possibly related to finding <UUID> (cross-pass candidate; snapshots differ — not confirmed duplicate). - Discovery Snapshot: Emit for the finding. If
Discovery Snapshot: <discovery_commit>is missing or empty, emitdiscovery_commit. Never omit or drop the finding because this field is absent.Discovery Snapshot: (legacy — not recorded) - Vulnerability Description & Impact: A clear explanation of the bug and the concrete impact on the system.
- Reproduction Evidence:
- The PoC script path () and execution command (
repro_file_path).run_command - A clean snippet of the stdout/stderr showing the successful exploit
trigger ().
repro_output - Evidence base: label the reproduction evidence with the snapshot it
was gathered on: . If
Evidence base: <repro_snapshot_id>is missing or empty, writerepro_snapshot_id. Do NOT assume it equals the header/pass snapshot.Evidence base: (not recorded)
- The PoC script path (
- Risk Rationale: The independent validation reasoning (), production viability reasoning (
reasoning), and outrage factor analysis (critic_reasoning).outrage_commentary - Remediation & Patch:
- The recommended mitigation strategy.
- The verified patch diff () and re-attack status to prove the fix is resilient.
patch_diff - Apply against: label the patch diff with the snapshot it applies to:
. If
Apply against: <patch_base_snapshot>is missing or empty, writepatch_base_snapshot. IfApply against: (not recorded)is present and differs from this finding'spatch_base_snapshot, add a one-line caution that the diff was generated against a different snapshot and may not apply cleanly to the discovery snapshot.discovery_commit
- PII & Secrets Redaction: Before writing any finding data (including
description, PoC script/command, and reproducer logs) to the report, you
must scan and redact any hardcoded API keys, tokens, credentials, PII
(names, emails, phone numbers), internal hostnames/domain names, and overly
weaponized payload parameters, replacing them with standard placeholders
like ,
<REDACTED_SECRET>,<REDACTED_PII>, or<REDACTED_INTERNAL_HOST>to ensure the report is safe for broader distribution.<REDACTED_PAYLOAD>
-
Generate Review Packet:
-
Report Header & Disclaimer: At the very top of the report (before the Executive Summary):Snapshot provenance banners — emit these BEFORE item 1 below, at the very top of the report, each as its own separated blockquote, in this order:a. Non-authoritative / HALT banner (3-state rule). Readfrom
active_snapshot. - Ifworkspace/.mantis_state.jsonis absent (MODE-OFF — noactive_snapshotwas requested, today's default): do NOT emit this banner. The run is byte-for-byte today's behavior; the report's--syncfindings and other verdicts are valid as today. Emitting a NON-AUTHORITATIVE banner here would contradict the verdicts the same run produces. - IfVERIFIED_SECUREIS present butactive_snapshotissnapshot_pinned(HALT mode): emit as the FIRST line of the report:falseOmit this banner when> **WARNING — NON-AUTHORITATIVE RESULTS:** The target could not be pinned to an immutable snapshot for this pass (HALT mode: the tree raced or was too big / live / copy-failed). Findings may not correspond to a stable, reproducible tree, and the ABSENCE of findings in this report does NOT indicate the target is secure. Treat all results as provisional.is absent (MODE-OFF) OR whenactive_snapshotisactive_snapshot.snapshot_pinned(PINNED).trueb. Dirty working tree warning. Ifisvcs_info.dirty, emit:true> **WARNING — DIRTY WORKING TREE:** The target had uncommitted local modifications when it was scanned. Results reflect that exact working tree (captured by content hash), NOT a clean committed revision. The recorded commit alone will not reproduce this state.c. Mixed-snapshot banner. Let HEADER_SID =. If HEADER_SID is present and non-empty AND any INCLUDED finding has aactive_snapshot.snapshot_idthat is missing, empty, or not string-equal to HEADER_SID, emit:discovery_commitCompare snapshot IDs as EXACT strings only — no fuzzy or prefix match.> **WARNING — MIXED SNAPSHOTS:** This report combines findings discovered on different code snapshots (e.g. findings retried from earlier passes). The pass snapshot is <HEADER_SID>. Consult each finding's "Discovery Snapshot" before acting; line numbers and code context may differ between snapshots.-
Display the target codebase version information read fromin
"vcs_info":workspace/.mantis_state.json- If is
"vcs_type", show:"git".Target Version: Git branch [branch] at commit [commit_hash] [(dirty) if dirty is true] - If is
"vcs_type", show:"hg".Target Version: Mercurial branch [branch] at revision [commit_hash] [(dirty) if dirty is true] - If is
"vcs_type", show:"multi-vcs".Target Version: Multi-VCS (repo) manifest [revision] [(dirty) if dirty is true] - If is
"vcs_type", show:"none".Target Version: None (No version control detected) - If is
"vcs_type", or if"unknown"is missing, show:vcs_info.Target Version: Unknown (VCS detection failed/error)
After theline, append the pass snapshot identity on a second line:Target Version:- If is present and non-empty, write:
active_snapshot.snapshot_id.Snapshot ID: [snapshot_id] (pinned: [snapshot_pinned]) - If is absent or
active_snapshotis empty, write:snapshot_id. This is display-only provenance; it does not gate or drop any finding.Snapshot ID: (legacy — snapshot not recorded)
- If
-
Include a prominent disclaimer note stating: “This report was automatically generated by Mantis AI. All findings and patches are AI-generated and must be manually verified by a security or subject matter expert before deployment or disclosure.”
-
-
Grouping by Patch Status (Exclusivity): Organize the Executive Summary table and the main body of the report by grouping findings. Exploit chains MUST be excluded from these main groups and reported ONLY in their dedicated "Exploit Chains (Not End-to-End Reproduced)" section. For standard (non-chain) findings, group them into three distinct categories based on their remediation status (strictly mutually exclusive):
- Category 1: Patch Independently Verified: Findings where
is
patch_status."VERIFIED_SECURE" - Category 2: Patch Proposed / Mitigation Identified: Findings where
is in
patch_statusOR (["MITIGATION_PROPOSED", "VERIFICATION_INCOMPLETE"]is present ANDpatch_diffis unset/empty).patch_status - Category 3: Unpatched / Verification Failed: Findings where
is in
patch_statusOR (["VERIFICATION_FAILED", "ERROR"]is not present ANDpatch_diffis unset/empty).patch_status
- Category 1: Patch Independently Verified: Findings where
-
Dedicated Exploit Chains Section: Create a dedicated section titledspecifically for exploit chains. Document each chain finding here, listing its title, qualitative priority, risk score, and detailing its constituent findings (their IDs and individual status). Do not mix exploit chains with standard findings in Categories 1, 2, or 3.
"Exploit Chains (Not End-to-End Reproduced)" -
Pass-Numbered Output: Do not overwrite the samefile on every execution. Instead, determine the current run/pass number
review_packet.mdof the pipeline (resolved fromNin"pass_number". If missing or invalid, scanworkspace/.mantis_state.jsonfor folders matchingworkspace/archive/orfindings_pass_Nand resolveloopN_findingstoN, defaulting to 1 if no archives exist). Then derivemax_found + 1from<snapshot_tag>: take the snapshot ID exactly as stored and replace every character NOT inactive_snapshot.snapshot_idwith a single underscore[A-Za-z0-9.-](do NOT truncate — the result stays well under any filename length limit). Write the report to:_- when
workspace/report/review_packet_pass_<N>_<snapshot_tag>.mdis present and non-empty (e.g.active_snapshot.snapshot_id). Thereview_packet_pass_1_content_9f86d081884c...mdsuffix guarantees a reused pass number run against a DIFFERENT snapshot writes a distinct file and cannot overwrite the earlier packet.<snapshot_tag> - (no suffix — exactly the legacy name) when
workspace/report/review_packet_pass_<N>.mdis absent oractive_snapshotis empty, preserving today's backward-compatible behavior.snapshot_id
-
Latest Copy/Symlink: After writing the pass-numbered report above, update a symlink or write a copy of THAT exact file (whether or not it carries asuffix) to
<snapshot_tag>, so the latest version is always reachable. Theworkspace/report/review_packet-latest.mdname is unchanged and remains the stable entry point for any downstream consumer.review_packet-latest.md -
Use clean, professional Markdown formatting with clear headers, tables for metadata, and syntax-highlighted code blocks for logs and diffs.
-
Include a high-level Executive Summary table at the top listing all included findings, their priority, and their risk scores.
-
Optional sections (recommended):
- Resolved this campaign: A short rollup using the same fold, but
filtering to findings where is
patch_statusorVERIFIED_SECURE. This gives stakeholders a visible "what got fixed" view alongside the open findings.MITIGATION_PROPOSED - Unresolved — retry cap reached: A callout listing open findings whose
reproduction attempt count is at the cap. The count is NOT a field on the
finding JSON; it lives in the cache file
, keyed by each finding's
state_root/workspace/archive/.repro_attempts.json(or, ifsignatureis absent, by its computedsignature=stable_key— same key selection asnormalized_title + "@" + primary_file_path). For each open finding in the working set, look up itsmantis-reproduce(orsignaturefallback) in that cache; include the finding in this callout if the cached value is at the retry cap. Read the cached value per the schema's value-shape rule: a bare integer V meansstable_key; an object means{count: V, last_snapshot: UNKNOWN}. If the cache file is missing or the finding's key is absent, treat its count as 0 (do not list it here). These are items the planner stopped carrying{count: V.count, last_snapshot: V.last_snapshot or UNKNOWN}
- Resolved this campaign: A short rollup using the same fold, but
filtering to findings where
[!NOTE] De-dup caveat: de-dup is by finding identity, per the SAME-BUG PREDICATE at the top of this stage: two findings fold only if EITHER (i) they share the exact same(UUID), OR (ii) ALL THREE hold — a shared non-emptyid, a shared non-emptylineage_id, AND at least one line-inclusivesignaturematch. NEVER fold oncode_pathsalone or onlineage_idalone (basename-derived lineage can link two distinct same-named files; asignaturestrips the line number so it collides between distinct same-file bugs) — collapsing on either alone can silently drop a real finding. A bug re-discovered under a new UUID that does NOT satisfy predicate (ii) — a regression, a file rename that shifts the line, or a non-deterministic re-find — lists as a SEPARATE entry from its archived ancestor: over-reporting (safe), never hiding. With stable finding signatures and lineage tracking landed (Phase 3), a re-discovered finding folds into its ancestor's single entry ONLY when predicate (ii) is fully satisfied; the UUID-only match remains the safe branch for legacy/un-upgraded findings.signature- is authoritative: Note that
review_packet-latest.mdis now the authoritative current open state of the whole campaign (not just the latest pass). The per-passreview_packet-latest.mdfiles remain as-is for historical reference.review_packet_pass_<N>_<snapshot_tag>.md
-
步骤0 — 定位器解析。
LOCATOR RESOLUTION (before reading ANY target code or artifact):
0. ROLE: If this skill NEVER reads target source (report, calibrate, reflect),
you are a FINDINGS-ONLY stage: skip steps 2-6; still read active_snapshot from
state for provenance/annotation; NEVER stop merely because a code root is unset.
1. Determine CODE_ROOT, in this priority order:
a. If --target_root is passed on THIS invocation, CODE_ROOT = --target_root.
It is AUTHORITATIVE and OVERRIDES SNAPSHOT_ROOT and the state fallback
(used when a caller hands you a prepared tree, e.g. a patched shadow).
b. Else if --snapshot_root (or SNAPSHOT_ROOT) is passed, use it.
c. Else read state_root/workspace/.mantis_state.json (state_root from
--state_root if passed, else ./workspace/... relative to the current dir)
-> active_snapshot.root / .snapshot_id / .snapshot_pinned.
d. Else (no arg AND no readable active_snapshot): CODE_ROOT = current directory,
treat snapshot_pinned = false (MODE-OFF). Do NOT stop.
2. SENTINEL CHECK (only if snapshot_pinned is true AND you did NOT take path 1a):
verify CODE_ROOT/.mantis_snapshot_id exists and equals SNAPSHOT_ID. If missing
or different -> STOP "snapshot sentinel mismatch". (A --target_root tree (1a) is
deliberately mutated and is sentinel-EXEMPT.)
3. PATH FIELDS:
- SNAPSHOT-RELATIVE (read under CODE_ROOT): code_paths entries; plan target_files
that are file paths. Strip ONLY a trailing ":<digits>". A code_paths entry
containing "://" is a URL/endpoint, NOT a file read. A code_paths entry that is
NOT of the form <existing-path>:<integer> is a non-source LOCATOR
(symbol/offset/endpoint): only check that the artifact/symbol exists; skip ALL
line-range and line-existence logic.
- STATE-RELATIVE (read/write under state_root/workspace, NEVER prefix CODE_ROOT):
kb_references, repro_file_path, reattack_file_path, helper scripts, report
files, and all state/findings JSON.
4. Never WRITE under CODE_ROOT when snapshot_pinned is true. Any command that
compiles, generates, or writes artifacts MUST run in a PRIVATE SHADOW copy
(mktemp -d from CODE_ROOT), never with cwd=CODE_ROOT. Read-only inspection may
cd into CODE_ROOT.
5. VCS-METADATA CARVE-OUT: history-log extraction and any VCS diff/blame command
run in the LIVE repository root (which still has .git/.hg/.repo), NOT CODE_ROOT
(the snapshot copy strips VCS metadata). Do NOT stop merely because CODE_ROOT
lacks .git/.hg/.repo.
6. Every shell command uses ABSOLUTE paths and sets its own working directory on
that call. Do NOT assume the working directory persists between calls.以下仅针对漏洞发现的说明适用于报告生成器:
- 报告生成器属于仅处理漏洞发现的阶段(Block A,角色步骤0):跳过定位器步骤2–6,不需要或解析CODE_ROOT,且绝不会因代码根或哨兵未设置而停止。
- 仍需从 读取
workspace/.mantis_state.json(active_snapshot、root、snapshot_id)和snapshot_pinned用于溯源——用于构建报告头、顶部横幅和输出文件名。vcs_info - 报告生成器接触的所有路径(、
workspace/findings/*.json、workspace/.mantis_state.json、workspace/report/*)均为状态相对路径,绝不会添加CODE_ROOT前缀。workspace/archive/*
编译一份专业的Markdown报告,详细说明已验证/复现的漏洞和利用链。
按以下步骤执行报告生成阶段:
-
加载漏洞发现 — 完整加载本次审查内容,加上遗留的未解决漏洞发现(按最新优先合并;无脚本)。 构建一个以漏洞发现ID为键的工作集,每个漏洞发现仅保留其最新状态:相同漏洞判定规则(适用于本阶段所有当前与归档漏洞发现的去重、合并和抑制;过度报告始终安全,隐藏真实漏洞绝不允许):两个漏洞发现属于同一漏洞,当且仅当(i)它们具有完全相同的(UUID);或(ii)同时满足以下三个条件——共享非空的
id、共享非空的lineage_id,且至少有一个包含行号的signature条目完全相同。否则它们为不同漏洞——需同时展示。绝不能仅通过code_paths或lineage_id就将两个漏洞发现视为同一漏洞:两者的粒度均大于漏洞的真实标识(基于文件名的lineage可能关联两个不同的同名文件;signature会去除行号,可能导致同一文件中的不同漏洞发生冲突),仅通过其中一个合并可能会静默丢弃真实漏洞。signature设计说明(重新锚定 vs 合并):的重新锚定(第二阶段)仅提供行提示以引导重新发现——不会重写遗留漏洞发现的mantis-plan。重新发现的漏洞会在当前快照的新行位置显示。由于合并规则要求包含行号的code_paths匹配,重新发现的漏洞不会与其祖先合并(行号不同)。这属于安全的过度报告——两个条目都会显示,当前条目展示新位置。未来阶段可在两个漏洞发现具有相同code_paths和signature且祖先的行在当前快照中已确认不存在时,放宽规则为仅路径匹配,但目前为防止静默丢弃风险,仍使用保守的包含行号的匹配规则。lineage_id- 读取所有活跃的,将每个活跃漏洞发现添加到工作集,以其
workspace/findings/*.json(UUID)为键——包含所有修复状态,因此本次审查中id/VERIFIED_SECURE的修复内容仍会在分类1/2中展示。绝不能合并两个活跃漏洞发现,即使它们共享MITIGATION_PROPOSED或lineage_id——每个活跃signature都作为独立条目保留。id - 按审查次数降序扫描(以及旧版
workspace/archive/findings_pass_<N>/)。仅当归档漏洞发现仍未解决(见步骤4),且工作集中没有与它属于同一漏洞的发现(按上述规则),且未添加过同一漏洞的更早(更高审查次数)归档副本时,才添加该归档漏洞发现。首次遇到的副本即为最新状态;忽略更低目录中同一漏洞的后续副本。(仅当存在真正的同一漏洞替代它时,才会抑制归档漏洞发现;仅loop<N>_findings/或lineage_id巧合不会抑制它。)signature - 替代合并(第三阶段): 当归档漏洞发现与当前漏洞发现属于同一漏洞(规则ii)时,当前漏洞发现替代它——仅显示当前(最新)状态的单个条目;不展示归档副本。当规则不满足时(不同的,例如文件重命名,或
signature缺失),将两者作为独立条目展示(安全的过度报告,绝不隐藏)。lineage_id- 防止漏报保障: 如果当前(替代)漏洞发现不满足可处理规则(以下步骤4),但归档祖先满足该规则(例如,祖先已且未解决,但当前审查的复现因新快照上的临时构建/环境失败而导致
reproduced),绝不能因临时降级而抑制已确认的未解决漏洞。相反,需在报告中保留祖先的最后确认状态(显示为“未解决——新快照上的复现待处理”),确保已确认的漏洞不会从报告中静默消失。当前漏洞发现的更新元数据(例如更新后的not_attempted行号)可作为注释附加,但显示的结论/状态必须是祖先的最后确认状态,而非临时降级后的状态。code_paths
- 防止漏报保障: 如果当前(替代)漏洞发现不满足可处理规则(以下步骤4),但归档祖先满足该规则(例如,祖先已
- 可处理/质量规则(适用于活跃和归档漏洞发现):仅当漏洞发现为利用链(存在,或标题/历史中包含“Exploit Chain”),或
constituent_findings为repro_status,或(reproduced为repro_status且带有实证执行证据——外部堆栈跟踪、Sanitizer跟踪(ASan/UBSan/MSan/TSan)或崩溃日志)时,才纳入报告。不纳入误报、statically_confirmed、NON_VIABLE、DUPLICATE或缺乏实证跟踪的普通failed_to_reproduce漏洞发现。statically_confirmed - 未解决规则(仅适用于步骤2中的归档遗留漏洞发现):归档漏洞发现“仍未解决”的条件是满足(4),且不是
patch_status/VERIFIED_SECURE,且MITIGATION_PROPOSED不是status/FALSE_POSITIVE,且DUPLICATE不是production_viability。(活跃漏洞发现无论NON_VIABLE如何都会加载,因此本次审查的修复内容仍会显示;已修复的归档漏洞发现不会在每次审查中重新列出——可使用可选的“本次周期已解决”汇总部分展示累计修复情况。)patch_status - 规模处理: 按最新优先顺序逐个目录处理;绝不一次性加载整个归档。
- 严重性过滤: 将优先级为的漏洞发现排除在报告主体之外。必须将这些低优先级问题放在报告末尾单独的“附录:低优先级漏洞发现”部分,确保报告主体聚焦于高风险问题。
"LOW"
- 读取所有活跃的
-
提取关键工件: 对于每个已复现的漏洞发现,提取并格式化以下内容:
- 头元数据: 标题、ID(UUID)、推断暴露面、最终风险评分和定性优先级。
- 审查周期溯源: 为每个未解决的漏洞发现标注首次发现的审查次数与当前审查次数(例如),以便清晰展示遗留漏洞发现。首次发现时间=漏洞发现
发现于审查2 · 截至审查7仍未解决条目中最低的history(或包含该漏洞发现的最低编号归档目录的pass_number);当前状态=上述合并后保留的副本。pass_number - 重复漏洞提示: 如果漏洞发现存在字段(当跨审查候选漏洞未匹配时由
possible_duplicate_of设置),需发出提示:mantis-dedupe这可让利益相关者看到该回归提示。可能与漏洞发现<UUID>相关(跨审查候选;快照不同——未确认重复)。 - 发现快照: 显示漏洞发现的。若
发现快照:<discovery_commit>缺失或为空,显示discovery_commit。绝不能因该字段缺失而省略或丢弃漏洞发现。发现快照:(旧版——未记录) - 漏洞描述与影响: 清晰说明漏洞内容及其对系统的具体影响。
- 复现证据:
- PoC脚本路径()和执行命令(
repro_file_path)。run_command - 展示成功触发漏洞的stdout/stderr干净片段()。
repro_output - 证据基准: 为复现证据标注其收集时的快照:。若
证据基准:<repro_snapshot_id>缺失或为空,写入repro_snapshot_id。请勿假设其等于报告头/审查快照。证据基准:(未记录)
- PoC脚本路径(
- 风险依据: 独立验证推理()、生产可行性推理(
reasoning)和严重程度分析(critic_reasoning)。outrage_commentary - 修复与补丁:
- 推荐的缓解策略。
- 已验证的补丁差异()和重新攻击状态,以证明修复有效。
patch_diff - 适用快照: 为补丁差异标注其适用的快照:。若
适用快照:<patch_base_snapshot>缺失或为空,写入patch_base_snapshot。若适用快照:(未记录)存在且与该漏洞发现的patch_base_snapshot不同,需添加一行提示,说明该差异是针对不同快照生成的,可能无法在发现快照上干净应用。discovery_commit
- PII与敏感信息脱敏: 在将任何漏洞发现数据(包括描述、PoC脚本/命令和复现日志)写入报告之前,必须扫描并脱敏任何硬编码的API密钥、令牌、凭证、PII(姓名、邮箱、电话号码)、内部主机名/域名和过度武器化的 payload 参数,替换为标准占位符如、
<REDACTED_SECRET>、<REDACTED_PII>或<REDACTED_INTERNAL_HOST>,确保报告可安全广泛分发。<REDACTED_PAYLOAD>
-
生成审查报告包:
-
报告头与免责声明: 在报告最顶部(执行摘要之前):快照溯源横幅——在以下第1项之前,放在报告最顶部,每个横幅作为独立的块引用,按以下顺序排列:a. 非权威/暂停横幅(三态规则)。 从读取
workspace/.mantis_state.json。- 若active_snapshot缺失(MODE-OFF——未请求active_snapshot,当前默认):不显示此横幅。本次运行与当前行为完全一致;报告中的--sync漏洞发现和其他结论均有效。在此处显示非权威横幅会与同一运行生成的结论矛盾。- 若VERIFIED_SECURE存在但active_snapshot为snapshot_pinned(暂停模式):在报告第一行显示:false当> **警告——非权威结果:** 本次审查无法将目标固定到不可变快照(暂停模式:代码树发生冲突或过大/活跃/复制失败)。漏洞发现可能与稳定、可复现的代码树不对应,报告中未发现漏洞并不代表目标是安全的。请将所有结果视为临时内容。缺失(MODE-OFF)或active_snapshot为active_snapshot.snapshot_pinned(已固定)时,省略此横幅。trueb. 脏工作树警告。 若为vcs_info.dirty,显示:true> **警告——脏工作树:** 扫描目标时存在未提交的本地修改。结果反映的是该精确工作树(由内容哈希捕获),而非干净的提交版本。仅记录的提交无法复现此状态。c. 混合快照横幅。 设HEADER_SID =。若HEADER_SID存在且非空,且任何纳入报告的漏洞发现的active_snapshot.snapshot_id缺失、为空或与HEADER_SID字符串不完全匹配,显示:discovery_commit仅按精确字符串比较快照ID——不使用模糊或前缀匹配。> **警告——混合快照:** 本报告整合了在不同代码快照上发现的漏洞发现(例如从过往审查重试的漏洞发现)。本次审查的快照为<HEADER_SID>。采取行动前请查看每个漏洞发现的“发现快照”;不同快照之间的行号和代码上下文可能不同。-
显示从的
workspace/.mantis_state.json读取的目标代码库版本信息:"vcs_info"- 若为
"vcs_type",显示:"git"。目标版本:Git分支[branch],提交[commit_hash] [(dirty) 若dirty为true] - 若为
"vcs_type",显示:"hg"。目标版本:Mercurial分支[branch],版本[commit_hash] [(dirty) 若dirty为true] - 若为
"vcs_type",显示:"multi-vcs"。目标版本:多版本控制系统(repo)清单[revision] [(dirty) 若dirty为true] - 若为
"vcs_type",显示:"none"。目标版本:无(未检测到版本控制) - 若为
"vcs_type",或"unknown"缺失,显示:vcs_info。目标版本:未知(版本控制检测失败/出错)
在行之后,添加第二行显示审查快照标识:目标版本:- 若存在且非空,写入:
active_snapshot.snapshot_id。快照ID:[snapshot_id] (已固定:[snapshot_pinned]) - 若缺失或
active_snapshot为空,写入:snapshot_id。这仅用于展示溯源信息,不会限制或丢弃任何漏洞发现。快照ID:(旧版——未记录快照)
- 若
-
添加醒目的免责声明:“本报告由Mantis AI自动生成。所有漏洞发现和补丁均为AI生成,部署或披露前必须经过安全或主题专家手动验证。”
-
-
按补丁状态分组(互斥): 将执行摘要表格和报告主体按漏洞发现分组。利用链必须排除在这些主要分组之外,仅在专门的“利用链(未端到端复现)”部分报告。 对于标准(非链)漏洞发现,根据其修复状态分为三个不同的类别(严格互斥):
- 类别1:补丁已独立验证:为
patch_status的漏洞发现。"VERIFIED_SECURE" - 类别2:已提出补丁/已识别缓解措施:属于
patch_status,或(存在["MITIGATION_PROPOSED", "VERIFICATION_INCOMPLETE"]且patch_diff未设置/为空)的漏洞发现。patch_status - 类别3:未打补丁/验证失败:属于
patch_status,或(不存在["VERIFICATION_FAILED", "ERROR"]且patch_diff未设置/为空)的漏洞发现。patch_status
- 类别1:补丁已独立验证:
-
专门的利用链部分: 创建一个标题为的专门部分,用于报告利用链。在此处记录每个链发现,列出其标题、定性优先级、风险评分,并详细说明其组成漏洞发现(ID和各自状态)。请勿将利用链与标准漏洞发现混合在类别1、2或3中。
"利用链(未端到端复现)" -
带审查次数的输出: 每次执行时不要覆盖同一个文件。相反,确定管道的当前运行/审查次数
review_packet.md(从N的workspace/.mantis_state.json解析。若缺失或无效,扫描"pass_number"中匹配workspace/archive/或findings_pass_N的文件夹,将loopN_findings解析为N,若无归档则默认值为1)。然后从max_found + 1派生active_snapshot.snapshot_id:按存储的快照ID原样保留,将所有不在<snapshot_tag>中的字符替换为单个下划线[A-Za-z0-9.-](不要截断——结果不会超过任何文件名长度限制)。将报告写入:_ -
当存在且非空时,写入
active_snapshot.snapshot_id(例如workspace/report/review_packet_pass_<N>_<snapshot_tag>.md)。review_packet_pass_1_content_9f86d081884c...md后缀可确保针对不同快照运行相同审查次数时,写入独立文件,不会覆盖之前的报告包。<snapshot_tag> -
当缺失或
active_snapshot为空时,写入snapshot_id(无后缀——与旧版名称完全一致),保留当前的向后兼容行为。workspace/report/review_packet_pass_<N>.md -
最新副本/符号链接: 写入上述带审查次数的报告后,更新符号链接或写入该文件的副本(无论是否带有后缀)到
<snapshot_tag>,以便始终可访问最新版本。workspace/report/review_packet-latest.md名称保持不变,仍是下游消费者的稳定入口。review_packet-latest.md -
使用清晰、专业的Markdown格式,包含明确的标题、元数据表格,以及日志和差异的语法高亮代码块。
-
在顶部包含高级执行摘要表格,列出所有纳入报告的漏洞发现、其优先级和风险评分。
-
可选部分(推荐):
- 本次周期已解决: 使用相同的合并规则,但过滤为
patch_status或VERIFIED_SECURE的漏洞发现的简短汇总。这可让利益相关者在查看未解决漏洞的同时,看到“已修复内容”的视图。MITIGATION_PROPOSED - 未解决——已达重试上限: 列出复现尝试次数达到上限的未解决漏洞发现的提示。次数不是漏洞发现JSON的字段;存储在缓存文件中,以每个漏洞发现的
state_root/workspace/archive/.repro_attempts.json为键(若signature缺失,则使用计算的signature=stable_key——与normalized_title + "@" + primary_file_path使用相同的键选择)。对于工作集中的每个未解决漏洞发现,在该缓存中查找其mantis-reproduce(或备用的signature);若缓存值达到重试上限,则将该漏洞发现纳入此提示。按架构的值形状规则读取缓存值:纯整数V表示stable_key;对象表示{count: V, last_snapshot: UNKNOWN}。若缓存文件缺失或漏洞发现的键不存在,将其次数视为0(不列入此处)。这些是审查计划停止重试的条目{count: V.count, last_snapshot: V.last_snapshot or UNKNOWN}
- 本次周期已解决: 使用相同的合并规则,但过滤
[!NOTE] 去重注意事项: 去重基于漏洞发现标识,遵循本阶段顶部的相同漏洞判定规则:两个漏洞发现仅在(i)共享完全相同的(UUID),或(ii)同时满足三个条件——共享非空的id、共享非空的lineage_id,且至少有一个包含行号的signature匹配时才会合并。绝不能仅通过code_paths或lineage_id合并(基于文件名的lineage可能关联两个不同的同名文件;signature会去除行号,可能导致同一文件中的不同漏洞发生冲突)——仅通过其中一个合并可能会静默丢弃真实漏洞。重新发现的漏洞若使用新UUID且不满足规则(ii)——回归、文件重导致行号变化、或非确定性重新发现——会作为独立条目与归档祖先并列:属于过度报告(安全),绝不隐藏。随着稳定的漏洞发现签名和lineage跟踪落地(第三阶段),重新发现的漏洞仅在完全满足规则(ii)时才会合并到其祖先的单个条目中;仅UUID匹配仍是旧版/未升级漏洞发现的安全分支。signature- 为权威版本: 注意
review_packet-latest.md现在是整个审查周期当前未解决状态的权威版本(不仅是最新审查)。带审查次数的review_packet-latest.md文件保持原样,作为历史参考。",review_packet_pass_<N>_<snapshot_tag>.md
-