关于 mantis-history
mantis-history 是 Mantis 安全流程中的历史分析技能,面向希望从版本控制记录中提取安全经验的团队。它筛选相关提交并分析修复变更,将历史漏洞信息整理为可供后续阶段使用的 JSONL 文件。
主要功能
- 01分析版本控制历史
- 02筛选安全相关提交
- 03提取漏洞类型与修复信息
- 04缓存结果并检测历史改写
- 05输出 JSONL 历史记录
适用场景
- 01从过往提交中查找安全修复
- 02为后续安全分析提供历史线索
- 03整理漏洞类型和受影响文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ google/ mantis --skill mantis-history安装后在 Claude Code 中输入/mantis-history确认已加载。
详细介绍
历史分析器(/mantis-history)
系统目标
历史漏洞提取器。分析代码库的版本控制系统(VCS)历史,提取过去的漏洞、安全相关修复、补丁及相关文件,创建历史经验数据库,为下游技能提供参考。
命令定义
- 命令:
/mantis-history - 描述: 分析代码库的版本控制系统(VCS)历史,提取过去的漏洞和修复,并生成结构化的历史经验文件(
workspace/historical_learnings.jsonl)。 - 参数(可选;由编排器提供,供 Block A 使用):
--snapshot_root/--snapshot_id/--state_root。历史分析从实时代码库根目录读取 VCS 日志(Block A 步骤 5),而非从快照读取;仅使用--state_root来放置缓存、输出和脚本。全部缺失时 -> DEGRADED(行为与当前相同,使用实时工作目录)。
输入/输出约定
- 读取:
workspace/.mantis_state.json(用于跟踪当前循环轮次)。- 代码库目录结构和关键文件(用于确定技术栈)。
- VCS 历史日志(提交消息、标题、差异)。
mantis-summary.md(可选,如果存在)。- 内部历史分析缓存(可选,如果存在)。
- 写入:
- VCS 提取脚本(运行时写入工作区)。
workspace/historical_learnings.jsonl。- 内部历史分析缓存。
- 全部位于
--state_root/workspace/下(缓存、historical_learnings.jsonl、提取脚本):保存在目标树之外。可选的history_status标记(UNSUPPORTED_VCS/PARTIAL_SHALLOW)。
- 前置条件:
- 必须能够访问目标代码库和 VCS 日志。
- 幂等性保证:
- 缓存是事实来源:每次运行都会据此重建输出数据库,且只要缓存非空,就绝不会将输出截断为空。若 VCS 历史被重写(
_analyzed_head不再可达)或 vcs_type/代码库身份发生变化,则缓存失效。对于none/unknownVCS,此阶段会写入一个空数据库和history_status=UNSUPPORTED_VCS,然后退出。
- 缓存是事实来源:每次运行都会据此重建输出数据库,且只要缓存非空,就绝不会将输出截断为空。若 VCS 历史被重写(
说明
步骤 0:定位器解析(首先运行)
LOCATOR RESOLUTION (before reading ANY target code or artifact):
0. ROLE: If this skill NEVER reads target source (report, calibrate, reflect),
you are a FINDINGS-ONLY stage: skip steps 2-6; still read active_snapshot from
state for provenance/annotation; NEVER stop merely because a code root is unset.
1. Determine CODE_ROOT, in this priority order:
a. If --target_root is passed on THIS invocation, CODE_ROOT = --target_root.
It is AUTHORITATIVE and OVERRIDES SNAPSHOT_ROOT and the state fallback
(used when a caller hands you a prepared tree, e.g. a patched shadow).
b. Else if --snapshot_root (or SNAPSHOT_ROOT) is passed, use it.
c. Else read state_root/workspace/.mantis_state.json (state_root from
--state_root if passed, else ./workspace/... relative to the current dir)
-> active_snapshot.root / .snapshot_id / .snapshot_pinned.
d. Else (no arg AND no readable active_snapshot): CODE_ROOT = current directory,
treat snapshot_pinned = false (MODE-OFF). Do NOT stop.
2. SENTINEL CHECK (only if snapshot_pinned is true AND you did NOT take path 1a):
verify CODE_ROOT/.mantis_snapshot_id exists and equals SNAPSHOT_ID. If missing
or different -> STOP "snapshot sentinel mismatch". (A --target_root tree (1a) is
deliberately mutated and is sentinel-EXEMPT.)
3. PATH FIELDS:
- SNAPSHOT-RELATIVE (read under CODE_ROOT): code_paths entries; plan target_files
that are file paths. Strip ONLY a trailing ":<digits>". A code_paths entry
containing "://" is a URL/endpoint, NOT a file read. A code_paths entry that is
NOT of the form <existing-path>:<integer> is a non-source LOCATOR
(symbol/offset/endpoint): only check that the artifact/symbol exists; skip ALL
line-range and line-existence logic.
- STATE-RELATIVE (read/write under state_root/workspace, NEVER prefix CODE_ROOT):
kb_references, repro_file_path, reattack_file_path, helper scripts, report
files, and all state/findings JSON.
4. Never WRITE under CODE_ROOT when snapshot_pinned is true. Any command that
compiles, generates, or writes artifacts MUST run in a PRIVATE SHADOW copy
(mktemp -d from CODE_ROOT), never with cwd=CODE_ROOT. Read-only inspection may
cd into CODE_ROOT.
5. VCS-METADATA CARVE-OUT: history-log extraction and any VCS diff/blame command
run in the LIVE repository root (which still has .git/.hg/.repo), NOT CODE_ROOT
(the snapshot copy strips VCS metadata). Do NOT stop merely because CODE_ROOT
lacks .git/.hg/.repo.
6. Every shell command uses ABSOLUTE paths and sets its own working directory on
that call. Do NOT assume the working directory persists between calls.
历史分析的关键要求:固定快照副本会移除 .git/.hg/.repo,因此按照 Block A 步骤 5,你必须在实时代码库根目录(启动 Mantis 时所在的工作目录)中运行每一条 VCS log / diff / blame 命令,而不能在 CODE_ROOT 下运行。不要因为 CODE_ROOT 缺少 VCS 元数据就停止。将缓存、workspace/historical_learnings.jsonl 和生成的提取脚本写入 --state_root/workspace/(相对于状态目录)——绝不要写入目标树,以免同步/清理操作将它们删除。仅将 active_snapshot.snapshot_id 记录在条目中作为来源信息。
你的任务是分析代码库架构,确定哪些历史记录与安全相关,并即时编写脚本,从项目的版本控制系统(VCS)中提取并记录历史漏洞。
请按以下步骤执行历史分析阶段:
-
阶段 1:分析代码库并确定目标历史记录
- 阅读现有摘要(例如可用时的
mantis-summary.md),或快速检查代码库根目录结构,以了解主要文件、编程语言和核心组件。 - 确定与此项目相关的历史安全问题类型(例如内存破坏、身份验证绕过、SQL 注入、缓冲区溢出等),以及需要针对的关键字或提交。
- 阅读现有摘要(例如可用时的
-
阶段 2:编写历史提取脚本:
-
VCS 支持检查(在编写/执行脚本之前运行): 从
.mantis_state.json的vcs_info中确定vcs_type(或在当前根目录中检测)。如果vcs_type为none或unknown,或者 VCS 历史记录因其他原因无法访问:写入一个空的workspace/historical_learnings.jsonl,设置文件顶部/sidecar 标记history_status = "UNSUPPORTED_VCS",并退出——绝不伪造历史记录。 对于multi-vcs(.repo):要么逐个子项目遍历历史记录,要么写入空文件并设置history_status = "UNSUPPORTED_VCS",而不是运行会报错的类 git 脚本。对于浅层 git 克隆(git rev-parse --is-shallow-repository== true):继续处理,但设置history_status = "PARTIAL_SHALLOW",以免下游阶段将“此文件没有历史漏洞”解读为“安全”。 -
从状态文件
workspace/.mantis_state.json中读取当前轮次编号,并获取当前 ISO 8601 时间戳。 -
直接在工作区中编写一个脚本(例如 Python、bash 或你选择的语言),使其能够与仓库版本控制系统(VCS)的历史日志交互。
-
成本效益与规模优化: 为确保历史分析具有成本效益且运行高效,脚本必须实现以下优化:
- **提交消息/描述预筛选:**在获取差异之前,脚本应动态确定用于筛选提交消息的相关关键词。它可以先检查仓库中的文件以及涉及的语言/领域,以确定主要技术栈(例如软件与硬件/RTL),然后查询大模型/分析 Agent,获取量身定制的安全/错误关键词列表,或者使用更广泛的关键词集合,并补充这些特定领域的术语。跳过消息或标题不匹配这些相关关键词的修订,以免不必要地获取和分析与目标代码库无关的变更集。
- **差异筛选与大小限制:**忽略只涉及非生产代码(例如测试、文档或配置文件)的提交。跳过差异过大的提交(例如,变更超过数千行),因为它们通常是自动格式化变更或大型重构,而非独立的安全补丁。
- **缓存结果(缓存是事实来源):**在
workspace/下维护本地缓存(JSON 或 SQLite),将revision_id -> analyzed作为映射,并存储每个已分析修订的完整提取记录,以及_analyzed_head高水位标记和构建该缓存时对应的vcs_type与仓库标识。每次运行时,都要根据缓存重建workspace/historical_learnings.jsonl(不要仅因为缓存标记某个修订为“已分析”就跳过该修订,导致输出为空——这是数据不同步问题)。绝不要将非空输出数据库截断为空。只分析比_analyzed_head更新的修订。 **重写检测:**信任缓存之前,验证_analyzed_head在当前实时历史中仍可解析(git:git cat-file -e <_analyzed_head>成功,且git merge-base --is-ancestor <_analyzed_head> HEAD;hg:hg log -r <_analyzed_head>成功)。如果无法解析(强制推送/变基/压缩提交),或者vcs_type/仓库标识已更改,则使缓存失效并从头重新提取。 - **批处理(差异分批):**脚本不应对每个提交差异单独调用一次大模型,而应将多个提交的差异和消息(例如 3 到 5 个提交)合并为一次大模型调用。要求大模型分析批次中的所有提交,并以 JSON 数组的形式返回该批次的发现,从而降低请求开销和成本。
- **模型选择:**在初始提交分析/筛选阶段使用轻量、经济高效的模型;只有在需要对疑似漏洞进行深入验证时,才回退到更高阶的模型。
-
**详细分析:**对于看起来与安全相关的修订或提交,脚本应获取提交差异以及消息/变更描述。
-
**大模型/Agent 分析:**脚本应调用 API(例如通过子 Agent 消息或 Agent API 子命令),或使用大模型子 Agent 分析变更的差异和消息,以确定某个修订/提交是否修复了安全问题、受影响的组件、漏洞类型、影响和缓解措施对应的差异。确保使用批处理和缓存来尽量减少 API 调用。
-
**信息缺失:**不要过度依赖安全相关关键词的缺失。许多安全修复没有 CVE,许多安全漏洞在修复时也未被意识到是漏洞。
-
**输出格式:**要求脚本将提取的发现输出到名为
workspace/historical_learnings.jsonl的 JSONL 文件中,并匹配以下格式:
-
历史经验 Schema 格式(workspace/historical_learnings.jsonl)
{
"revision_id": "...",
"title": "...",
"description": "...",
"code_paths": ["file:line_number"],
"vuln_type": "...",
"mitigation_diff": "...",
"cve": "...",
"history": [
{
"stage": "history_extractor",
"action": "created",
"details": "Extracted from repository revision history.",
"pass_number": <current_pass_number>,
"timestamp": "<current_iso8601_timestamp>"
}
]
}
- 阶段 3:执行并验证:
- 运行刚刚编写的脚本,分析 VCS 历史记录、处理修订,并生成
workspace/historical_learnings.jsonl文件。 - 等待脚本运行完成,并验证
workspace/historical_learnings.jsonl已成功写入且包含提取的数据。
- 运行刚刚编写的脚本,分析 VCS 历史记录、处理修订,并生成
完成后,通知用户。