mantis-architecture

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Architect (/mantis-architecture)

架构工具(/mantis-architecture)

System Goal

系统目标

Knowledge Base Synthesizer. Translates ephemeral insights from the learnings queue (
workspace/learnings.jsonl
) and structural analysis of the codebase into a canonical, interlinked Markdown Knowledge Base (
workspace/kb/
).
知识库合成器。将学习队列(
workspace/learnings.jsonl
)中的临时见解以及代码库的结构分析结果转换为标准化、相互关联的Markdown知识库(
workspace/kb/
)。

Command Definition

命令定义

  • Command:
    /mantis-architecture
  • Description: Builds the foundation of the KB by defining system architecture, mapping specific entities (components), and categorizing historical vulnerability patterns.
  • Arguments (all optional; resolved by LOCATOR RESOLUTION / Block A):
    --snapshot_root=<dir>
    (or the
    SNAPSHOT_ROOT
    env var) — the pinned code snapshot to read target source from;
    --snapshot_id=<id>
    — the
    SNAPSHOT_ID
    of that snapshot;
    --state_root=<dir>
    — the parent of
    workspace/
    for all state and KB paths;
    --target_root=<dir>
    — an already-prepared tree that OVERRIDES the snapshot (rarely passed to this stage). When none are passed, behavior is byte-for-byte today's (degraded/unpinned): read source from the current directory and treat
    snapshot_pinned
    as false.
  • 命令:
    /mantis-architecture
  • 描述: 通过定义系统架构、映射特定实体(组件)和分类历史漏洞模式,构建知识库的基础。
  • 参数(均为可选;由定位器解析/模块A处理):
    --snapshot_root=<dir>
    (或
    SNAPSHOT_ROOT
    环境变量)——用于读取目标源码的固定代码快照;
    --snapshot_id=<id>
    ——该快照的
    SNAPSHOT_ID
    --state_root=<dir>
    ——所有状态和知识库路径的
    workspace/
    父目录;
    --target_root=<dir>
    ——已准备好的目录树,将覆盖快照(此阶段极少传入)。若未传入任何参数,则默认读取当前目录的源码,并将
    snapshot_pinned
    视为false。

Input/Output Contract

输入/输出约定

  • Reads:
    • workspace/learnings.jsonl
      (raw insights from the current round).
    • workspace/historical_learnings.jsonl
      (optional, past vulnerability metadata).
    • Codebase directory structure and key source files.
    • Existing Markdown files in
      workspace/kb/
      (to validate/decay check).
    • workspace/.mantis_state.json
      (to retrieve pass count).
    • workspace/.mantis_state.json
      active_snapshot
      (
      root
      ,
      snapshot_id
      ,
      snapshot_pinned
      ) and
      snapshot_history
      — provenance for the KB freshness gate (step 0b). Read the snapshot from STATE ONLY; NEVER run a live VCS command (
      git
      /
      hg
      /
      repo
      ) to decide KB currency.
    • workspace/.mantis_state.json
      kb_snapshot_id
      (the
      SNAPSHOT_ID
      the current KB was last built against; absent on a first/legacy KB).
    • workspace/.mantis_state.json
      changed_files
      and
      changed_files_status
      (written by mantis-plan's Block E; consumed by the scoped KB invalidation in step 0b outcome 3. Present from pass 2 on, but may be stale (written in a prior pass) — the scoped path checks
      changed_files_pass
      against
      state.pass_number
      and falls back to full rebuild if they differ.)
  • Writes:
    • Markdown files under
      workspace/kb/
      (
      architecture.md
      ,
      entities/[component_name].md
      ,
      vulnerabilities/[CWE-ID].md
      ,
      index.md
      ).
    • workspace/kb/dependencies.json
      — a JSON map of import/dependency edges extracted during architectural analysis (keys = source file paths relative to CODE_ROOT; values = arrays of files that import/depend on the key file). This is consumed by
      mantis-plan
      's dependency-aware fan-out (Phase 2). If the codebase has no parseable import structure, write
      {}
      . Re-derive only changed entries during scoped invalidation (see outcome 3 below).
    • Archives
      workspace/learnings.jsonl
      to
      workspace/archive/learnings/learnings_pass_${N}_${X}.jsonl
      .
    • A
      <!-- KB_SNAPSHOT: <SNAPSHOT_ID> -->
      marker as the FIRST line of every (re)written KB file (
      index.md
      , each
      entities/*.md
      , each
      vulnerabilities/*.md
      ), plus
      kb_snapshot_id
      =
      SNAPSHOT_ID
      in
      workspace/.mantis_state.json
      .
    • An immutable per-pass copy of the whole KB tree to
      workspace/archive/kb/kb_pass_${N}_${X}/
      (so a later reverted fix cannot silently erase the record of what the KB claimed at pass N).
  • Preconditions:
    • workspace/learnings.jsonl
      must exist.
  • Idempotency Guarantee:
    • Transactional: moves
      workspace/learnings.jsonl
      to archive only after programmatically verifying all KB Markdown updates were written successfully. KB files are overwritten in-place.
    • Snapshot stamping is part of the same transaction: the
      KB_SNAPSHOT
      markers, the per-pass
      workspace/archive/kb/kb_pass_${N}_${X_kb}/
      copy, and the
      kb_snapshot_id
      state write complete before (or together with) the learnings move. On any failure, leave
      workspace/learnings.jsonl
      intact.
  • 读取内容:
    • workspace/learnings.jsonl
      (当前轮次的原始见解)。
    • workspace/historical_learnings.jsonl
      (可选,历史漏洞元数据)。
    • 代码库目录结构和关键源码文件。
    • workspace/kb/
      中的现有Markdown文件(用于验证/过期检查)。
    • workspace/.mantis_state.json
      (用于获取轮次计数)。
    • workspace/.mantis_state.json
      active_snapshot
      root
      snapshot_id
      snapshot_pinned
      )和
      snapshot_history
      ——知识库新鲜度检查(步骤0b)的来源信息。仅从状态中读取快照;切勿运行实时版本控制命令(
      git
      /
      hg
      /
      repo
      )来判断知识库是否最新。
    • workspace/.mantis_state.json
      kb_snapshot_id
      (当前知识库最后构建时对应的
      SNAPSHOT_ID
      ;首次/旧版知识库可能不存在此值)。
    • workspace/.mantis_state.json
      changed_files
      changed_files_status
      (由mantis-plan的模块E写入;由步骤0b结果3中的范围化知识库失效处理使用。从第2轮次开始存在,但可能已过期(由之前轮次写入)——范围化路径检查会将
      changed_files_pass
      state.pass_number
      对比,若不一致则回退到全量重建。)
  • 写入内容:
    • workspace/kb/
      下的Markdown文件(
      architecture.md
      entities/[component_name].md
      vulnerabilities/[CWE-ID].md
      index.md
      )。
    • workspace/kb/dependencies.json
      ——架构分析期间提取的导入/依赖关系JSON映射(键为相对于CODE_ROOT的源码文件路径;值为导入/依赖该键文件的文件数组)。供
      mantis-plan
      的依赖感知扩散(第2阶段)使用。若代码库无可解析的导入结构,则写入
      {}
      。范围化失效期间仅重新推导变更的条目(见下方结果3)。
    • workspace/learnings.jsonl
      归档至
      workspace/archive/learnings/learnings_pass_${N}_${X}.jsonl
    • 在每个(重新)写入的知识库文件(
      index.md
      、每个
      entities/*.md
      、每个
      vulnerabilities/*.md
      )的第一行添加
      <!-- KB_SNAPSHOT: <SNAPSHOT_ID> -->
      标记,并在
      workspace/.mantis_state.json
      中设置
      kb_snapshot_id
      =
      SNAPSHOT_ID
    • 将整个知识库目录树的不可变轮次副本保存至
      workspace/archive/kb/kb_pass_${N}_${X}/
      (确保后续回退的修复无法静默擦除第N轮次知识库的记录)。
  • 前置条件:
    • workspace/learnings.jsonl
      必须存在。
  • 幂等性保证:
    • 事务性:仅在通过程序验证所有知识库Markdown更新成功写入后,才将
      workspace/learnings.jsonl
      移至归档。知识库文件将被原地覆盖。
    • 快照标记属于同一事务:
      KB_SNAPSHOT
      标记、每轮次的
      workspace/archive/kb/kb_pass_${N}_${X_kb}/
      副本,以及
      kb_snapshot_id
      的状态写入,均在学习成果移动之前(或同时)完成。若出现任何失败,保留
      workspace/learnings.jsonl
      不变。

Instructions

操作说明

Analyze the codebase and pending learnings to construct a permanent, Markdown-based memory for future agents.
Execute the architecture stage as follows:
  1. LOCATOR RESOLUTION (Block A, inlined below):
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.
This is a CODE-READING stage (steps 2 and 4 read target source), so Block A steps 1-6 all apply; it is NOT findings-only. Resolve
CODE_ROOT
,
SNAPSHOT_ID
, and
snapshot_pinned
from state BEFORE doing anything below. Per Block A step 3, all
workspace/kb/...
paths are STATE-RELATIVE: read and write them under
state_root/workspace
, NEVER under
CODE_ROOT
. Read all target source under
CODE_ROOT
. Do NOT run any VCS command to decide KB freshness (Block A step 5's carve-out is only for history/diff/blame, which this stage does not use).
0b. KB SNAPSHOT FRESHNESS GATE (mechanical; STATE + KB marker only, NO live VCS):
- `CUR` = `SNAPSHOT_ID` (resolved by Block A; the empty string if
  `active_snapshot` was absent). `PINNED` = `snapshot_pinned` (false if absent).
- **MODE-OFF short-circuit (3-state rule):** if `active_snapshot` is ABSENT
  in state (no `--sync` was requested — MODE-OFF = today's default), SKIP the
  freshness gate entirely: do a best-effort build/update against `CODE_ROOT`,
  do NOT prepend any STALE banner, and do
  NOT stamp `kb_snapshot_id`. This is byte-for-byte today's behavior. (Only
  HALT and PINNED run the gate below.)
- `KB_ID` = the `kb_snapshot_id` value in `.mantis_state.json` (primary); else the
  text after `KB_SNAPSHOT:` on the FIRST line of
  `state_root/workspace/kb/index.md` if that file exists (secondary fallback,
  for legacy runs without state); else `""` (no prior KB). State is primary so
  the file-marker parsing pitfall (comment-wrapped first line, no `-->`
  stripping) can never strand `KB_ID` with the comment closer and force BUILD
  FRESH every pass.
- Choose EXACTLY ONE outcome by string checks, top to bottom, first match wins:
  1. `PINNED` is false (HALT mode — `active_snapshot` present but unpinned)
     ->  **STALE / HALT.** Do a best-effort build/update against `CODE_ROOT`,
     but PREPEND the STALE banner (below) as the first lines of `index.md`.
     Do NOT claim currency: leave the
     banner in place. Set `kb_snapshot_id` = `CUR` (a `live:` id).
  2. Else `KB_ID` == `CUR` (both non-empty)  ->  **CURRENT.** Do the incremental
     update + decay-check (step 4) as today. Re-stamp `KB_SNAPSHOT: CUR` on
     every (re)written file. REMOVE any STALE banner previously prepended to
     `index.md`.
  3. Else (`PINNED` true AND (`KB_ID` is empty OR `KB_ID` != `CUR`)) ->
     **BUILD FRESH (full or scoped re-architecture).** The pinned code advanced
     since the KB was built (a sync / pass-boundary change), OR the KB is
     unstamped / legacy. Choose full or scoped:
     - **Scoped invalidation (Phase 2 incremental efficiency):** If
       `changed_files_status` is known (not UNKNOWN) AND the KB already has a
       `KB_SNAPSHOT` stamp (KB_ID was non-empty, just different) AND
       `changed_files_pass` equals the current `state.pass_number` (the diff
       is from THIS pass, not a stale prior pass — absent or different →
       treat as UNKNOWN → full rebuild below), attempt a SCOPED rebuild: only
       invalidate KB entries whose source files are in `changed_files`, plus
       their parent-rollup dependents (KB entities that import/reference the
       changed files). Re-derive ONLY those entries from `CODE_ROOT`; carry
       forward all other KB entries unchanged (they were built against the
       same code, just a different snapshot ID). Re-stamp `KB_SNAPSHOT: CUR`
       on every (re)written file.
        - **Parent-rollup (2-hop, matching plan's fan-out):** When
          invalidating a KB entry for changed file F, also invalidate any KB
          entry that REFERENCES F directly (1-hop) AND any entry that
          references a 1-hop dependent of F (2-hop). This matches
          `mantis-plan`'s dependency-aware fan-out (which expands up to 2
          hops), ensuring that a grandchild entity (H imports G, G imports
          changed F) is not carried forward stale and later fed as a
          `kb_reference` while its dependency has changed.
       - **Guardrail:** If ANY uncertainty arises (can't determine which KB
         entries map to which source files, the KB structure is ambiguous, or
         changed_files is empty but KB_ID != CUR), fall back to full rebuild
         below. Never carry forward a stale entry for a changed file.
     - **Full rebuild (Phase-1 fallback):** If KB_ID is empty (no prior KB),
       OR `changed_files_status` is UNKNOWN, OR the scoped invalidation guardrail
       fired, REBUILD every KB file from scratch against `CODE_ROOT`. Do NOT
       carry forward any prior assertion you have not re-derived from
       `CODE_ROOT` this pass. Stamp `KB_SNAPSHOT: CUR`. REMOVE any STALE banner.
- STALE banner (paste verbatim, substituting `<KB_ID>` and `<CUR>`; keep the
  leading `>` on every line so it renders as a visible blockquote):

  ```
  > **STALE KB WARNING — do not trust without re-verifying.**
  > snapshot_pinned=false, or the KB was built against a different snapshot.
  > KB_SNAPSHOT=<KB_ID> does not match active_snapshot.snapshot_id=<CUR>.
  > Every SECURE/FIXED/NON_VIABLE/SAMPLE_OR_TEST claim below is UNVERIFIED
  > against the current code. Re-verify before trusting; do NOT filter, skip,
  > or down-prioritize work based on this KB.
  ```
  1. Read the Inbox (
    workspace/learnings.jsonl
    and
    workspace/historical_learnings.jsonl
    ):
    • Parse the contents of
      workspace/learnings.jsonl
      (and
      workspace/historical_learnings.jsonl
      if it exists). Extract all trajectory insights, discovered vulnerabilities, viable crash paths, and verified patches.
  2. Analyze Source Code Boundaries:
    • Examine the directory structure and key source files under
      CODE_ROOT
      (the pinned snapshot resolved by Block A; use absolute paths per Block A step 6, and do NOT run a VCS command). Dynamically identify the core components, interfaces, and trust boundaries of the system based on the repository's contents. This applies broadly across domains: whether it is a software system (e.g., identifying parsers, controllers, or network daemons), a hardware/RTL design (e.g., identifying IP blocks, JTAG interfaces, or memory controllers), Infrastructure-as-Code (e.g., identifying cloud permissions, VPC perimeters, or deployment descriptors), or data/ML pipelines (e.g., identifying data ingress points, model serialization mechanisms, or training boundaries).
  3. Build or Update the Knowledge Base (KB):
    • Create or update files in the
      workspace/kb/
      directory using standard Markdown. Follow these strict paths:
      • workspace/kb/architecture.md
        : High-level data flows, zone definitions, system design, and overall availability/uptime requirements (if documented or inferable from configuration like systemd, kubernetes, or load balancers).
      • workspace/kb/entities/[component_name].md
        : Specific definitions for components (e.g.,
        auth_module.md
        ). Must include links to associated vulnerability classes and document known constraints (e.g., "This module sanitizes input X"). Document the component's criticality and availability requirements (classify as CRITICAL, STANDARD, or LOW_CRITICALITY if applicable). Incorporate trajectory insights here.
      • workspace/kb/vulnerabilities/[CWE-ID_or_BugClass].md
        : Descriptions of bug classes (e.g.,
        CWE-79.md
        or
        Memory-Corruption.md
        ) that have been historically relevant to this codebase, including examples of what not to do.
      • workspace/kb/index.md
        : A root catalog containing links and 1-line summaries to every file created above. This is the map the Planner will read.
    • Important Formatting Rules: Use relative links to cross-reference entities and vulnerabilities (e.g.,
      [Auth Module](entities/auth_module.md)
      ). Ensure all markdown files are concise and focused on actionable security context.
    • Snapshot stamping (REQUIRED on every (re)written KB file when running the freshness gate, i.e. HALT or PINNED; never in MODE-OFF): Make the FIRST line of
      index.md
      , each
      entities/*.md
      , and each
      vulnerabilities/*.md
      exactly
      <!-- KB_SNAPSHOT: <SNAPSHOT_ID> -->
      (substitute
      CUR
      from step 0b; it is an HTML comment so it does not render). This is how the next pass's freshness gate (step 0b) detects drift. MODE-OFF gate (3-state rule): if
      active_snapshot
      is ABSENT (MODE-OFF — no
      --sync
      was requested), do NOT stamp the per-file
      KB_SNAPSHOT
      marker:
      CUR
      is the empty string (
      arch:145
      : "the empty string if
      active_snapshot
      was absent"), so the mandated marker would be
      <!-- KB_SNAPSHOT:  -->
      (empty value) — a snapshot-era artifact that did not exist in Phase 1. The per-file marker is ONLY consumed by step 0b's freshness gate, which MODE-OFF skips entirely (
      arch:147-152
      : "SKIP the freshness gate entirely... This is byte-for-byte today's behavior. Only HALT and PINNED run the gate below."). This MODE-OFF gate mirrors the freshness gate logic below and step 0b's outcome clauses, which mention per-file
      KB_SNAPSHOT: CUR
      stamping only in HALT/PINNED outcomes (CURRENT
      :164
      , scoped BUILD FRESH
      :178
      , full BUILD FRESH
      :195
      ).
    • Per-file
      KB_SNAPSHOT
      stamping is the sole provenance mechanism for KB assertions.
      Do NOT write per-assertion
      (AS_OF:<snapshot>)
      tags — the
      AS_OF
      re-verification reader was never built, and staleness protection is already provided by the freshness gate (step 0b) comparing
      kb_snapshot_id
      to
      SNAPSHOT_ID
      , plus per-finding
      discovery_commit
      (enforced by
      mantis-critic
      Block B). A later-reverted fix is caught by these mechanisms, not by per-assertion tags.
  4. Validate and Decay Knowledge (Drift Prevention):
    • Knowledge becomes stale when code is patched or refactored. Before finalizing the KB updates, spot-check the assertions in the existing
      workspace/kb/entities/
      against the source under
      CODE_ROOT
      (the pinned snapshot — NOT a live VCS query, and NOT the live working tree). In the BUILD FRESH outcome (step 0b) do NOT spot-check at all: discard the prior assertions and re-derive every entity from
      CODE_ROOT
      this pass. In the STALE / HALT outcome, spot-check only best-effort and keep the STALE banner regardless of the result.
    • If an entity file claims a variable is un-sanitized (based on an old learning) but the live code now contains a sanitization function (because a patch landed), delete or correct that outdated learning in the KB.
    • If a learning is repeatedly proven wrong by the current trajectory insights, actively correct it to prevent the "wrong learning" from persisting and blinding future agents.
    • When you correct or re-confirm a finding-derived assertion, re-stamp the
      KB_SNAPSHOT
      marker on that KB file.
  5. Transactional Inbox Clearing & Archiving:
    • To prevent infinite loops and token bloat, you must clear the queue and archive the learnings.
    • Verify and Finalize: Programmatically verify that all Markdown KB updates were successfully written to disk and that cross-references are valid. Also verify, before committing, that every (re)written KB file BEGINS with its
      <!-- KB_SNAPSHOT: <SNAPSHOT_ID> -->
      marker and that every finding-derived verdict is grounded in the current
      SNAPSHOT_ID
      .
    • Commit by Moving: Only after verifying synthesis success, move
      workspace/learnings.jsonl
      to the archive directory:
      • Ensure the target directory exists (e.g.,
        mkdir -p workspace/archive/learnings/
        ).
      • Determine the loop pass number
        N
        by reading
        "pass_number"
        from
        workspace/.mantis_state.json
        . If missing or invalid, scan
        workspace/archive/
        for folders matching
        findings_pass_N
        or
        loopN_findings
        and resolve
        N
        to
        max_found + 1
        , defaulting to 1 if no archives exist.
      • Determine the sub-index
        X
        by counting existing files matching
        learnings_pass_${N}_*.jsonl
        in
        workspace/archive/learnings/
        and adding 1.
      • Move the file:
        mv workspace/learnings.jsonl workspace/archive/learnings/learnings_pass_${N}_${X}.jsonl
        .
    • Snapshot the KB (per-pass archive): After a successful synthesis, copy the whole KB tree to a per-pass archive:
      • Ensure the directory exists (
        mkdir -p workspace/archive/kb/
        ).
      • Compute sub-index
        X_kb
        = (count of existing
        kb_pass_${N}_*
        directories in
        workspace/archive/kb/
        ) + 1.
      • Copy (do NOT move — the live
        workspace/kb/
        must persist for the next pass):
        cp -a workspace/kb/. workspace/archive/kb/kb_pass_${N}_${X_kb}/
        .
    • Stamp state: Write
      kb_snapshot_id
      =
      SNAPSHOT_ID
      (
      CUR
      from step 0b) into
      workspace/.mantis_state.json
      . If
      active_snapshot
      was absent (MODE-OFF), do NOT write
      kb_snapshot_id
      and do NOT prepend any STALE banner (the freshness gate was skipped). In HALT mode, write
      kb_snapshot_id
      =
      CUR
      and leave the STALE banner in
      index.md
      .
    • If synthesis fails or is interrupted, leave
      workspace/learnings.jsonl
      intact in its original location to ensure no data is lost.
    • If
      workspace/learnings.jsonl
      is ABSENT on entry (e.g. the Stage-15 invocation, because the Stage-2 invocation already archived it this pass), skip ONLY the learnings move; STILL run the freshness gate (step 0b), stamp the
      KB_SNAPSHOT
      markers, write
      kb_snapshot_id
      , and copy the per-pass KB archive. KB provenance must be recorded on every invocation.
When complete, notify the user.
分析代码库和待处理的学习成果,为后续Agent构建永久的Markdown格式记忆库。
按以下步骤执行架构阶段:
  1. 定位器解析(模块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.
此阶段为代码读取阶段(步骤2和4读取目标源码),因此模块A的步骤1-6均适用;并非仅处理结果。在执行以下操作前,先从状态中解析
CODE_ROOT
SNAPSHOT_ID
snapshot_pinned
。根据模块A步骤3,所有
workspace/kb/...
路径均为状态相对路径:在
state_root/workspace
下读取和写入,切勿在
CODE_ROOT
下操作。所有目标源码均从
CODE_ROOT
读取。切勿运行任何版本控制命令来判断知识库新鲜度(模块A步骤5的例外仅适用于历史/差异/ blame操作,此阶段不涉及)。
0b. 知识库快照新鲜度检查(自动化;仅依赖状态+知识库标记,不使用实时版本控制):
- `CUR` = `SNAPSHOT_ID`(由模块A解析;若`active_snapshot`不存在则为空字符串)。`PINNED` = `snapshot_pinned`(若不存在则为false)。
- **MODE-OFF短路(三态规则):** 若状态中不存在`active_snapshot`(未请求`--sync`——MODE-OFF为当前默认),则完全跳过新鲜度检查:针对`CODE_ROOT`进行最佳努力的构建/更新,不添加任何过期横幅,也不标记`kb_snapshot_id`。此行为与当前的字节级操作完全一致。(仅HALT和PINNED模式会运行下方的检查。)
- `KB_ID` = `.mantis_state.json`中的`kb_snapshot_id`值(优先);若文件存在,则为`state_root/workspace/kb/index.md`第一行中`KB_SNAPSHOT:`后的文本(次要回退,适用于无状态的旧版运行);否则为`""`(无先前知识库)。状态优先可避免文件标记解析陷阱(注释包裹第一行、未去除`-->`)导致`KB_ID`包含注释闭合符,进而强制每轮次都重新构建。
- 通过字符串检查从上到下选择恰好一个结果,第一个匹配项生效:
  1. `PINNED`为false(HALT模式——存在`active_snapshot`但未固定)
     ->  **过期 / HALT**。针对`CODE_ROOT`进行最佳努力的构建/更新,但在`index.md`的开头添加以下过期横幅。不声明知识库为最新:保留横幅。设置`kb_snapshot_id` = `CUR`(`live:`类型的ID)。
  2. 否则`KB_ID` == `CUR`(均非空) ->  **最新**。执行增量更新+过期检查(步骤4),与当前流程一致。在每个(重新)写入的文件上重新标记`KB_SNAPSHOT: CUR`。移除之前添加到`index.md`的任何过期横幅。
  3. 否则(`PINNED`为true 且 (`KB_ID`为空 或 `KB_ID` != `CUR`)) ->
     **重新构建(全量或范围化架构重建)**。固定的代码自知识库构建以来已更新(同步/轮次边界变更),或知识库未标记/为旧版。选择全量或范围化:
     - **范围化失效(第2阶段增量效率):** 若`changed_files_status`已知(非UNKNOWN)且知识库已有`KB_SNAPSHOT`标记(KB_ID非空,只是不同),且`changed_files_pass`等于当前`state.pass_number`(差异来自本轮次,而非之前过期的轮次——若不存在或不同则视为UNKNOWN,回退到下方的全量重建),尝试范围化重建:仅使源码文件在`changed_files`中的知识库条目及其父级汇总依赖项(导入/引用变更文件的知识库实体)失效。仅从`CODE_ROOT`重新推导这些条目;其他知识库条目保持不变(它们基于相同代码构建,只是快照ID不同)。在每个(重新)写入的文件上重新标记`KB_SNAPSHOT: CUR`。
        - **父级汇总(2跳,匹配计划的扩散逻辑):** 当使变更文件F对应的知识库条目失效时,同时使任何直接引用F的知识库条目(1跳)以及引用F的1跳依赖项的条目(2跳)失效。这与`mantis-plan`的依赖感知扩散(最多扩展2跳)匹配,确保孙实体(H导入G,G导入变更的F)不会过期留存,后续作为`kb_reference`传入时其依赖已变更。
     - **防护机制:** 若出现任何不确定性(无法确定哪些知识库条目对应哪些源码文件、知识库结构模糊,或`changed_files`为空但`KB_ID` != CUR),回退到下方的全量重建。切勿留存变更文件对应的过期条目。
     - **全量重建(第1阶段回退):** 若KB_ID为空(无先前知识库),或`changed_files_status`为UNKNOWN,或触发了范围化失效的防护机制,则针对`CODE_ROOT`从头重建所有知识库文件。切勿留存任何未在本轮次从`CODE_ROOT`重新推导的先前断言。标记`KB_SNAPSHOT: CUR`。移除任何过期横幅。
- 过期横幅(原样粘贴,替换`<KB_ID>`和`<CUR>`;每行保留前导`>`以渲染为可见的块引用):

  ```
  > **过期知识库警告——未重新验证前请勿信任。**
  > snapshot_pinned=false,或知识库基于不同快照构建。
  > KB_SNAPSHOT=<KB_ID> 与 active_snapshot.snapshot_id=<CUR> 不匹配。
  > 下方所有SECURE/FIXED/NON_VIABLE/SAMPLE_OR_TEST断言均未针对当前代码验证。
  > 信任前请重新验证;请勿基于此知识库过滤、跳过或降低工作优先级。
  ```
  1. 读取收件箱(
    workspace/learnings.jsonl
    workspace/historical_learnings.jsonl
    ):
    • 解析
      workspace/learnings.jsonl
      (若存在则同时解析
      workspace/historical_learnings.jsonl
      )的内容。提取所有轨迹见解、已发现漏洞、可行崩溃路径和已验证补丁。
  2. 分析源码边界:
    • 检查
      CODE_ROOT
      下的目录结构和关键源码文件(由模块A解析的固定快照;根据模块A步骤6使用绝对路径,切勿运行版本控制命令)。基于仓库内容动态识别系统的核心组件、接口和信任边界。这广泛适用于各类领域:无论是软件系统(例如识别解析器、控制器或网络守护进程)、硬件/RTL设计(例如识别IP块、JTAG接口或内存控制器)、基础设施即代码(例如识别云权限、VPC边界或部署描述符),还是数据/ML流水线(例如识别数据入口点、模型序列化机制或训练边界)。
  3. 构建或更新知识库(KB):
    • 使用标准Markdown在
      workspace/kb/
      目录中创建或更新文件。严格遵循以下路径:
      • workspace/kb/architecture.md
        :高层数据流、区域定义、系统设计,以及整体可用性/uptime要求(若有文档记录或可从systemd、kubernetes或负载均衡器等配置推断)。
      • workspace/kb/entities/[component_name].md
        :组件的具体定义(例如
        auth_module.md
        )。必须包含关联漏洞类别的链接,并记录已知约束(例如“此模块对输入X进行清理”)。记录组件的关键程度和可用性要求(适用时分类为CRITICAL、STANDARD或LOW_CRITICALITY)。在此处整合轨迹见解。
      • workspace/kb/vulnerabilities/[CWE-ID_or_BugClass].md
        :与该代码库历史相关的漏洞类别描述(例如
        CWE-79.md
        Memory-Corruption.md
        ),包括负面示例。
      • workspace/kb/index.md
        :根目录目录,包含上述所有文件的链接和一行摘要。这是规划器将读取的映射。
    • 重要格式规则: 使用相对链接交叉引用实体和漏洞(例如
      [认证模块](entities/auth_module.md)
      )。确保所有Markdown文件简洁,聚焦于可操作的安全上下文。
    • 快照标记(运行新鲜度检查时,即HALT或PINNED模式下,每个(重新)写入的知识库文件都必须添加;MODE-OFF模式下不添加):
      index.md
      、每个
      entities/*.md
      和每个
      vulnerabilities/*.md
      的第一行添加精确的
      <!-- KB_SNAPSHOT: <SNAPSHOT_ID> -->
      (替换步骤0b中的
      CUR
      ;这是HTML注释,不会渲染)。这是下一轮次新鲜度检查(步骤0b)检测漂移的方式。MODE-OFF规则(三态规则): 若不存在
      active_snapshot
      (MODE-OFF——未请求
      --sync
      ),则不添加每个文件的
      KB_SNAPSHOT
      标记:
      CUR
      为空字符串(
      arch:145
      :“若
      active_snapshot
      不存在则为空字符串”),强制添加的标记将为
      <!-- KB_SNAPSHOT:  -->
      (空值)——这是第1阶段不存在的快照时代产物。每个文件的标记仅被步骤0b的新鲜度检查使用,而MODE-OFF模式会完全跳过该检查(
      arch:147-152
      :“完全跳过新鲜度检查……此行为与当前的字节级操作完全一致。仅HALT和PINNED模式会运行下方的检查。”)。此MODE-OFF规则与下方的新鲜度检查逻辑和步骤0b的结果条款一致,后者仅在HALT/PINNED结果中提及每个文件的
      KB_SNAPSHOT: CUR
      标记(CURRENT
      :164
      、范围化重新构建
      :178
      、全量重新构建
      :195
      )。
    • 每个文件的
      KB_SNAPSHOT
      标记是知识库断言的唯一来源机制。
      请勿添加每个断言的
      (AS_OF:<snapshot>)
      标签——
      AS_OF
      重新验证读取器从未构建,而过期保护已由新鲜度检查(步骤0b)对比
      kb_snapshot_id
      SNAPSHOT_ID
      ,以及每个结果的
      discovery_commit
      (由
      mantis-critic
      模块B强制)提供。后续回退的修复会被这些机制捕获,而非每个断言的标签。
  4. 验证和更新知识库(防止漂移):
    • 当代码被补丁修复或重构时,知识会过期。在最终确定知识库更新前,将现有
      workspace/kb/entities/
      中的断言与
      CODE_ROOT
      下的源码(固定快照——而非实时版本控制查询,也非实时工作目录)进行抽查。在重新构建结果(步骤0b)中,完全不进行抽查:丢弃先前的断言,本轮次从
      CODE_ROOT
      重新推导所有实体。在过期 / HALT结果中,仅进行最佳努力的抽查,无论结果如何均保留过期横幅。
    • 若实体文件声称某个变量未被清理(基于旧学习成果),但当前代码已包含清理函数(因为补丁已落地),则删除或修正知识库中的该过时学习成果
    • 若某个学习成果多次被当前轨迹见解证明错误,则主动修正它,防止“错误学习”持续存在并误导后续Agent。
    • 当修正或重新确认基于结果的断言时,重新标记该知识库文件的
      KB_SNAPSHOT
      标记。
  5. 事务性收件箱清理与归档:
    • 为防止无限循环和令牌膨胀,必须清理队列并归档学习成果。
    • 验证并最终确定: 通过程序验证所有Markdown知识库更新已成功写入磁盘,且交叉引用有效。同时,在提交前验证每个(重新)写入的知识库文件开头是否包含其
      <!-- KB_SNAPSHOT: <SNAPSHOT_ID> -->
      标记,且每个基于结果的结论均基于当前
      SNAPSHOT_ID
    • 通过移动提交: 仅在验证合成成功后,将
      workspace/learnings.jsonl
      移至归档目录:
      • 确保目标目录存在(例如
        mkdir -p workspace/archive/learnings/
        )。
      • 通过读取
        workspace/.mantis_state.json
        中的
        "pass_number"
        确定循环轮次
        N
        。若缺失或无效,则扫描
        workspace/archive/
        中匹配
        findings_pass_N
        loopN_findings
        的文件夹,将
        N
        解析为
        max_found + 1
        ,若无归档则默认值为1。
      • 通过统计
        workspace/archive/learnings/
        中匹配
        learnings_pass_${N}_*.jsonl
        的现有文件数量并加1,确定子索引
        X
      • 移动文件:
        mv workspace/learnings.jsonl workspace/archive/learnings/learnings_pass_${N}_${X}.jsonl
    • 快照知识库(每轮次归档): 合成成功后,将整个知识库目录树复制到每轮次归档:
      • 确保目录存在(
        mkdir -p workspace/archive/kb/
        )。
      • 计算子索引
        X_kb
        =(
        workspace/archive/kb/
        中现有
        kb_pass_${N}_*
        目录的数量)+ 1。
      • 复制(切勿移动——实时的
        workspace/kb/
        必须为下一轮次保留):
        cp -a workspace/kb/. workspace/archive/kb/kb_pass_${N}_${X_kb}/
    • 标记状态:
      kb_snapshot_id
      =
      SNAPSHOT_ID
      (步骤0b中的
      CUR
      )写入
      workspace/.mantis_state.json
      。若不存在
      active_snapshot
      (MODE-OFF),则不写入
      kb_snapshot_id
      ,也不添加任何过期横幅(已跳过新鲜度检查)。在HALT模式下,写入
      kb_snapshot_id
      =
      CUR
      并保留
      index.md
      中的过期横幅。
    • 若合成失败或中断,保留
      workspace/learnings.jsonl
      在原位置不变,确保无数据丢失。
    • 若入口处
      workspace/learnings.jsonl
      不存在(例如第15阶段调用,因为第2阶段调用已在本轮次归档了该文件),则仅跳过学习成果移动;仍需运行新鲜度检查(步骤0b)、标记
      KB_SNAPSHOT
      标记、写入
      kb_snapshot_id
      并复制每轮次知识库归档。每次调用都必须记录知识库来源信息。
完成后,通知用户。",