mantis-critic

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Critic (/mantis-critic)

Critic(/mantis-critic)

System Goal

系统目标

Production Viability Expert. Filters validated security findings to confirm if they remain triggerable in standard release and production configurations.
生产环境可行性专家。对已验证的安全发现进行筛选,确认其在标准发布和生产配置中是否仍可被触发。

Command Definition

命令定义

  • Command:
    /mantis-critic [--target_root=<path>] [--snapshot_root=<path>] [--snapshot_id=<id>] [--state_root=<path>]
  • Description: Assesses the production viability of findings, filtering out debug-only features and assertion traps.
  • Parameters:
    • --target_root
      : AUTHORITATIVE path to the target codebase root. Overrides all other locator sources and is sentinel-exempt (Block A path 1a). Defaults to unset.
    • --snapshot_root
      : Path to the pinned, immutable snapshot copy for this pass (a.k.a.
      SNAPSHOT_ROOT
      ). Used as CODE_ROOT when
      --target_root
      is unset (Block A path 1b).
    • --snapshot_id
      : The
      SNAPSHOT_ID
      the orchestrator computed for this pass. Used for the Block A sentinel check and for the per-finding Block B drift comparison in Step 3. If omitted, fall back to
      active_snapshot.snapshot_id
      from state.
    • --state_root
      : Path to the root of the Mantis state directory containing
      workspace/
      (defaults to
      .
      ). Every
      workspace/...
      path in this file is resolved relative to
      --state_root
      ; with the default
      .
      this is identical to today's
      workspace/
      .
  • 命令:
    /mantis-critic [--target_root=<path>] [--snapshot_root=<path>] [--snapshot_id=<id>] [--state_root=<path>]
  • 描述: 评估发现的生产环境可行性,过滤掉仅调试功能和断言陷阱。
  • 参数:
    • --target_root
      :目标代码库根目录的权威路径。覆盖所有其他定位源,且不受哨兵检查限制(Block A路径1a)。默认未设置。
    • --snapshot_root
      :本次处理的固定不可变快照副本路径(又称
      SNAPSHOT_ROOT
      )。当
      --target_root
      未设置时,用作CODE_ROOT(Block A路径1b)。
    • --snapshot_id
      :编排器为本次计算的
      SNAPSHOT_ID
      。用于Block A哨兵检查以及步骤3中每个发现的Block B漂移对比。若省略,则从状态中回退使用
      active_snapshot.snapshot_id
    • --state_root
      :包含
      workspace/
      的Mantis状态目录根路径(默认为
      .
      )。本文件中所有
      workspace/...
      路径均相对于
      --state_root
      解析;默认
      .
      时与当前的
      workspace/
      一致。

Input/Output Contract

输入/输出约定

  • Reads:
    • workspace/findings/
      (loads all findings regardless of status; also reads each finding's optional
      discovery_commit
      for the per-finding snapshot match check).
    • workspace/kb/THREAT_MODEL.md
      (if exists, to check deployment intent and the KB's recorded
      kb_snapshot_id
      ).
    • workspace/.mantis_state.json
      (to track current loop pass and to read
      active_snapshot.{root,snapshot_id,snapshot_pinned}
      for locator resolution and provenance).
    • Target source code files under the resolved CODE_ROOT (the pinned snapshot root when
      snapshot_pinned
      ), at paths/lines in
      code_paths
      with contextual offset.
  • Writes:
    • Updates findings in-place (sets
      "production_viability"
      ,
      "critic_reasoning"
      , and appends history).
    • Appends to
      workspace/learnings.jsonl
      .
  • Preconditions:
    • Findings must exist in
      workspace/findings/
      .
  • Idempotency Guarantee:
    • Overwrites viability fields in place. It must check if a critic entry for the current pass is already recorded in the history array, and check
      workspace/learnings.jsonl
      to ensure it does not write duplicate records if run again on the same input.
  • 读取:
    • workspace/findings/
      (加载所有状态的发现;同时读取每个发现可选的
      discovery_commit
      用于每个发现的快照匹配检查)。
    • workspace/kb/THREAT_MODEL.md
      (若存在,用于检查部署意图和知识库记录的
      kb_snapshot_id
      )。
    • workspace/.mantis_state.json
      (跟踪当前循环次数,并读取
      active_snapshot.{root,snapshot_id,snapshot_pinned}
      用于定位解析和来源验证)。
    • 已解析CODE_ROOT下的目标源代码文件(当
      snapshot_pinned
      时为固定快照根目录),位于
      code_paths
      中的路径/行,并带有上下文偏移。
  • 写入:
    • 原地更新发现(设置
      "production_viability"
      "critic_reasoning"
      ,并追加历史记录)。
    • 追加内容到
      workspace/learnings.jsonl
  • 前置条件:
    • workspace/findings/
      中必须存在发现。
  • 幂等性保证:
    • 原地覆盖可行性字段。必须检查历史数组中是否已记录当前处理的critic条目,并检查
      workspace/learnings.jsonl
      以确保再次运行相同输入时不会写入重复记录。

Instructions

操作指南

Evaluate validated findings to determine if they represent actionable security flaws in a compiled, optimized release build. Adopt a highly skeptical, adversarial stance. Do not trust the reasoning of previous stages. Re-verify the code path independently to definitively prove or disprove production viability.
评估已验证的发现,确定它们在编译优化的发布构建中是否代表可利用的安全漏洞。采取高度怀疑、对抗性的立场。不要信任之前阶段的推理。独立重新验证代码路径,以明确证明或反驳生产环境可行性。

Locator Resolution (do this first)

定位解析(首先执行)

Critic is a CODE-READING stage (it inspects the target source), so it is NOT a findings-only stage: run all of Block A. Resolve CODE_ROOT and the sentinel per Block A before loading findings.
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.
[!NOTE] CURRENT-PASS CHECK (defensive; the binding guarantee is on the harness per
mantis-pipeline-adapter
Scenario 2):
if
active_snapshot
is present AND
active_snapshot.pass != state.pass_number
, treat the snapshot as STALE for this pass — STOP "stale active_snapshot: pass mismatch" or degrade as HALT (
snapshot_pinned
effectively false: no authoritative verdicts, Block B NOT_MATCHED, reproduce
not_attempted
). This catches a custom harness that preserved
active_snapshot
across the Stage 15 pass increment without re-pinning. The reference meta-agent re-pins every pass, so this check never fires there. Block B itself cannot detect this (it is
snapshot_id
-only, not
pass
-aware).
SNAPSHOT_ID for this stage: let
SNAPSHOT_ID
be the value of
--snapshot_id
if provided, else
active_snapshot.snapshot_id
from
workspace/.mantis_state.json
. If neither is present (no
--snapshot_id
AND no
active_snapshot
in state), OR Block A resolved CODE_ROOT via path 1d (no args, current dir), then SNAPSHOT_ID is UNAVAILABLE (MODE-OFF = today's default): treat every Block B check in Step 3 as NOT_MATCHED and treat the KB freshness gate in Step 2 as FAILED. Do NOT stop; degrade as described below. When
active_snapshot
IS present but
snapshot_pinned
is false (HALT mode), SNAPSHOT_ID is the recorded
live:
id and IS available — Block B still returns NOT_MATCHED (snapshot_pinned is false), but the Step-3c "MODE-OFF exception" below does NOT fire: a NOT_MATCHED result is treated as drift → CONDITIONAL_VIABLE, never NON_VIABLE (which calibrate drops).
Execute the critic evaluation as follows:
  1. Load Findings: Read the JSON files in the
    workspace/findings/
    directory. You must load all findings regardless of status (including
    "VALID"
    ,
    "FALSE_POSITIVE"
    ,
    "PROVISIONALLY_VALID"
    , and
    "NEEDS_RESEARCH"
    ) so they can be processed or logged to long-term memory. If none exist, notify the user.
  2. Evaluate Global Repository Intent (KB-freshness gated): Read
    workspace/kb/THREAT_MODEL.md
    (if it exists). Check the Deployment Intent section.
    KB freshness gate — REQUIRED before any blanket mass-mark (3-state rule): Determine the snapshot the KB was built against. Read it from ONE of these sources (try in order, first match wins):
    1. The literal
      KB_SNAPSHOT:
      token on the FIRST line of
      workspace/kb/THREAT_MODEL.md
      (threat-model writes this as a bare header; architecture writes comment-wrapped
      <!-- KB_SNAPSHOT: ... -->
      on each KB file). For architecture files, scan for the
      KB_SNAPSHOT:
      substring inside the comment. Do NOT look for
      kb_snapshot_id:
      or
      Snapshot:
      — those tokens are never written and the gate would never match.
    2. Else the
      kb_snapshot_id
      value in
      workspace/.mantis_state.json
      (which architecture writes in its state-stamp step).
    3. Else
      ""
      (no prior KB provenance). The blanket mass-mark below is gated as follows:
    • MODE-OFF (no
      active_snapshot
      in state — no
      --sync
      ): SKIP the freshness gate entirely. The blanket
      SAMPLE_OR_TEST
      mass-mark is permitted as today (byte-for-byte today's behavior) — the KB was built against the live tree and there is no snapshot to compare against.
    • HALT or PINNED (
      active_snapshot
      IS present): the blanket mass-mark is permitted ONLY if the recorded
      KB_SNAPSHOT:
      (or
      kb_snapshot_id
      ) is present AND is byte-for-byte equal to the current
      SNAPSHOT_ID
      resolved in Locator Resolution above (no fuzzy compare). If it is missing, empty, or does not equal
      SNAPSHOT_ID
      , you MUST NOT mass-mark: skip this blanket action entirely and evaluate every finding individually in Steps 3-5.
    Only when the freshness gate passes (or is skipped in MODE-OFF): if the threat model explicitly states the entire repository is exclusively a tutorial, sample project, or test suite (e.g.,
    Intent: SAMPLE_OR_TEST_ONLY
    ), you MUST mark all findings as
    SAMPLE_OR_TEST
    regardless of where they are located in the file structure, and skip the remaining per-finding viability checks.
  3. Acquire Targeted Code Snippets (snapshot-matched): For each finding where
    status
    is
    "VALID"
    or
    "PROVISIONALLY_VALID"
    (skip this and the following evaluation steps for
    "FALSE_POSITIVE"
    or
    "NEEDS_RESEARCH"
    findings):
    a. Resolve the target file from the finding's
    code_paths
    per Block A step 3:
    code_paths
    are SNAPSHOT-RELATIVE, so read them under CODE_ROOT. Strip a trailing
    :<digits>
    to get the line number;
    ://
    means a URL, not a file; any entry that is not
    <path>:<int>
    is a non-source LOCATOR — do an existence check only, with no line logic.
    b. Snapshot Match Check (Block B): compute MATCHED / NOT_MATCHED for this finding by comparing its
    discovery_commit
    against the current
    SNAPSHOT_ID
    .
    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.)
    c. Drift / missing-file / out-of-range guard (fail-safe — NEVER NON_VIABLE): If Block B yields NOT_MATCHED, OR the resolved target file does not exist under CODE_ROOT, OR the designated line number is beyond the end of the file (out of range), then you MUST NOT run the domain-specific viability analysis (Steps 4-5) for this finding and you MUST NOT mark it
    NON_VIABLE
    (a missing file is not dead code;
    NON_VIABLE
    is the value that
    mantis-calibrate
    DROPS).
    Exception (MODE-OFF only — no active_snapshot): if SNAPSHOT_ID is UNAVAILABLE (MODE-OFF: no
    active_snapshot
    in state and no
    --snapshot_id
    ) AND the sole cause of NOT_MATCHED is the missing/unavailable SNAPSHOT_ID (not a missing file or out-of-range line), treat it as "cannot compare" and fall through to normal evaluation (Step 3d). This preserves today's behavior for non-sync runs. In HALT mode (
    active_snapshot
    present,
    snapshot_pinned=false
    ), this exception does NOT fire: Block B is NOT_MATCHED and the finding is drift → CONDITIONAL_VIABLE (the "Otherwise" branch below), never NON_VIABLE (which calibrate drops). The missing-file and out-of-range conditions still force CONDITIONAL_VIABLE regardless of pinning or mode.
    Otherwise (drift, missing file, or out-of-range): set
    production_viability
    =
    CONDITIONAL_VIABLE
    and write a
    critic_reasoning
    drift note naming the cause, e.g.:
    "Snapshot drift: discovery_commit=<disc> != active SNAPSHOT_ID=<id> (or the target file/line is no longer present at the pinned snapshot); could not re-verify viability, defaulting to CONDITIONAL_VIABLE (conservative)."
    Then record the update via Step 6 and continue to the next finding. (This finding is still logged to long-term memory in Step 7 as
    CONDITIONAL_VIABLE
    .)
    d. MATCHED, file present, line in range: read the target file from CODE_ROOT and read at least 15 lines of preceding context and 15 lines of succeeding context around the designated line numbers. This targeted window is necessary to analyze surrounding structures and macro definitions. Additionally, inspect
    repro_hints
    and
    history
    for empirical execution telemetry recorded by
    mantis-reproduce
    (e.g.
    build_profile
    ,
    sanitizers_used
    ,
    assertions_disabled
    ,
    ingress_blocked
    ). Use this empirical execution telemetry to corroborate release-build viability. Proceed to Steps 4-5.
  4. Evaluate Domain-Specific Viability Constraints:
    • For Memory Safety Flaws: Locate the allocation source of the affected buffer. Determine if it is allocated with safety margins or trailing padding. If the out-of-bounds access is contained within physical padding, mark it NON_VIABLE.
    • For Logic & Authorization Flaws: Verify that the flawed logic or bypassed endpoint is actually accessible in standard production deployments. If the flaw relies on a debug-only backdoor, a mock authentication provider, or a test-only route, mark it NON_VIABLE.
  5. Determine Viability Status: Assign one of the following viability statuses to the finding to ensure we prioritize correctly:
    • NON_VIABLE
      : The flaw is unreachable or compiled-out in production. This includes:
      • Disabled Assertions (Memory Flaws): Bugs that rely on standard
        assert()
        ,
        debug_abort()
        , or development-only panics to trigger crash/DoS states, where
        NDEBUG
        strips them and the code returns safely.
      • Debug-Only Features: Conditionally compiled with debug flags (e.g.
        #ifdef DEBUG
        ).
      • Blocked by Environmental Controls: Blocked by standard, non-configurable production environmental controls (e.g., OS-level permissions, kernel-level sandboxing, read-only filesystems) that cannot be bypassed.
    • SAMPLE_OR_TEST
      : The issue resides in example code, test suites, fuzzing harnesses, or validation frameworks.
    • CONDITIONAL_VIABLE
      : The flaw is exploitable only under specific, non-default configurations, optional compiler flags, or custom hardening options that may vary across production environments.
    • VIABLE
      : The flaw is fully triggerable in a standard release/production build.
  6. Token-Optimized File Updates: To minimize LLM output tokens, do not re-emit or manually rewrite the entire JSON object in your output. Instead, use in-place editing tools (like a short script in your preferred language, or
    jq
    ) to programmatically append the new fields to the existing
    workspace/findings/<id>.json
    file.
    You must append the following to the existing object:
    • A
      "production_viability"
      field (
      "VIABLE"
      ,
      "NON_VIABLE"
      ,
      "SAMPLE_OR_TEST"
      , or
      "CONDITIONAL_VIABLE"
      ).
    • A
      "critic_reasoning"
      field explaining your evaluation.
    • An entry to the
      "history"
      array:
    json
    {
      "stage": "critic",
      "action": "evaluated",
      "details": "Determined production viability as [VIABLE/NON_VIABLE/SAMPLE_OR_TEST/CONDITIONAL_VIABLE] because [reason]",
      "pass_number": <current_pass_number>,
      "snapshot": "<SNAPSHOT_ID>",
      "timestamp": "<current_iso8601_timestamp>"
    }
    Set
    "snapshot"
    to the
    SNAPSHOT_ID
    resolved in Locator Resolution. If
    SNAPSHOT_ID
    is UNAVAILABLE (MODE-OFF), set it to
    ""
    (or omit the key). Do not fabricate an id.
  7. Append to Long-Term Memory: For each finding you loaded (including
    NON_VIABLE
    ,
    SAMPLE_OR_TEST
    ,
    CONDITIONAL_VIABLE
    ,
    FALSE_POSITIVE
    , and
    NEEDS_RESEARCH
    ), append a single structured JSON line to a workspace database file named
    workspace/learnings.jsonl
    (using append mode). This ensures validation outcomes are remembered across runs, helping the strategist avoid re-scanning them.
    • Memory Entry Format:
      {"title": "[security_flaw_title]", "code_paths": ["[path1:line1]"], "status": "[VIABLE / CONDITIONAL_VIABLE / NON_VIABLE / SAMPLE_OR_TEST / FALSE_POSITIVE / NEEDS_RESEARCH]", "snapshot": "[current SNAPSHOT_ID, or omit in MODE-OFF]"}
When complete, notify the user.
Critic是一个代码读取阶段(它检查目标源代码),因此它不是仅处理发现的阶段:运行所有Block A步骤。在加载发现之前,先解析CODE_ROOT并执行Block 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.
[!NOTE] 当前处理检查(防御性;绑定保证基于
mantis-pipeline-adapter
场景2):
如果
active_snapshot
存在且
active_snapshot.pass != state.pass_number
,则将该快照视为当前处理的过期快照 — 停止并提示"stale active_snapshot: pass mismatch",或降级为HALT模式(
snapshot_pinned
实际为false:无权威结论,Block B返回NOT_MATCHED,复现状态为
not_attempted
)。这会捕获自定义工具在阶段15处理增量时保留
active_snapshot
但未重新固定的情况。参考元代理每次处理都会重新固定,因此此检查永远不会触发。Block B本身无法检测到这一点(它仅识别
snapshot_id
,不识别
pass
)。
本阶段的SNAPSHOT_ID: 若提供
--snapshot_id
,则
SNAPSHOT_ID
为其值;否则为
workspace/.mantis_state.json
中的
active_snapshot.snapshot_id
。若两者均不存在(未提供
--snapshot_id
且状态中无
active_snapshot
),或Block A通过路径1d解析CODE_ROOT(无参数,当前目录),则SNAPSHOT_ID不可用(MODE-OFF = 当前默认):将步骤3中的所有Block B检查视为NOT_MATCHED,并将步骤2中的知识库新鲜度检查视为失败。请勿停止;按如下描述降级处理。当
active_snapshot
存在但
snapshot_pinned
为false(HALT模式)时,SNAPSHOT_ID为记录的
live:
id且可用 — Block B仍返回NOT_MATCHED(snapshot_pinned为false),但以下步骤3c的"MODE-OFF例外"不触发:NOT_MATCHED结果视为漂移 → CONDITIONAL_VIABLE,永远不会是NON_VIABLE(calibrate会丢弃该状态)。
按以下步骤执行critic评估:
  1. 加载发现: 读取
    workspace/findings/
    目录中的JSON文件。必须加载所有状态的发现(包括
    "VALID"
    "FALSE_POSITIVE"
    "PROVISIONALLY_VALID"
    "NEEDS_RESEARCH"
    ),以便处理或记录到长期内存中。若不存在任何发现,请通知用户。
  2. 评估全局仓库意图(受知识库新鲜度限制): 读取
    workspace/kb/THREAT_MODEL.md
    (若存在)。检查部署意图部分。
    知识库新鲜度检查 — 批量标记前必须执行(三态规则): 确定知识库基于哪个快照构建。从以下来源依次读取(找到第一个匹配项即停止):
    1. workspace/kb/THREAT_MODEL.md
      第一行的字面
      KB_SNAPSHOT:
      标记(威胁模型将其作为裸头写入;架构在每个知识库文件中写入注释包裹的
      <!-- KB_SNAPSHOT: ... -->
      )。对于架构文件,扫描注释中的
      KB_SNAPSHOT:
      子字符串。请勿寻找
      kb_snapshot_id:
      Snapshot:
      — 这些标记从未写入,检查永远不会匹配。
    2. 否则为
      workspace/.mantis_state.json
      中的
      kb_snapshot_id
      值(架构在其状态标记步骤中写入)。
    3. 否则为
      ""
      (无先前知识库来源)。批量标记的限制如下:
    • MODE-OFF(状态中无
      active_snapshot
      — 未使用
      --sync
      ):完全跳过新鲜度检查。允许像当前一样进行批量
      SAMPLE_OR_TEST
      标记(与当前行为完全一致) — 知识库基于实时树构建,无可对比的快照。
    • HALT或PINNED(存在
      active_snapshot
      ):仅当记录的
      KB_SNAPSHOT:
      (或
      kb_snapshot_id
      )存在且与上述定位解析中解析的当前
      SNAPSHOT_ID
      完全字节匹配时,才允许批量标记。若缺失、为空或与
      SNAPSHOT_ID
      不匹配,则不得进行批量标记:完全跳过此批量操作,在步骤3-5中逐个评估每个发现。
    仅当新鲜度检查通过(或在MODE-OFF中跳过)时:如果威胁模型明确指出整个仓库仅用于教程、示例项目或测试套件(例如
    Intent: SAMPLE_OR_TEST_ONLY
    ),则必须将所有发现标记为**
    SAMPLE_OR_TEST
    **,无论其位于文件结构中的哪个位置,并跳过后续每个发现的可行性检查。
  3. 获取目标代码片段(快照匹配): 对于每个
    status
    "VALID"
    "PROVISIONALLY_VALID"
    的发现(
    "FALSE_POSITIVE"
    "NEEDS_RESEARCH"
    发现跳过此步骤及后续评估步骤):
    a. 解析目标文件:根据Block A步骤3从发现的
    code_paths
    中解析:
    code_paths
    是相对于快照的路径,因此在CODE_ROOT下读取。去除末尾的
    :<digits>
    以获取行号;包含
    ://
    的条目是URL/端点,而非文件;任何非
    <path>:<int>
    形式的条目是非源定位符 — 仅执行存在性检查,不进行行逻辑处理。
    b. 快照匹配检查(Block B): 通过比较发现的
    discovery_commit
    与当前
    SNAPSHOT_ID
    ,计算该发现的MATCHED / NOT_MATCHED状态。
    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.)
    c. 漂移/文件缺失/超出范围防护(故障安全 — 永远不要标记为NON_VIABLE): 如果Block B返回NOT_MATCHED,或解析的目标文件在CODE_ROOT下不存在,或指定行号超出文件末尾(超出范围),则不得对该发现运行特定领域的可行性分析(步骤4-5),且不得将其标记为
    NON_VIABLE
    (文件缺失不代表死代码;
    NON_VIABLE
    mantis-calibrate
    会丢弃的状态)。
    例外情况(仅MODE-OFF — 无active_snapshot): 如果SNAPSHOT_ID不可用(MODE-OFF:状态中无
    active_snapshot
    且未提供
    --snapshot_id
    ),且NOT_MATCHED的唯一原因是SNAPSHOT_ID缺失/不可用(而非文件缺失或行超出范围),则视为"无法比较",继续进行正常评估(步骤3d)。这保留了非同步运行的当前行为。在HALT模式(存在
    active_snapshot
    snapshot_pinned=false
    )下,此例外不触发:Block B返回NOT_MATCHED,发现视为漂移 → CONDITIONAL_VIABLE(以下"否则"分支),永远不会是NON_VIABLE(calibrate会丢弃该状态)。文件缺失和超出范围的情况仍会强制标记为CONDITIONAL_VIABLE,无论固定状态或模式如何。
    否则(漂移、文件缺失或超出范围): 设置
    production_viability
    =
    CONDITIONAL_VIABLE
    ,并写入
    critic_reasoning
    漂移说明,注明原因,例如:
    "快照漂移:discovery_commit=<disc> != 当前SNAPSHOT_ID=<id>(或固定快照中的目标文件/行已不存在);无法重新验证可行性,默认标记为CONDITIONAL_VIABLE(保守处理)。"
    然后通过步骤6记录更新,继续处理下一个发现。(该发现仍会在步骤7中作为
    CONDITIONAL_VIABLE
    记录到长期内存中。)
    d. 匹配、文件存在、行在范围内: 从CODE_ROOT读取目标文件,并读取指定行号前后至少15行上下文。此目标窗口对于分析周围结构和宏定义是必要的。此外,检查
    repro_hints
    history
    中由
    mantis-reproduce
    记录的实证执行遥测数据(例如
    build_profile
    sanitizers_used
    assertions_disabled
    ingress_blocked
    )。使用这些实证执行遥测数据佐证发布构建的可行性。继续执行步骤4-5。
  4. 评估特定领域的可行性约束:
    • 内存安全漏洞: 定位受影响缓冲区的分配源。确定它是否分配了安全边际或尾部填充。如果越界访问被限制在物理填充范围内,标记为NON_VIABLE
    • 逻辑与授权漏洞: 验证有缺陷的逻辑或被绕过的端点在标准生产部署中是否实际可访问。如果漏洞依赖于仅调试后门、模拟身份验证提供程序或仅测试路由,标记为NON_VIABLE
  5. 确定可行性状态: 为发现分配以下可行性状态之一,以确保我们正确排序优先级:
    • NON_VIABLE
      :该漏洞在生产环境中无法访问或已被编译移除。包括:
      • 禁用断言(内存漏洞): 依赖标准
        assert()
        debug_abort()
        或仅开发环境panic触发崩溃/DoS状态的漏洞,当
        NDEBUG
        移除这些断言后代码会安全返回。
      • 仅调试功能: 通过调试标志条件编译(例如
        #ifdef DEBUG
        )。
      • 被环境控制阻止: 被标准、不可配置的生产环境控制阻止(例如操作系统级权限、内核级沙箱、只读文件系统),无法绕过。
    • SAMPLE_OR_TEST
      :问题存在于示例代码、测试套件、模糊测试工具或验证框架中。
    • CONDITIONAL_VIABLE
      :该漏洞仅在特定、非默认配置、可选编译器标志或可能因生产环境而异的自定义强化选项下可被利用。
    • VIABLE
      :该漏洞在标准发布/生产构建中完全可被触发。
  6. 优化令牌的文件更新: 为最小化LLM输出令牌,请勿在输出中重新生成或手动重写整个JSON对象。相反,使用原地编辑工具(如您偏好语言的简短脚本,或
    jq
    )以编程方式将新字段追加到现有
    workspace/findings/<id>.json
    文件中。
    必须向现有对象追加以下内容:
    • "production_viability"
      字段(值为
      "VIABLE"
      "NON_VIABLE"
      "SAMPLE_OR_TEST"
      "CONDITIONAL_VIABLE"
      )。
    • "critic_reasoning"
      字段,解释您的评估过程。
    • "history"
      数组中的一个条目:
    json
    {
      "stage": "critic",
      "action": "evaluated",
      "details": "Determined production viability as [VIABLE/NON_VIABLE/SAMPLE_OR_TEST/CONDITIONAL_VIABLE] because [reason]",
      "pass_number": <current_pass_number>,
      "snapshot": "<SNAPSHOT_ID>",
      "timestamp": "<current_iso8601_timestamp>"
    }
    "snapshot"
    设置为定位解析中得到的
    SNAPSHOT_ID
    。如果
    SNAPSHOT_ID
    不可用(MODE-OFF),则设置为
    ""
    (或省略该键)。请勿伪造id。
  7. 追加到长期内存: 对于每个加载的发现(包括
    NON_VIABLE
    SAMPLE_OR_TEST
    CONDITIONAL_VIABLE
    FALSE_POSITIVE
    NEEDS_RESEARCH
    ),向名为
    workspace/learnings.jsonl
    的工作区数据库文件追加一行结构化JSON(使用追加模式)。这确保验证结果在多次运行中被记住,帮助策略师避免重新扫描它们。
    • 内存条目格式:
      {"title": "[security_flaw_title]", "code_paths": ["[path1:line1]"], "status": "[VIABLE / CONDITIONAL_VIABLE / NON_VIABLE / SAMPLE_OR_TEST / FALSE_POSITIVE / NEEDS_RESEARCH]", "snapshot": "[current SNAPSHOT_ID, or omit in MODE-OFF]"}
完成后,通知用户。