mantis-pipeline-adapter

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Mantis Pipeline Designer (/mantis-pipeline-adapter)

Mantis Pipeline Designer (/mantis-pipeline-adapter)

System Goal

系统目标

Interactive Pipeline Design Consultant. Assists the user in designing and implementing their own deterministic orchestrator harness for Mantis Skills. Helps the user apply best practices for reliability, token efficiency, and custom environment integration.
交互式管道设计顾问。协助用户为Mantis Skills设计和实现自己的确定性编排器工具包。帮助用户应用可靠性、令牌效率和自定义环境集成的最佳实践。

Command Definition

命令定义

  • Command:
    /mantis-pipeline-adapter
  • Description: Interactively guides the design and implementation of custom deterministic orchestrator harnesses.
  • 命令:
    /mantis-pipeline-adapter
  • 描述: 交互式指导自定义确定性编排器工具包的设计与实现。

Input/Output Contract

输入/输出契约

  • Reads:
    • workspace/.mantis_state.json
      (to track current loop pass).
    • workspace/.mantis_state.json
      fields
      active_snapshot
      ,
      snapshot_history
      , and
      vcs_info.snapshot_id
      — the per-pass snapshot pin, present only when the target harness has opted into sync (absent on today's single-snapshot runs; see Reference Architecture Guideline 5).
    • schema.json
      (as the canonical pipeline specification reference).
    • workspace/findings/*.json
      (as the State Store).
    • workspace/learnings.jsonl
      (to understand memory rotation).
    • User's interactive configuration input.
  • Writes:
    • Outputs user-customized orchestrator harness code, configurations, or architecture documentation.
  • Preconditions:
    • User initiates interactive design session.
  • Idempotency Guarantee:
    • As a consulting agent, it advises the user to implement idempotency in their custom harness using three primary mechanisms: (1) state store synchronization, (2) atomic transactional file/VCS operations, and (3) proper locks (e.g. database/file level locks).
  • 读取:
    • workspace/.mantis_state.json
      (用于跟踪当前循环轮次)。
    • workspace/.mantis_state.json
      中的
      active_snapshot
      snapshot_history
      vcs_info.snapshot_id
      字段——每轮次的快照固定标识,仅当目标工具包选择同步时存在(在当前单快照运行中不存在;请参考参考架构指南5)。
    • schema.json
      (作为规范的管道规格参考)。
    • workspace/findings/*.json
      (作为状态存储)。
    • workspace/learnings.jsonl
      (用于理解内存轮转机制)。
    • 用户的交互式配置输入。
  • 写入:
    • 输出用户定制的编排器工具包代码、配置或架构文档。
  • 前置条件:
    • 用户启动交互式设计会话。
  • 幂等性保证:
    • 作为咨询Agent,它建议用户使用三种主要机制在自定义工具包中实现幂等性:(1)状态存储同步,(2)原子事务性文件/VCS操作,(3)适当的锁(如数据库/文件级锁)。

Instructions

操作指南

Interactively guide the user in designing and building a deterministic pipeline that wraps Mantis Skills.
Follow these guidelines during the consultation:
  1. Understand User Context: Ask about their target programming language, agent framework (if any), execution environments (VMs, local containers, physical hardware), and scale requirements.
  2. Recommend Core Principles: Guide them to implement the reference architecture patterns (detailed below), specifically emphasizing:
    • Deterministic Orchestration: Use code (not LLM) for control flow.
    • State Store: Use a database or structured filesystem as the single source of truth.
    • Token Efficiency: Use the UUID-based referencing pattern to avoid LLM text duplication.
    • Custom Environment Integration: Use Custom MCP servers for isolated testing (VMs) or hardware interaction.
  3. Ensure Schema Consistency: Advise the user to strictly adhere to the inter-stage data contracts defined in schema.json when building their harness.
  4. Adaptive Design: Help them draft the code/architecture tailored to their specific stack, rather than imposing a rigid template.
  5. Advise on Scale and Concurrency: If they have high-scale needs, guide them on decomposing the pipeline and implementing locking mechanisms to prevent race conditions.
  6. Suggest Evaluations: Remind them to perform empirical evaluations when choosing cheaper models for utility stages.
  7. Advise the Pass Lifecycle Contract (living / synced codebases): If the user wants their harness to continue a run after the target code changes, or to sync the target repo at the start of a new pass, walk them through the harness-agnostic Pass Lifecycle Contract in Reference Architecture Guideline 5 below. Emphasize that this support is opt-in: a harness that does not implement the contract MUST leave
    snapshot_pinned
    unset, which preserves today's single-snapshot behavior byte-for-byte. When
    --sync
    is requested, the harness PINs in the PIN step and passes
    --snapshot_root
    /
    --snapshot_id
    normally; Block A (Locator Resolution) is universal across all code-reading stages.
  8. Advise on Semantic Retrieval at Scale: If the user is targeting a large codebase (e.g., thousands of source files, multi-pass campaigns, or multiple teams contributing findings), walk them through the optional semantic retrieval patterns in Reference Architecture Guidelines 6 and 7 below. Emphasize that these are opt-in: they augment the pipeline via a dedicated query skill or MCP tools, but never modify the existing skills' own deterministic logic or fail-safe invariants.
  9. Advise on SAST Seeding: If the user wants to augment LLM-based discovery with external SAST tool findings (CodeQL, Semgrep, etc.), walk them through the optional SAST seeding pattern in Reference Architecture Guideline 8 below. Emphasize that this is opt-in: it ingests external findings as candidates that must earn their verdict through unchanged downstream gates, and it follows exactly the RAG pattern (provenance-tracked, snapshot-aware, fallback on failure).
  10. Advise on Structural Code Indexing: If the user is targeting a large codebase where grep-based call-site discovery is unreliable, walk them through the optional structural code index stage in Reference Architecture Guideline 9 below. Emphasize that this is an optional first-class stage: it provides structural context (function boundaries, call graphs) to improve LLM reasoning, runs after the snapshot is pinned and before the first code-reading analysis stage, and degrades gracefully to grep when unavailable.
  11. Advise on Tiered Iterative Reproduction & Multi-Conversation Retries: If the user is targeting complex services where single-shot repro is brittle, walk them through the tiered iterative reproduction strategy and multi-conversation retry pattern in Reference Architecture Guideline 10.
交互式指导用户设计并构建封装Mantis Skills的确定性管道。
咨询过程中请遵循以下准则:
  1. 了解用户上下文: 询问他们的目标编程语言、Agent框架(如有)、执行环境(虚拟机、本地容器、物理硬件)以及规模需求。
  2. 推荐核心原则: 引导他们实现以下参考架构模式(下文详述),重点强调:
    • 确定性编排: 使用代码(而非LLM)控制流程。
    • 状态存储: 使用数据库或结构化文件系统作为单一事实来源。
    • 令牌效率: 使用基于UUID的引用模式避免LLM文本重复。
    • 自定义环境集成: 使用自定义MCP服务器进行隔离测试(虚拟机)或硬件交互。
  3. 确保Schema一致性: 建议用户在构建工具包时严格遵守schema.json中定义的阶段间数据契约。
  4. 自适应设计: 帮助他们根据特定技术栈起草代码/架构,而非强加僵化模板。
  5. 规模与并发建议: 如果用户有高规模需求,指导他们分解管道并实现锁定机制以防止竞态条件。
  6. 建议评估工作: 提醒他们在为通用阶段选择更便宜的模型时,需进行实证评估。
  7. 轮次生命周期契约建议(动态/同步代码库): 如果用户希望其工具包在目标代码变更后继续运行,或在新一轮次开始时同步目标仓库,请引导他们了解参考架构指南5中的工具包无关轮次生命周期契约。强调这是可选功能:未实现该契约的工具包必须保留
    snapshot_pinned
    未设置,这将完全保留当前单快照行为。当请求
    --sync
    时,工具包在PIN步骤中固定快照,并正常传递
    --snapshot_root
    /
    --snapshot_id
    ;Block A(定位器解析)在所有代码读取阶段通用。
  8. 大规模语义检索建议: 如果用户针对大型代码库(如数千个源文件、多轮次活动或多团队提交发现结果),请引导他们了解参考架构指南6和7中的可选语义检索模式。强调这是可选功能:它们通过专用查询技能或MCP工具增强管道,但绝不修改现有技能自身的确定性逻辑或故障安全不变量。
  9. SAST注入建议: 如果用户希望通过外部SAST工具发现结果(CodeQL、Semgrep等)增强基于LLM的发现,请引导他们了解参考架构指南8中的可选SAST注入模式。强调这是可选功能:它将外部发现结果作为候选输入,这些候选必须通过未修改的下游验证门才能获得最终结论,并且完全遵循RAG模式(可追溯来源、感知快照、失败时回退)。
  10. 结构化代码索引建议: 如果用户针对大型代码库,其中基于grep的调用站点发现不可靠,请引导他们了解参考架构指南9中的可选结构化代码索引阶段。强调这是可选的一级阶段:它提供结构化上下文(函数边界、调用图)以提升LLM推理能力,在快照固定后、首个代码读取分析阶段前运行,不可用时优雅降级为grep。
  11. 分层迭代复现与多对话重试策略建议: 如果用户针对复杂服务,其中单次复现不可靠,请引导他们了解参考架构指南10中的分层迭代复现策略和多对话重试模式。

Reference Architecture Guidelines

参考架构指南

Use the following guidelines as your technical reference when advising the user.
为用户提供建议时,请以下列准则作为技术参考。

Core Principles

核心原则

  1. Deterministic Orchestration: Do not let the LLM decide the control flow of the pipeline. Use a programmatic harness to call skills sequentially or in parallel.
  2. State on Disk / Database: Use the filesystem (
    workspace/findings/*.json
    ) or a database as the single source of truth. Skills should read from and write to this store. For horizontal scaling, recommend a centralized database.
  3. Deterministic Reporting: Treat findings as internal state. Minimize the use of the LLM to convert JSON findings into Markdown reports for human consumption; instead, write deterministic scripts to render the JSON into reports or upload them to bug trackers. Only use an LLM for non-deterministic subsets of this (like textual synthesis), such as by providing an executive summary if necessary.
  4. Token Efficiency & Reusable Deterministic Tools: Structure LLM outputs to return only the minimum necessary information (e.g., UUIDs, status codes). Do not force the LLM to write one-off scripts (e.g., Python or bash) on the fly for routine tasks like appending JSON fields or merging findings, as this wastes reasoning tokens. Instead, the harness should provide reusable, deterministic tools (such as pre-written helper scripts or MCP endpoints) that the LLM can simply invoke to perform text manipulation and state updates.
  5. State Store & Memory Rotation: To prevent token bloat and infinite loops, ephemeral queues (like
    workspace/learnings.jsonl
    ) must be rotated. Upon successful completion and verification of the Knowledge Base synthesis stage, the orchestrator should ensure the archive directory exists (e.g.,
    mkdir -p workspace/archive/learnings/
    ) and move
    workspace/learnings.jsonl
    to a numbered archive (e.g.,
    workspace/archive/learnings/learnings_pass_${N}_${X}.jsonl
    where
    ${N}
    is the loop pass and
    ${X}
    is a sub-index). If the synthesis fails, the active queue must be left intact to prevent data loss.
  1. 确定性编排: 不要让LLM决定管道的控制流。使用程序化工具包按顺序或并行调用技能。
  2. 磁盘/数据库状态: 使用文件系统(
    workspace/findings/*.json
    )或数据库作为单一事实来源。技能应从此存储读取并写入。对于水平扩展,建议使用集中式数据库。
  3. 确定性报告: 将发现结果视为内部状态。尽量减少使用LLM将JSON发现结果转换为Markdown报告供人类阅读;相反,编写确定性脚本将JSON渲染为报告或上传到缺陷跟踪系统。仅在非确定性子集(如文本合成)中使用LLM,例如必要时提供执行摘要。
  4. 令牌效率与可重用确定性工具: 构建LLM输出以仅返回必要的最小信息(如UUID、状态码)。不要强迫LLM为常规任务(如追加JSON字段或合并发现结果)动态编写一次性脚本(如Python或bash),这会浪费推理令牌。相反,工具包应提供可重用的确定性工具(如预编写的辅助脚本或MCP端点),LLM只需调用这些工具即可执行文本操作和状态更新。
  5. 状态存储与内存轮转: 为防止令牌膨胀和无限循环,必须轮转临时队列(如
    workspace/learnings.jsonl
    )。在知识库合成阶段成功完成并验证后,编排器应确保归档目录存在(例如
    mkdir -p workspace/archive/learnings/
    ),并将
    workspace/learnings.jsonl
    移动到编号归档文件中(例如
    workspace/archive/learnings/learnings_pass_${N}_${X}.jsonl
    ,其中
    ${N}
    是循环轮次,
    ${X}
    是子索引)。如果合成失败,活动队列必须保持不变以防止数据丢失。

Architectural Overview

架构概述

mermaid
graph TD
    Harness[Programmatic Harness / Orchestrator] <--> DB[(State Store: Disk/DB)]

    subgraph Stages [Decomposed Stages]
        KB[KB Architect]
        TM[Threat Modeler]
        P[Plan]
        R[Researcher]
        D[Deduplicator]
        V[Validator/Review]
        C[Critic]
        Rep[Reproducer]
        Ch[Chainer]
        Pat[Patcher]
        Cal[Calibrator]
        Ref[Reflector]
    end

    Harness --> KB
    Harness --> TM
    Harness --> P
    Harness --> R
    Harness --> D
    Harness --> V
    Harness --> C
    Harness --> Rep
    Harness --> Ch
    Harness --> Pat
    Pat -.->|Re-attack Bypass Loop| Rep
    Harness --> Cal
    Harness --> Ref

    subgraph LLM Pool [Tailored LLMs]
        ModelA[Frontier Model: Deep Reasoning]
        ModelB[Flash/Lite Model: Fast & Cheap]
        ModelC[Alternative Provider: Diversified Logic]
    end

    KB -.-> ModelA
    TM -.-> ModelB
    P -.-> ModelB
    R -.-> ModelA
    R -.-> ModelC
    D -.-> ModelB
    V -.-> ModelB
    C -.-> ModelA
    Rep -.-> ModelA
    Ch -.-> ModelA
    Pat -.-> ModelA
    Cal -.-> ModelB
    Ref -.-> ModelB
mermaid
graph TD
    Harness[Programmatic Harness / Orchestrator] <--> DB[(State Store: Disk/DB)]

    subgraph Stages [Decomposed Stages]
        KB[KB Architect]
        TM[Threat Modeler]
        P[Plan]
        R[Researcher]
        D[Deduplicator]
        V[Validator/Review]
        C[Critic]
        Rep[Reproducer]
        Ch[Chainer]
        Pat[Patcher]
        Cal[Calibrator]
        Ref[Reflector]
    end

    Harness --> KB
    Harness --> TM
    Harness --> P
    Harness --> R
    Harness --> D
    Harness --> V
    Harness --> C
    Harness --> Rep
    Harness --> Ch
    Harness --> Pat
    Pat -.->|Re-attack Bypass Loop| Rep
    Harness --> Cal
    Harness --> Ref

    subgraph LLM Pool [Tailored LLMs]
        ModelA[Frontier Model: Deep Reasoning]
        ModelB[Flash/Lite Model: Fast & Cheap]
        ModelC[Alternative Provider: Diversified Logic]
    end

    KB -.-> ModelA
    TM -.-> ModelB
    P -.-> ModelB
    R -.-> ModelA
    R -.-> ModelC
    D -.-> ModelB
    V -.-> ModelB
    C -.-> ModelA
    Rep -.-> ModelA
    Ch -.-> ModelA
    Pat -.-> ModelA
    Cal -.-> ModelB
    Ref -.-> ModelB

1. UUID-Based Referencing Pattern

1. 基于UUID的引用模式

To prevent the LLM from repeating large blocks of text (which increases latency, cost, and the risk of mangling data), use UUIDs as the primary key for all findings.
为防止LLM重复大段文本(增加延迟、成本和数据损坏风险),使用UUID作为所有发现结果的主键。

A. Researcher Stage

A. 研究员阶段

  • Action: Sweeps the codebase and identifies potential vulnerabilities.
  • LLM Output: Generates a unique UUID for each finding and writes
    workspace/findings/<UUID>.json
    containing the full details (matching the standard schema in Mantis Researcher).
  • 操作: 扫描代码库并识别潜在漏洞。
  • LLM输出: 为每个发现结果生成唯一UUID,并写入包含完整详细信息的
    workspace/findings/<UUID>.json
    (符合Mantis Researcher中的标准Schema)。

B. Deduplication Stage (Optimized)

B. 去重阶段(优化版)

Instead of asking the LLM to read all findings, merge them in context, and write them back, use the following pattern:
  1. Harness Action: Reads all
    workspace/findings/*.json
    files and prepares a summary list for the LLM containing only key identifiers. To align with the standard schema, map the
    code_paths
    array (which uses
    "file:line"
    format) to a simplified summary for the LLM:
    [ { "id": "UUID", "file": "path", "line": 12, "snippet": "..." } ]
    .
  2. LLM Action: Analyzes the summary and outputs a mapping of duplicates:
    json
    {
      "primary_uuid_1": ["duplicate_uuid_a", "duplicate_uuid_b"],
      "primary_uuid_2": []
    }
  3. Harness Action (Deterministic):
    • Reads the content of the affected files.
    • Programmatically merges fields following the rules in Mantis Deduplicator (e.g., union of
      code_paths
      , taking highest severity, concatenating history).
    • Updates
      workspace/findings/primary_uuid_1.json
      on disk.
    • Ensures the trash directory exists (e.g.,
      mkdir -p workspace/findings/.trash/
      ).
    • Moves
      workspace/findings/duplicate_uuid_a.json
      and
      workspace/findings/duplicate_uuid_b.json
      to the trash staging directory (
      workspace/findings/.trash/
      ).
不要让LLM读取所有发现结果、在上下文中合并并写回,而是使用以下模式:
  1. 工具包操作: 读取所有
    workspace/findings/*.json
    文件,并为LLM准备仅包含关键标识符的摘要列表。为符合标准Schema,将
    code_paths
    数组(使用
    "file:line"
    格式)映射为LLM的简化摘要:
    [ { "id": "UUID", "file": "path", "line": 12, "snippet": "..." } ]
  2. LLM操作: 分析摘要并输出重复项映射:
    json
    {
      "primary_uuid_1": ["duplicate_uuid_a", "duplicate_uuid_b"],
      "primary_uuid_2": []
    }
  3. 工具包操作(确定性):
    • 读取受影响文件的内容。
    • 按照Mantis Deduplicator中的规则以编程方式合并字段(例如
      code_paths
      的并集、取最高严重性、串联历史记录)。
    • 更新磁盘上的
      workspace/findings/primary_uuid_1.json
    • 确保垃圾目录存在(例如
      mkdir -p workspace/findings/.trash/
      )。
    • workspace/findings/duplicate_uuid_a.json
      workspace/findings/duplicate_uuid_b.json
      移动到垃圾暂存目录(
      workspace/findings/.trash/
      )。

C. Validation & Review Stages (Reviewer, Critic)

C. 验证与评审阶段(评审员、评论员)

  • Harness Action: For each finding
    workspace/findings/<UUID>.json
    , pass only the relevant code context and finding description to the LLM.
  • LLM Action: Output only a structured verification result (e.g.,
    {"valid": true, "reason": "..."}
    ).
  • Harness Action (Deterministic): Programmatically update the
    workspace/findings/<UUID>.json
    file with the validation status and reason.
  • 工具包操作: 对于每个发现结果
    workspace/findings/<UUID>.json
    ,仅将相关代码上下文和发现描述传递给LLM。
  • LLM操作: 仅输出结构化验证结果(例如
    {"valid": true, "reason": "..."}
    )。
  • 工具包操作(确定性): 以编程方式更新
    workspace/findings/<UUID>.json
    文件,添加验证状态和原因。

2. Adaptable Reproducers via Custom MCP

2. 通过自定义MCP实现自适应复现器

When validating findings, the agent may need to interact with diverse environments (VMs, physical hardware). Use the Model Context Protocol (MCP) to expose a clean, restricted API.
  • Architecture:
    [Reproducer Agent] <--- MCP ---> [Custom MCP Server] <--- API ---> [Target Env]
  • Custom Environments:
    • VMs: Implement tools like
      reboot_vm()
      ,
      execute_payload()
      .
    • Hardware/USB: Implement tools like
      power_cycle_device()
      (via smart plug),
      send_usb_packet()
      .
  • Integration Note: If the user's harness uses raw LLM APIs (e.g., direct Gemini API calls) instead of an MCP-native client framework, the harness must manually register these tools in the API's schema format and handle dispatching tool calls to the MCP server.
验证发现结果时,Agent可能需要与多样化环境(虚拟机、物理硬件)交互。使用**模型上下文协议(MCP)**公开清晰、受限的API。
  • 架构:
    [Reproducer Agent] <--- MCP ---> [Custom MCP Server] <--- API ---> [Target Env]
  • 自定义环境:
    • 虚拟机: 实现
      reboot_vm()
      execute_payload()
      等工具。
    • 硬件/USB: 实现
      power_cycle_device()
      (通过智能插头)、
      send_usb_packet()
      等工具。
  • 集成说明: 如果用户的工具包使用原始LLM API(如直接调用Gemini API)而非MCP原生客户端框架,工具包必须手动将这些工具注册到API的Schema格式中,并处理将工具调用分派到MCP服务器的逻辑。

3. Decomposition & Multi-Model Strategy

3. 分解与多模型策略

A. Pipeline Decomposition & Concurrency

A. 管道分解与并发

The pipeline can be split into independent services. When scaling horizontally (e.g., multiple workers running the
Reproducer
stage in parallel):
  • Concurrency Control: Implement database or file locking to ensure two workers do not attempt to process or update the same finding simultaneously.
  • Parallel Trajectory Search: For deep reasoning stages (
    Reproducer
    ,
    Patcher
    ), spawn multiple parallel agents attempting to solve the exact same finding using diverse logic paths. For the
    Reproducer
    stage, prune all other trajectories as soon as one worker succeeds to save compute costs while escaping LLM "give up" loops. For the
    Patcher
    stage, wait for all patches to be generated and tested, then evaluate the successful ones to select the most minimal, idiomatic, and correct fix.
管道可拆分为独立服务。水平扩展时(例如多个并行运行
Reproducer
阶段的工作进程):
  • 并发控制: 实现数据库或文件锁定,确保两个工作进程不会同时处理或更新同一个发现结果。
  • 并行轨迹搜索: 对于深度推理阶段(
    Reproducer
    Patcher
    ),生成多个并行Agent,使用不同逻辑路径尝试解决同一个发现结果。对于
    Reproducer
    阶段,一旦某个工作进程成功,立即修剪所有其他轨迹以节省计算成本,同时避免LLM“放弃”循环。对于
    Patcher
    阶段,等待所有补丁生成并测试完成,然后评估成功的补丁以选择最精简、符合编码规范且正确的修复方案。

B. Heterogeneous LLM Selection (Multi-Model)

B. 异构LLM选择(多模型)

Match task complexity with the appropriate model tier:
  • Frontier Models: For deep reasoning (Research, Reproduce, Patch).
  • Flash/Lite Models: For structured utility tasks (Dedupe, Calibrate).
  • Variability: Run different models in parallel during the Research stage to increase bug-hunting coverage.
根据任务复杂度匹配相应的模型层级:
  • 前沿模型: 用于深度推理(研究、复现、补丁)。
  • 快速/轻量模型: 用于结构化通用任务(去重、校准)。
  • 多样性: 在研究阶段并行运行不同模型以提高漏洞发现覆盖率。

C. Importance of Evaluation

C. 评估的重要性

Emphasize that using cheaper models for utility stages (like deduplication or calibration) must be validated with empirical evaluations against a benchmark dataset to ensure quality is not degraded.
强调为通用阶段(如去重或校准)使用更便宜的模型时,必须针对基准数据集进行实证评估以确保质量不下降。

4. The Planning Stage and workspace/plan.json

4. 规划阶段与workspace/plan.json

The planning stage plays a critical role in structuring the security campaign. The strategist (
/mantis-plan
) generates
workspace/plan.json
to define targeted investigations, context pointers, and specific questions for the auditor. The researcher (
/mantis-researcher
) reads
workspace/plan.json
at startup to guide its sweep. By decoupling strategy and execution via this structured contract, the orchestrator can easily direct subagents, parallelize sweeps, and maintain historical context across pipeline runs without repeating work.
规划阶段在构建安全活动中起着关键作用。策略器(
/mantis-plan
)生成
workspace/plan.json
,定义针对性调查、上下文指针和审计员的具体问题。研究员(
/mantis-researcher
)在启动时读取
workspace/plan.json
以指导扫描。通过此结构化契约解耦策略与执行,编排器可以轻松指导子Agent、并行化扫描,并在管道运行之间维护历史上下文而无需重复工作。

5. The Pass Lifecycle Contract (Living / Synced Codebases)

5. 轮次生命周期契约(动态/同步代码库)

A custom orchestrator (a bespoke CLI, an ADK agent, an MCP-native pipeline, or any deterministic harness) does not inherit the living-project lifecycle that
mantis-meta-agent
implements. To support continue-after-edits and opt-in boundary sync without producing silent wrong results (false
VERIFIED_SECURE
, false
failed_to_reproduce
, dropped regressions), the harness must implement the following harness-agnostic contract. This is the same contract recorded in schema.json under Non-JSON Contracts; the
Block A
Block G
and
SNAPSHOT_ID
references below name mechanisms each Mantis stage already carries in its own
SKILL.md
.
Mantis runs under multiple harnesses (various CLIs, ADK, custom deterministic pipelines), so the lifecycle must not live only in
mantis-meta-agent
. Any harness is conformant iff, per pass, it:
  1. SYNCs first (Block C) — the very first action; never mid-pass.
  2. Detects
    vcs_info
    + computes
    SNAPSHOT_ID
    (Block D steps 1-5) — only after sync.
  3. PINs the immutable copy + writes the sentinel + appends
    snapshot_history
    (Block D step 5, not RECORD).
  4. Records
    vcs_info
    (incl.
    snapshot_id
    ) +
    active_snapshot
    . Never record an id or pin before syncing.
  5. Runs every stage with
    --snapshot_root=<SNAPSHOT_ROOT> --snapshot_id=<SNAPSHOT_ID> --state_root=<workspace parent>
    .
  6. Archives & increments (existing Stage 15); retried findings keep their original
    discovery_commit
    .
A harness that does not implement the contract MUST leave
snapshot_pinned
unset → today's behavior. When
--sync
is requested, the harness PINs in the PIN step and passes
--snapshot_root
/
--snapshot_id
normally; Block A (Locator Resolution) is universal across all code-reading stages.
自定义编排器(定制CLI、ADK Agent、MCP原生管道或任何确定性工具包)不继承
mantis-meta-agent
实现的动态项目生命周期。为支持编辑后继续和*可选边界同步且不产生静默错误结果(错误的
VERIFIED_SECURE
、错误的
failed_to_reproduce
、遗漏的回归),工具包必须实现以下工具包无关契约。此契约与schema.jsonNon-JSON Contracts下记录的契约相同;下文的
Block A
Block G
SNAPSHOT_ID
引用指每个Mantis阶段在其自身
SKILL.md
中已有的机制。
Mantis在多种工具包下运行(各种CLI、ADK、自定义确定性管道),因此生命周期不能仅存在于
mantis-meta-agent
中。任何工具包符合要求当且仅当,每轮次它:
  1. 首先执行SYNC(Block C)——这是第一个操作;绝不在轮次中途执行。
  2. 检测
    vcs_info
    并计算
    SNAPSHOT_ID
    (Block D步骤1-5)——仅在同步后执行。
  3. 固定不可变副本 + 写入标记 + 追加
    snapshot_history
    (Block D步骤5,不是RECORD)。
  4. 记录
    vcs_info
    (包括
    snapshot_id
    ) +
    active_snapshot
    。绝不在同步前记录ID或固定快照。
  5. 运行所有阶段时传递
    --snapshot_root=<SNAPSHOT_ROOT> --snapshot_id=<SNAPSHOT_ID> --state_root=<workspace parent>
  6. 归档并递增(现有阶段15);重试的发现结果保留其原始
    discovery_commit
未实现该契约的工具包必须保留
snapshot_pinned
未设置 → 当前行为。当请求
--sync
时,工具包在PIN步骤中固定快照,并正常传递
--snapshot_root
/
--snapshot_id
;Block A(定位器解析)在所有代码读取阶段通用。

Advisory notes when helping a builder implement this contract

帮助构建者实现此契约的建议说明

  • Opt-in, default off. Sync/pinning is a feature the builder turns on. A harness that never sets
    snapshot_pinned
    behaves exactly like today (one live snapshot per run). Downstream stages treat an absent
    active_snapshot
    /
    discovery_commit
    as the conservative branch, so an un-upgraded harness is always safe — just not living-project-aware. Do not advise treating these absent fields as an error.
  • Store snapshots OUTSIDE
    workspace/
    .
    The pinned copy (
    SNAPSHOT_ROOT
    ) must live under
    <state_root>/.mantis_snapshots/pass_<N>
    (or a clean-VCS worktree/archive), and its path must not contain the segment
    /workspace/
    — otherwise
    mantis-patch
    's state-vs-code path guard misfires. Keep the last 2 snapshots and garbage-collect older ones with the matching teardown (
    rm -rf
    for copies,
    git worktree remove/prune
    for worktrees).
  • Non-destructive sync only. Sync is the first action of a pass, never mid-pass, and must be skipped when the tree is dirty, ahead of upstream, detached, or has no upstream. The harness must never run
    git reset --hard
    ,
    git checkout -- .
    ,
    git clean
    , or
    hg update -C
    , or any command that discards uncommitted/untracked/local-commit state — user edits and in-progress work must survive every pass.
  • Full-fidelity
    SNAPSHOT_ID
    s, including dirty / no-VCS.
    Compute the id over the whole pinned copy: clean git/hg →
    commit_hash
    ; dirty git/hg →
    commit_hash + ":" + content_hash
    ; multi-vcs →
    revision + ":" + content_hash
    ; no-VCS / unknown copyable tree →
    "content:" + content_hash
    . The embedded content hash is exactly what lets an unchanged dirty or no-VCS tree MATCH across passes and still receive verification + dedup — and what makes a
    repo sync
    that advances commits under an unchanged manifest
    revision
    compare unequal. Never trust a bare branch name or manifest revision string as an identity.
  • Pass the three roots to EVERY stage. Include the findings-only stages (report, calibrate, reflect): they do not read target code, but they still read
    active_snapshot
    for provenance/annotation. When the harness archives and increments, retried findings must keep their original
    discovery_commit
    .
  • 可选功能,默认关闭。 同步/固定是构建者开启的功能。从未设置
    snapshot_pinned
    的工具包行为与当前完全相同(每次运行一个实时快照)。下游阶段将缺失的
    active_snapshot
    /
    discovery_commit
    视为保守分支,因此未升级的工具包始终安全——只是不感知动态项目。不要建议将这些缺失字段视为错误。
  • 将快照存储在
    workspace/
    之外。
    固定副本(
    SNAPSHOT_ROOT
    )必须位于
    <state_root>/.mantis_snapshots/pass_<N>
    (或干净的VCS工作树/归档)下,其路径不得包含
    /workspace/
    段——否则
    mantis-patch
    的状态与代码路径保护机制会误触发。保留最后2个快照,并通过相应的清理操作垃圾回收旧快照(副本使用
    rm -rf
    ,工作树使用
    git worktree remove/prune
    )。
  • 仅非破坏性同步。 同步是轮次的第一个操作,绝不在轮次中途执行,并且当代码树脏、领先于上游、分离或没有上游时必须跳过。工具包绝不能运行
    git reset --hard
    git checkout -- .
    git clean
    hg update -C
    ,或任何丢弃未提交/未跟踪/本地提交状态的命令——用户编辑和进行中的工作必须在每轮次后保留。
  • 全保真
    SNAPSHOT_ID
    ,包括脏状态/无VCS。
    基于整个固定副本计算ID:干净的git/hg →
    commit_hash
    ;脏的git/hg →
    commit_hash + ":" + content_hash
    ;多VCS →
    revision + ":" + content_hash
    ;无VCS/未知可复制树 →
    "content:" + content_hash
    。嵌入的内容哈希正是让未更改的脏状态或无VCS树在轮次间匹配并仍能接收验证 + 去重的原因——也是使清单
    revision
    不变但提交前进的仓库同步比较不相等的原因。永远不要信任裸分支名称或清单修订字符串作为标识。
  • 将三个根传递给每个阶段。 包括仅处理发现结果的阶段(报告、校准、反思):它们不读取目标代码,但仍读取
    active_snapshot
    用于来源/注释。当工具包归档并递增时,重试的发现结果必须保留其原始
    discovery_commit

Conformance scenarios

合规场景

The scenarios below expose nearly every issue in the snapshot model. They are reference checks, not features: the harness is responsible for preventing or handling each one in its own environment. The table is a quick-reference; prose detail follows for each scenario. The State column uses the 3-STATE RULE (MODE-OFF / HALT / PINNED, branched on
active_snapshot
presence — see the global backward-compat rule in schema.json and the advisory notes above);
SNAPSHOT_ID
formats follow the ladder in the advisory notes above (e.g.
live:<ts>
signals an unpinned/HALT pass).
Invariant legend (the labels below name safety properties enforced by the blocks and the global backward-compat rule in schema.json):
LabelPropertyEnforced by
INV-1No false
VERIFIED_SECURE
Block G + HALT ceiling
INV-2No false
failed_to_reproduce
Block F + HALT ceiling
INV-3No dropped regressionBlock B NOT_MATCHED + POSSIBLE REGRESSION
INV-4Within-pass consistencyBlock A sentinel + single pinned snapshot
INV-5No user data lossBlock C non-destructive sync + Block A step 4
INV-6Fail-safe on missing dataGlobal backward-compat rule
Quick-reference table:
#ScenarioStateHarness behaviorStage behaviorBlock / INVKey fields
1Colocated statePINNEDHALT-and-yield (safe default), or relocate
state_root
outside
CODE_ROOT
when explicitly authorized (e.g.
--auto_relocate_state
);
SNAPSHOT_ROOT
path must not contain
/workspace/
mantis-patch
state-vs-code guard misfires; Block A step 3 confuses SNAPSHOT- vs STATE-relative paths
A:3, D:3; INV-5
active_snapshot.root
,
snapshot_root
,
state_root
2Stale active_snapshot (
active_snapshot.pass != state.pass_number
)
PINNED → STOP or HALT-degradeBlock D step 0: handles same-pass re-entry only; if dir missing → STOP, yield to userBlock A step 2 sentinel may still MATCH (dir retained); CURRENT-PASS CHECK (
active_snapshot.pass == state.pass_number
) required: mismatch → STOP or HALT-degrade (Block B NOT_MATCHED, no authoritative verdicts)
A:2, D:0, B; INV-1, INV-3, INV-4, INV-6
active_snapshot.{root, snapshot_id, snapshot_pinned, pass}
,
state.pass_number
,
discovery_commit
3Pin failureHALTBlock D step 2/4: skip copy on ENOSPC/error → step 5b; still write
active_snapshot
+ pass roots
Authoritative verdicts forbidden; Block B always NOT_MATCHED; reproduce
not_attempted
; patch
VERIFICATION_INCOMPLETE
D:2, D:4, D:5b; INV-1, INV-2, INV-6
active_snapshot.{snapshot_id, snapshot_pinned}
4Patched shadowsPINNED (pass);
--snapshot_pinned=false
arg
Pass
--target_root=<PATCHED_SHADOW_ROOT>
+
--snapshot_pinned=false
to reattack sub-agent
Block A step 1a:
CODE_ROOT=--target_root
(authoritative); step 2 sentinel SKIPPED (sentinel-EXEMPT)
A:1a, A:2; INV-4
target_root
,
snapshot_pinned
(arg),
snapshot_root
,
discovery_commit
5Different-snapshot duplicate candidatesPINNEDNo special action — both passes pinned correctly; dedupe handles itBlock B pairwise:
discovery_commit
differs → NOT_MATCHED → keep ACTIVE +
possible_duplicate_of
; POSSIBLE REGRESSION if archived was RESOLVED
B; INV-3, INV-6
discovery_commit
,
possible_duplicate_of
,
status
,
patch_status
6Absent sink evidenceAnyNo special action — Block F is a stage-level mechanical gateBlock F: evidence absent (build error, exit 127, sink unreached) →
not_attempted
(retry-eligible), NEVER
failed_to_reproduce
; HALT ceiling additionally forces
not_attempted
F; INV-2, INV-6
repro_status
,
reattack_status
,
repro_hints
Per-scenario detail:
1. Colocated state (
state_root
nested inside
CODE_ROOT
/ snapshot root) — The pinned
SNAPSHOT_ROOT
must live under
<state_root>/.mantis_snapshots/pass_<N>
(or a clean-VCS worktree/archive), and its path must not contain the segment
/workspace/
— otherwise
mantis-patch
's state-vs-code path guard misfires (state files appear to be "under
CODE_ROOT
"). If
state_root
itself is inside
CODE_ROOT
, the harness must HALT-and-yield (safe default) or, when explicitly authorized (e.g.
--auto_relocate_state
), relocate it outside the snapshot before pinning. Block A step 3 distinguishes SNAPSHOT-RELATIVE path fields (read under
CODE_ROOT
) from STATE-RELATIVE fields (read under
state_root/workspace
, never prefixed with
CODE_ROOT
); colocation breaks this separation.
2. Stale active_snapshot (
active_snapshot.pass != state.pass_number
active_snapshot
was preserved across the Stage 15 pass increment) — Block D step 0 (crash-resume) handles only the SAME-pass re-entry case (
active_snapshot.pass == N
→ reuse). It does NOT catch a stale snapshot carried across the Stage 15 pass increment, because Stage 15 deliberately preserves
active_snapshot
while bumping
pass_number
(see Stage 15). Two sub-cases:
(a) The prior snapshot dir is now MISSING: Block D step 0 STOPs and yields to the user (never re-pin to a possibly-drifted live tree). (b) The prior snapshot dir still EXISTS (default keep-2 retention) and its sentinel matches the preserved
active_snapshot.snapshot_id
: Block A step 2 sentinel check SUCCEEDS (it only compares the sentinel file to
SNAPSHOT_ID
, not to the current pass). Block B's pairwise
discovery_commit
check would MATCH a carried-forward finding against a new finding stamped with the same stale
SNAPSHOT_ID
, silently dropping it as
DUPLICATE
— a false authoritative verdict.
To prevent (b), the HARNESS MUST guarantee that
active_snapshot.pass == state.pass_number
before any consumer stage reads it. The reference harness (
mantis-meta-agent
) satisfies this by re-pinning every pass (Block D step 0 sees
active_snapshot.pass != N
→ re-pins → refreshes
active_snapshot.pass
before any stage runs), so sub-case (b) never fires there. A custom harness that preserves
active_snapshot
across the Stage 15 pass increment WITHOUT re-pinning MUST either (a) re-pin every pass (the reference behavior), or (b) inject an equivalent pre-stage gate that refreshes
active_snapshot.pass
or clears
active_snapshot
entirely before invoking stages. Stages CANNOT self-detect this staleness via Block B (which is
snapshot_id
-only, not
pass
-aware): a carried-forward finding and a new finding stamped with the same stale
SNAPSHOT_ID
will MATCH in Block B despite the snapshot being stale. The
active_snapshot.pass
field is defined in
schema.json
#/$defs/state/active_snapshot/pass
for exactly this check. The harness's Block D step 0 reuse check is NOT a substitute: it only fires on same-pass re-entry. (Stages that read
active_snapshot
MAY additionally self-check defensively — see each stage's Step 0 sentinel check — but the binding guarantee is on the harness.)
3. Pin failure (snapshot copy fails — disk full, permissions, too-large tree) — Block D step 2 (free-space precheck): compare
du -s
of the live tree to
df
free space at
state_root
; if it won't fit → skip copy → step 5b. Block D step 4 (failure-tolerant verify): check copy exit status + sanity check (file count/size within ~90%); on failure → step 5b (unpinned/HALT). Step 5b:
SNAPSHOT_ROOT=<live root>
,
snapshot_pinned=false
,
SNAPSHOT_ID="live:"+ISO8601
. The harness still writes
active_snapshot
and still passes
--snapshot_root
/
--snapshot_id
to stages so they see the HALT signal. Every stage then degrades conservatively: authoritative verdicts forbidden (
VERIFIED_SECURE
,
failed_to_reproduce
,
DUPLICATE
,
FALSE_POSITIVE
,
NON_VIABLE
); Block B always returns NOT_MATCHED; reproduce records
not_attempted
; patch's best attainable is
VERIFICATION_INCOMPLETE
.
4. Patched shadows (
--target_root
pointing at a pre-mutated tree; sentinel-exempt path 1a in Block A) —
mantis-patch
passes
--target_root=<PATCHED_SHADOW_ROOT>
and
--snapshot_pinned=false
to the reproduce sub-agent for re-attack verification. Block A step 1a:
CODE_ROOT = --target_root
(authoritative override, overrides
--snapshot_root
and state fallback). Block A step 2: sentinel check SKIPPED (a
--target_root
tree is deliberately mutated and is sentinel-EXEMPT). The
--snapshot_pinned=false
argument is the sentinel-exemption, NOT a HALT signal — detect HALT by reading STATE (
active_snapshot.snapshot_id
starts with
live:
, equivalently
active_snapshot.snapshot_pinned
is
false
in state), never from the argument passed on this invocation. The finding's
discovery_commit
is unaffected — it retains the pass-level
SNAPSHOT_ID
from when it was discovered; only the
--snapshot_pinned=false
argument is local to the reattack invocation.
5. Different-snapshot duplicate candidates (cross-pass dedupe where
discovery_commit
differs — the pairwise Block B NOT_MATCHED path) — Both passes pinned correctly; the findings simply come from different snapshots.
mantis-dedupe
Block B pairwise check compares the CURRENT finding's
discovery_commit
against the ARCHIVED finding's
discovery_commit
(NOT against the global
SNAPSHOT_ID
). If they differ → NOT_MATCHED. NOT_MATCHED keeps the current finding ACTIVE and sets
possible_duplicate_of
(a soft, non-terminal hint — the finding is NOT filtered or trashed). If the archived finding was RESOLVED (
patch_status
in {
VERIFIED_SECURE
,
MITIGATION_PROPOSED
} OR
status
==
FALSE_POSITIVE
OR
production_viability
==
NON_VIABLE
) AND the pair is NOT_MATCHED → POSSIBLE REGRESSION: keep ACTIVE, add a history note, never filter (a reverted fix re-discovered on new code must never be trashed).
6. Absent sink evidence (Block F — PoC compiles but produces no reached-sink evidence;
not_attempted
vs
failed_to_reproduce
) —
mantis-reproduce
Block F: if EVIDENCE is ABSENT (any compiler/build nonzero exit, exit 127 command-not-found, exit 2 "No such file", or the sink was never reached) →
repro_status = not_attempted
(retry-eligible), STOP. NEVER
failed_to_reproduce
. In
--reattack
mode: leave
reattack_status
UNSET with a history note "setup_failed" — NEVER
failed_to_bypass
.
failed_to_reproduce
is reserved for when the harness PROVABLY reached the vulnerable entrypoint — i.e. reached-sink evidence, not setup evidence — but the bug did not fire. Reached-sink evidence must originate INSIDE the invoked path or from target-produced tracing/backtraces: (a) a PoC script/source harness writes
MANTIS_REACHED_ENTRYPOINT
to a sidecar file at the point just before the sink call, within its own execution flow (the marker write is part of the invoked path, not a pre-launch step); OR (b) for binary/firmware/raw-payload targets, the captured crash backtrace or sanitizer trace (ASan/UBSan/MSan/TSan) explicitly names the target sink function (target-produced tracing). A marker written by an external wrapper BEFORE invoking the target is SETUP EVIDENCE ONLY (proves "launch attempted," not "sink reached") and does NOT by itself justify
failed_to_reproduce
— treat it as EVIDENCE ABSENT for the decision gate. Evidence is recorded in
repro_hints
. In HALT mode, the HALT ceiling additionally forces
not_attempted
(no
failed_to_reproduce
), since a negative result on an unpinned tree cannot be trusted as authoritative.

以下场景暴露了快照模型中的几乎所有问题。它们是参考检查,而非功能:工具包负责在自身环境中预防或处理每个问题。下表是快速参考;每个场景的详细说明如下。状态列使用3-STATE规则(MODE-OFF / HALT / PINNED,基于
active_snapshot
是否存在分支——请参考schema.json中的全局向后兼容规则和上述建议说明);
SNAPSHOT_ID
格式遵循上述建议说明中的层级(例如
live:<ts>
表示未固定/HALT轮次)。
不变量图例(以下标签命名由块和schema.json中的全局向后兼容规则强制执行的安全属性):
标签属性强制执行者
INV-1无错误的
VERIFIED_SECURE
Block G + HALT上限
INV-2无错误的
failed_to_reproduce
Block F + HALT上限
INV-3无遗漏的回归Block B NOT_MATCHED + POSSIBLE REGRESSION
INV-4轮次内一致性Block A标记 + 单一固定快照
INV-5无用户数据丢失Block C非破坏性同步 + Block A步骤4
INV-6缺失数据时的故障安全全局向后兼容规则
快速参考表:
#场景状态工具包行为阶段行为块 / 不变量关键字段
1状态与代码同位置PINNEDHALT并返回(安全默认),或在明确授权时(如
--auto_relocate_state
)将
state_root
重新定位到
CODE_ROOT
之外;
SNAPSHOT_ROOT
路径不得包含
/workspace/
mantis-patch
状态与代码路径保护机制误触发;Block A步骤3混淆SNAPSHOT-与STATE-相对路径
A:3, D:3; INV-5
active_snapshot.root
,
snapshot_root
,
state_root
2过期的active_snapshot(
active_snapshot.pass != state.pass_number
PINNED → STOP或HALT降级Block D步骤0:仅处理同轮次重新进入;如果目录缺失 → STOP,返回给用户Block A步骤2标记可能仍匹配(目录保留);需要CURRENT-PASS检查(
active_snapshot.pass == state.pass_number
):不匹配 → STOP或HALT降级(Block B NOT_MATCHED,无权威结论)
A:2, D:0, B; INV-1, INV-3, INV-4, INV-6
active_snapshot.{root, snapshot_id, snapshot_pinned, pass}
,
state.pass_number
,
discovery_commit
3固定失败HALTBlock D步骤2/4:在ENOSPC/错误时跳过复制 → 步骤5b;仍写入
active_snapshot
并传递根参数
禁止权威结论;Block B始终返回NOT_MATCHED;复现状态为
not_attempted
;补丁状态为
VERIFICATION_INCOMPLETE
D:2, D:4, D:5b; INV-1, INV-2, INV-6
active_snapshot.{snapshot_id, snapshot_pinned}
4补丁影子PINNED(轮次);
--snapshot_pinned=false
参数
传递
--target_root=<PATCHED_SHADOW_ROOT>
+
--snapshot_pinned=false
给重攻击子Agent
Block A步骤1a:
CODE_ROOT=--target_root
(权威);步骤2标记跳过(标记豁免)
A:1a, A:2; INV-4
target_root
,
snapshot_pinned
(参数),
snapshot_root
,
discovery_commit
5不同快照的重复候选PINNED无特殊操作——两个轮次均正确固定快照;去重处理它Block B成对比较:
discovery_commit
不同 → NOT_MATCHED → 保留ACTIVE +
possible_duplicate_of
;如果归档结果已RESOLVED则标记为POSSIBLE REGRESSION
B; INV-3, INV-6
discovery_commit
,
possible_duplicate_of
,
status
,
patch_status
6缺失 sink 证据任何无特殊操作——Block F是阶段级机械门Block F:证据缺失(构建错误、退出码127、未到达sink)→
not_attempted
(可重试),绝不标记为
failed_to_reproduce
;HALT上限额外强制设置为
not_attempted
F; INV-2, INV-6
repro_status
,
reattack_status
,
repro_hints
按场景详细说明:
1. 状态与代码同位置
state_root
嵌套在
CODE_ROOT
/ 快照根目录内) — 固定的
SNAPSHOT_ROOT
必须位于
<state_root>/.mantis_snapshots/pass_<N>
(或干净的VCS工作树/归档)下,其路径不得包含
/workspace/
段——否则
mantis-patch
的状态与代码路径保护机制会误触发(状态文件似乎位于
CODE_ROOT
下)。如果
state_root
本身在
CODE_ROOT
内,工具包必须HALT并返回(安全默认),或在明确授权时(如
--auto_relocate_state
)在固定前将其重新定位到快照之外。Block A步骤3区分SNAPSHOT-RELATIVE路径字段(在
CODE_ROOT
下读取)与STATE-RELATIVE字段(在
state_root/workspace
下读取,从不以
CODE_ROOT
为前缀);同位置会破坏这种分离。
2. 过期的active_snapshot
active_snapshot.pass != state.pass_number
——
active_snapshot
在阶段15轮次递增后保留)——Block D步骤0(崩溃恢复)仅处理同轮次重新进入的情况(
active_snapshot.pass == N
→ 重用)。它不会捕获阶段15轮次递增后携带的过期快照,因为阶段15在增加
pass_number
时故意保留
active_snapshot
(请参考阶段15)。两个子场景:
(a) 先前的快照目录现在缺失:Block D步骤0 STOP并返回给用户(绝不重新固定到可能漂移的实时代码树)。(b) 先前的快照目录仍然存在(默认保留2个),且其标记与保留的
active_snapshot.snapshot_id
匹配:Block A步骤2标记检查成功(它仅比较标记文件与
SNAPSHOT_ID
,不与当前轮次比较)。Block B的成对
discovery_commit
检查会将携带的发现结果与带有相同过期
SNAPSHOT_ID
的新发现结果匹配,静默将其标记为
DUPLICATE
——错误的权威结论。
为防止(b),工具包必须保证在任何消费阶段读取
active_snapshot
之前,
active_snapshot.pass == state.pass_number
。参考工具包(
mantis-meta-agent
)通过每轮次重新固定来满足此要求(Block D步骤0发现
active_snapshot.pass != N
→ 重新固定 → 在任何阶段运行前刷新
active_snapshot.pass
),因此子场景(b)永远不会触发。在阶段15轮次递增后保留
active_snapshot
不重新固定的自定义工具包必须要么(a)每轮次重新固定(参考行为),要么(b)注入等效的预阶段门,在调用阶段前刷新
active_snapshot.pass
或完全清除
active_snapshot
。阶段无法通过Block B自行检测这种过期(它仅感知
snapshot_id
,不感知
pass
):携带的发现结果与带有相同过期
SNAPSHOT_ID
的新发现结果在Block B中会匹配,尽管快照已过期。
active_snapshot.pass
字段在
schema.json
#/$defs/state/active_snapshot/pass
中定义,正是为了此检查。工具包的Block D步骤0重用检查不能替代:它仅在同轮次重新进入时触发。(读取
active_snapshot
的阶段可以额外进行防御性自检——请参考每个阶段的步骤0标记检查——但绑定保证在工具包上。)
3. 固定失败(快照复制失败——磁盘已满、权限问题、代码树过大)——Block D步骤2(空闲空间预检查):将实时代码树的
du -s
state_root
df
空闲空间比较;如果无法容纳 → 跳过复制 → 步骤5b。Block D步骤4(容错验证):检查复制退出状态 + 健全性检查(文件计数/大小在~90%以内);失败时 → 步骤5b(未固定/HALT)。步骤5b:
SNAPSHOT_ROOT=<live root>
snapshot_pinned=false
SNAPSHOT_ID="live:"+ISO8601
。工具包仍写入
active_snapshot
,并仍将
--snapshot_root
/
--snapshot_id
传递给阶段,以便它们看到HALT信号。每个阶段随后保守降级:禁止权威结论(
VERIFIED_SECURE
failed_to_reproduce
DUPLICATE
FALSE_POSITIVE
NON_VIABLE
);Block B始终返回NOT_MATCHED;复现记录
not_attempted
;补丁的最佳可达状态为
VERIFICATION_INCOMPLETE
4. 补丁影子
--target_root
指向预修改的代码树;Block A中的标记豁免路径1a)——
mantis-patch
传递
--target_root=<PATCHED_SHADOW_ROOT>
--snapshot_pinned=false
给复现子Agent进行重攻击验证。Block A步骤1a:
CODE_ROOT = --target_root
(权威覆盖,覆盖
--snapshot_root
和状态回退)。Block A步骤2:标记检查跳过(
--target_root
代码树是故意修改的,标记豁免)。
--snapshot_pinned=false
参数是标记豁免,不是HALT信号——通过读取STATE检测HALT(
active_snapshot.snapshot_id
live:
开头,等效于状态中
active_snapshot.snapshot_pinned
false
),绝不是从此调用传递的参数。发现结果的
discovery_commit
不受影响——它保留发现时的轮次级
SNAPSHOT_ID
;仅
--snapshot_pinned=false
参数是重攻击调用的本地参数。
5. 不同快照的重复候选(跨轮次去重,
discovery_commit
不同——Block B成对NOT_MATCHED路径)——两个轮次均正确固定快照;发现结果 simply 来自不同快照。
mantis-dedupe
Block B成对检查比较当前发现结果的
discovery_commit
与归档发现结果的
discovery_commit
不是与全局
SNAPSHOT_ID
比较)。如果不同 → NOT_MATCHED。NOT_MATCHED保留当前发现结果为ACTIVE,并设置
possible_duplicate_of
(软、非终端提示——发现结果不被过滤或删除)。如果归档发现结果已RESOLVED(
patch_status
{VERIFIED_SECURE, MITIGATION_PROPOSED}
status==FALSE_POSITIVE
production_viability==NON_VIABLE
)且对是NOT_MATCHED → POSSIBLE REGRESSION:保留ACTIVE,添加历史记录,绝不过滤(在新代码上重新发现的已修复漏洞绝不能被删除)。
6. 缺失sink证据(Block F——PoC编译但未产生到达sink的证据;
not_attempted
vs
failed_to_reproduce
)——
mantis-reproduce
Block F:如果证据缺失(任何编译器/构建非零退出码、退出码127命令未找到、退出码2“无此文件”或从未到达sink)→
repro_status = not_attempted
(可重试),STOP。绝不标记为
failed_to_reproduce
。在
--reattack
模式下:保留
reattack_status
未设置,并添加历史记录“setup_failed”——绝不标记为
failed_to_bypass
failed_to_reproduce
仅保留给工具包证明到达了易受攻击的入口点的情况——即到达sink的证据,而非设置证据——但漏洞未触发。到达sink的证据必须来自调用路径内部或目标生成的跟踪/回溯:(a) PoC脚本/源工具包在sink调用前的点将
MANTIS_REACHED_ENTRYPOINT
写入辅助文件,在其自身执行流程内(标记写入是调用路径的一部分,不是预启动步骤);OR (b) 对于二进制/固件/原始 payload 目标,捕获的崩溃回溯或 sanitizer 跟踪(ASan/UBSan/MSan/TSan)明确命名目标sink函数(目标生成的跟踪)。外部包装器在调用目标前写入的标记仅为设置证据(证明“尝试启动”,而非“到达sink”),本身不足以证明
failed_to_reproduce
——将其视为决策门的证据缺失。证据记录在
repro_hints
中。在HALT模式下,HALT上限额外强制设置为
not_attempted
(无
failed_to_reproduce
),因为未固定代码树上的负面结果不能被信任为权威。

6. Semantic Retrieval (RAG) for Large Codebases

6. 大型代码库的语义检索(RAG)

For small repositories, the planner can manually scan
workspace/kb/index.md
and the researcher can grep for call-sites. At scale (thousands of files, deep directory trees, multi-pass campaigns), these approaches miss relevant context and waste tokens reading irrelevant files. A semantic retrieval layer lets the planner and researcher query for relevant KB entries and code locations without reading everything.
Two implementations are supported, sharing the same data contract:
  • Option A (Default — Skill-Based): A dedicated skill that runs a BM25/TF-IDF helper script over
    chunks.jsonl
    . Zero external dependencies — works air-gapped, no vector embeddings or vector store required. Optional vector embedding support if available.
  • Option B (Maximum Scale — MCP-Based): The harness owns a persistent vector index using vector embeddings, serving persistent
    semantic_search_kb
    /
    semantic_search_code
    MCP tools. Better for very large codebases where per-invocation BM25 is too slow.
Both are opt-in. The existing skills are not modified; the planner and researcher receive runtime instructions to use whichever retrieval mechanism is available, falling back to today's manual behavior if neither is present. Retrieval results are coverage HINTs only — they decide ordering and prioritization, never the membership of the audit set. A miss must never cause a file, call-site, or investigation to be skipped or dropped.
对于小型仓库,规划器可以手动扫描
workspace/kb/index.md
,研究员可以grep调用站点。在规模较大时(数千个文件、深层目录树、多轮次活动),这些方法会遗漏相关上下文,并浪费令牌读取无关文件。语义检索层允许规划器和研究员查询相关KB条目和代码位置,而无需读取所有内容。
支持两种实现,共享相同的数据契约:
  • 选项A(默认——基于技能): 专用技能对
    chunks.jsonl
    运行BM25/TF-IDF辅助脚本。零外部依赖——可在离线环境中工作,无需向量嵌入或向量存储。如果可用,可选支持向量嵌入。
  • 选项B(最大规模——基于MCP): 工具包拥有使用向量嵌入的持久向量索引,提供持久化的
    semantic_search_kb
    /
    semantic_search_code
    MCP工具。非常适合基于每次调用BM25太慢的超大型代码库。
两者均为可选功能。现有技能未修改;规划器和研究员接收运行时指令以使用可用的检索机制,如果两者都不存在则回退到当前手动行为。检索结果仅为覆盖范围提示——它们决定顺序和优先级,绝不决定审计集的成员资格。检索失败绝不能导致文件、调用站点或调查被跳过或丢弃。

A. Shared Data Contract:
chunks.jsonl

A. 共享数据契约:
chunks.jsonl

After Stage 2 (
/mantis-architecture
) completes, chunks are extracted into
workspace/kb/chunks.jsonl
(one JSON object per line). The harness can do this post-hoc by reading
workspace/kb/*.md
, or the architecture skill can be instructed to write it during synthesis as a text-only side effect. Two chunk types are produced:
  1. KB chunks from the existing
    workspace/kb/*.md
    files:
    json
    {"id": "auth_module:0", "source_file": "workspace/kb/entities/auth_module.md", "entity_type": "entity", "chunk_text": "The auth module handles..."}
  2. Code chunks from
    CODE_ROOT
    (the pinned snapshot). Each chunk includes the file path and line range so the researcher can request specific files from the snapshot:
    json
    {"id": "src/parser.c:0", "source_file": "src/parser.c", "start_line": 1, "end_line": 80, "chunk_text": "int parse_input(..."}
The first line of
chunks.jsonl
is a provenance header recording the
SNAPSHOT_ID
the chunks were built against:
json
{"_provenance": true, "snapshot_id": "abc123", "kb_snapshot_id": "abc123"}
Before serving queries, check
snapshot_id
in the provenance header against the current
SNAPSHOT_ID
; rebuild if they differ. In MODE-OFF (no
active_snapshot
),
kb_snapshot_id
is never stamped — skip the index entirely and let skills fall back to manual scanning. Never build code chunks from the live tree — they must reflect the pinned copy the skills are reading.
阶段2(
/mantis-architecture
)完成后,块被提取到
workspace/kb/chunks.jsonl
(每行一个JSON对象)。工具包可以通过读取
workspace/kb/*.md
事后完成此操作,也可以指示架构技能在合成期间作为纯文本副作用写入。生成两种块类型:
  1. 来自现有
    workspace/kb/*.md
    文件的KB块:
    json
    {"id": "auth_module:0", "source_file": "workspace/kb/entities/auth_module.md", "entity_type": "entity", "chunk_text": "The auth module handles..."}
  2. 来自
    CODE_ROOT
    (固定快照)的代码块:
    每个块包含文件路径和行范围,以便研究员可以从快照请求特定文件:
    json
    {"id": "src/parser.c:0", "source_file": "src/parser.c", "start_line": 1, "end_line": 80, "chunk_text": "int parse_input(..."}
chunks.jsonl
的第一行是记录块构建所针对的
SNAPSHOT_ID
的来源头:
json
{"_provenance": true, "snapshot_id": "abc123", "kb_snapshot_id": "abc123"}
在提供查询前,检查来源头中的
snapshot_id
与当前
SNAPSHOT_ID
是否匹配;如果不同则重建。在MODE-OFF(无
active_snapshot
)下,从不标记
kb_snapshot_id
——完全跳过索引,让技能回退到手动扫描。永远不要从实时代码树构建代码块——它们必须反映技能正在读取的固定副本。

B. Option A: Skill-Based Retrieval (Default — No Infrastructure)

B. 选项A: 基于技能的检索(默认——无基础设施)

A dedicated skill reads
chunks.jsonl
and writes+runs a helper script (e.g.
workspace/helpers/search_chunks.py
) that performs BM25/TF-IDF similarity search. The script is generated by the agent at runtime — no code is shipped with the skill (same pattern as
mantis-dedupe
's
merge_findings.py
). This requires zero external dependencies — no embedding model, no vector store, no MCP server. It works in air-gapped and VPC-SC environments.
A complete reference blueprint for this skill is available at references/mantis-kb-query.md. Builders can adapt it to their environment. The blueprint includes Block A (Locator Resolution), chunk provenance checking, the versioned helper script contract (
MANTIS_HELPER_VERSION = 1
), and the JSON output schema.
  • Invocation: The planner or researcher spawns the skill as a sub-agent with a query string. The skill writes the helper if not already present, runs it, and returns top-K matching chunks as JSON.
  • Optional embeddings: If vector embeddings are available, the agent can be instructed to use cosine similarity instead of BM25. This is a runtime configuration toggle, not a different skill.
  • Snapshot safety: The skill reads
    active_snapshot
    from state via Block A (same as every other skill) and checks chunk provenance before serving.
专用技能读取
chunks.jsonl
并编写+运行辅助脚本(如
workspace/helpers/search_chunks.py
),执行BM25/TF-IDF相似度搜索。脚本由Agent在运行时生成——技能不附带代码(与
mantis-dedupe
merge_findings.py
模式相同)。这需要零外部依赖——无嵌入模型、无向量存储、无MCP服务器。可在离线和VPC-SC环境中工作。
此技能的完整参考蓝图可在references/mantis-kb-query.md获取。构建者可根据自身环境调整。蓝图包括Block A(定位器解析)、块来源检查、版本化辅助脚本契约(
MANTIS_HELPER_VERSION = 1
)和JSON输出Schema。
  • 调用: 规划器或研究员使用查询字符串生成子Agent技能。技能在辅助脚本不存在时写入,运行它,并返回前K个匹配块作为JSON。
  • 可选嵌入: 如果向量嵌入可用,可以指示Agent使用余弦相似度而非BM25。这是运行时配置切换,不是不同的技能。
  • 快照安全: 技能通过Block A从状态读取
    active_snapshot
    (与其他所有技能相同),并在提供查询前检查块来源。

C. Option B: MCP-Based Retrieval (For Maximum Scale)

C. 选项B: 基于MCP的检索(最大规模)

For very large codebases where per-invocation BM25 is too slow, the harness can own a persistent vector index using vector embeddings, serving two MCP tools (following the same pattern as Guideline 2's Custom MCP for VMs/hardware):
  • semantic_search_kb(query: string) → [{id, source_file, entity_type, chunk_text, score}]
    — Searches KB chunks. Returns relevant entity/vulnerability markdown context.
  • semantic_search_code(query: string) → [{file, start_line, end_line, snippet, score}]
    — Searches code chunks from the pinned snapshot. Returns relevant code locations.
The harness manages the vector index lifecycle: build from
chunks.jsonl
(or directly from
CODE_ROOT
), rebuild when
SNAPSHOT_ID
changes, and handle freshness checks. In HALT mode, serve with a
STALE
flag or refuse. In MODE-OFF, skip entirely.
对于基于每次调用BM25太慢的超大型代码库,工具包可以拥有使用向量嵌入的持久向量索引,提供两个MCP工具(遵循指南2中针对虚拟机/硬件的自定义MCP相同模式):
  • semantic_search_kb(query: string) → [{id, source_file, entity_type, chunk_text, score}]
    — 搜索KB块。返回相关实体/漏洞Markdown上下文。
  • semantic_search_code(query: string) → [{file, start_line, end_line, snippet, score}]
    — 搜索固定快照中的代码块。返回相关代码位置。
工具包管理向量索引生命周期:从
chunks.jsonl
(或直接从
CODE_ROOT
)构建,
SNAPSHOT_ID
更改时重建,并处理新鲜度检查。在HALT模式下,带有
STALE
标记提供服务或拒绝。在MODE-OFF下,完全跳过。

D. Per-Skill Augmentation Guidance

D. 按技能增强指南

When a retrieval mechanism (skill or MCP) is available, instruct the following skills to use it. These are runtime instructions passed by the harness or meta-agent when invoking the skill — the skill files themselves are not modified:
  • mantis-architecture: No changes needed. The harness chunks the existing
    workspace/kb/*.md
    files after the architect completes Stage 2. If the builder prefers, they may instruct the architect to also write
    workspace/kb/chunks.jsonl
    during synthesis (Step 3) as a text-only side effect — but this is optional, since the harness can extract chunks post-hoc.
  • mantis-plan: If a retrieval mechanism is available, instruct the planner to use it to discover
    kb_references
    for each investigation instead of only manually scanning
    workspace/kb/index.md
    . For each investigation, query with the investigation title and target file names, then add the top-K matching KB entity/vulnerability files to the
    kb_references
    array. Manual scanning of
    index.md
    remains the fallback when no mechanism is available.
  • mantis-researcher: If a retrieval mechanism is available, instruct Wave 1 sub-agents to use it to PRIORITIZE relevant call-sites and cross-module data flows into sinks (e.g., "where does untrusted input reach
    memcpy
    in the parser module"). Semantic search SUPPLEMENTS grep as a ranking HINT ONLY — it decides ORDER, never MEMBERSHIP of the audit set. It MUST NEVER replace the exhaustive Step-3 call-site sweep; every call-site or data-flow that a full grep would reach must still be audited whether or not it ranks in top-K. Audit the union of grep results and semantic search results. The researcher's existing Wave 1/Wave 2 structure is unchanged.
当检索机制(技能或MCP)可用时,指示以下技能使用它。这些是工具包或元Agent调用技能时传递的运行时指令——技能文件本身未修改:
  • mantis-architecture: 无需更改。工具包在架构师完成阶段2后对现有
    workspace/kb/*.md
    文件分块。如果构建者偏好,他们可以指示架构师在合成期间(步骤3)也将
    workspace/kb/chunks.jsonl
    作为纯文本副作用写入——但这是可选的,因为工具包可以事后提取块。
  • mantis-plan: 如果检索机制可用,指示规划器使用它为每个调查发现
    kb_references
    ,而非仅手动扫描
    workspace/kb/index.md
    。对于每个调查,使用调查标题和目标文件名查询,然后将前K个匹配的KB实体/漏洞文件添加到
    kb_references
    数组。无机制可用时,手动扫描
    index.md
    仍是回退方案。
  • mantis-researcher: 如果检索机制可用,指示Wave 1子Agent使用它将相关调用站点和跨模块数据流优先排序到sink(例如“不受信任的输入在解析器模块中到达
    memcpy
    的位置”)。语义搜索仅作为排名提示补充grep——它决定顺序,绝不决定审计集的成员资格。绝不能替代详尽的步骤3调用站点扫描;完整grep会找到的每个调用站点或数据流,无论是否在前K排名中,都必须被审计。审计grep结果和语义搜索结果的并集。研究员现有的Wave 1/Wave 2结构不变。

E. Snapshot Safety

E. 快照安全

The retrieval index — whether served by the skill or the harness — is a cache of the pinned snapshot, never a live view:
  • Build code chunks from
    CODE_ROOT
    (the pinned snapshot), not the live tree.
  • Rebuild when
    SNAPSHOT_ID
    changes (new pass, new pin).
  • In HALT mode (
    snapshot_pinned=false
    ), serve results with a
    STALE
    flag or refuse to serve — same conservative degradation as every other stage.
  • In MODE-OFF, skip the index entirely.

检索索引——无论是由技能还是工具包提供——都是固定快照的缓存,绝不是实时视图:
  • CODE_ROOT
    (固定快照)构建代码块,而非实时代码树。
  • SNAPSHOT_ID
    更改时(新轮次、新固定)重建。
  • 在HALT模式下(
    snapshot_pinned=false
    ),带有
    STALE
    标记提供结果或拒绝服务——与其他所有阶段相同的保守降级。
  • 在MODE-OFF下,完全跳过索引。

7. Embedding-Based Deduplication Pre-Filtering

7. 基于嵌入的去重预过滤

When the pipeline runs many passes over a large codebase, the deduplicator (
/mantis-dedupe
) must compare each current finding against every archived finding — an O(n×m) comparison performed by an LLM reading summaries. At scale (hundreds of findings across many passes), this is token-expensive and slow.
The harness can use embeddings as a fast pre-filter to reduce the candidate space before invoking
/mantis-dedupe
. The skill's existing deterministic matching (
code_paths
+
title
+
discovery_commit
) remains the sole authority for hard dedup decisions.
This is entirely harness-side and opt-in.
/mantis-dedupe
is not modified.
当管道在大型代码库上运行多轮次时,去重器(
/mantis-dedupe
)必须将每个当前发现结果与每个归档发现结果进行比较——这是LLM读取摘要执行的O(n×m)比较。在规模较大时(多轮次数百个发现结果),这会耗费大量令牌且速度缓慢。
工具包可以使用嵌入作为快速预过滤器,在调用
/mantis-dedupe
前减少候选空间。技能现有的确定性匹配(
code_paths
+
title
+
discovery_commit
)仍然是硬去重决策的唯一权威
这完全是工具包端的可选功能
/mantis-dedupe
未修改。

A. How It Works

A. 工作原理

  1. Harness Action: Reads all
    workspace/findings/*.json
    (current) and
    workspace/archive/findings_pass_*/*.json
    (archived). For each finding, computes an embedding from a normalized text representation (e.g.,
    title + description + first code_paths entry with line stripped
    ).
  2. Harness Action: Computes pairwise cosine similarity between current and archived findings. Surfaces candidate pairs above a configurable threshold (e.g., 0.85).
  3. Harness Action: Writes a candidate-pairs manifest (e.g.,
    workspace/helpers/dedup_candidates.json
    ) containing the UUID pairs and similarity scores.
  4. mantis-dedupe invocation: The harness invokes
    /mantis-dedupe
    as usual. If the candidate manifest exists, instruct the skill to read it and prioritize those pairs for the LLM's pairwise comparison, instead of comparing every finding against every archived finding. All existing deterministic matching rules apply unchanged — the manifest only narrows the search space.
  1. 工具包操作: 读取所有
    workspace/findings/*.json
    (当前)和
    workspace/archive/findings_pass_*/*.json
    (归档)。对于每个发现结果,从规范化文本表示(例如
    title + description + 去掉行号的第一个code_paths条目
    )计算嵌入。
  2. 工具包操作: 计算当前与归档发现结果之间的成对余弦相似度。显示高于可配置阈值(例如0.85)的候选对。
  3. 工具包操作: 写入候选对清单(例如
    workspace/helpers/dedup_candidates.json
    ),包含UUID对和相似度分数。
  4. 调用mantis-dedupe: 工具包照常调用
    /mantis-dedupe
    。如果候选清单存在,指示技能读取它并优先处理这些对进行LLM成对比较,而非将每个发现结果与每个归档发现结果比较。所有现有确定性匹配规则保持不变——清单仅缩小搜索空间。

B. Safety Guardrails

B. 安全护栏

  • Pre-filter only, never the decision. The embedding similarity score can never cause a
    DUPLICATE
    verdict, a trash move, or a
    possible_duplicate_of
    assignment. Only the skill's existing
    code_paths
    ,
    title
    , and
    discovery_commit
    checks can do that. A miss in the pre-filter only over-retains a duplicate (safe — the LLM sees it and skips it); it never under-retains (never drops a real duplicate).
  • No false negatives. The threshold should be set low enough (e.g., 0.75) to avoid missing true duplicates. Better to surface too many candidates than to miss a real one — the LLM and deterministic matching will filter false positives.
  • Fallback on failure. If the embedding computation is unavailable, the candidate manifest is absent, or any error occurs,
    /mantis-dedupe
    falls back to its existing O(n×m) comparison. The skill must not stop or error if the manifest is missing.
  • Snapshot awareness. The harness should not compute embeddings across different
    discovery_commit
    values without flagging them as cross-snapshot candidates — the skill's Block B pairwise check will handle the final MATCHED/NOT_MATCHED decision.
  • 仅预过滤,绝不决策。 嵌入相似度分数绝不能导致
    DUPLICATE
    结论、删除操作或
    possible_duplicate_of
    赋值。只有技能现有的
    code_paths
    title
    discovery_commit
    检查可以做到。预过滤遗漏仅会过度保留重复项(安全——LLM会看到并跳过);绝不会保留不足(绝不会丢弃真正的重复项)。
  • 无假阴性。 阈值应设置得足够低(例如0.75)以避免遗漏真正的重复项。宁可显示过多候选也不要遗漏真正的重复项——LLM和确定性匹配会过滤假阳性。
  • 失败时回退。 如果嵌入计算不可用、候选清单缺失或发生任何错误,
    /mantis-dedupe
    回退到现有的O(n×m)比较。如果清单缺失,技能不得停止或报错。
  • 快照感知。 工具包不应跨不同
    discovery_commit
    值计算嵌入而不将其标记为跨快照候选——技能的Block B成对检查将处理最终的MATCHED/NOT_MATCHED决策。

C. Shared Infrastructure

C. 共享基础设施

If the builder also implements Guideline 6 (Semantic Retrieval), reuse the same vector embedding infrastructure for finding embeddings. The finding embedding is a different payload (finding JSON, not KB chunks) but the same embedding capability can serve both.

如果构建者还实现了指南6(语义检索),则将相同的向量嵌入基础设施重用于发现结果嵌入。发现结果嵌入是不同的负载(发现结果JSON,而非KB块),但相同的嵌入能力可以同时服务两者。

8. SAST Seeding (External Tool Ingestion)

8. SAST注入(外部工具输入)

Mantis's discovery engine is 100% LLM-generative (grep swarm + reasoning). A weak LLM can structurally under-detect whole-program taint classes (injection, path traversal, deserialization, UAF, format-string) that mature SAST tools (CodeQL, Semgrep-taint) encode as interprocedural queries. A SAST seeding adapter ingests external tool findings as
PROVISIONALLY_VALID
/
NEEDS_RESEARCH
candidates that must earn their verdict through the unchanged downstream gates. This is purely additive (INV-2-strengthening) — it expands detection breadth without weakening any verification gate.
This follows exactly the RAG pattern from Guideline 6: opt-in, default off, provenance-tracked, snapshot-aware, fallback on failure.
Platform-agnostic IR (not SARIF): Rather than tying the adapter to SARIF (a complex, tool-specific format), the adapter consumes a minimal JSONL intermediate representation (IR). Any SAST tool's output (SARIF, Semgrep JSON, Bandit JSON, etc.) is converted to this IR by a thin wrapper. This maximizes platform agnosticism — the adapter works with any tool that can produce the simple JSONL format.
Two implementations are supported, sharing the same data contract:
  • Option A (Default — Skill-Based): A dedicated skill (
    /mantis-sast-seed
    ) reads the IR and uses LLM reasoning to normalize findings into mantis finding JSONs. The LLM reads actual source code at each reported location under CODE_ROOT to verify the finding and enrich the description with root-cause analysis. Zero external dependencies — works air-gapped.
  • Option B (Maximum Control — Harness-Based): The harness directly normalizes SAST output into finding JSONs using deterministic code (e.g., a SARIF-to-finding converter script), bypassing the LLM for the normalization step. The harness writes finding JSONs to
    workspace/findings/
    before invoking
    /mantis-dedupe
    .
Both are opt-in. The existing skills are not modified. Seeded findings enter
workspace/findings/
alongside researcher findings and flow through the unchanged downstream gates (dedupe -> review -> critic -> reproduce -> patch -> calibrate).
A complete reference blueprint is available at references/mantis-sast-seed.md.
Mantis的发现引擎100%基于LLM生成(grep集群 + 推理)。弱LLM可能在结构上无法检测成熟SAST工具(CodeQL、Semgrep-taint)作为过程间查询编码的全程序污点类(注入、路径遍历、反序列化、UAF、格式字符串)。SAST注入适配器将外部工具发现结果作为
PROVISIONALLY_VALID
/
NEEDS_RESEARCH
候选输入,这些候选必须通过未修改的下游验证门才能获得最终结论。这纯粹是附加功能(增强INV-2)——它扩展了检测广度而不削弱任何验证门。
这完全遵循指南6中的RAG模式:可选、默认关闭、可追溯来源、感知快照、失败时回退。
平台无关IR(非SARIF): 与其将适配器绑定到SARIF(复杂、工具特定格式),适配器使用最小化JSONL中间表示(IR)。任何SAST工具的输出(SARIF、Semgrep JSON、Bandit JSON等)都通过薄包装器转换为此IR。这最大化了平台无关性——适配器可与任何能生成简单JSONL格式的工具配合使用。
支持两种实现,共享相同的数据契约:
  • 选项A(默认——基于技能): 专用技能(
    /mantis-sast-seed
    )读取IR并使用LLM推理将发现结果规范化为mantis发现结果JSON。LLM读取CODE_ROOT下每个报告位置的实际源代码以验证发现结果,并使用根因分析丰富描述。零外部依赖——可在离线环境中工作。
  • 选项B(最大控制——基于工具包): 工具包使用确定性代码(如SARIF到发现结果转换器脚本)直接将SAST输出规范化为发现结果JSON,绕过LLM进行规范化步骤。工具包在调用
    /mantis-dedupe
    前将发现结果JSON写入
    workspace/findings/
两者均为可选功能。现有技能未修改。注入的发现结果与研究员发现结果一起进入
workspace/findings/
,并流经未修改的下游验证门(去重 -> 评审 -> 评论 -> 复现 -> 补丁 -> 校准)。
完整参考蓝图可在references/mantis-sast-seed.md获取。

A. Shared Data Contract:
sast_findings.jsonl

A. 共享数据契约:
sast_findings.jsonl

The IR is a JSONL file at
workspace/sast_findings.jsonl
(STATE-RELATIVE). It follows the same provenance-header pattern as
chunks.jsonl
(Guideline 6A).
Line 1 — Provenance header:
json
{"_provenance": true, "scan_snapshot_id": "abc123def456", "tool": "codeql", "tool_version": "2.15.0", "scan_timestamp": "2026-07-22T10:00:00Z"}
  • scan_snapshot_id
    : The SNAPSHOT_ID the scan was run against. This is the primary provenance anchor — compared byte-for-byte to the current pass
    SNAPSHOT_ID
    (same comparison as Block B). If the harness ran the SAST tool against the pinned CODE_ROOT, it sets this to
    SNAPSHOT_ID
    .
  • tool
    : Tool name (e.g.,
    codeql
    ,
    semgrep
    ,
    bandit
    ). Informational.
  • tool_version
    : Tool version. Informational.
  • scan_timestamp
    : ISO 8601. Informational.
Lines 2+ — One finding per line:
json
{"rule_id": "cpp/sql-injection", "rule_name": "SQL injection", "cwe": "CWE-89", "severity": "HIGH", "code_paths": ["src/db/query.c:42"], "message": "User input flows into SQL query without sanitization"}
FieldTypeRequiredDescription
rule_id
stringYesTool-specific rule identifier
severity
stringYes
CRITICAL
,
HIGH
,
MEDIUM
,
LOW
(Mantis scale)
code_paths
arrayYesArray of
"file:line"
strings (SNAPSHOT-RELATIVE)
message
stringYesOriginal SAST finding message
rule_name
stringNoHuman-readable rule name
cwe
stringNoCWE identifier (e.g.,
CWE-89
)
IR conversion (harness responsibility): The harness converts SAST tool output to this IR before invoking the adapter. Conversion examples:
  • SARIF: extract
    ruleId
    , map
    level
    to severity (
    error
    ->
    HIGH
    ,
    warning
    ->
    MEDIUM
    ,
    note
    ->
    LOW
    ), extract
    locations
    to
    code_paths
    , copy
    message.text
    .
  • Semgrep JSON: extract
    check_id
    as
    rule_id
    , map
    extra.severity
    to Mantis severity, extract
    path:start.line
    as
    code_paths
    , copy
    extra.message
    .
IR是位于
workspace/sast_findings.jsonl
(STATE-RELATIVE)的JSONL文件。它遵循与
chunks.jsonl
(指南6A)相同的来源头模式。
第1行——来源头:
json
{"_provenance": true, "scan_snapshot_id": "abc123def456", "tool": "codeql", "tool_version": "2.15.0", "scan_timestamp": "2026-07-22T10:00:00Z"}
  • scan_snapshot_id
    : 扫描所针对的SNAPSHOT_ID。这是主要来源锚点——与当前轮次
    SNAPSHOT_ID
    逐字节比较(与Block B相同的比较)。如果工具包针对固定的CODE_ROOT运行SAST工具,则将其设置为
    SNAPSHOT_ID
  • tool
    : 工具名称(如
    codeql
    semgrep
    bandit
    )。信息性字段。
  • tool_version
    : 工具版本。信息性字段。
  • scan_timestamp
    : ISO 8601格式。信息性字段。
第2行及以后——每行一个发现结果:
json
{"rule_id": "cpp/sql-injection", "rule_name": "SQL injection", "cwe": "CWE-89", "severity": "HIGH", "code_paths": ["src/db/query.c:42"], "message": "User input flows into SQL query without sanitization"}
字段类型必填描述
rule_id
string工具特定规则标识符
severity
string
CRITICAL
HIGH
MEDIUM
LOW
(Mantis分级)
code_paths
array
"file:line"
字符串数组(SNAPSHOT-RELATIVE)
message
stringSAST发现结果原始消息
rule_name
string人类可读规则名称
cwe
stringCWE标识符(如
CWE-89
IR转换(工具包职责): 工具包在调用适配器前将SAST工具输出转换为此IR。转换示例:
  • SARIF: 提取
    ruleId
    ,将
    level
    映射为严重性(
    error
    ->
    HIGH
    warning
    ->
    MEDIUM
    note
    ->
    LOW
    ),提取
    locations
    code_paths
    ,复制
    message.text
  • Semgrep JSON: 提取
    check_id
    作为
    rule_id
    ,将
    extra.severity
    映射为Mantis严重性,提取
    path:start.line
    code_paths
    ,复制
    extra.message

B. Option A: Skill-Based Ingestion (Default — No Infrastructure)

B. 选项A: 基于技能的输入(默认——无基础设施)

A dedicated skill reads
sast_findings.jsonl
, applies allow-listing, verifies provenance, computes
signature
/
lineage_id
/
discovery_commit
, and writes finding JSONs. The LLM reads actual source code at each reported location under CODE_ROOT to verify the finding and enrich the description.
  • Invocation: The harness invokes
    /mantis-sast-seed
    with
    --snapshot_root
    /
    --snapshot_id
    /
    --state_root
    after Stage 6 (Research) and before Stage 7 (Dedupe). The seeded findings land in
    workspace/findings/
    before
    /mantis-dedupe
    runs.
  • Inert until wired: If
    sast_findings.jsonl
    is absent, the skill outputs nothing and notifies the caller. It never fails — it simply returns empty.
  • Anti-hallucination: The LLM MUST read the actual code at each reported location before writing the finding JSON. It MUST NOT invent findings not present in the SAST output. The
    sast_provenance.line_verified
    field records whether verification succeeded.
  • Snapshot safety: The skill reads
    active_snapshot
    from state via Block A and stamps
    discovery_commit
    only when the snapshot is pinned and the finding's location is verified under CODE_ROOT.
专用技能读取
sast_findings.jsonl
,应用允许列表,验证来源,计算
signature
/
lineage_id
/
discovery_commit
,并写入发现结果JSON。LLM读取CODE_ROOT下每个报告位置的实际源代码以验证发现结果,并丰富描述。
  • 调用: 工具包在阶段6(研究)后、阶段7(去重)前使用
    --snapshot_root
    /
    --snapshot_id
    /
    --state_root
    调用
    /mantis-sast-seed
    。注入的发现结果在
    /mantis-dedupe
    运行前进入
    workspace/findings/
  • 未连接时无操作: 如果
    sast_findings.jsonl
    缺失,技能不输出任何内容并通知调用者。它绝不会失败——只是返回空。
  • 反幻觉: LLM必须在写入发现结果JSON前读取每个报告位置的实际代码。它绝不能发明SAST输出中不存在的发现结果。
    sast_provenance.line_verified
    字段记录验证是否成功。
  • 快照安全: 技能通过Block A从状态读取
    active_snapshot
    ,仅当快照固定且发现结果位置在CODE_ROOT下验证通过时才标记
    discovery_commit

C. Option B: Harness-Based Ingestion (For Deterministic Ingestion)

C. 选项B: 基于工具包的输入(确定性输入)

For maximum determinism, the harness can normalize SAST output into finding JSONs using deterministic code. This bypasses the LLM for the normalization step:
  1. Harness Action: Reads the SAST tool output, parses it deterministically, and writes finding JSONs to
    workspace/findings/
    .
  2. Harness Action: Stamps
    discovery_commit
    only if the scan provably ran against the pinned CODE_ROOT.
  3. Harness Action: Applies allow-listing filters.
  4. mantis-dedupe invocation: Proceeds as usual — the seeded findings are indistinguishable from researcher findings.
为了最大程度的确定性,工具包可以使用确定性代码将SAST输出规范化为发现结果JSON。这绕过LLM进行规范化步骤:
  1. 工具包操作: 读取SAST工具输出,确定性解析,并将发现结果JSON写入
    workspace/findings/
  2. 工具包操作: 仅当扫描针对固定的CODE_ROOT运行时才标记
    discovery_commit
  3. 工具包操作: 应用允许列表过滤器。
  4. 调用mantis-dedupe: 照常进行——注入的发现结果与研究员发现结果无法区分。

D. Provenance Verification

D. 来源验证

The adapter stamps
discovery_commit
ONLY if the scan provably ran against a line-identical pinned CODE_ROOT. Verification ladder:
  1. Read
    active_snapshot
    from
    workspace/.mantis_state.json
    (via Block A). If absent, this is MODE-OFF — skip to step 5.
  2. If
    snapshot_pinned
    is false, this is HALT — skip to step 6.
  3. Read the IR provenance header's
    scan_snapshot_id
    .
  4. VERIFIED:
    scan_snapshot_id
    present AND exactly equals
    SNAPSHOT_ID
    . Stamp
    discovery_commit = SNAPSHOT_ID
    . Status =
    PROVISIONALLY_VALID
    .
  5. MODE-OFF:
    active_snapshot
    absent. OMIT
    discovery_commit
    . Status =
    PROVISIONALLY_VALID
    (MODE-OFF permits all verdicts).
  6. HALT:
    snapshot_pinned
    is false. OMIT
    discovery_commit
    . Status =
    NEEDS_RESEARCH
    .
  7. DRIFT:
    scan_snapshot_id
    present but differs. OMIT
    discovery_commit
    entirely. Status =
    NEEDS_RESEARCH
    .
  8. UNVERIFIED:
    scan_snapshot_id
    absent. OMIT
    discovery_commit
    . Status =
    NEEDS_RESEARCH
    .
Line-existence verification (additional check when VERIFIED or DRIFT and CODE_ROOT is resolved): For each finding, verify each
code_paths
entry: strip trailing
:line
, check file exists under CODE_ROOT, check line number is within file's line count. If file missing or line out of range -> downgrade to DRIFT (omit
discovery_commit
, status =
NEEDS_RESEARCH
).
This is the exact same "UNTRUSTED-IF-ABSENT" pattern as
discovery_commit
(schema.json) and
signature
/
lineage_id
.
适配器仅当扫描针对逐行相同的固定CODE_ROOT运行时才标记
discovery_commit
。验证阶梯:
  1. workspace/.mantis_state.json
    读取
    active_snapshot
    (通过Block A)。如果缺失,这是MODE-OFF——跳至步骤5。
  2. 如果
    snapshot_pinned
    为false,这是HALT——跳至步骤6。
  3. 读取IR来源头的
    scan_snapshot_id
  4. 已验证:
    scan_snapshot_id
    存在且完全等于
    SNAPSHOT_ID
    。标记
    discovery_commit = SNAPSHOT_ID
    。状态 =
    PROVISIONALLY_VALID
  5. MODE-OFF:
    active_snapshot
    缺失。省略
    discovery_commit
    。状态 =
    PROVISIONALLY_VALID
    (MODE-OFF允许所有结论)。
  6. HALT:
    snapshot_pinned
    为false。省略
    discovery_commit
    。状态 =
    NEEDS_RESEARCH
  7. 漂移:
    scan_snapshot_id
    存在但不同。完全省略
    discovery_commit
    。状态 =
    NEEDS_RESEARCH
  8. 未验证:
    scan_snapshot_id
    缺失。省略
    discovery_commit
    。状态 =
    NEEDS_RESEARCH
行存在验证(已验证或漂移且CODE_ROOT已解析时的附加检查):对于每个发现结果,验证每个
code_paths
条目:去掉尾部的
:line
,检查文件是否存在于CODE_ROOT下,检查行号是否在文件行数范围内。如果文件缺失或行号超出范围 -> 降级为漂移(省略
discovery_commit
,状态 =
NEEDS_RESEARCH
)。
这与
discovery_commit
(schema.json)和
signature
/
lineage_id
的“缺失则不可信”模式完全相同。

E. Allow-Listing and Noise Control

E. 允许列表与噪声控制

workspace/sast_allowlist.json
(optional config file, STATE-RELATIVE):
json
{
  "enabled": true,
  "severity_filter": ["CRITICAL", "HIGH"],
  "cwe_allowlist": {
    "enabled": true,
    "cwes": ["CWE-89", "CWE-78", "CWE-79", "CWE-22", "CWE-787", "CWE-416", "CWE-502"]
  },
  "rule_allowlist": {
    "enabled": false,
    "rules": []
  },
  "per_rule_cap": 5,
  "total_cap": 50
}
If the config file is absent, defaults apply: CRITICAL+HIGH only,
per_rule_cap=5
,
total_cap=50
.
How allow-listing protects the retry cap: The reproduce stage (
/mantis-reproduce
) has a hard ceiling of 6 attempts per finding (absolute, never reset). If 1000 SAST findings are seeded without filtering, the reproduce stage would need up to 6000 attempts — starving the retry budget. The allow-listing chain (severity filter -> CWE/rule filters -> per-rule cap -> total cap) ensures only a bounded, high-signal set of candidates enters the pipeline. The review (13-rule negative filter) and critic (production viability) stages further filter before reproduce runs.
workspace/sast_allowlist.json
(可选配置文件,STATE-RELATIVE):
json
{
  "enabled": true,
  "severity_filter": ["CRITICAL", "HIGH"],
  "cwe_allowlist": {
    "enabled": true,
    "cwes": ["CWE-89", "CWE-78", "CWE-79", "CWE-22", "CWE-787", "CWE-416", "CWE-502"]
  },
  "rule_allowlist": {
    "enabled": false,
    "rules": []
  },
  "per_rule_cap": 5,
  "total_cap": 50
}
如果配置文件缺失,应用默认值:仅CRITICAL+HIGH,
per_rule_cap=5
total_cap=50
允许列表如何保护重试上限: 复现阶段(
/mantis-reproduce
)每个发现结果有6次尝试的硬上限(绝对,永不重置)。如果不过滤就注入1000个SAST发现结果,复现阶段最多需要6000次尝试——耗尽重试预算。允许列表链(严重性过滤器 -> CWE/规则过滤器 -> 每规则上限 -> 总上限)确保只有有限、高信号的候选进入管道。评审(13条规则负过滤器)和评论(生产可行性)阶段在复现运行前进一步过滤。

F. Per-Skill Augmentation Guidance

F. 按技能增强指南

When the SAST seed skill is available, instruct the harness to invoke it between Stage 6 (Research) and Stage 7 (Dedupe). These are runtime instructions passed by the harness — the skill files themselves are not modified:
  • mantis-meta-agent: Invoke
    /mantis-sast-seed
    with
    --snapshot_root
    /
    --snapshot_id
    /
    --state_root
    after
    /mantis-researcher
    completes and before
    /mantis-dedupe
    .
  • mantis-dedupe: No changes needed. Seeded findings are in
    workspace/findings/
    alongside researcher findings. Dedupe processes them identically (signature-based matching, Block B pairwise check).
  • mantis-review: No changes needed. The 13-rule negative filter applies to seeded findings identically.
  • mantis-report: No changes needed. The
    sast_provenance
    field is informational and can be displayed in reports.
当SAST注入技能可用时,指示工具包在阶段6(研究)和阶段7(去重)之间调用它。这些是工具包传递的运行时指令——技能文件本身未修改:
  • mantis-meta-agent:
    /mantis-researcher
    完成后、
    /mantis-dedupe
    前使用
    --snapshot_root
    /
    --snapshot_id
    /
    --state_root
    调用
    /mantis-sast-seed
  • mantis-dedupe: 无需更改。注入的发现结果与研究员发现结果一起在
    workspace/findings/
    中。去重以相同方式处理它们(基于签名的匹配、Block B成对检查)。
  • mantis-review: 无需更改。13条规则负过滤器同样适用于注入的发现结果。
  • mantis-report: 无需更改。
    sast_provenance
    字段是信息性的,可在报告中显示。

G. Snapshot Safety

G. 快照安全

The SAST seed adapter follows Block A (Locator Resolution) exactly like every other code-reading skill:
  • Resolve CODE_ROOT from
    --snapshot_root
    / state
    active_snapshot
    .
  • Honor the sentinel check (Block A step 2).
  • Read source files under CODE_ROOT (SNAPSHOT-RELATIVE) for line-existence verification.
  • Write findings under
    state_root/workspace/findings/
    (STATE-RELATIVE).
  • Never write under CODE_ROOT when pinned.
  • In MODE-OFF: proceed without
    discovery_commit
    . All verdicts permitted.
  • In HALT: omit
    discovery_commit
    . Seeded findings get
    NEEDS_RESEARCH
    .
  • In PINNED: verify each finding's location under CODE_ROOT, stamp
    discovery_commit = SNAPSHOT_ID
    if verified.
The SAST tool output itself is NOT snapshot-aware — it may have been produced against a different tree. The adapter's provenance verification is what bridges the gap: it re-grounds each finding against the pinned CODE_ROOT before stamping
discovery_commit
.
SAST注入适配器完全遵循Block A(定位器解析),与其他所有代码读取技能相同:
  • --snapshot_root
    / 状态
    active_snapshot
    解析CODE_ROOT。
  • 遵守标记检查(Block A步骤2)。
  • 在CODE_ROOT下(SNAPSHOT-RELATIVE)读取源文件以进行行存在验证。
  • state_root/workspace/findings/
    下(STATE-RELATIVE)写入发现结果。
  • 固定时绝不在CODE_ROOT下写入。
  • 在MODE-OFF下:无
    discovery_commit
    继续。允许所有结论。
  • 在HALT下:省略
    discovery_commit
    。注入的发现结果标记为
    NEEDS_RESEARCH
  • 在PINNED下:验证CODE_ROOT下每个发现结果的位置,验证通过则标记
    discovery_commit = SNAPSHOT_ID
SAST工具输出本身不感知快照——它可能是针对不同代码树生成的。适配器的来源验证是弥合差距的关键:它在标记
discovery_commit
前将每个发现结果重新锚定到固定的CODE_ROOT。

H. Safety Guardrails

H. 安全护栏

  • Purely additive. Seeded findings are
    PROVISIONALLY_VALID
    /
    NEEDS_RESEARCH
    candidates. They must pass through the unchanged downstream gates: dedupe (Block B), review (13-rule filter), critic (viability), reproduce (Block F reached-sink evidence + HALT ceiling), patch (Block G re-attack), calibrate (sanity caps). No gate is weakened.
  • No false
    VERIFIED_SECURE
    .
    Seeded findings start at
    PROVISIONALLY_VALID
    — they can never reach
    VERIFIED_SECURE
    without passing through the full patch + re-attack pipeline.
  • No false
    failed_to_reproduce
    .
    Seeded findings that reach reproduce are subject to the same Block F evidence gate and HALT ceiling.
  • No dropped regression. If a SAST-seeded finding matches an archived finding with a different
    discovery_commit
    , Block B returns NOT_MATCHED ->
    possible_duplicate_of
    -> finding stays active.
  • Fail-safe on missing data. If
    sast_findings.jsonl
    is absent, no findings written. If a finding can't be verified,
    NEEDS_RESEARCH
    .
  • No existing skills modified. The adapter writes findings to
    workspace/findings/
    before
    /mantis-dedupe
    runs.
  • sast_provenance
    is informational only.
    It does not affect any safety- critical invariant, gate, or verdict. The finding's
    discovery_commit
    is the field that governs Block B snapshot matching.

  • 纯粹附加。 注入的发现结果是
    PROVISIONALLY_VALID
    /
    NEEDS_RESEARCH
    候选。它们必须通过未修改的下游验证门:去重(Block B)、评审(13条规则过滤器)、评论(可行性)、复现(Block F到达sink证据 + HALT上限)、补丁(Block G重攻击)、校准(健全性上限)。没有验证门被削弱。
  • 无错误的
    VERIFIED_SECURE
    注入的发现结果从
    PROVISIONALLY_VALID
    开始——不通过完整的补丁 + 重攻击管道绝不能达到
    VERIFIED_SECURE
  • 无错误的
    failed_to_reproduce
    到达复现的注入发现结果受相同的Block F证据门和HALT上限约束。
  • 无遗漏的回归。 如果SAST注入的发现结果与具有不同
    discovery_commit
    的归档发现结果匹配,Block B返回NOT_MATCHED ->
    possible_duplicate_of
    -> 发现结果保持活跃。
  • 缺失数据时的故障安全。 如果
    sast_findings.jsonl
    缺失,不写入任何发现结果。如果发现结果无法验证,标记为
    NEEDS_RESEARCH
  • 未修改现有技能。 适配器在
    /mantis-dedupe
    运行前将发现结果写入
    workspace/findings/
  • sast_provenance
    仅为信息性。
    它不影响任何安全关键不变量、验证门或结论。发现结果的
    discovery_commit
    是控制Block B快照匹配的字段。

9. Structural Code Index (AST-Level Context)

9. 结构化代码索引(AST级上下文)

For small repositories, the researcher can grep for call-sites and the planner can infer dependencies. At scale, grep-based call-site discovery is unreliable (misses indirect calls, cannot distinguish calls from comments/strings, no function boundary awareness). A structural code index provides AST-level context (function boundaries, call graphs, symbol tables) to improve LLM reasoning quality during discovery.
This follows the RAG pattern from Guideline 6: optional, provenance-tracked, snapshot-aware, fallback on failure. The structural index is a coverage HINT only — it decides ordering and prioritization, never the membership of the audit set. A miss must never cause a file, call-site, or investigation to be skipped or dropped.
The full specification — including the manifest schema, SQLite serving store, capability-based per-partition backend selection, canonical symbol IDs, query interface, baseline-plus-delta overlay, deterministic partial coverage, and safety guardrails — lives in a single source of truth:
../mantis-structural-index/SKILL.md
A thin reference blueprint is at references/mantis-structural-index.md.
Two implementations are supported, sharing the same query contract:
  • Option A (Default — Skill-Based): The
    mantis-structural-index
    skill generates and runs helper scripts (
    build_structural_index.py
    and
    query_structural_index.py
    , both
    # MANTIS_HELPER_VERSION = 5
    ) using capability-based per-partition backend selection, degrading to grep.
  • Option B (Maximum Power — MCP-Based): The harness owns a persistent structural index serving
    find_callers(symbol)
    ,
    find_callees(function)
    ,
    get_function_boundary(file, line)
    MCP tools, backed by the same SQLite serving store.
Both are optional. A non-conformant harness simply skips the structural index stage. The structural index supplements grep as a ranking HINT ONLY — it decides ORDER, never MEMBERSHIP of the audit set.
Consumers MUST use the query interface (
query_structural_index.py
) rather than filtering JSONL directly. The query interface provides bounded results, pagination, explicit name resolution, precision/backend metadata, and coverage on empty results.
对于小型仓库,研究员可以grep调用站点,规划器可以推断依赖关系。在规模较大时,基于grep的调用站点发现不可靠(遗漏间接调用、无法区分调用与注释/字符串、无函数边界感知)。结构化代码索引提供AST级上下文(函数边界、调用图、符号表)以提升发现期间的LLM推理质量。
这遵循指南6中的RAG模式:可选、可追溯来源、感知快照、失败时回退。结构化索引仅为覆盖范围提示——它决定顺序和优先级,绝不决定审计集的成员资格。索引缺失绝不能导致文件、调用站点或调查被跳过或丢弃。
完整规范——包括清单Schema、SQLite服务存储、基于能力的分区后端选择、规范符号ID、查询接口、基线加增量覆盖、确定性部分覆盖和安全护栏——位于单一事实来源:
../mantis-structural-index/SKILL.md
精简参考蓝图位于references/mantis-structural-index.md
支持两种实现,共享相同的查询契约:
  • 选项A(默认——基于技能):
    mantis-structural-index
    技能生成并运行辅助脚本(
    build_structural_index.py
    query_structural_index.py
    ,均为
    # MANTIS_HELPER_VERSION = 5
    ),使用基于能力的分区后端选择,降级为grep。
  • 选项B(最大能力——基于MCP): 工具包拥有持久化结构化索引,提供
    find_callers(symbol)
    find_callees(function)
    get_function_boundary(file, line)
    MCP工具,由相同的SQLite服务存储支持。
两者均为可选功能。不符合要求的工具包只需跳过结构化索引阶段。结构化索引仅作为排名提示补充grep——它决定顺序,绝不决定审计集的成员资格。
消费者必须使用查询接口(
query_structural_index.py
)而非直接过滤JSONL。查询接口提供有限结果、分页、显式名称解析、精度/后端元数据和空结果覆盖范围。

D. Per-Skill Augmentation Guidance

D. 按技能增强指南

When a structural index is available, instruct the following skills to use it. These are the consumption contract — runtime instructions passed by the harness. The structural index is a HINT-only enhancement; skills that do not use it behave exactly as they do today:
  • mantis-architecture: Optionally read the pre-built structural index (built by
    mantis-structural-index
    at Stage 0.5) during KB synthesis, cross-referencing it with
    dependencies.json
    .
  • mantis-plan: Use the structural index for function-level dependency fan-out (more precise than file-level
    dependencies.json
    ).
  • mantis-researcher: Wave 1 sub-agents use
    find_callers()
    to SUPPLEMENT grep as a ranking HINT for call-site discovery — it decides ORDER, never MEMBERSHIP. It MUST NEVER replace the exhaustive Step-3 call-site sweep; every call-site that a full grep would reach must still be audited whether or not it ranks in the structural index. Audit the union of grep results and structural index results. Wave 2 deep auditors use
    get_function_boundary()
    to start with the enclosing function, expanding to callers/callees/file as needed for cross-function context. The researcher's existing Wave 1/Wave 2 structure is unchanged.
当结构化索引可用时,指示以下技能使用它。这些是消费契约——工具包传递的运行时指令。结构化索引是仅提示的增强;不使用它的技能行为与当前完全相同:
  • mantis-architecture: 可选在KB合成期间读取预构建的结构化索引(由
    mantis-structural-index
    在阶段0.5构建),与
    dependencies.json
    交叉引用。
  • mantis-plan: 使用结构化索引进行函数级依赖扇出(比文件级
    dependencies.json
    更精确)。
  • mantis-researcher: Wave 1子Agent使用
    find_callers()
    补充grep作为调用站点发现的排名提示——它决定顺序,绝不决定成员资格。绝不能替代详尽的步骤3调用站点扫描;完整grep会找到的每个调用站点,无论是否在结构化索引中排名,都必须被审计。审计grep结果和结构化索引结果的并集。Wave 2深度审计员使用
    get_function_boundary()
    从封闭函数开始,根据跨函数上下文需要扩展到调用者/被调用者/文件。研究员现有的Wave 1/Wave 2结构不变。

E. Integration with RAG (Guideline 6)

E. 与RAG集成(指南6)

  • Structural index entries can be added to
    chunks.jsonl
    as
    entity_type: "structural"
    chunks.
  • Code chunks can become function-boundary-aligned (instead of dumb line-range slices) by using function boundaries from the structural index.
  • The structural index and the RAG index can share the same vector embedding infrastructure if both are implemented.

  • 结构化索引条目可作为
    entity_type: "structural"
    块添加到
    chunks.jsonl
  • 通过使用结构化索引中的函数边界,代码块可与函数边界对齐(而非简单的行范围切片)。
  • 如果同时实现结构化索引和RAG索引,它们可以共享相同的向量嵌入基础设施。

10. Tiered Iterative Reproduction & Multi-Conversation Retry Strategy

10. 分层迭代复现与多对话重试策略

For complex services, attempting a single-shot reproduction directly against a full sandboxed service often suffers from high search entropy, brittle configuration, and hard-to-debug failures. A tiered strategy breaks reproduction into incremental milestones, while an inter-conversation retry architecture prevents reasoning deadlocks and context bloat.
对于复杂服务,直接针对完整沙箱服务尝试单次复现通常会遇到高搜索熵、配置脆弱和故障难以调试的问题。分层策略将复现分解为增量里程碑,而对话间重试架构可防止推理死锁和上下文膨胀。

A. Orchestration & Inter-Conversation Retries

A. 编排与对话间重试

  1. Intra-Conversation Retries (Local Agent Trajectory):
    • The active subagent conversation retries 2–3 times locally within its context window to adjust parameters, fix setup bugs, or refine payloads.
  2. Inter-Conversation Retries (Fresh Context + Accumulated Artifacts):
    • Trigger: If intra-conversation retries fail to reach Tier 3 (
      reproduced
      ), the orchestrator terminates the stalled conversation and launches a new subagent conversation (a fresh context window).
    • Context Provisioning: The orchestrator populates the new prompt with structured attempt data from
      state_root/workspace/archive/.repro_attempts.json
      and trajectory learnings from
      workspace/learnings.jsonl
      (e.g., "Attempt 1 failed due to missing auth header X; Attempt 2 proved parser strips unescaped quotes").
    • Benefit: Eliminates context bloat and reasoning inertia ("hallucination traps"), enabling a fresh agent to solve the problem using prior empirical observations without repeating past mistakes.
  3. Attempt Cap Accounting & Arithmetic:
    • The orchestrator maintains
      state_root/workspace/archive/.repro_attempts.json
      .
    • Tier 3 Increment Only: Only Tier-3 full sandboxed service executions (or full end-to-end reproducer runs) increment the per-finding attempt counter toward the absolute hard ceiling of 6.
    • Stepping-Stone Sub-Budget: Internal Tier-1 and Tier-2 trial runs are bounded by a local sub-budget (max 3 trial executions per conversation) and do not consume the absolute 6-attempt cap.
  1. 对话内重试(本地Agent轨迹):
    • 活动子Agent对话在其上下文窗口内本地重试2–3次,调整参数、修复设置错误或优化payload。
  2. 对话间重试(新鲜上下文 + 累积工件):
    • 触发条件: 如果对话内重试未能达到Tier 3(
      reproduced
      ),编排器终止停滞的对话并启动新的子Agent对话(新鲜上下文窗口)。
    • 上下文提供: 编排器使用
      state_root/workspace/archive/.repro_attempts.json
      中的结构化尝试数据和
      workspace/learnings.jsonl
      中的轨迹学习结果填充新提示(例如*“尝试1因缺少认证头X失败;尝试2证明解析器会去除未转义的引号”*)。
    • 优势: 消除上下文膨胀和推理惯性(“幻觉陷阱”),使新鲜Agent能够使用先前的实证观察解决问题,而不重复过去的错误。
  3. 尝试上限统计与计算:
    • 编排器维护
      state_root/workspace/archive/.repro_attempts.json
    • 仅Tier 3递增: 只有Tier-3完整沙箱服务执行(或完整端到端复现器运行)才会将每个发现结果的尝试计数器向绝对硬上限6递增。
    • 垫步子预算: 内部Tier-1和Tier-2试验运行受限于本地子预算(每个对话最多3次试验执行),不消耗绝对6次尝试上限。

B. Harness-Enforced Tier 4 (Staging & Live Pre-Production Execution)

B. 工具包强制Tier 4( staging与预生产环境执行)

To prevent un-gated exploit execution on live infrastructure, Tier 4 (Staging / Pre-Production verification) is strictly owned and enforced by the programmatic orchestrator harness, never by LLM discretion:
  • Sandbox Boundary:
    mantis-reproduce
    executes strictly within isolated local sandboxes (Tiers 1–3) ending at Tier 3 (
    reproduced
    /
    failed_to_reproduce
    ).
  • Deterministic Gate: The harness intercepts a Tier 3
    reproduced
    verdict. If live/staging validation (Tier 4) is configured, the harness MUST NOT automatically invoke remote execution. It must enforce a programmatic Human-in-the-Loop gate:
    • Prompt the human operator for explicit interactive confirmation, OR
    • Require a cryptographically signed approval token / authorization callback.
  • Fail-Closed Default: If human approval is missing or denied, Tier 4 is skipped and the Tier 3 sandboxed verdict remains authoritative.
为防止在实时基础设施上无限制地执行漏洞利用,Tier 4(Staging / 预生产验证)严格由程序化编排器工具包拥有和强制执行,绝不允许LLM自行决定:
  • 沙箱边界:
    mantis-reproduce
    严格在隔离的本地沙箱(Tiers 1–3)内执行,结束于Tier 3(
    reproduced
    /
    failed_to_reproduce
    )。
  • 确定性门: 工具包拦截Tier 3的
    reproduced
    结论。如果配置了实时/staging验证(Tier 4),工具包绝不能自动调用远程执行。它必须强制执行程序化的人工介入门
    • 提示人工操作员进行显式交互式确认,OR
    • 需要加密签名的批准令牌 / 授权回调。
  • 默认关闭失败: 如果缺少人工批准或被拒绝,跳过Tier 4,Tier 3沙箱结论保持权威。

C. Local Ingress / Middlebox Edge Annotation (Post-Tier-3 Sandbox Verification)

C. 本地入口/中间盒边缘注释(Tier-3沙箱验证后)

To eliminate false-positive findings caused by default edge filters ("Works on localhost:8080, but dies at the WAF/proxy"), the orchestrator can optionally execute a Tier 3 PoC through a local reverse proxy or API gateway (e.g. NGINX, Envoy, ModSecurity) running inside the local sandbox:
  • Annotation Only: A payload blocked by a local middlebox MUST NOT downgrade a Tier 3
    reproduced
    verdict to
    failed_to_reproduce
    .
  • Critic Integration: The harness records
    ingress_blocked: true
    (or edge filter details) in the finding's
    repro_hints
    or history. This provides empirical evidence for
    /mantis-critic
    to classify
    production_viability
    as
    "CONDITIONAL_VIABLE"
    (mitigated by default edge proxy configuration).
为消除默认边缘过滤器导致的假阳性发现结果(“在localhost:8080上有效,但在WAF/代理处失败”),编排器可选择在本地沙箱内通过本地反向代理或API网关(如NGINX、Envoy、ModSecurity)执行Tier 3 PoC:
  • 仅注释: 被本地中间盒阻止的payload绝不能将Tier 3的
    reproduced
    结论降级为
    failed_to_reproduce
  • 评论员集成: 工具包在发现结果的
    repro_hints
    或历史记录中记录
    ingress_blocked: true
    (或边缘过滤器详细信息)。这为
    /mantis-critic
    production_viability
    分类为
    "CONDITIONAL_VIABLE"
    (由默认边缘代理配置缓解)提供实证证据。