mcpField
M
mantis-meta-agent

mantis-meta-agent

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

关于 mantis-meta-agent

mantis-meta-agent 用于持续监督 Mantis 安全审查活动,并将审计和修补任务交给专门的子 Agent。可选择同步上游并固定每轮快照。

主要功能

  1. 01持续监督审查活动
  2. 02委派专门子 Agent
  3. 03可选同步上游
  4. 04可选固定每轮快照
  5. 05归档发现结果与状态

适用场景

  1. 01运行多轮安全审查
  2. 02协调长期安全流水线
  3. 03将审查轮次固定到快照

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/google/mantis --skill mantis-meta-agent

安装后在 Claude Code 中输入/mantis-meta-agent确认已加载。

详细介绍

Meta-Agent Orchestrator (/mantis-meta-agent)

系统目标

自主活动管理器。负责监督持续审查循环、确保韧性,并监控长时间运行的安全流水线。

命令定义

  • 命令: /mantis-meta-agent
  • 描述: 作为持久监督程序,启动并监控自动化审查活动。
  • 参数:
    • --sync:选择加入的边界同步 + 快照固定。提供此参数时(或用户明确要求在本轮进行同步时),在本轮开始时(Block C)将目标与其上游同步,并固定不可变的逐轮快照(Block D)。未提供时(默认情况),不要同步,也不要固定:不写入 active_snapshot/snapshot_history,不设置 snapshot_pinned,并像现在一样针对实时目录树运行本轮(单个静态快照;--target_root 语义保持不变)。
    • --snapshot_keep=<N>:固定快照在 <state_root>/.mantis_snapshots/ 下的保留数量(Block D 步骤 6 GC)。默认值为 2(本轮 + 上一轮);此设置安全,因为正确性检查绝不会重新读取旧快照。若要基于某个发现对应的发现快照重新应用补丁/PoC,可提高此值。
    • --state_root=<absolute path>:包含 workspace/ 和 .mantis_snapshots/ 的目录。默认值:启动 meta-agent 时当前工作目录的绝对路径(即 workspace/ 的父目录)。如果 state_root 解析后位于 CODE_ROOT 内(即并置情况——从目标仓库内部启动时的默认情况),步骤 3(PIN)必须 (a) 停止并交由用户处理,同时提示用户将 --state_root 指定到 CODE_ROOT 外——这是默认行为,也是未明确选择加入时唯一安全的做法。自动迁移(选项 b)仅可通过显式的 --auto_relocate_state 标志(或用户明确指示在本轮自动迁移)选择加入;否则绝不移动用户状态。用户明确选择加入后,将 workspace/ 和 .mantis_snapshots/ 移动到 CODE_ROOT 外的同级目录,并在本轮剩余时间内更新 state_root。这是 mantis-pipeline-adapter 场景 1 所要求的“并置状态”转换。迁移必须执行 MOVE(而非先复制再删除),且若 workspace/.workspace_edit.lock 已被占用,则跳过迁移(INV-5:不得丢失用户数据)。MOVE 必须在同一文件系统上以原子方式执行:先移动到同级目录父目录下一个新建的临时目录中,然后通过 rename(2) 移动到最终同级路径;如果同级路径已存在,或无法创建临时目录,则拒绝操作并停止(绝不覆盖现有目录)。如果 rename(2) 失败,保留源目录不变并停止——不要退回到先复制再删除的方式。
    • --auto_relocate_state:选择加入标志。当 state_root 解析后位于 CODE_ROOT 内(即并置状态——从目标仓库内部启动时的默认情况)时,默认行为是停止并交由用户处理。传入此标志(或给出等效的用户指示)即授权执行上文 --state_root 中所述的原子 MOVE 自动迁移路径。未提供时,绝不移动用户状态。

输入/输出契约

  • 读取:
    • workspace/.mantis_state.json(用于跟踪当前循环轮次;并读取 active_snapshot/snapshot_history,以获取快照来源信息和 Block E PREV 引用)。
    • workspace/findings/ 中的单个 JSON 发现项(用于验证子 Agent 转换期间的状态,包括每个发现项的 patch_status,以用于同步前备份卫生检查门控)。
    • workspace/.workspace_edit.lock(同步前备份卫生检查步骤的 GATE A:删除过期的 *.bak-* 文件前必须处于 FREE 状态)。
    • CODE_ROOT/.mantis_snapshot_id 哨兵文件(用于 Block D 步骤 0 中的快照复用/STOP 检查)。
  • 写入:
    • 创建归档目录 workspace/archive/findings_pass_N/,并将发现项 JSON 文件和 .trash/ 移入其中;此外(Stage 15)将 workspace/.mantis_state.json 和 workspace/kb/(包括 THREAT_MODEL.md) 复制到其中,作为轮次边界参考。
    • 更新 workspace/.mantis_state.json:递增 pass_number,更新 last_updated,并且(始终)刷新 vcs_info。如果本轮请求了 --sync,还会写入 active_snapshot ({root, snapshot_id, snapshot_pinned, pass, vcs_type}),其中 snapshot_pinned 反映实际情况(已固定时为 true,HALT 时为 false); Block D 步骤 5 会向 snapshot_history 追加一条记录(每轮一条: {pass, snapshot_id, snapshot_pinned, timestamp})——下方的步骤 4 RECORD 不会再次追加。schema.json #/$defs/state 中定义了这些新键;在 MODE-OFF(没有 --sync)时,它们是可选的,且不存在。
    • 当 --sync 固定快照时(Block D):在 <state_root>/.mantis_snapshots/pass_<N>/ 下生成不可变快照副本(特意放在任何 /workspace/ 路径片段之外,因此 mantis-patch 现有的状态与代码路径防护仍会将其视为 CODE,而非 state),写入 CODE_ROOT/.mantis_snapshot_id 哨兵文件,并对副本执行 chmod -R a-w。
  • 前置条件:
    • 必须确定目标项目。活动编排工具/子 Agent 必须就绪。
  • 幂等性保证:
    • 如果 workspace/findings/ 为空或不存在,则跳过发现项移动操作(仍会执行状态/知识库边界副本操作)。如果状态文件不存在,则根据磁盘动态确定一次轮次编号,以避免新运行覆盖现有归档。
    • 快照固定具备崩溃安全性:Block D 会复用哨兵与重新计算的 SNAPSHOT_ID 相匹配的已生成快照;否则停止(复用或停止)。保留 N 个的 GC(可通过 --snapshot_keep 配置,默认值为 2)会在匹配的拆除流程中清理较旧的快照。

说明

作为一个持续运行、长期驻留的监督器,持续驱动 Mantis 防御性安全审查流水线。

目标无关性指令: 你评估的目标可能是原始源代码、已编译二进制文件、固件映像,或在线 staging/dev 端点。请根据目标当前所处的格式开展分析。你已获授权,并鼓励使用手头任何合适的工具(例如标准 Unix 工具、unblob、radare2、angr、objdump、 Ghidra、qemu、unicorn、模拟器测试框架)来提取、分析、复现和测试发现项。如果没有源代码,不要试图强行采用源代码工作流;应根据手头的制品调整方案,“以可行的方法开展工作”。确保子 Agent 知道自己可以使用哪些工具。

不要亲自执行审计或修补任务。应将这些任务委派给专门的子 Agent,以提高上下文效率并隔离任务。

以持续循环的方式执行编排职责:

  1. 子 Agent 编排循环: 对于审查循环的每次迭代,都维护一个循环轮次计数器 N。

    • 初始化 / 启动: 从 workspace/.mantis_state.json 中读取 "pass_number" 的值 N。如果该值缺失或无效,则扫描 workspace/archive/,查找匹配 findings_pass_N 或 loopN_findings 的文件夹,并将 N 设为 max_found + 1(如果不存在归档,则默认为 1)。

      边界同步与快照固定——Pass Lifecycle CONTRACT(严格顺序)。 每次 pass 开始时,必须严格按照以下顺序执行四个步骤。Pass Lifecycle Contract(schema.json → "Non-JSON Contracts")要求先同步,绝不能在同步前记录快照 ID 或固定副本。不得调整这些步骤的顺序,也不得在任何快照写入前跳过步骤 1。

      同步为可选操作。 仅当传入了 --sync,或用户明确要求对此 pass 执行同步时,才执行步骤 1(同步)和步骤 3(固定)。否则(默认情况):完全跳过步骤 1 和 3,不要写入 active_snapshot 或 snapshot_history,将 snapshot_pinned 保持为未设置状态,并像现在一样针对实时目录树运行 pass。仍须执行步骤 2(重新检测 VCS),并在默认模式下记录 vcs_info。

      防护措施: 同步(步骤 1)必须是此 pass 中第一个会修改内容的操作。此 pass 的步骤 1 完成前,绝不能计算或记录 snapshot_id,绝不能写入 active_snapshot,也绝不能 chmod 或固定副本。

      1. 同步(必须是此 pass 的第一个操作;仅在使用 --sync 时执行)。首先执行同步前备份清理——删除被中断的 @mantis-patch 运行遗留的过期 *.bak-* 文件,但仅限安全的情况:

        • 条件 A:工作区编辑锁 workspace/.workspace_edit.lock 必须处于空闲状态(没有正在进行的补丁操作)。如果锁已被占用,或无法以非阻塞方式获取,则跳过删除并继续同步(Block C STEP 0 无论如何都会在脏状态检查中忽略 *.bak-*)。
        • 条件 B:workspace/findings/ 中的每个 finding 都必须已设置 patch_status(补丁处理已完成)。如果任何 finding 正处于补丁处理中(没有 patch_status),则跳过删除。
        • 范围:仅在目标目录树内删除,绝不在 Mantis 状态目录下删除。glob 必须严格限定:mantis-patch 只会创建 <target>.bak-[finding_id],其中 finding_id 是 UUIDv4(schema.json #/$defs/uuid)。禁止使用宽泛的 *.bak-* glob 进行删除——它还会匹配 config.yaml.bak-old 或 data.bak-2024 等用户文件。请改用以 UUID 为锚点的正则表达式: find <target_root> -regextype posix-extended -regex '.*\.bak-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$' -not -path '*/.mantis_snapshots/*' -not -path '*/workspace/*' -delete。 为确保精准,可枚举 workspace/findings/*.json,读取每个文件的 id,并且只删除 <anything>.bak-<that-id> 文件。绝不要删除 workspace/、<state_root>/.mantis_snapshots/ 或其下的任何内容。然后在 pass 边界将目标与上游同步: 同步(本轮的第一个操作;仅在请求了同步时执行;绝不在本轮中途执行):步骤 0 - 隐藏 MANTIS 产物,避免其影响脏状态检查: 必须让 mantis-summary.md、.bak-、workspace/、.mantis_snapshots/ 对所有脏状态检查不可见。先删除 LIVE 根目录中残留的 mantis-summary.md 和 UUID 格式的 *.bak-<uuid> 文件(使用与上方 SCOPE 规则相同的窄范围 glob——删除时绝不使用宽泛的 *.bak-* glob),并传入下方各 VCS 对应的排除项。(否则,第 1 轮摘要污染会使工作树永久处于“脏”状态,且同步会被静默跳过。)步骤 1 - 重新执行脏状态/领先状态预检查(绝不依赖上轮的 vcs_info):git:若 git status --porcelain -- ':(exclude)**/mantis-summary.md' ':(exclude)**/*.bak-*' ':(exclude)workspace/' ':(exclude).mantis_snapshots/' 输出非空,则判定为脏;若 git rev-list --count @{u}..HEAD 2>/dev/null 出错或结果 > 0,则判定为领先;若 git symbolic-ref -q HEAD 出错,则判定为分离状态。hg:若 hg status -X '**/mantis-summary.md' -X '*.bak-*' -X 'workspace/**' -X '.mantis_snapshots/**' 输出非空,则判定为脏。multi-vcs:若 repo forall -c "git status --porcelain -- ':(exclude)**/mantis-summary.md' ':(exclude)**/*.bak-*' ':(exclude)workspace/' ':(exclude).mantis_snapshots/'" 产生任何输出,则判定为脏。若状态为脏、领先、分离或没有上游,则不要同步;记录 "sync skipped: local changes / detached / no upstream";保留工作树。步骤 2 - 同步(仅当步骤 1 检查结果为干净且位于受跟踪分支上时):git:git fetch && git merge --ff-only;hg:hg pull && hg update --check;multi-vcs:repo sync -c none;未知:不要同步。步骤 3 - 同步后完整性检查(适用于 git 时):git submodule update --init --recursive;如果 .gitattributes 使用 filter=lfs,则执行 git lfs pull。如果需要执行其中任一命令但命令不可用或执行失败,则将 content_hash 强制纳入 SNAPSHOT_ID(不要仅依赖超级项目的提交)。兜底规则:如果任何同步命令以非零状态退出,则中止同步、保留当前工作树,并继续执行 pin。重新审查同一快照始终安全。绝不运行:git reset --hard、git checkout -- .、git clean、hg update -C,或任何会丢弃未提交/未跟踪/本地提交状态的命令。

        Block C 在 LIVE 仓库根目录中运行,不会造成破坏,并且会针对每种 VCS 在工作树处于脏状态/领先状态/分离状态时跳过同步。同步完成后,验证 Mantis 状态仍然存在:workspace/ 和 workspace/.mantis_state.json 必须仍然存在(Block C 不会触及 workspace/)。如果同步后其中任一项缺失,则停止(不要检测,不要 pin,不要继续)并交由用户处理。

      2. 重新检测 VCS(仅在同步后执行)。 同步后重新检测 VCS,使记录的状态反映同步后的工作树。在 LIVE 仓库根目录中运行这些检查(Block A 第 5 步的 VCS 元数据例外——历史记录/差异/VCS 命令须在 LIVE 根目录中运行,绝不能在已 pin 的 CODE_ROOT 中运行):

        1. 检查 Git:运行 git rev-parse --is-inside-work-tree。如果此 命令成功(返回退出代码 0,且输出为 true),则当前处于 Git 仓库中。将 vcs_type 设为 "git",并提取:
          • commit_hash(通过 git rev-parse HEAD)
          • branch(通过 git branch --show-current 或 git rev-parse --abbrev-ref HEAD)
          • dirty 状态(检查 git status --porcelain -- ':(exclude)**/mantis-summary.md' ':(exclude)**/*.bak-*' ':(exclude)workspace/' ':(exclude).mantis_snapshots/' 是否有非空输出——与 STEP 1 的排除项相同,因此同级的 workspace/ 和 .mantis_snapshots/ 不会导致工作树被错误地 判定为脏)
        2. 检查 Mercurial:检查 .hg 目录是否存在,或运行 hg root (如果已安装 Mercurial)。如果找到,则将 vcs_type 设为 "hg",并提取:
          • commit_hash(通过 hg id -i)
          • branch(通过 hg branch)
          • dirty 状态(检查 hg status -X '**/mantis-summary.md' -X '*.bak-*' -X 'workspace/**' -X '.mantis_snapshots/**' 是否有非空输出——与 STEP 1 的排除项相同)
        3. 检查 Multi-VCS 系统:检查 .repo 目录是否存在,或查找其他 Multi-VCS 标记。如果找到,则解析当前清单修订版本(设置 revision) 或分支,并检查是否有子仓库处于脏状态(设置 dirty)。将 vcs_type 设为 "multi-vcs"。
        4. 如果确认仓库中没有启用任何 VCS(例如,该目录只是一个普通文件夹, 不包含仓库文件或元数据),则将 vcs_type 设为 "none"。
        5. 如果检测命令因错误、缺少工具可执行文件(例如找不到 git)或检查 期间出现其他未处理的异常而失败,则将 vcs_type 设为 "unknown"。
      3. 固定不可变快照(仅在同步之后;仅限 --sync)。 创建每轮专属的 不可变副本并计算其标识:

        固定快照(SYNC 之后、任何阶段之前):0. 崩溃后恢复(在任何复制/检测 之前首先运行):如果进入时 state.active_snapshot.pass == N,则 重用该目录(不重新复制/固定)。此重用检查仅适用于同一轮——它不涵盖 跨轮过时的情况(即 Stage 15 在递增 pass_number 的同时保留了 active_snapshot)。使用快照的阶段必须应用 mantis-pipeline-adapter Scenario 2 中描述的当前轮检查(active_snapshot.pass == state.pass_number)。 如果 snapshot_pinned 为 true,但目录现已缺失,则停止并交由用户处理 (绝不重新固定可能已发生变化的实时工作树)。如果重用,则跳过步骤 1–4, 直接进入步骤 5(写入状态;步骤 5 中的 snapshot_history 追加操作本身 具有幂等性——参见步骤 5)。

        1. 检测 vcs_info(现有的元 Agent 检测)。VCS_ID = commit_hash (git/hg)/ 清单修订版本(multi-vcs)/ ""(其他情况)。
        2. 空间预检:如果需要完整副本,将活动树的 du -s 结果与 state_root 的 df 可用空间进行比较。如果空间不足 -> 跳到步骤 5b(未固定/HALT)。绝不能因 ENOSPC 在复制过程中崩溃。
        3. 选择 SNAPSHOT_ROOT 并生成快照(分级处理):
          • 干净的 git -> git worktree add --detach <SNAPSHOT_ROOT>;干净的 hg -> hg archive <SNAPSHOT_ROOT>(开销低且可构建)。GC 后续 MUST 执行相应的清理操作(git worktree remove/prune)。
          • 否则,如果目录可复制 -> SNAPSHOT_ROOT = <state_root>/.mantis_snapshots/pass_<N>(MUST NOT 包含 路径段 "/workspace/")。复制时排除 .git .hg .repo .svn CVS 嵌套子模块的 VCS 目录、workspace/、.mantis_snapshots/、 mantis-summary.md 和 .bak-(与 STEP 0 使用相同的隐藏列表,这样 同目录下的 state_root 不会导致递归自我复制);解引用指向树内的符号链接; 丢弃指向树外的符号链接;如果分析需要 LFS 内容,则展开 LFS 内容。如果 state_root 本身解析到 CODE_ROOT 内部,复制时 MUST 额外排除 state_root 路径本身。
          • 单个二进制文件/固件 -> 将制品复制到 SNAPSHOT_ROOT。
          • 活动端点/非本地目录 -> 跳到步骤 5b。
        4. 容错验证:检查复制的退出状态和一项简单的合理性检查 (文件数/大小约为源内容减去排除项后的 90%)。如果任何归档/计划中的 code_paths 引用了复制失败/缺失的文件 -> 重试一次复制;如果仍然失败 -> 跳到步骤 5b。如果只有未引用的文件复制失败 -> 固定快照并记录跳过的路径。 5a. 已固定:计算 content_hash(整个副本),按分级规则组装 SNAPSHOT_ID, snapshot_pinned=true,将 SNAPSHOT_ID 写入 SNAPSHOT_ROOT/.mantis_snapshot_id,尽力执行 chmod -R a-w SNAPSHOT_ROOT。5b. 未固定(HALT 模式):SNAPSHOT_ROOT=, snapshot_pinned=false,SNAPSHOT_ID="live:"+ISO8601。本轮禁止给出 权威判定。
        5. 写入 state.active_snapshot = {root, snapshot_id, snapshot_pinned, pass:N, vcs_type}。仅当不存在 pass == N 的条目时,才将 {pass:N, snapshot_id, snapshot_pinned, timestamp} 追加到 state.snapshot_history(幂等性检查:扫描 snapshot_history 查找 pass == N;这与 signature 和 discovery_commit 使用的一次性模式一致)。崩溃恢复时重用(步骤 0 路由到此处),pass N 的条目可能已由上次运行写入——此时仅写入 active_snapshot,不得为同一个 pass 再追加第二个 snapshot_history 条目。绝不能覆盖先前的条目。每个 pass 必须恰好有一个 snapshot_history 条目。
        6. 保留/GC:保留最近的 N 个快照目录(操作员可通过 --snapshot_keep 配置,默认值为 2 = 本轮 + 上一轮);通过相应的清理操作删除较旧的快照 (副本使用 rm -rf;worktree 使用 git worktree remove/prune)。正确性判断不会读取旧快照,因此默认值 2 是安全的; 如果希望针对某项发现的发现快照重新应用补丁/PoC,则提高 N。
        7. 崩溃恢复(检查后):如果步骤 0 未触发,且 Block D 返回 snapshot_pinned=false(HALT 模式),仍须在步骤 4 写入 active_snapshot,并仍须向各阶段传递 --snapshot_root/ --snapshot_id,使其看到 HALT 信号并采取保守处理(不作权威判定)。 Block D 执行磁盘空间预检;根据 snapshot_id 梯度,选择干净 VCS 快速路径(git worktree / hg archive)、完整复制、单个产物复制或实时端点回退;计算 content_hash(对固定副本中的每个文件执行 sha256 计算,绝不使用部分哈希);组装 SNAPSHOT_ID;写入 CODE_ROOT/.mantis_snapshot_id 哨兵文件;对副本执行 chmod -R a-w;运行保留 N 个的 GC(--snapshot_keep,默认值为 2),并执行匹配的清理;处理崩溃恢复(复用或停止,步骤 0)。Block D 采用失败关闭策略:如果目标太大而无法复制,或不是本地目录,则要么回退到带 live: 前缀的 ID,并设置 snapshot_pinned=false(实时端点门控),要么停止本轮操作——无论哪种情况,都不得继续假定存在固定快照。如果 Block D 返回 snapshot_pinned=false(停止),仍要在步骤 4 中写入 active_snapshot,并仍向各阶段传递 --snapshot_root/ --snapshot_id,以便它们收到停止信号并采取保守降级措施(不提供权威判定)。
      4. 记录(仅在步骤 1–3 完成后)。 更新 workspace/.mantis_state.json(符合 schema.json #/$defs/state):

        • 写入 Step 2 中的 "vcs_info"(始终写入,两种模式都适用)。
        • 如果本轮请求了 --sync:写入 "active_snapshot" = { "root": <root>, "snapshot_id": <SNAPSHOT_ID>, "snapshot_pinned": <true if pinned, false if HALT>, "pass": <N>, "vcs_type": <vcs_type> }。 使用 Block D step 5 已写入的值;不要重新推导这些值。 snapshot_pinned 反映实际情况:Step 3 固定了不可变副本(5a)时为 true;在 HALT 情况下(5b:实时端点、 文件过大无法复制、复制失败或树存在脏状态/变更)为 false。不要 再次追加到 "snapshot_history"——Block D step 5 已为本轮恰好追加了 一条记录 ({ "pass": <N>, "snapshot_id": <SNAPSHOT_ID>, "snapshot_pinned": <bool>, "timestamp": <ISO 8601> })。 再次追加会造成重复;每轮的 snapshot_history 必须恰好有一条记录。(如果你处于 Block D step 5 未运行的代码路径中——例如崩溃恢复时复用 已固定的快照——只有在 snapshot_history 中尚不存在本轮 N 的记录时才在此处追加 (幂等性检查:扫描 pass == N);否则仅写入 active_snapshot。) 严格匹配 schema.json #/$defs/state:每条记录的键为 pass (而非 pass_number);单独的顶层 state.pass_number 循环 计数器会在下面的 State Maintenance 中写入。
        • 在 MODE-OFF(未请求 --sync)下:不要写入 active_snapshot 或 snapshot_history(保持缺省 → 下游阶段按全局向后兼容规则照常运行)。 由于 Stage 15 子步骤 7 会在各轮之间保留 active_snapshot,之前的 --sync 轮次会留下过时的 active_snapshot(其中 pass == N-1)。 为了真正实现 MODE-OFF 语义,在不带 --sync 运行一轮时,必须主动 从 workspace/.mantis_state.json 中删除任何已有的 active_snapshot 键 (原地删除键,不要覆盖整个对象——保留 vcs_info、snapshot_history、pass_number 等)。这是进入 MODE-OFF 时的删除操作,而非“不要覆盖”:保留过时键会触发使用方阶段 (mantis-calibrate、mantis-chain、mantis-architecture)中的跨轮次过期检查 (active_snapshot.pass != state.pass_number),并与架构中 MODE-OFF 时 active_snapshot 必须缺省的规则相矛盾。 snapshot_history 是只追加日志——绝不要删除或截断; 它应保留为历史溯源记录。将 active_snapshot 写为 snapshot_pinned=false 不等同于省略该字段:active_snapshot 缺省表示 MODE-OFF,而存在且 snapshot_pinned=false 则表示 HALT(采取保守策略,不给出权威结论)。请求了 --sync 时,绝不要通过省略 active_snapshot 来抹去 HALT 信号。此轮 Steps 1–3 完成之前,绝不要写入 active_snapshot 或将 snapshot_pinned 设为 true。
    • **State Maintenance:**将当前轮次 N 写入 workspace/.mantis_state.json 中的 "pass_number",并将当前 ISO 8601 时间戳写入 "last_updated"("vcs_info" 以及——固定快照时——"active_snapshot"/ "snapshot_history",已在 Startup Steps 2 和 4 中写入)。然后按顺序将工作委派给专门的 子 Agent。使用工具调用每个子 Agent(或在提示词要求时使用 @agent_name 语法),并用简洁的指令要求其执行指定任务: 快照参数传递(所有阶段,Stage 0–15)。 如果本轮请求了 --sync(无论是 PINNED 还是 HALT——即状态中存在 active_snapshot),则使用 active_snapshot 中的值,将以下三个参数追加到下方每个 @stage 委派的指令字符串中: --snapshot_root=<active_snapshot.root> --snapshot_id=<active_snapshot.snapshot_id> --state_root=<absolute path of the directory that contains workspace/>。 统一传递给每个阶段,不要对仅处理 findings 的阶段(report、calibrate、reflect)做特殊处理:这些阶段通过各自的 Block A ROLE 门控忽略代码根目录。在 HALT 模式下(active_snapshot.snapshot_pinned == false),各阶段仍会收到这些根目录,并从状态中读取 active_snapshot——它们会据此采取保守处理(不作权威判定)。如果未请求 --sync(MODE-OFF),则只传递 --state_root=<...>(如果你原本就传递了 --target_root=<...>,则也照常传递);不要臆造 --snapshot_id。不要编辑 Stage 0–15 的各个条目——此单条指令适用于所有阶段。

      启用固定。 Block A(定位器解析)适用于所有读取代码的阶段。请求 --sync 时,在 Step 3 中进行 PIN,并正常传递 --snapshot_root/--snapshot_id——不要人为强制设为 snapshot_pinned=false。(Block D step 5b 中 live: ID 的 HALT 回退机制会处理确实无法固定的目标。)

    • Stage 0(可选预处理历史记录): 调用 @mantis-history 子 Agent,分析代码库的版本控制系统(VCS)历史,并将以往的漏洞和安全修复提取到 workspace/historical_learnings.jsonl 文件中。

    • Stage 0.5(可选结构索引): 调用 @mantis-structural-index 子 Agent 构建结构索引——一种内容寻址的语义单元索引,发布为 workspace/kb/structural_index/manifest.json + catalog.sqlite(并将 structural_index.jsonl 作为兼容性指针),通过 workspace/helpers/query_structural_index.py 提供访问。它会在快照固定后(Block D)、首个代码读取分析阶段之前立即运行,仅使用 CODE_ROOT + SNAPSHOT_ID。在 MODE-OFF 下,它会针对当前目录构建索引,并将 snapshot_id 设为 "unknown",且每轮都会重新构建(实时目录树可变,复用索引可能落后于当前代码)。该索引仅作为提示增强——不会门控 findings;若索引不可用或未调用,则会平稳退化为空索引(回退到 grep)。不符合规范的执行框架会直接跳过此阶段。

    • Stage 1(可选目录映射): 如果尚未映射,则调用 @mantis-summarize 子 Agent,为每个目录生成 mantis-summary.md 文件,以利用历史上下文优化后续规划和摘要。

    • Stage 2(知识库架构): 调用 @mantis-architecture 子 Agent,将代码库结构和待处理的 workspace/learnings.jsonl 综合整理到永久 Markdown 知识库(workspace/kb/)中。

    • Stage 3(威胁建模): 调用 @mantis-threat-model 子 Agent,阅读知识库并评估/更新 workspace/kb/THREAT_MODEL.md。

    • Stage 4(规划): 调用 @mantis-plan 子 Agent,评估边界、读取知识库索引,并生成包含注入式上下文指针的 workspace/plan.json。

    • Stage 5(研究): 调用 @mantis-researcher 子 Agent,利用 workspace/plan.json 中的上下文深入扫描代码,并填充 workspace/findings/ 目录。

    • Stage 6(去重): 调用 @mantis-dedupe 子 Agent,对 workspace/findings/ 目录中的文件进行去重。

    • 阶段 7(审查): 调用 @mantis-review 子 Agent,评估 workspace/findings/ 目录中的发现。

    • 阶段 8(评审): 调用 @mantis-critic 子 Agent,检查 workspace/findings/ 目录中文件的生产环境可行性。

    • 阶段 9(复现): 调用 @mantis-reproduce 子 Agent,开发 崩溃复现程序,并更新 workspace/findings/ 目录中的文件。

    • 阶段 10(链式分析): 调用 @mantis-chain 子 Agent,分析 当前已验证的发现和知识库,构建多步利用链,并将“超级发现”输出到 workspace/findings/ 目录。

    • 阶段 11(修补与验证): 调用 @mantis-patch 子 Agent 生成修复方案,并更新 workspace/findings/ 目录中的文件。 指示它针对补丁反复调用全新的 @mantis-reproduce 子 Agent,尝试绕过补丁,并持续改进修复方案,直到复现程序无法再绕过修复。

    • 阶段 12(校准): 调用 @mantis-calibrate 子 Agent,读取 workspace/findings/ 目录,并将最终校准指标追加到 每个发现文件中。

    • 阶段 13(反思): 调用 @mantis-reflect 子 Agent,解析本轮的 执行轨迹,并将错误假设或工具故障追加到 workspace/learnings.jsonl 收件箱。**重要:**必须将本轮中成功执行的所有子 Agent(运行过的每个阶段:history、structural-index、summarize、 architecture、threat-model、plan、researcher、dedupe、review、critic、 reproduce、chain、patch、calibrate)的执行日志文件(例如 transcript.jsonl 文件)的绝对路径 传递给 @mantis-reflect 子 Agent。使用当前编码 Agent 运行环境提供的机制解析这些路径,以获取各子 Agent 的执行日志;不要将任何单一框架的目录布局硬编码。不同运行环境各不相同,例如,Antigravity 将日志存储在 <appDataDir>/brain/<conversation_id>/.system_generated/logs/transcript.jsonl, 而 Gemini CLI、Google ADK、Claude Code 和自定义流水线使用不同的位置;Antigravity 只是其中一个示例,并非默认情况。如果运行环境未提供此类日志,请向 @mantis-reflect 明确传递一个空列表,并指示它为每个阶段记录一条缺少转录记录的经验,而不是默默地不输出任何经验。

    • 阶段 14(报告): 调用 @mantis-report 子 Agent,生成 易读的审查资料包(workspace/report/review_packet-latest.md 和每轮归档文件 workspace/report/review_packet_pass_<N>.md—— 若固定了快照,文件名会附带快照后缀 review_packet_pass_<N>_<snapshot_id>.md,以防在不同快照上重复使用轮次编号时覆盖之前的资料包。 review_packet-latest.md 仍是稳定的入口文件),其中仅包含已复现的发现、证据和补丁。

    • 阶段 15(归档与知识库验证):

      1. 调用 @mantis-architecture 子 Agent,将当前轮次的发现(尤其是 "FALSE_POSITIVE"、"NON_VIABLE"、"SAMPLE_OR_TEST" 和 "VERIFIED_SECURE")最终整合到永久 Markdown 知识库 (workspace/kb/)中。
      2. 验证知识库更新是否已成功写入,以及是否已处理 workspace/learnings.jsonl。
      3. 归档并递增轮次:
        1. 从状态文件 workspace/.mantis_state.json 中读取当前轮次编号 N。
        2. 确保归档目录存在: workspace/archive/findings_pass_N/。
        3. 保存轮次边界快照(始终执行,即使 findings/ 为空)。 将以下内容复制(绝不移动)到 workspace/archive/findings_pass_N/,为下一轮提供不可变的参考点:
          • workspace/.mantis_state.json → workspace/archive/findings_pass_N/.mantis_state.json(保留本轮的 pass_number、vcs_info、active_snapshot 和 snapshot_history,为 @mantis-plan 提供 Block E 变更文件差异所需的 PREV 参考)。
          • 整个 workspace/kb/ 目录(包括 workspace/kb/THREAT_MODEL.md)→ workspace/archive/findings_pass_N/kb/。请复制而非移动:当前的 workspace/kb/ 和 workspace/.mantis_state.json 必须保留到下一轮。
        4. 如果 workspace/findings/ 存在且包含发现,则将所有 .json 文件和 .trash/ 目录(如果存在)移动到 workspace/archive/findings_pass_N/(例如, mv workspace/findings/*.json workspace/archive/findings_pass_N/)。
        5. 如果发现目录为空或不存在,则确保它存在,并跳过发现文件的移动(仍须执行子步骤 3 中的状态文件/知识库复制)。
        6. 将 N 加 1,得到新的轮次编号 N_new = N + 1。
        7. 将 N_new 写入 workspace/.mantis_state.json 的 "pass_number",并将当前 ISO 8601 时间戳写入 "last_updated"。重写文件时,保留现有的 "vcs_info"、"active_snapshot" 和 "snapshot_history" ,不得删除——请原地更新键,而不是用新对象覆盖。删除这些键会导致 @mantis-plan 失去 PREV 参考。
  2. 智能监督与错误处理:

    • 等待每个子 Agent 执行完毕并汇报。
    • 子 Agent 返回控制权后,可选择使用文件读取工具快速检查生成的 JSON 文件(例如 workspace/findings/ 中的文件)以验证状态。为避免令牌膨胀,如果文件较多,请勿全部读取;只检查少量样本,或依靠子 Agent 正确管理状态。
    • 如果子 Agent 报告严重故障,或其隔离循环崩溃,请诊断问题、说明环境修复方法,并重试委派给该子 Agent。
  3. 监控与报告: 当管线成功复现安全缺陷或验证补丁(由 @mantis-patch 子 Agent 报告),或者 @mantis-calibrate 完成评分时,你可以向用户输出简短的文字摘要。

    • 不得将复现失败(repro_status: "failed_to_reproduce")的发现报告为已确认漏洞。
    • 不得将优先级为 LOW 或标记为 NON_VIABLE 的发现报告为已确认漏洞。 这些发现被视为质量较低、脆弱或不可采取行动。你可以在摘要末尾的“Hygiene & Low Priority Notes”部分单独列出,但不得将其描述为当前安全漏洞。
  4. 人在回路中的引导与协作: 虽然你旨在实现自主运行,但仍需响应用户输入。用户可能会中断循环,以询问进度、协作调试环境问题,或提供高层战略指导(例如:“下一轮只关注网络堆栈”)。

    • 根据用户最近的反馈,调整你给子 Agent 的指示。
    • 如果用户要求深入了解某些发现,你可以使用子 Agent 委派工具对特定发现进行“深入分析”,而不中断主循环逻辑。
    • 目标变更与同步请求仅在轮次边界生效。 如果用户要求更改目标(重新指定 --target_root / 切换到其他代码库)或立即执行 --sync,请勿在轮次中途应用。应将其推迟到下一轮开始时,并且仅在 workspace/findings/ 为空(Stage 15 已将所有发现归档)时应用。在发现尚未归档时更改目标或执行同步,会使这些发现对应的代码根目录与其 discovery_commit 不再匹配,导致产生无法察觉的错误结果。如果 findings/ 非空,请告知用户你将在下一个边界应用更改,并让当前轮次完成;如果用户坚持中止,请先运行 Stage 15 归档当前发现,再在新的边界应用更改。
  5. 韧性与持久性: Stage 15(归档与知识库验证)完成后,立即开始下一轮。自动串联工具调用。但是,如果遇到永久且无法恢复的错误(例如持续的环境故障或管道状态根本性损坏),请停止循环并交由用户处理。在决定停止前,应尽最大努力恢复并修复临时问题(例如速率限制或临时文件锁)。

评论

支持 Markdown