mantis-plan
Formulates a targeted defensive security reviewing plan based on the active threat model and historical learnings. Use when starting a security review campaign to map the codebase boundaries and generate a roadmap (workspace/plan.json). Don't use for executing code reviews, writing test scripts, or
By google · 1,021 installs
npx skills add google/mantis --skill mantis-plan
Source repository · Upstream listing
Strategist (/mantis plan)
System Goal
Security Architect. Analyzes code structure, directory metadata, and historical
records to map the external boundary and formulate an adaptive review roadmap.
Command Definition
Command: /mantis plan
Description: Formulates a targeted defensive security reviewing plan based
on the active threat model and historical learnings.
Arguments (optional; supplied by the orchestrator, consumed by Block A):
snapshot root / SNAPSHOT ROOT : absolute path to the pinned read only
code snapshot (CODE ROOT for all snapshot relative paths).
snapshot id / SNAPSHOT ID : the pass snapshot identifier (sentinel +
Block B comparisons).
state root : absolute path to the workspace/ state dir (plan.json,
.mantis state.json, findings/, kb/, archive/). STATE RELATIVE — never
prefixed with CODE ROOT.
All flags absent MODE OFF/legacy mode (Block A step 1d): behaves exactly
as today.
Input/Output Contract
Reads :
workspace/.mantis state.json (to track current loop pass).
workspace/kb/THREAT MODEL.md (if exists).
workspace/kb/index.md (checks existence to determine Mode A vs B).
Mode A: traverses production directories and source files, reads
mantis summary.md (if available).
Mode B: reads workspace/kb/index.md , workspace/kb/THREAT MODEL.md ,
workspace/archive/.repro attempts.json (if exists), VCS diffs or file
timestamps/hashes.
workspace/kb/structural index/manifest.json (to check structural index
availability/status).
workspace/helpers/query structural index.py (to invoke bounded
structural index queries).
workspace/.mantis state.json NEW fields:
active snapshot.{snapshot id, snapshot pinned, vcs type} ,
snapshot history (read, written by the meta agent). vcs type is read
because Block E branches on it. Plan runs Block E in the LIVE repo root to
compute changed files / changed files status (COMPUTED or UNKNOWN) and
writes them back to state.
Writes :
workspace/plan.json .
Copies retry eligible finding JSON files from
workspace/archive/findings pass K/ or workspace/archive/loopK findings/
(where K is the pass it was archived in) to workspace/findings/
(preserving their original UUID filenames).
Preconditions :
Codebase must be accessible.
Idempotency Guarantee :
Overwrites workspace/plan.json directly. In Mode B, copies a finding back
verbatim only when Block B is MATCHED and its file is unchanged and present;
otherwise it schedules a fresh re discovery investigation. Consults
.repro attempts.json under the cache read rule.
Instructions
Step 0: Locator Resolution (run before everything else)
[!NOTE] CURRENT PASS CHECK (defensive; the binding guarantee is on the
harness per mantis pipeline adapter Scenario 2): if active snapshot is
present AND active snapshot.pass != state.pass number , treat the snapshot as
STALE for this pass — STOP "stale active snapshot: pass mismatch" or degrade
as HALT ( snapshot pinned effectively false: no authoritative verdicts, Block
B NOT MATCHED, reproduce not attempted ). This catches a custom harness that
preserved active snapshot across the Stage 15 pass increment without
re pinning. The reference meta agent re pins every pass, so this check never
fires there. Block B itself cannot detect this (it is snapshot id only, not
pass aware).
Skill specific notes for the strategist:
Plan is a CODE READING stage in Mode A (it crawls production directories); the
findings only skip does NOT apply.
Mode A crawling and every target files path are SNAPSHOT RELATIVE: crawl and
resolve them under CODE ROOT.
workspace/kb/ , workspace/plan.json , workspace/.mantis state.json ,
workspace/archive/ , and workspace/findings/ are STATE RELATIVE: read/write
them under state root, NEVER under CODE ROOT.
Never write, compile, or generate under CODE ROOT (Block A step 4). The plan
script writes ONLY workspace/plan.json (state relative). The VCS diff in Block
E runs in the LIVE repo root per Block A step 5, NOT CODE ROOT.
Analyze the repository structure and create a detailed defensive security review
plan that avoids duplication of prior efforts while digging deep into complex
inter procedural paths and un scanned code boundaries.
Target Agnosticism Directive: The target you are evaluating may be raw
source code, a compiled binary, a firmware blob, or a live staging/dev
endpoint. Ground your planning in whatever format the target is currently in.
You are authorized and encouraged to use whatever suitable tools are at your
disposal (e.g., standard Unix tools, unblob , radare2 , angr , objdump ,
Ghidra , qemu , unicorn ) to explore the artifact structure. If source code
is not available, do not attempt to force a source code workflow (e.g.
searching for .c or .py files); adapt and 'do what works' for the artifact
at hand.
Execute the planning stage as follows:
1. Check for Threat Model Context: Check the knowledge base directory for a
workspace/kb/THREAT MODEL.md file. If it exists, read the file it
completely to understand the program's official security boundaries, threat
actors, assets, high risk interfaces, and trusted inputs.
2. Determine Mode & Retrieve Learnings: Check if the knowledge base index
workspace/kb/index.md exists.
MODE A: First Pass Exhaustive Mode (No workspace/kb/index.md found):
If this is the first run, guarantee complete coverage of the codebase. To
avoid hitting output token limits on large repositories, do not generate
the workspace/plan.json manually in your text response. Instead, execute
a shell command to run a short script in your preferred language that:
1. Uses find or os.walk to crawl all production directories. If a
mantis summary.md file exists in a directory, use its contents to
understand the directory structure instead of reading every individual
source file. Otherwise, crawl all production source code files (e.g.,
.c , .cpp , .py , .js , .go , .rs , .java ).
2. Ignores test folders, build artifacts, and vendor dependencies (e.g.,
node modules , .git , tests/ ).
3. Programmatically formats the list into the workspace/plan.json schema
and writes it directly to disk. Because this is an automated script,
instruct it to use a generic, overarching baseline question for the
"question" field (e.g., "Conduct a baseline audit for memory safety
and logic flaws"), reserving highly contextual custom questions for Mode
B.
MODE B: Strategic Learning Mode ( workspace/kb/index.md exists): Read
workspace/kb/index.md and workspace/kb/THREAT MODEL.md to review the
compounded historical knowledge of the codebase, including trust
boundaries, vulnerability classes, and architectural components. Adapt your
focus to design new, targeted deep dives and regression reviews for
components and files that have histories of vulnerabilities. You may
generate the workspace/plan.json manually using your file writing tools
for this mode, as the scope will be much narrower.
Targeted Re Evaluation & Retries : Review the KB index, entity files,
and the reproduction attempt cache file
( workspace/archive/.repro attempts.json if it exists). You must
identify findings that need re evaluation or retries:
Also read the snapshot context from workspace/.mantis state.json :
active snapshot.{snapshot id, snapshot pinned} and snapshot history
(both written by the meta agent). Then COMPUTE changed files /
changed files status for THIS pass by running Block E below in the LIVE
repository root (per Block A step 5 — VCS metadata carve out; the pinned
snapshot root strips .git/.hg/.repo, so the diff MUST run against the
live tree). Write the computed changed files (array of repo relative
paths) and changed files status ( COMPUTED or UNKNOWN ) back to
workspace/.mantis state.json , then use them for the rest of the stage.
Also write changed files pass = the current pass number from state,
so consumers can detect a stale (prior pass) diff. Use the following to
know which files changed since the previous pass:
CHANGED SINCE PREVIOUS: run in the LIVE repository root (NOT
SNAPSHOT ROOT). CUR = current commit/revision; PREV = snapshot history
entry BEFORE this pass. If PREV missing OR vcs type in {none,unknown} OR
the SNAPSHOT ID for prev or cur is a content:/live:/+content hash
fallback OR the diff command errors changed files status = UNKNOWN.
Treat EVERY file as CHANGED. NEVER treat as unchanged. NEVER drop. (Note:
snapshot pinned false alone is NOT a trigger for UNKNOWN — in HALT
mode, active snapshot is present and snapshot history has a PREV
entry, so the diff can still run. In MODE OFF — no active snapshot —
there is no PREV entry, so PREV is missing and the diff degrades to
UNKNOWN, but this does NOT force a full Mode A crawl; see the Mode A
trigger below.) Else: git :
git diff name status M C diff filter=RAMDCT PREV CUR (the M
flag detects renames; C detects copies; name status outputs
R<score \told path\tnew path for renames so both old and new paths are
visible; diff filter=RAMDCT includes Renamed, Added, Modified,
Deleted, Copied, and Type changed files) hg :
hg status C rev PREV:CUR ( C / copies shows the source path on a
following line for renames/copies; hg codes: A=added, R=removed,
M=modified) multi vcs :
repo forall c 'git diff name status M C diff filter=RAMDCT PREV CUR'
(any error UNKNOWN) A finding's file is CHANGED if any of its
code paths (path part) is in the set, OR if its path was renamed to or
renamed from (parse R<score \told\tnew lines: both old and new paths
are in the changed set). If a finding's primary file appears as a rename
source (old path), treat the NEW path as changed too — the bug likely
moved with the file.
Also apply this cache read rule wherever you inspect
workspace/archive/.repro attempts.json . FIRST pick the cache KEY
exactly the way mantis reproduce writes it: if the finding has a
signature field, the key is that signature ; otherwise the key is
stable key = normalized title + "@" + primary file path (title
lowercased with all non alphanumerics removed; primary file path =
first code paths entry with any trailing :line stripped). THEN read
the value V under that key: if V is an integer then count=V and
last snapshot=UNKNOWN; if V is an object then count=V.count and
last snapshot=V.last snapshot (default UNKNOWN). If no entry is found
under the chosen key, also try the OTHER key form before concluding
count=0, so a signature keyed writer and a stable key reader never miss
each other and wrongly reset the attempt budget. (The cache mixes both
value forms AND both key styles during migration.)
1. Schedule for Research: For findings in the archive marked
"NEEDS RESEARCH" , schedule a targeted investigation in
workspace/plan.json (to gather missing context and resolve them to
"VALID" or "FALSE POSITIVE" ).
2. Copy for Retry (snapshot gated) or Re discover: For each archived
finding that would otherwise be retry eligible (repro not attempted,
or failed to reproduce with fewer than 2 attempts per the cache read
rule abo