Skip to content

Commit 3ecca78

Browse files
committed
Define structured triage and calibration checklists in schema.json, update Reviewer/Calibrator skills, add Patcher safety guards, and document pipeline assumptions
- Add triage_checklist (12 validity constraints) to schema.json and mantis-review/SKILL.md. - Add calibration_checklist (27 sanity caps) to schema.json and mantis-calibrate/SKILL.md. - Add other recommended schemas to schema.json (kb_index, threat_model, tx_log_entry, repro_attempts, report_summary, execution_log_entry). - Improve finding validation rules in schema.json (re-attack validation, exploit chain bypass check). - Fix duplicate_of schema to not allow null values when status is DUPLICATE. - Add path and Cwd safety guards to mantis-patch/SKILL.md to prevent accidental usage of original workspace. - Document static codebase assumption in README_AGENTS.md. - Document exploit chain reproduction limitation in README_AGENTS.md. - Document patch verification and re-attack constraints in README_AGENTS.md. - Add Continuous Pipeline item to Roadmap in README.md. TAG=agy CONV=56291245-d9db-4780-b260-5992eb52e24e Change-Id: Ia34008450c35c956a1e522eb38690590496b5790
1 parent 2a2731e commit 3ecca78

6 files changed

Lines changed: 465 additions & 17 deletions

File tree

‎README.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ skill performance, see the [Agent Reference Guide](README_AGENTS.md).
229229

230230
## Roadmap / Future Work
231231

232+
* **Continuous Pipeline:** The current pipeline is designed to be run as a
233+
point-in-time review of a codebase, and not as something that is intended to
234+
regularly sync with upstream changes mid-run. It should be straightforward
235+
(if a little tricky) to tweak the pipeline to better support this, but it
236+
probably will not work today.
232237
* **Skill Self-Improvement (Meta-Learning):** The current
233238
`workspace/learnings.jsonl` and Knowledge Base (KB) architecture tracks
234239
codebase-specific empirical outcomes to adapt the `THREAT_MODEL.md` and

‎README_AGENTS.md‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ The Mantis Skills suite is designed as a modular, decoupled set of tools that
4242
can be executed sequentially or in parallel. Each stage reads and writes to a
4343
shared state stored on disk.
4444

45+
> [!IMPORTANT] **Static Codebase Assumption:** The pipeline is designed to run
46+
> against a **single, static version (snapshot) of the codebase** at a time. It
47+
> is not designed as a continuous process that watches a live codebase or
48+
> handles concurrent modifications to the source code files by external
49+
> processes during execution. If the source files are modified during a run, it
50+
> may lead to inconsistent findings, broken line references, or failed patch
51+
> applications. Rescans should be initiated as separate, distinct runs (e.g.,
52+
> triggered by a new commit or changelist).
53+
4554
```mermaid
4655
graph TD
4756
subgraph CoreStages [Pipeline Execution Loop]
@@ -263,6 +272,45 @@ deterministic execution, you can build a pipeline that:
263272

264273
--------------------------------------------------------------------------------
265274

275+
## Exploit Chains and Reproduction Limits
276+
277+
The Mantis pipeline supports identifying complex, multi-step exploit chains (via
278+
`/mantis-chain`), but **it does not attempt to programmatically write or execute
279+
end-to-end reproduction scripts for these chains**.
280+
281+
* **Constituent Reproduction Only:** The pipeline only reproduces the
282+
individual, constituent findings.
283+
* **Static Confirmation:** An exploit chain finding is marked as
284+
`statically_confirmed` if all its constituent findings have been
285+
successfully reproduced individually.
286+
* **Simplification Decision:** This is an intentional design decision to limit
287+
complexity, as automated multi-stage exploit orchestration is highly
288+
environment-dependent. Users wishing to verify end-to-end chains must write
289+
custom orchestrators or manually verify the combined flow.
290+
291+
--------------------------------------------------------------------------------
292+
293+
## Patch Verification and Re-attack Constraints
294+
295+
The `schema.json` contract defines validation rules for findings that have been
296+
patched. While `/mantis-patch` is designed to verify patches using a re-attack
297+
step (confirming `reattack_status`), the schema **does not strictly require
298+
re-attack fields** (`reattack_status`, etc.) even when `patch_status` is
299+
`VERIFIED_SECURE`.
300+
301+
This is an intentional design decision to support:
302+
303+
* **Binary-only targets:** Compiled binaries or firmware blobs skip code
304+
modification and re-attack testing, instead providing a high-level
305+
mitigation recommendation in the `patch_diff` field. These may still be
306+
marked as resolved/secure without undergoing a functional re-attack.
307+
* **Verification Fallbacks:** If the re-attack tool execution fails (due to
308+
timeouts or sandbox infrastructure issues), the pipeline can still output
309+
the generated patch that passed the initial post-patch verification run,
310+
rather than failing validation entirely.
311+
312+
--------------------------------------------------------------------------------
313+
266314
## The Reality of Non-Determinism
267315

268316
A critical concept to understand when using AI for security research is

‎mantis-calibrate/SKILL.md‎

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ produce a final risk score (1-10).
3232
- Updates finding files in-place with scoring/calibration fields
3333
(`impact_score`, `likelihood_score`, `availability_tier`,
3434
`inferred_exposure`, `attacker_position`, `mantis_risk_score`,
35-
`priority`, `sanity_triage_applied`, `outrage_commentary`,
36-
`executive_summary`).
35+
`priority`, `sanity_triage_applied`, `calibration_checklist`,
36+
`outrage_commentary`, `executive_summary`).
3737
- Reusable helper script `workspace/helpers/append_calibrate.py`.
3838
- **Preconditions**:
3939
- Confirmed or raw findings must exist in `workspace/findings/`.
@@ -607,8 +607,50 @@ Execute the calibration as follows:
607607
- `"priority"` (CRITICAL, HIGH, MEDIUM, LOW)
608608
- `"sanity_triage_applied"` (semicolon-separated list of Section 3 rules
609609
that fired, most-restrictive first, or null)
610+
- `"calibration_checklist"` object containing evaluations for all 27
611+
sanity caps (each key in the object maps to the sanity cap rule of the
612+
matching name from Section 3 above):
613+
614+
```json
615+
{
616+
"repro_failure": { "fires": <bool>, "reason": "<string>" },
617+
"unreachable_inputs": { "fires": <bool>, "reason": "<string>" },
618+
"third_party_reachability": { "fires": <bool>, "reason": "<string>" },
619+
"minor_config_hygiene": { "fires": <bool>, "reason": "<string>" },
620+
"non_security_critical": { "fires": <bool>, "reason": "<string>" },
621+
"vague_code_paths": { "fires": <bool>, "reason": "<string>" },
622+
"unreliable_triggers": { "fires": <bool>, "reason": "<string>" },
623+
"prerequisite_shell": { "fires": <bool>, "reason": "<string>" },
624+
"physical_long_term": { "fires": <bool>, "reason": "<string>" },
625+
"trusted_controller_zero_delta": { "fires": <bool>, "reason": "<string>" },
626+
"standard_host_attacks": { "fires": <bool>, "reason": "<string>" },
627+
"static_confirmation": { "fires": <bool>, "reason": "<string>" },
628+
"strict_xss": { "fires": <bool>, "reason": "<string>" },
629+
"internal_nested": { "fires": <bool>, "reason": "<string>" },
630+
"probabilistic_llm": { "fires": <bool>, "reason": "<string>" },
631+
"supply_chain_prerequisites": { "fires": <bool>, "reason": "<string>" },
632+
"non_default_config": { "fires": <bool>, "reason": "<string>" },
633+
"confidential_computing_host": { "fires": <bool>, "reason": "<string>" },
634+
"trusted_controller_critical_bypass": { "fires": <bool>, "reason": "<string>" },
635+
"local_attack_vector": { "fires": <bool>, "reason": "<string>" },
636+
"self_contained_blast": { "fires": <bool>, "reason": "<string>" },
637+
"rarely_exposed": { "fires": <bool>, "reason": "<string>" },
638+
"equivalent_primitives": { "fires": <bool>, "reason": "<string>" },
639+
"documented_insecure_config": { "fires": <bool>, "reason": "<string>" },
640+
"physical_temporary": { "fires": <bool>, "reason": "<string>" },
641+
"high_privilege_external": { "fires": <bool>, "reason": "<string>" },
642+
"trusted_controller_standard_bypass": { "fires": <bool>, "reason": "<string>" }
643+
}
644+
```
645+
646+
For each rule, `fires` must be `true` if the sanity cap rule applies
647+
(fires) to this finding, capping or downgrading its score/priority, or
648+
`false` if it does not apply. The `reason` must describe the evaluation.
649+
610650
- `"outrage_commentary"` (your reasoning about the outrage factor)
651+
611652
- `"executive_summary"`
653+
612654
- An entry to the `"history"` array:
613655

614656
```json

‎mantis-patch/SKILL.md‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ Execute the patching and verification stage as follows:
133133
location (e.g., `/tmp/mantis-shadow-[finding_id]/`).
134134
- Perform all edits, compilation, and reproduction testing inside
135135
this temporary shadow directory.
136+
- **Critical Guard (Path and Working Directory Safety):** You must
137+
ensure that every command executed (compilation, testing,
138+
verification) runs with its working directory (`Cwd`) explicitly
139+
set to the shadow directory. If the finding's `run_command`
140+
contains absolute paths to the original workspace, you must
141+
rewrite them to point to the corresponding paths in the shadow
142+
directory before execution. Do not execute any modification or
143+
verification commands against the original workspace.
136144
- Generate the unified patch diff by comparing the original source
137145
files in the workspace with the modified files in the shadow
138146
directory.
@@ -160,18 +168,26 @@ Execute the patching and verification stage as follows:
160168
`"repro_file_path"` and `"run_command"` from the reproduction entry to
161169
verify the patch.
162170

171+
* **Cwd Enforcement:** You must execute the reproducer script with the
172+
working directory (`Cwd`) set to the shadow directory (if using Option
173+
A). Ensure the command targets the copy in the shadow directory, not the
174+
original workspace.
175+
163176
- **VERIFIED SECURE:** If the post-patch sandbox run fails to reproduce
164177
the bug, the initial patch holds. However, you must now perform a
165178
**Re-attack**: assume the patch is flawed and explicitly attempt to
166179
write a new reproducer variant that bypasses your patch to reach the
167180
same root cause. Only if the re-attack also fails to bypass the fix
168181
should you mark the patch as fully successful! To ensure true
169182
independence, launch a fresh `@mantis-reproduce --reattack` subagent
170-
against the patched code directory to perform this re-attack. The
183+
against the patched code directory to perform this re-attack.
184+
**Important:** Ensure you explicitly pass the shadow directory path (not
185+
the original workspace) as the target directory for the subagent. The
171186
reproducer agent running with `--reattack` will write its outcomes
172187
directly into the primary finding's `reattack_status`,
173188
`reattack_file_path`, `reattack_run_command`, and `reattack_output`
174189
fields on disk, keeping the initial `repro_*` fields untouched.
190+
175191
- **VERIFICATION FAILED:** If the sandbox execution still triggers the
176192
bug, or if your re-attack successfully bypasses your patch, the patch is
177193
insufficient. Re-evaluate and adapt your fix.

‎mantis-review/SKILL.md‎

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ to verify validity and filter out noise and false positives.
2727
- Target source code files (at paths/lines in `code_paths`).
2828
- **Writes**:
2929
- Updates findings on disk in-place (sets `"status"`, `"reasoning"`,
30-
`"repro_hints"`, and appends history).
30+
`"repro_hints"`, `"triage_checklist"`, and appends history).
3131
- Writes helper script `workspace/helpers/append_review.py`.
3232
- **Preconditions**:
3333
- `workspace/findings/` exists with finding files.
@@ -124,6 +124,7 @@ Execute your validation as follows:
124124
resources on hallucinated bugs.
125125

126126
- **Status Resolution:**
127+
127128
- Mark as **FALSE_POSITIVE** if it violates any of the 12 rules above.
128129
- Mark as **VALID** if it passes all rules and has a clear,
129130
triggerable flaw.
@@ -133,6 +134,15 @@ Execute your validation as follows:
133134
- Mark as **NEEDS_RESEARCH** if the review is inconclusive due to high
134135
complexity, unresolved external APIs, or massive call graphs.
135136

137+
- **Checklist Construction:**
138+
139+
- Construct the `triage_checklist` object evaluating all 12 negative
140+
constraints. For each rule, set `passes` to `true` if the finding
141+
satisfies the constraint (i.e. it does not violate the rule, meaning
142+
the bug remains potentially valid under that rule), or `false` if
143+
the finding violates the rule (which requires it to be marked as
144+
`FALSE_POSITIVE`).
145+
136146
4. **Construct Reproduction Script Hints:** For every finding marked as
137147
**VALID** or **PROVISIONALLY_VALID**, provide high-signal `"repro_hints"`
138148
explaining how a reproducer agent can trigger the bug, what inputs or
@@ -155,6 +165,32 @@ Execute your validation as follows:
155165
- A `"reasoning"` field.
156166
- A `"repro_hints"` field (optional for `"NEEDS_RESEARCH"` or
157167
`"FALSE_POSITIVE"`).
168+
- A `"triage_checklist"` object containing evaluations for all 12 negative
169+
constraints (each key in the object maps to the constraint of the
170+
matching name from Section 3 above):
171+
172+
```json
173+
{
174+
"ignore_hypothetical_misuse": { "passes": <bool>, "reason": "<string>" },
175+
"ignore_missing_hygiene": { "passes": <bool>, "reason": "<string>" },
176+
"require_strict_reproducibility": { "passes": <bool>, "reason": "<string>" },
177+
"avoid_pedantic_linting": { "passes": <bool>, "reason": "<string>" },
178+
"no_security_flaw_stretching": { "passes": <bool>, "reason": "<string>" },
179+
"evaluate_questionable_file_paths": { "passes": <bool>, "reason": "<string>" },
180+
"ignore_resource_exhaustion_dos": { "passes": <bool>, "reason": "<string>" },
181+
"intrinsic_security_flaws": { "passes": <bool>, "reason": "<string>" },
182+
"verify_mitigations_pragmatically": { "passes": <bool>, "reason": "<string>" },
183+
"refine_code_paths_strictly": { "passes": <bool>, "reason": "<string>" },
184+
"ignore_simd_vector_padding": { "passes": <bool>, "reason": "<string>" },
185+
"ensure_source_code_coherence": { "passes": <bool>, "reason": "<string>" }
186+
}
187+
```
188+
189+
For each rule, `passes` must be `true` if the finding satisfies the
190+
validity constraint (i.e. it is NOT ruled out by the constraint), or
191+
`false` if it violates the constraint (ruling it out). The `reason` must
192+
describe the evaluation.
193+
158194
- An entry to the `"history"` array:
159195

160196
```json

0 commit comments

Comments
 (0)