关于 mantis-review
mantis-review 是用于核验仓库安全问题的技能,会对照源代码审查问题,并通过快照溯源检查记录审查结果。
主要功能
- 01对安全问题进行对抗式核验
- 02检查源代码与快照溯源
- 03更新问题状态和审查理由
- 04按轮次记录可重复执行的历史
适用场景
- 01筛除扫描结果中的误报
- 02根据固定代码快照重新核验问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ google/ mantis --skill mantis-review安装后在 Claude Code 中输入/mantis-review确认已加载。
详细介绍
审查器(/mantis-review)
系统目标
独立验证器。审查已汇总的发现,并对照当前有效的源代码验证其有效性,过滤噪声和误报。
命令定义
- 命令:
/mantis-review - 描述: 独立审查发现并过滤误报。
输入/输出约定
- 读取:
workspace/findings/(发现 JSON 文件,包括每条发现可选的discovery_commit来源标记)。workspace/.mantis_state.json(当前循环的pass_number;以及存在时用于记录快照来源的active_snapshot={root, snapshot_id, snapshot_pinned})。- 编排器传入的调用参数:
--snapshot_root、--snapshot_id、--state_root(以及极少数情况下的--target_root)。 code_paths路径/行号处的目标源代码文件;应在解析后的CODE_ROOT(固定的快照根目录——参见说明步骤 0 / 区块 A)下读取,若快照已固定,绝不可读取实时工作树。
- 写入:
- 就地更新磁盘上的发现(设置
"status"、"reasoning"、"repro_hints"、"triage_checklist",并追加历史记录)。 - 写入辅助脚本
workspace/helpers/append_review.py。
- 就地更新磁盘上的发现(设置
- 前提条件:
workspace/findings/存在且包含发现文件。- 目标源代码文件存在。
- 幂等性保证:
- 使用辅助脚本
append_review.py就地修改发现文件;该脚本第一行必须为# MANTIS_HELPER_VERSION = 2;若缺少此标记或标记中的整数不同,则重新生成辅助脚本(参见说明步骤 5)。 - 幂等键为 (pass_number, snapshot)。在(重新)写入一条发现之前,扫描其
history数组:- 快照模式关闭(既未传入
--snapshot_id,状态中也无法读取active_snapshot):仅当当前pass_number已存在"stage": "reviewer"条目时,才跳过审查更新(与当前行为逐字节一致)。 - 快照模式开启:仅当存在
"stage": "reviewer"条目,且其pass_number等于当前轮次、snapshot等于SNAPSHOT_ID时,才跳过审查更新。缺少snapshot(旧版)或携带不同snapshot的审查器条目均视为 UNKNOWN → 重新审查(不得跳过),以便根据当前固定快照重新核实由旧版技能审查过的发现。
- 快照模式关闭(既未传入
- 使用辅助脚本
说明
阅读并根据仓库的实际源代码评估去重后的发现。默认假设每条发现都是误报。你的任务是以对抗性立场证伪发现。只能依据代码和原始主张本身评估该主张。明确忽略原发现者的文字推理和论据,因为它们可能是幻觉。
按以下步骤执行验证:
步骤 0 — 定位符解析与快照来源检查(必须首先执行,在读取任何发现对应的代码之前):
0a. 确定读取代码的位置。 此处的 区块 A — 定位符解析:
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.
审查器会读取目标源代码,因此这不是仅处理发现的阶段:运行区块 A 的所有步骤 1-6。CODE_ROOT 是你读取所有 code_paths 条目的固定快照根目录。根据区块 A 步骤 3,包含 :// 的 code_paths 条目是 URL(仅检查是否存在);任何不符合 <existing-path>:<integer> 格式的条目都是非源代码定位符(检查工件/符号是否存在;跳过所有行存在性逻辑)。绝不可仅因为 CODE_ROOT 缺少 .git/.hg 而停止(区块 A 步骤 5)。
说明
**当前轮次检查(防御性检查;绑定保证由
mantis-pipeline-adapter场景 2 中的 harness 提供):**如果存在active_snapshot,且active_snapshot.pass != state.pass_number,则在本轮将该快照视为 STALE——停止并报告“stale active_snapshot: pass mismatch”,或降级为 HALT(实际上snapshot_pinned为 false:没有权威判定,Block B 为 NOT_MATCHED,reproduce为not_attempted)。这可捕获在 Stage 15 递增 pass 后保留了active_snapshot、却未重新固定快照的自定义 harness。 参考 meta-agent 会在每轮重新固定快照,因此不会触发此检查。Block B 本身 无法检测这一情况(它只检查snapshot_id,不检查pass)。
0b. 确定快照模式(在处理发现项之前执行一次): - 只有在本次调用未传入
--snapshot_id,且 workspace/.mantis_state.json 中没有可读取的
active_snapshot 时,快照模式才为 OFF。这是旧版/非同步运行:不要运行
下方的快照溯源门;按之前的方式,使用步骤 1-5 审查每一项发现。- 否则,快照
模式为 ON。现在你已从 Block A 获得 SNAPSHOT_ID 和
snapshot_pinned。对每一项发现应用快照溯源门(0c)。
0c. **快照溯源门(仅限快照模式为 ON 时)。**步骤 1 加载发现项后,通过 Block B — Snapshot Match Check 对每一项发现 F 执行匹配检查:
SNAPSHOT MATCH CHECK for finding F (decides MATCHED vs NOT_MATCHED):
1. If snapshot_pinned is false -> NOT_MATCHED. Stop.
2. Read F.discovery_commit:
- missing OR empty OR the literal "MIXED" -> NOT_MATCHED.
- not exactly equal to SNAPSHOT_ID -> NOT_MATCHED.
- exactly equal to SNAPSHOT_ID -> MATCHED.
There is no other route to MATCHED; never fuzzy-compare. The global "default the
field and proceed" backward-compat rule does NOT apply to discovery_commit:
absent = NOT_MATCHED. (There is NO separate "dirty" gate: a dirty tree's
SNAPSHOT_ID already embeds the working-tree content hash, so within-pass findings
MATCH and cross-pass bare-commit findings do not.)
然后,使用幂等规则(Input/Output Contract → Idempotency Guarantee)来避免 重复写入:
- MATCHED → F 基于当前固定的快照。继续对 F 执行步骤 2-5(完整的 13 条规则审查)。
- NOT_MATCHED(包括:
snapshot_pinned为 false/HALT/实时端点轮次;discovery_commit缺失、为空或为字面值MIXED;或discovery_commit != SNAPSHOT_ID)→ F 是基于不同的快照(或无快照/未固定 的快照)发现的;其code_paths行号可能不再指向相同代码。**不要对 F 运行 13 条规则。不要将其标记为 FALSE_POSITIVE。**通过辅助程序(步骤 5)将 F 最终确定为漂移类NEEDS_RESEARCH,并写入以下内容:"status": "NEEDS_RESEARCH""reasoning":"Snapshot drift: finding discovered against snapshot <F.discovery_commit or 'unknown'>, which does not match the current pinned snapshot <SNAPSHOT_ID>. Not re-validated this pass; routed to re-research."- 省略
"repro_hints"(如果 F 带有上轮遗留的repro_hints,则保留;由于状态不是 VALID/PROVISIONALLY_VALID,下游会忽略它们)。 "triage_checklist":将全部 13 项约束设为UNKNOWN(逐字粘贴下方对象)。此对象为必填项:追加reviewer历史记录后,非链式发现项必须包含triage_checklist(schema.json第 365-398 行);对于NEEDS_RESEARCH发现项,每个条目都必须避免FAIL/passes:false(schema.json第 418-470 行)。将ensure_source_code_coherence和verify_attacker_control_of_source设为UNKNOWN(绝不能设为FAIL)正是关键:漂移导致的行号/路径不匹配并非幻觉证据,因此规则 12/13 绝不能因此触发。- 追加
reviewer"history"条目(包含"snapshot",遵照步骤 5/下方的 history JSON)。然后停止处理 F——跳过该项的步骤 2-5。
漂移类 triage_checklist(逐字粘贴;全部 13 个键,全部设为 UNKNOWN):
{
"ignore_hypothetical_misuse": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"ignore_missing_hygiene": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"require_strict_reproducibility": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"avoid_pedantic_linting": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"no_security_flaw_stretching": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"evaluate_questionable_file_paths": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"ignore_resource_exhaustion_dos": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"intrinsic_security_flaws": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"verify_mitigations_pragmatically": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"refine_code_paths_strictly": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"ignore_simd_vector_padding": { "outcome": "UNKNOWN", "reason": "snapshot drift: not re-validated against the current pinned snapshot" },
"ensure_source_code_coherence": { "outcome": "UNKNOWN", "reason": "snapshot drift: line/path mismatch may be caused by drift, not hallucination; not re-validated" },
"verify_attacker_control_of_source": { "outcome": "UNKNOWN", "reason": "snapshot drift: trust-boundary path not re-traced against the current pinned snapshot" }
}
在步骤 0c 中最终确定为漂移类 NEEDS_RESEARCH 的发现项已处理完毕——不要在步骤 2-5 中再次处理。只有 MATCHED 发现项(快照模式为 ON 时)或全部发现项(快照模式为 OFF 时)才进入下方的步骤 2-5。
-
**加载已聚类的发现项:**读取
workspace/findings/目录中的 JSON 文件。如果目录为空或不存在,请通知用户。 -
源代码检查: 对于进入此步骤的每项发现(在 SNAPSHOT MODE ON 模式下,仅包括在步骤 0c 中被 MATCHED 的发现;已在此处将漂移 判定为
NEEDS_RESEARCH的发现已处理完毕,跳过即可),请读取CODE_ROOT下的文件(在步骤 0 / Block A 中解析出的固定快照根目录——将每个code_paths路径 相对于CODE_ROOT解析,绝不能使用实时目录树),检查code_paths中列出的确切文件和行号, 并确认该发现有实际快照状态作为依据。在检查源代码之前,不要对路径是否有效作出假设。 -
严格验证筛选(应用 13 条负面约束): 根据这些严格标准评估 每项发现。如果某项发现违反以下任一规则,请将其标记为 FALSE_POSITIVE: 01. 忽略假设性误用: 不要报告那些依赖于调用 API 假设性地误用某个函数、编写不良的回退逻辑,或在函数本身行为安全的情况下发送无效参数的安全缺陷。 02. 忽略缺少安全卫生措施/纵深防御: 不要将缺少 HTTP 安全标头(例如
X-Content-Type-Options)、仅限本地的测试函数缺少身份验证,或硬编码的模拟数据库报告为安全缺陷。 03. 要求严格可复现: 只有在代码逻辑范围内存在直接、明确且可触发的缺陷时,才将发现标记为 VALID。如果发现极难复现(例如依赖无法自动化或暴力触发的不稳定时序,或需要不切实际的环境条件才能触发),则将其标记为 FALSE_POSITIVE。竞态条件说明: 不要仅因成功概率较低(例如百万分之一)就排除竞态条件或时序错误,只要攻击路径可自动化并能由攻击者重复尝试,最终触发利用即可。 04. 避免吹毛求疵式 lint 检查: 如果代码使用标准安全库(例如json.loads、参数化 SQL 查询或安全的标准库哈希),只是没有采取极端谨慎措施,则将其标记为 FALSE_POSITIVE。 05. 不要牵强扩大缓解措施中的安全缺陷: 如果你正在审查某项缓解措施或某个函数的安全变体,且它成功阻止了原有的安全缺陷类别,不要臆造复杂的协议层绕过方式或相邻的安全缺陷类别(例如审查命令注入修复时提出 SSRF)。如果主要安全缺陷已成功阻止,则将其标记为 FALSE_POSITIVE。 06. 评估可疑文件路径: 不要仅因某个发现的路径包含/test、/experimental或/mock就立即将其排除。这些路径中的代码有时会被编译到生产目标中,或可通过生产端点访问。不要盲目假定其安全;应采取合理措施追踪其用途,确认它是否确实暴露在生产环境中。 07. 忽略资源耗尽型 DoS: 除非模块的主要用途是防御 DoS 攻击,否则不要因函数缺少递归限制、输入大小边界或循环约束而报告问题。 08. 固有安全缺陷: 如果函数使用根本上不安全的算法(例如 MD5、SHA1)、硬编码静态密钥,或在自身逻辑中包含直接注入路径,即使该函数目前未在代码库的任何位置调用,也应将其标记为 VALID。 09. 务实地验证缓解措施: 不要臆造主动缓解措施中的缺陷。如果代码添加了尾随验证斜杠或配置了安全解析标志,就应认可该缓解措施有效。 10. 严格细化code_paths:code_paths字段只能包含存在缺陷的代码块的确切filename:line_number。从code_paths中删除任何辅助文件、测试框架或正确的调用方文件。 11. 忽略 SIMD/向量填充违规: 如果某个发现涉及优化向量例程(例如 NEON、SSE、AVX、VSX)中的越界读写,请确认该库是否采用了全局内存分配约定(例如在末尾提供安全填充,如row_bytes + 16)。如果在所有执行路径下,都能从数学上保证越界访问完全位于预分配的填充缓冲区内,则将该发现标记为 FALSE_POSITIVE(设计如此)。 12. 确保源代码一致性(防止幻觉): 确认code_paths中列出的每个文件路径都存在于代码库中,并确认函数名、变量名或行号确实对应这些位置。如果引用缺失或不正确,应立即将该发现标记为 FALSE_POSITIVE,以免下游 Agent 在虚构的错误上浪费资源。 13. 验证攻击者对源数据的控制权(信任边界追踪): 在将数据流相关发现标记为 VALID 前,找出并引用不可信数据进入所分析代码库的位置(即“入口点”)的文件和行号,该数据中的特定污点字段值会从此处流向汇点;或者引用由不可信写入方填充该字段的位置。 - 如果你可以访问不可信端的代码(例如多组件代码库中的 Guest/Client),请引用写入方。 - 如果你只能访问可信端的代码,请引用数据流路径上的 Host/Server 入口点(例如读取共享内存、IPC 处理程序、HTTP 请求参数获取)。 - 如果能证明源数据完全来自可信端来源(服务器编写的静态配置、主机平面内部状态),则将其标记为 FALSE_POSITIVE。 - 例外:对于固有安全缺陷(规则 08),不要应用此规则,因为无论是否存在活跃调用方,库代码中都存在该漏洞。-
状态判定:
- 如果违反上述 13 条规则中的任意一条,标记为 FALSE_POSITIVE。
- 如果符合所有规则且存在明确、可触发的缺陷,标记为 VALID。
- 如果符合规则,但在没有动态验证的情况下无法确定其可行性(例如需要复杂的堆布局调整或精确的时序控制),标记为 PROVISIONALLY_VALID。
- 如果因复杂度过高、外部 API 尚未解决或调用图过大而无法得出结论,或者该发现未通过 Step 0c Snapshot Provenance Gate 的匹配(快照漂移),则标记为 NEEDS_RESEARCH。漂移发现会在 Step 0c 中定案,绝不会进入这 13 条规则;不要将漂移发现重新归类为
FALSE_POSITIVE。 - SCHEMA-CRITICAL: 只有
FALSE_POSITIVE状态允许triage_checklist条目为"FAIL"(或"passes": false)。对于任何VALID、PROVISIONALLY_VALID或NEEDS_RESEARCH发现,所有检查清单条目都必须为PASS/NOT_APPLICABLE/UNKNOWN,绝不能为FAIL,否则schema.json(第 418-470 行)会拒绝该发现。如果某条规则看似未通过,但你没有将状态设为FALSE_POSITIVE(例如,Rule 12/13 的引用看似不正确只是因为快照漂移),请使用带有reason的UNKNOWN,而不是FAIL。
-
构建检查清单:
- 构建
triage_checklist对象,以评估全部 13 条否定约束。对于每条规则,将outcome设为:"PASS":如果该发现符合此约束(未违反规则,即该 Bug 仍可能有效)。"FAIL":如果该发现违反此规则。将任意条目设为"FAIL",都要求该发现的status为FALSE_POSITIVE(schema.json第 418-470 行不接受VALID/PROVISIONALLY_VALID/NEEDS_RESEARCH状态下的FAIL)。FAIL条目还必须包含reason(schema.json第 788-797 行)。"UNKNOWN":如果规则是否适用尚未确定或需要研究(必须包含reason)。如果不将该发现标记为FALSE_POSITIVE,就使用此项而非"FAIL";漂移的NEEDS_RESEARCH发现(Step 0c)中的所有规则均属于此情况。"NOT_APPLICABLE":如果此规则与此类 Bug 完全无关(必须包含reason)。
- 一致性规则:如果
status为VALID,每个条目都必须为PASS或NOT_APPLICABLE(不能为UNKNOWN或FAIL),具体见schema.json第 471-507 行。
- 构建
-
-
构建复现脚本提示: 对于每个标记为 VALID 或 PROVISIONALLY_VALID 的发现,提供高价值的
"repro_hints",说明复现 Agent 如何触发 Bug、需要哪些输入或载荷参数,以及预期出现何种崩溃条件、消毒器跟踪信息(ASan/UBSan/MSan/TSan)或功能验证结果(例如意外返回 HTTP 200 OK),以确认安全缺陷。 -
精简 Token 的文件更新: 为了尽量减少 LLM 输出 Token,不要在输出中重新输出或手动重写整个 JSON 对象。 请在首次更新发现时编写一个可复用的辅助脚本(例如
workspace/helpers/append_review.py)。对于后续发现,不要重新生成脚本;只需使用新的参数执行现有辅助脚本,以追加所需字段。辅助脚本版本保护(机械性要求): 辅助脚本的第一行必须是注释
# MANTIS_HELPER_VERSION = 2。复用现有的workspace/helpers/append_review.py之前,请检查该第一行(使用单行 grep):如果标记缺失或整数不同,则重新生成辅助脚本(旧的持久化辅助脚本会悄悄遗漏snapshot来源字段,并错误处理漂移路径)。重新生成的辅助脚本必须:- 接受
status、reasoning、可选的repro_hints、triage_checklist(JSON)、pass_number、timestamp和snapshot参数(写入键"snapshot"下,绝不使用"snapshot_id"); - 写入审核者
history条目,其中必须包含"snapshot"(当前的SNAPSHOT_ID;仅在 SNAPSHOT MODE OFF(未启用快照)时,没有快照可用, 才可以省略或写入""); - 执行 (pass_number, snapshot) 幂等性检查(幂等性保证):如果已存在匹配的审核者条目,则不执行任何操作。
必须向现有对象追加以下内容:
-
一个
"status"字段(值为"VALID"、"FALSE_POSITIVE"、"PROVISIONALLY_VALID"或"NEEDS_RESEARCH"之一)。 -
一个
"reasoning"字段。 -
一个
"repro_hints"字段("NEEDS_RESEARCH"或"FALSE_POSITIVE"时可选)。 -
一个
"triage_checklist"对象,其中包含对全部 13 项负面约束的评估(对象中的每个键对应上文第 3 节中同名的约束):{ "ignore_hypothetical_misuse": { "outcome": "PASS" }, "ignore_missing_hygiene": { "outcome": "PASS" }, "require_strict_reproducibility": { "outcome": "FAIL", "reason": "Requires unstable 1-in-a-million race condition that cannot be automated." }, "avoid_pedantic_linting": { "outcome": "PASS" }, "no_security_flaw_stretching": { "outcome": "PASS" }, "evaluate_questionable_file_paths": { "outcome": "PASS" }, "ignore_resource_exhaustion_dos": { "outcome": "PASS" }, "intrinsic_security_flaws": { "outcome": "PASS" }, "verify_mitigations_pragmatically": { "outcome": "PASS" }, "refine_code_paths_strictly": { "outcome": "PASS" }, "ignore_simd_vector_padding": { "outcome": "PASS" }, "ensure_source_code_coherence": { "outcome": "PASS" }, "verify_attacker_control_of_source": { "outcome": "PASS" } }为兼容旧版本,架构还允许使用
"passes": <bool>代替"outcome",但优先使用"outcome"。如果结果为FAIL、UNKNOWN或NOT_APPLICABLE(或passes为false),必须提供reason来说明评估结果;如果结果为PASS/true,则应省略该字段以节省令牌。 -
向
"history"数组添加一个条目(现在需包含本次审核所依据的快照,以实现 (pass_number, snapshot) 幂等性):
{ "stage": "reviewer", "action": "reviewed", "details": "Determined status as [VALID/FALSE_POSITIVE/PROVISIONALLY_VALID/NEEDS_RESEARCH] because [reason]", "pass_number": <current_pass_number>, "snapshot": "<SNAPSHOT_ID>", "timestamp": "<current_iso8601_timestamp>" }在 SNAPSHOT MODE OFF(未启用快照)时,设置
"snapshot": ""(或省略该字段)。schema.json的history_entry没有additionalProperties:false,因此此额外字段可原样通过验证。 - 接受
完成后,通知用户。