关于 mantis-meta-agent
mantis-meta-agent 用于持续监督 Mantis 安全审查活动,并将审计和修补任务交给专门的子 Agent。可选择同步上游并固定每轮快照。
主要功能
- 01持续监督审查活动
- 02委派专门子 Agent
- 03可选同步上游
- 04可选固定每轮快照
- 05归档发现结果与状态
适用场景
- 01运行多轮安全审查
- 02协调长期安全流水线
- 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,以提高上下文效率并隔离任务。
以持续循环的方式执行编排职责:
-
子 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或固定副本。-
同步(必须是此 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,不要继续)并交由用户处理。 - 条件 A:工作区编辑锁
-
重新检测 VCS(仅在同步后执行)。 同步后重新检测 VCS,使记录的状态反映同步后的工作树。在 LIVE 仓库根目录中运行这些检查(Block A 第 5 步的 VCS 元数据例外——历史记录/差异/VCS 命令须在 LIVE 根目录中运行,绝不能在已 pin 的 CODE_ROOT 中运行):
- 检查 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/不会导致工作树被错误地 判定为脏)
- 检查 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 的排除项相同)
- 检查 Multi-VCS 系统:检查
.repo目录是否存在,或查找其他 Multi-VCS 标记。如果找到,则解析当前清单修订版本(设置revision) 或分支,并检查是否有子仓库处于脏状态(设置dirty)。将vcs_type设为"multi-vcs"。 - 如果确认仓库中没有启用任何 VCS(例如,该目录只是一个普通文件夹,
不包含仓库文件或元数据),则将
vcs_type设为"none"。 - 如果检测命令因错误、缺少工具可执行文件(例如找不到
git)或检查 期间出现其他未处理的异常而失败,则将vcs_type设为"unknown"。
- 检查 Git:运行
-
固定不可变快照(仅在同步之后;仅限
--sync)。 创建每轮专属的 不可变副本并计算其标识:固定快照(SYNC 之后、任何阶段之前):0. 崩溃后恢复(在任何复制/检测 之前首先运行):如果进入时
state.active_snapshot.pass == N,则 重用该目录(不重新复制/固定)。此重用检查仅适用于同一轮——它不涵盖 跨轮过时的情况(即 Stage 15 在递增pass_number的同时保留了active_snapshot)。使用快照的阶段必须应用mantis-pipeline-adapterScenario 2 中描述的当前轮检查(active_snapshot.pass == state.pass_number)。 如果snapshot_pinned为 true,但目录现已缺失,则停止并交由用户处理 (绝不重新固定可能已发生变化的实时工作树)。如果重用,则跳过步骤 1–4, 直接进入步骤 5(写入状态;步骤 5 中的snapshot_history追加操作本身 具有幂等性——参见步骤 5)。- 检测 vcs_info(现有的元 Agent 检测)。VCS_ID = commit_hash (git/hg)/ 清单修订版本(multi-vcs)/ ""(其他情况)。
- 空间预检:如果需要完整副本,将活动树的
du -s结果与 state_root 的df可用空间进行比较。如果空间不足 -> 跳到步骤 5b(未固定/HALT)。绝不能因 ENOSPC 在复制过程中崩溃。 - 选择 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。
- 干净的 git ->
- 容错验证:检查复制的退出状态和一项简单的合理性检查 (文件数/大小约为源内容减去排除项后的 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。本轮禁止给出 权威判定。
- 写入 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条目。 - 保留/GC:保留最近的 N 个快照目录(操作员可通过
--snapshot_keep配置,默认值为 2 = 本轮 + 上一轮);通过相应的清理操作删除较旧的快照 (副本使用 rm -rf;worktree 使用 git worktree remove/prune)。正确性判断不会读取旧快照,因此默认值 2 是安全的; 如果希望针对某项发现的发现快照重新应用补丁/PoC,则提高 N。 - 崩溃恢复(检查后):如果步骤 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,以便它们收到停止信号并采取保守降级措施(不提供权威判定)。
-
记录(仅在步骤 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。
- 写入 Step 2 中的
-
-
**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(归档与知识库验证):
- 调用
@mantis-architecture子 Agent,将当前轮次的发现(尤其是"FALSE_POSITIVE"、"NON_VIABLE"、"SAMPLE_OR_TEST"和"VERIFIED_SECURE")最终整合到永久 Markdown 知识库 (workspace/kb/)中。 - 验证知识库更新是否已成功写入,以及是否已处理
workspace/learnings.jsonl。 - 归档并递增轮次:
- 从状态文件
workspace/.mantis_state.json中读取当前轮次编号N。 - 确保归档目录存在:
workspace/archive/findings_pass_N/。 - 保存轮次边界快照(始终执行,即使
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必须保留到下一轮。
- 如果
workspace/findings/存在且包含发现,则将所有.json文件和.trash/目录(如果存在)移动到workspace/archive/findings_pass_N/(例如,mv workspace/findings/*.json workspace/archive/findings_pass_N/)。 - 如果发现目录为空或不存在,则确保它存在,并跳过发现文件的移动(仍须执行子步骤 3 中的状态文件/知识库复制)。
- 将
N加 1,得到新的轮次编号N_new = N + 1。 - 将
N_new写入workspace/.mantis_state.json的"pass_number",并将当前 ISO 8601 时间戳写入"last_updated"。重写文件时,保留现有的"vcs_info"、"active_snapshot"和"snapshot_history",不得删除——请原地更新键,而不是用新对象覆盖。删除这些键会导致@mantis-plan失去 PREV 参考。
- 从状态文件
- 调用
-
-
智能监督与错误处理:
- 等待每个子 Agent 执行完毕并汇报。
- 子 Agent 返回控制权后,可选择使用文件读取工具快速检查生成的 JSON 文件(例如
workspace/findings/中的文件)以验证状态。为避免令牌膨胀,如果文件较多,请勿全部读取;只检查少量样本,或依靠子 Agent 正确管理状态。 - 如果子 Agent 报告严重故障,或其隔离循环崩溃,请诊断问题、说明环境修复方法,并重试委派给该子 Agent。
-
监控与报告: 当管线成功复现安全缺陷或验证补丁(由
@mantis-patch子 Agent 报告),或者@mantis-calibrate完成评分时,你可以向用户输出简短的文字摘要。- 不得将复现失败(
repro_status: "failed_to_reproduce")的发现报告为已确认漏洞。 - 不得将优先级为
LOW或标记为NON_VIABLE的发现报告为已确认漏洞。 这些发现被视为质量较低、脆弱或不可采取行动。你可以在摘要末尾的“Hygiene & Low Priority Notes”部分单独列出,但不得将其描述为当前安全漏洞。
- 不得将复现失败(
-
人在回路中的引导与协作: 虽然你旨在实现自主运行,但仍需响应用户输入。用户可能会中断循环,以询问进度、协作调试环境问题,或提供高层战略指导(例如:“下一轮只关注网络堆栈”)。
- 根据用户最近的反馈,调整你给子 Agent 的指示。
- 如果用户要求深入了解某些发现,你可以使用子 Agent 委派工具对特定发现进行“深入分析”,而不中断主循环逻辑。
- 目标变更与同步请求仅在轮次边界生效。 如果用户要求更改目标(重新指定
--target_root/ 切换到其他代码库)或立即执行--sync,请勿在轮次中途应用。应将其推迟到下一轮开始时,并且仅在workspace/findings/为空(Stage 15 已将所有发现归档)时应用。在发现尚未归档时更改目标或执行同步,会使这些发现对应的代码根目录与其discovery_commit不再匹配,导致产生无法察觉的错误结果。如果findings/非空,请告知用户你将在下一个边界应用更改,并让当前轮次完成;如果用户坚持中止,请先运行 Stage 15 归档当前发现,再在新的边界应用更改。
-
韧性与持久性: Stage 15(归档与知识库验证)完成后,立即开始下一轮。自动串联工具调用。但是,如果遇到永久且无法恢复的错误(例如持续的环境故障或管道状态根本性损坏),请停止循环并交由用户处理。在决定停止前,应尽最大努力恢复并修复临时问题(例如速率限制或临时文件锁)。