mantis-researcher
This skill performs rapid triage and deep-dive reviews of production source files to surface missing boundary checks, weak preconditions, unsanitized input, and interface violations. It turns a manual file-by-file audit into structured, deduplicated, and traceable findings driven by an audit plan, so security coverage scales across large codebases.
npx skills add https://github.com/google/mantis --skill mantis-researcherBefore / After Comparison
3 组Developers open source files one by one to compare boundary checks and input validation, losing an entire afternoon per pass and still missing issues buried in deep call chains.
This skill triages and deep-dives target files according to an audit plan, writing each finding as a separate JSON artifact, so one pass drops from hours to tens of minutes with far broader file coverage.
Mantis Researcher (/mantis-researcher)
System Goal
Resilience Code Auditor. Performs rapid triage and deep-dive reviews of source files to identify boundary checks, preconditions, missing sanitization, and interface violations.
Command Definition
- Command:
/mantis-researcher - Description: Audits production source code files based on the strategy in
workspace/plan.json. - Arguments (optional; supplied by the orchestrator, consumed by Block A):
--snapshot_root/SNAPSHOT_ROOT: absolute path to the pinned, read-only code snapshot for this pass. This is the CODE_ROOT that all snapshot-relative path fields resolve against (Block A step 1b).--snapshot_id/SNAPSHOT_ID: the pass snapshot identifier. Used for the sentinel check (Block A step 2) and stamped verbatim into every finding'sdiscovery_commit.--state_root: absolute path to theworkspace/state directory (plan.json,.mantis_state.json,findings/,kb/). State paths are STATE-RELATIVE and are NEVER prefixed with CODE_ROOT (Block A step 3).--target_root(authoritative override, Block A step 1a) is also honored if supplied.- All flags absent -> DEGRADED/legacy mode: CODE_ROOT falls back to the
current directory,
snapshot_pinnedis treated as false, and behavior matches today's exactly (nodiscovery_commitis written).
Input/Output Contract
- Reads:
workspace/plan.json(falls back to codebase sweep if missing/empty).workspace/.mantis_state.json(to track current loop pass).- referenced Markdown files in
"kb_references"(e.g.workspace/kb/entities/*.md). - Target source code files.
workspace/kb/structural_index/manifest.json(to check structural index availability/status).workspace/helpers/query_structural_index.py(to invoke bounded structural-index queries).
- Writes:
- Raw finding files to
workspace/findings/<uuid>.json(createsworkspace/findings/if missing).
- Raw finding files to
- Preconditions:
- Target files must be accessible.
- Idempotency Guarantee:
- Writes new findings as separate files with unique UUIDs. Rely on
mantis-dedupeto cluster and merge duplicate findings on subsequent steps.
- Writes new findings as separate files with unique UUIDs. Rely on
Instructions
Step 0: Locator Resolution (Snapshot-Aware Path Handling)
Run this BEFORE the numbered research steps below. It fixes the single CODE_ROOT
that every target_files / code_paths reference in this stage resolves
against, so all sub-agents audit the same pinned snapshot.
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.
Skill-specific notes for the researcher:
- The researcher is a CODE-READING stage, so Block A step 0's findings-only skip does NOT apply here — you MUST resolve CODE_ROOT and honor the sentinel.
workspace/plan.jsontarget_filesand findingcode_pathsare SNAPSHOT-RELATIVE: resolve them under CODE_ROOT (Block A step 3).kb_references,workspace/plan.json,workspace/.mantis_state.json, and everything underworkspace/findings/are STATE-RELATIVE: read/write them under --state_root, NEVER under CODE_ROOT.- Never write, compile, or generate anything under CODE_ROOT when pinned (Block A step 4).
Perform a thorough memory-safety, logical-correctness, and robustness review of the targeted codebase.
Execute the research stage as follows:
-
Load Reviewing Plan & Context: Read the active pass number from
workspace/.mantis_state.jsonand resolve the current ISO 8601 timestamp. Read theworkspace/plan.jsonfile to retrieve the target investigations. Ifworkspace/plan.jsonis missing or empty, perform a general list of the directories and review any primary source files. If the investigation contains a"kb_references"array, explicitly read those Markdown files (e.g.,workspace/kb/entities/auth.md) to gain compounded historical context before you begin auditing the"target_files". Also readactive_snapshotfromworkspace/.mantis_state.json(root,snapshot_id,snapshot_pinned). Holdactive_snapshot.snapshot_idin memory: it is the value you will stamp into every finding'sdiscovery_commit(see Findings Schema Format). Ifactive_snapshotis absent orsnapshot_pinnedis false, you are in DEGRADED/legacy mode — do NOT stop (Block A step 1d); you will simply omitdiscovery_commit. -
Sub-Agent Delegation (Wave-Based Swarm Parallelization): If the CLI or agent platform supports spawning sub-agents (e.g., using specialized sub-agent tools or multi-agent orchestrator directives):
-
Do not execute investigations sequentially if sub-agents are supported. Split the investigations in
workspace/plan.jsoninto parallel waves to maximize throughput and context efficiency. -
Wave 1: Lightweight Rapid Triage (Concurrency Peak): Spawn concurrent, lightweight sub-agents (e.g. up to 10-20 in parallel) to sweep all files listed in
workspace/plan.json. Each sub-agent should only output a fast classification:{"potentially_flawed": true/false, "reason": "..."}. -
Wave 2: Deep Security Flaw Hotspot Audits & Parallel Trajectory Search: Collect all files flagged in Wave 1. Spawn a wave of concurrent deep auditor sub-agents (e.g. up to 4-8 in parallel) to focus exclusively on those identified hotspots. For particularly complex files, spawn multiple subagents targeting the same file using either different prompt constraints or a diverse set of less expensive LLMs to explore parallel attack vectors. Rely on the subsequent deduplication stage to merge any overlapping findings.
-
Token Optimization (Distributed Writes): Instruct the Wave 2 sub-agents to generate unique UUIDs and write their findings directly to individual
workspace/findings/<id>.jsonfiles on disk. Do not ask them to return the full JSON payload in their messages back to you, as aggregating them will blow out your context window. Ask them to only return the list of UUIDs they created. -
Snapshot Isolation (Wave Pinning) — MANDATORY: Pass the SAME
--snapshot_root(CODE_ROOT resolved in Step 0) and the same--snapshot_idvalue to EVERY Wave-1 and Wave-2 sub-agent, and instruct each of them to obey Block A (resolvetarget_files/code_pathsunder that CODE_ROOT, honor the sentinel). Any Wave-2 sub-agent that writes a finding MUST stampdiscovery_commitwith that snapshot_id, exactly as specified in the Findings Schema Format. Sub-agents MUST NOT rungit pull/fetch/checkout/reset,hg pull/update,repo sync, or any command that changes the working tree or switches revisions — the snapshot is immutable for the whole pass. A sub-agent that cannot see the snapshot must report that, not re-sync. -
If sub-agents or concurrency are not supported by the current environment, fall back to performing the sweeps and deep-dives sequentially.
-
Structural Index (HINT-only enhancement): When a structural index is available (
workspace/kb/structural_index/manifest.jsonexists), use it to SUPPLEMENT the wave-based swarm above. The structural index decides ORDER, never MEMBERSHIP. It MUST NEVER replace the exhaustive Step-3 call-site sweep.-
Resolution-first protocol (MANDATORY before any structural query):
- Resolve the symbol first:
python3 workspace/helpers/query_structural_index.py resolve_symbol --name "<function_name>" [--language "<lang>"] [--file "<path>"] --state_root <state_root> - If the response has
ambiguous: true, investigate ALL matched symbols — never silently pick one. Narrow with--file/--languageif possible, or schedule investigations for every matched symbol. - Use the resolved
symbol_idfor bounded queries:python3 workspace/helpers/query_structural_index.py find_callers --symbol_id "<id>" --limit 100 --offset 0 --state_root <state_root>
- Resolve the symbol first:
-
Coverage-aware interpretation: Check
coverage.partition_statusin every structural index response:complete+precision == semantic+ empty results = "no indexed callers" (authoritative for indexed code — still run grep per the HINT-only rule).complete+precision != semantic+ empty results = "no indexed callers" — NOT authoritative. MUST run exhaustive grep.partial/empty/failed+ empty results = "not fully indexed" — MUST run exhaustive grep.- Use the
precisionandbackendfields on every result to weight trust (semantic>typecheck>ast>symbol-only>heuristic>deferred>coverage-only).
-
Wave 1 (Rapid Triage): Use
find_callers()to SUPPLEMENT grep as a ranking HINT — ORDER, never MEMBERSHIP. Structural index results prioritize which files to flag aspotentially_flawed; they MUST NEVER replace the exhaustive Step-3 call-site sweep. Audit the union of grep results and structural index results. -
Wave 2 (Deep Audit): Use
get_function_boundary(file, line)to start with the enclosing function, then expand to callers/callees/file as needed for deep dive context. -
Graceful degradation: If the structural index is absent (no
manifest.json), empty, or the query helper is missing, fall back to grep-based discovery (today's behavior). The structural index is a coverage HINT only.
-
-
-
Exhaustive Interface and Call-Site Reviewing: If a target source file defines public or API functions (such as numeric parsers, decoders, encoders, or converters) that document explicit size constraints or safety requirements (e.g., expecting callers to allocate buffers of a certain size):
- Run a repo-wide grep for the function name to build the exhaustive set of
candidate call-sites — this is the mandatory floor. Then use the structural
index query helper (
resolve_symbolthenfind_callers) to RANK and prioritize which call-sites to audit first (the index distinguishes actual calls from comments/strings/variable names). Audit the union of both result sets — the structural index may miss macro-based calls, function pointers, and dynamic dispatch, so grep remains the floor. - Search the codebase to find and review all call-sites of these functions across the entire repository to ensure the safety contracts are respected globally.
- Read the calling files and verify if every call-site strictly adheres to input constraints, properly manages bounds, and checks sizes.
- Flag any discrepancies as contract alignment bugs or missing checks.
- Run a repo-wide grep for the function name to build the exhaustive set of
candidate call-sites — this is the mandatory floor. Then use the structural
index query helper (
-
Unconstrained / Exploratory Investigations: If the investigation plan in
workspace/plan.jsoncontains instructions or a question explicitly asking for an unconstrained sweep, adversarial audit, or random exploration:- Ignore existing assumptions of safety and documented trust boundaries in
workspace/kb/THREAT_MODEL.md. - Treat all inputs and boundaries as untrusted and potentially malformed.
- Analyze implementation from scratch with full freedom and autonomy.
- If it is a random exploration/digging task with minimal instructions, focus on mapping the behavior of the target files, identifying key entry points, and looking for unexpected side effects or boundary cases without being constrained by a specific threat model.
- Ignore existing assumptions of safety and documented trust boundaries in
-
Compile and Write Findings: Instead of a single monolithic file, create a
workspace/findings/directory if it does not exist. For each potential finding, generate a unique UUID and write a valid JSON object into an individual file namedworkspace/findings/<id>.json. This keeps findings isolated and prevents token limit issues during subsequent analysis. Do not include any text before or after the JSON in the files.Signature & Lineage Computation (Step 5a):
For each finding, compute
signature,lineage_id, and optionallycweBEFORE writing the JSON file:cwe(optional): If the vulnerability maps to a known CWE, set th
...
User Reviews (0)
Write a Review
No reviews yet
Statistics
User Rating
Rate this Skill