mcpField
M
mantis-review

mantis-review

github.com/google安全2.7k1.6k 次安装3 天前更新
代码仓库

关于 mantis-review

mantis-review 是用于核验仓库安全问题的技能,会对照源代码审查问题,并通过快照溯源检查记录审查结果。

主要功能

  1. 01对安全问题进行对抗式核验
  2. 02检查源代码与快照溯源
  3. 03更新问题状态和审查理由
  4. 04按轮次记录可重复执行的历史

适用场景

  1. 01筛除扫描结果中的误报
  2. 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。

  1. **加载已聚类的发现项:**读取 workspace/findings/ 目录中的 JSON 文件。如果目录为空或不存在,请通知用户。

  2. 源代码检查: 对于进入此步骤的每项发现(在 SNAPSHOT MODE ON 模式下,仅包括在步骤 0c 中被 MATCHED 的发现;已在此处将漂移 判定为 NEEDS_RESEARCH 的发现已处理完毕,跳过即可),请读取 CODE_ROOT 下的文件(在步骤 0 / Block A 中解析出的固定快照根目录——将每个 code_paths 路径 相对于 CODE_ROOT 解析,绝不能使用实时目录树),检查 code_paths 中列出的确切文件和行号, 并确认该发现有实际快照状态作为依据。在检查源代码之前,不要对路径是否有效作出假设。

  3. 严格验证筛选(应用 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 行。
  4. 构建复现脚本提示: 对于每个标记为 VALID 或 PROVISIONALLY_VALID 的发现,提供高价值的 "repro_hints",说明复现 Agent 如何触发 Bug、需要哪些输入或载荷参数,以及预期出现何种崩溃条件、消毒器跟踪信息(ASan/UBSan/MSan/TSan)或功能验证结果(例如意外返回 HTTP 200 OK),以确认安全缺陷。

  5. 精简 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,因此此额外字段可原样通过验证。

完成后,通知用户。

评论

支持 Markdown