@@ -84,8 +84,6 @@ Follow these guidelines during the consultation:
8484 ` --snapshot_root ` /` --snapshot_id ` normally; Block A (Locator Resolution) is
8585 universal across all code-reading stages.
8686
87- ---
88-
8987## Reference Architecture Guidelines
9088
9189Use the following guidelines as your technical reference when advising the user.
@@ -179,8 +177,6 @@ graph TD
179177 Ref -.-> ModelB
180178```
181179
182- ---
183-
184180### 1. UUID-Based Referencing Pattern
185181
186182To prevent the LLM from repeating large blocks of text (which increases latency,
@@ -236,8 +232,6 @@ them back, use the following pattern:
236232- ** Harness Action (Deterministic):** Programmatically update the
237233 ` workspace/findings/<UUID>.json ` file with the validation status and reason.
238234
239- ---
240-
241235### 2. Adaptable Reproducers via Custom MCP
242236
243237When validating findings, the agent may need to interact with diverse
@@ -255,8 +249,6 @@ to expose a clean, restricted API.
255249 manually register these tools in the API's schema format and handle
256250 dispatching tool calls to the MCP server.
257251
258- ---
259-
260252### 3. Decomposition & Multi-Model Strategy
261253
262254#### A. Pipeline Decomposition & Concurrency
@@ -289,8 +281,6 @@ Emphasize that using cheaper models for utility stages (like deduplication or
289281calibration) must be validated with empirical evaluations against a benchmark
290282dataset to ensure quality is not degraded.
291283
292- ---
293-
294284### 4. The Planning Stage and workspace/plan.json
295285
296286The planning stage plays a critical role in structuring the security campaign.
@@ -302,8 +292,6 @@ structured contract, the orchestrator can easily direct subagents, parallelize
302292sweeps, and maintain historical context across pipeline runs without repeating
303293work.
304294
305- ---
306-
307295### 5. The Pass Lifecycle Contract (Living / Synced Codebases)
308296
309297A custom orchestrator (a bespoke CLI, an ADK agent, an MCP-native pipeline, or
@@ -371,3 +359,115 @@ PIN step and passes `--snapshot_root`/ `--snapshot_id` normally; Block A
371359 read ` active_snapshot ` for provenance/annotation. When the harness archives
372360 and increments, retried findings must keep their ** original**
373361 ` discovery_commit ` .
362+
363+ #### Conformance scenarios
364+
365+ The scenarios below expose nearly every issue in the snapshot model. They are
366+ ** reference checks** , not features: the harness is responsible for preventing or
367+ handling each one in its own environment. The table is a quick-reference; prose
368+ detail follows for each scenario. The ** State** column uses the 3-STATE RULE
369+ (MODE-OFF / HALT / PINNED, branched on ` active_snapshot ` presence — see the
370+ global backward-compat rule in [ schema.json] ( ../schema.json ) and the advisory
371+ notes above); ` SNAPSHOT_ID ` formats follow the ladder in the advisory notes
372+ above (e.g. ` live:<ts> ` signals an unpinned/HALT pass).
373+
374+ ** Invariant legend** (the labels below name safety properties enforced by the
375+ blocks and the global backward-compat rule in [ schema.json] ( ../schema.json ) ):
376+
377+ | Label | Property | Enforced by |
378+ | ----- | ------------------------------ | --------------------------------------------- |
379+ | INV-1 | No false ` VERIFIED_SECURE ` | Block G + HALT ceiling |
380+ | INV-2 | No false ` failed_to_reproduce ` | Block F + HALT ceiling |
381+ | INV-3 | No dropped regression | Block B NOT_MATCHED + POSSIBLE REGRESSION |
382+ | INV-4 | Within-pass consistency | Block A sentinel + single pinned snapshot |
383+ | INV-5 | No user data loss | Block C non-destructive sync + Block A step 4 |
384+ | INV-6 | Fail-safe on missing data | Global backward-compat rule |
385+
386+ ** Quick-reference table:**
387+
388+ | # | Scenario | State | Harness behavior | Stage behavior | Block / INV | Key fields |
389+ | --- | --------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | --------------------------------------------------------------------------- |
390+ | 1 | Colocated state | PINNED | Relocate ` state_root ` outside ` CODE_ROOT ` ; ` 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 ` |
391+ | 2 | Stale active_snapshot | PINNED → STOP | Block D step 0: if ` snapshot_pinned=true ` but dir missing → STOP, yield to user | Block A step 2 sentinel mismatch → STOP; Block B NOT_MATCHED | A:2, D:0, B; INV-4, INV-6 | ` active_snapshot.{root, snapshot_id, snapshot_pinned} ` , ` discovery_commit ` |
392+ | 3 | Pin failure | HALT | Block 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} ` |
393+ | 4 | Patched shadows | PINNED (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 ` |
394+ | 5 | Different-snapshot duplicate candidates | PINNED | No special action — both passes pinned correctly; dedupe handles it | Block 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 ` |
395+ | 6 | Absent sink evidence | Any | No special action — Block F is a stage-level mechanical gate | Block 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 ` |
396+
397+ ** Per-scenario detail:**
398+
399+ ** 1. Colocated state** (` state_root ` nested inside ` CODE_ROOT ` / snapshot root)
400+ — The pinned ` SNAPSHOT_ROOT ` must live under
401+ ` <state_root>/.mantis_snapshots/pass_<N> ` (or a clean-VCS worktree/archive), and
402+ its path ** must not** contain the segment ` /workspace/ ` — otherwise
403+ ` mantis-patch ` 's state-vs-code path guard misfires (state files appear to be
404+ "under ` CODE_ROOT ` "). If ` state_root ` itself is inside ` CODE_ROOT ` , the harness
405+ must relocate it outside the snapshot before pinning. Block A step 3
406+ distinguishes SNAPSHOT-RELATIVE path fields (read under ` CODE_ROOT ` ) from
407+ STATE-RELATIVE fields (read under ` state_root/workspace ` , never prefixed with
408+ ` CODE_ROOT ` ); colocation breaks this separation.
409+
410+ ** 2. Stale active_snapshot** (` active_snapshot ` points at a snapshot from a
411+ prior pass that no longer exists or doesn't match the current tree) — Block D
412+ step 0 (crash-resume): if ` snapshot_pinned ` was ` true ` but the dir is now
413+ missing → STOP and yield to the user (never re-pin to a possibly-drifted live
414+ tree). Block A step 2 sentinel check: verify ` CODE_ROOT/.mantis_snapshot_id `
415+ exists and equals ` SNAPSHOT_ID ` ; missing or different → STOP "snapshot sentinel
416+ mismatch". Block B returns NOT_MATCHED because the finding's ` discovery_commit `
417+ won't match the stale ` SNAPSHOT_ID ` .
418+
419+ ** 3. Pin failure** (snapshot copy fails — disk full, permissions, too-large
420+ tree) — Block D step 2 (free-space precheck): compare ` du -s ` of the live tree
421+ to ` df ` free space at ` state_root ` ; if it won't fit → skip copy → step 5b. Block
422+ D step 4 (failure-tolerant verify): check copy exit status + sanity check (file
423+ count/size within ~ 90%); on failure → step 5b (unpinned/HALT). Step 5b:
424+ ` SNAPSHOT_ROOT=<live root> ` , ` snapshot_pinned=false ` ,
425+ ` SNAPSHOT_ID="live:"+ISO8601 ` . The harness still writes ` active_snapshot ` and
426+ still passes ` --snapshot_root ` /` --snapshot_id ` to stages so they see the HALT
427+ signal. Every stage then degrades conservatively: authoritative verdicts
428+ forbidden (` VERIFIED_SECURE ` , ` failed_to_reproduce ` , ` DUPLICATE ` ,
429+ ` FALSE_POSITIVE ` , ` NON_VIABLE ` ); Block B always returns NOT_MATCHED; reproduce
430+ records ` not_attempted ` ; patch's best attainable is ` VERIFICATION_INCOMPLETE ` .
431+
432+ ** 4. Patched shadows** (` --target_root ` pointing at a pre-mutated tree;
433+ sentinel-exempt path 1a in Block A) — ` mantis-patch ` passes
434+ ` --target_root=<PATCHED_SHADOW_ROOT> ` and ` --snapshot_pinned=false ` to the
435+ reproduce sub-agent for re-attack verification. Block A step 1a:
436+ ` CODE_ROOT = --target_root ` (authoritative override, overrides ` --snapshot_root `
437+ and state fallback). Block A step 2: sentinel check SKIPPED (a ` --target_root `
438+ tree is deliberately mutated and is sentinel-EXEMPT). The
439+ ` --snapshot_pinned=false ` argument is the sentinel-exemption, NOT a HALT signal
440+ — detect HALT by reading STATE (` active_snapshot.snapshot_id ` starts with
441+ ` live: ` , equivalently ` active_snapshot.snapshot_pinned ` is ` false ` in state),
442+ never from the argument passed on this invocation. The finding's
443+ ` discovery_commit ` is unaffected — it retains the pass-level ` SNAPSHOT_ID ` from
444+ when it was discovered; only the ` --snapshot_pinned=false ` argument is local to
445+ the reattack invocation.
446+
447+ ** 5. Different-snapshot duplicate candidates** (cross-pass dedupe where
448+ ` discovery_commit ` differs — the pairwise Block B NOT_MATCHED path) — Both
449+ passes pinned correctly; the findings simply come from different snapshots.
450+ ` mantis-dedupe ` Block B pairwise check compares the CURRENT finding's
451+ ` discovery_commit ` against the ARCHIVED finding's ` discovery_commit ` (NOT
452+ against the global ` SNAPSHOT_ID ` ). If they differ → NOT_MATCHED. NOT_MATCHED
453+ keeps the current finding ACTIVE and sets ` possible_duplicate_of ` (a soft,
454+ non-terminal hint — the finding is NOT filtered or trashed). If the archived
455+ finding was RESOLVED (` patch_status ` in {` VERIFIED_SECURE ` ,
456+ ` MITIGATION_PROPOSED ` } OR ` status ` ==` FALSE_POSITIVE ` OR
457+ ` production_viability ` ==` NON_VIABLE ` ) AND the pair is NOT_MATCHED → POSSIBLE
458+ REGRESSION: keep ACTIVE, add a history note, never filter (a reverted fix
459+ re-discovered on new code must never be trashed).
460+
461+ ** 6. Absent sink evidence** (Block F — PoC compiles but produces no reached-sink
462+ evidence; ` not_attempted ` vs ` failed_to_reproduce ` ) — ` mantis-reproduce ` Block
463+ F: if EVIDENCE is ABSENT (any compiler/build nonzero exit, exit 127
464+ command-not-found, exit 2 "No such file", or the sink was never reached) →
465+ ` repro_status = not_attempted ` (retry-eligible), STOP. NEVER
466+ ` failed_to_reproduce ` . In ` --reattack ` mode: leave ` reattack_status ` UNSET with
467+ a history note "setup_failed" — NEVER ` failed_to_bypass ` . ` failed_to_reproduce `
468+ is reserved for when the harness PROVABLY reached the vulnerable entrypoint but
469+ the bug did not fire. Evidence is recorded in ` repro_hints ` (sidecar file
470+ containing ` MANTIS_REACHED_ENTRYPOINT ` , or crash backtrace/ASan naming the
471+ sink). In HALT mode, the HALT ceiling additionally forces ` not_attempted ` (no
472+ ` failed_to_reproduce ` ), since a negative result on an unpinned tree cannot be
473+ trusted as authoritative.
0 commit comments