@@ -198,6 +198,18 @@ Execute the reproduction stage under these constraints:
198198 viability, but always check status).
199199 - If no applicable findings exist, notify the user and exit.
200200
201+ ** Tier 0 — Structural Reachability Pre-Check (Advisory Queue Sorting):** If a
202+ structural code index (` mantis-structural-index ` ) is available, you MAY query
203+ ` query_structural_index.py ` (` find_callers ` ) before authoring code to check
204+ whether an AST call path exists from a public entrypoint to the vulnerable
205+ sink. Use this query to ** prioritize candidate execution order** (process
206+ findings with verified AST reachability first).
207+
208+ - ** CRITICAL HINT-ONLY GUARDRAIL:** AST reachability is a ranking HINT ONLY.
209+ Call graphs miss macros, function pointers, dynamic dispatch, and interface
210+ tables. An absent call path MUST NEVER reject a finding, skip reproduction,
211+ or set ` failed_to_reproduce ` .
212+
201213 ** Snapshot drift check:** For each loaded finding, if it already has a
202214 ` repro_snapshot_id ` and Block B (Step 0) returns NOT_MATCHED, treat any
203215 stored PoC/offsets as STALE: regenerate the reproducer from scratch against
@@ -285,11 +297,57 @@ Execute the reproduction stage under these constraints:
285297 standard execution. Use your best judgment to construct a working harness for
286298 the artifact.
287299
288- - * Optional Parallel Trajectory Search:* If your environment or agent
289- framework supports spawning subagents, you can deploy multiple concurrent
290- agents to attempt writing the reproducer via different logical approaches.
291- If any trajectory succeeds, immediately adopt its payload and discard the
292- others to escape potential "give up" loops.
300+ - * Parallel Trajectory Search vs. Tiered Iterative Reproduction:*
301+
302+ - ** Parallel Trajectory Search (Breadth-First):** When subagents are
303+ available, deploy concurrent workers taking diverse logical approaches to
304+ reproduce the bug. If any trajectory succeeds, immediately adopt its
305+ payload and discard the others to escape potential "give up" loops and
306+ prune compute costs.
307+
308+ - ** Tiered Iterative Reproduction (Depth-First Payload Refinement):** Each
309+ trajectory worker (or a single agent) uses a tiered escalation ladder
310+ (Tier 1 -> Tier 2 -> Tier 3) to refine its trigger payload incrementally
311+ rather than attempting a single-shot end-to-end launch.
312+
313+ - * Tiered Iterative Execution Ladder:*
314+
315+ - ** Tier 1 (Micro-Harness / Sink Logic Validation):** Construct a
316+ lightweight test calling the vulnerable function/module directly to
317+ verify that the core bug hypothesis is sound in isolation.
318+ - ** Tier 2 (Subsystem / Interface Validation):** Pass the payload through
319+ input serialization, parsers, routing, and auth wrappers to verify the
320+ input survives intermediate processing without sanitization or
321+ truncation.
322+ - ** Tier 3 (Full Sandboxed Service / E2E Validation):** Execute the
323+ self-contained PoC against the target service via public APIs inside the
324+ isolated sandbox (Docker, QEMU, VM). Yields the authoritative
325+ ` reproduced ` verdict per Block F.
326+
327+ - ** CRITICAL STEP-4 TIER-1 HARD GATE (Fail-Closed):**
328+
329+ - Tiers 1 and 2 are ** internal stepping stones only** . You ** MUST NEVER**
330+ record ` repro_status = "reproduced" ` or ` "statically_confirmed" ` based on
331+ a Tier-1 or Tier-2 execution.
332+ - If a crash can ** ONLY** be achieved by compiling a direct-call harness
333+ that feeds a private/static function or bypasses the public API (Step 4),
334+ and the payload cannot be escalated to trigger through Tier 3 (the public
335+ API / sandboxed service), you ** MUST TERMINATE AND RECORD**
336+ ` repro_status = "failed_to_reproduce" ` with details citing
337+ ` "Internal Invariant Protection" ` .
338+
339+ - * Attempt Cap Accounting & Local Retries:*
340+
341+ - ** Sub-Tier-3 Stepping-Stone Sub-Budget:** Internal Tier-1 and Tier-2
342+ trial runs are bounded local execution steps (max 3 trial executions per
343+ conversation) and ** DO NOT** increment the absolute per-finding attempt
344+ counter in ` state_root/workspace/archive/.repro_attempts.json ` .
345+ - ** Absolute Attempt Cap Counting:** Only Tier-3 full sandboxed service
346+ executions (or full end-to-end reproducer runs) increment the absolute
347+ attempt counter toward the hard ceiling of 6 (Section 6).
348+ - ** Intra-Conversation Retries:** When a tier fails, inspect logs, adjust
349+ payload parameters, fix harness setup, and retry up to 2-3 times within
350+ the active conversation before reporting back to the orchestrator.
293351
294352### Step 3a: Variant Hunting (re-attack only, MANDATORY)
295353
@@ -534,17 +592,25 @@ and apply INV-1 (downgrade `VERIFIED_SECURE` → `VERIFICATION_FAILED`).
534592 * Open the lock file ` state_root/workspace/archive/.repro_attempts.lock `
535593 (creating it if missing) and acquire an exclusive lock (` fcntl.flock `
536594 with ` fcntl.LOCK_EX ` ) inside a context manager (` with ` statement).
595+
537596 * Read the current contents of the cache file
538597 ` state_root/workspace/archive/.repro_attempts.json ` (treating it as ` {} `
539598 if missing or empty).
599+
540600 * Increment the ` count ` field of this finding's cache-key entry — keyed by
541601 ` signature ` if present, else ` stable_key ` , the SAME key selection defined
542- above (the ` {count, last_snapshot} ` object) — by 1.
602+ above (the ` {count, last_snapshot} ` object) — by 1 ONLY for Tier-3 (full
603+ end-to-end sandboxed service) executions. Internal Tier-1 and Tier-2
604+ stepping-stone trials MUST NOT increment ` count ` (they are governed by
605+ the sub-budget rule in Step 3).
606+
543607 * Write the updated JSON to a temporary file in the same directory (e.g.,
544608 ` state_root/workspace/archive/.repro_attempts.json.tmp ` ).
609+
545610 * Atomically replace the target cache file with the temporary file (e.g.,
546611 ` os.replace ` in Python) to ensure readers never see a truncated or
547612 incomplete file.
613+
548614 * Close the lock file descriptor to release the lock (automatically handled
549615 by exiting the ` with ` context manager).
550616
@@ -564,6 +630,11 @@ and apply INV-1 (downgrade `VERIFIED_SECURE` → `VERIFICATION_FAILED`).
564630
565631 - ` "repro_snapshot_id" ` : the current SNAPSHOT_ID this run executed against.
566632
633+ - ` "repro_hints" ` : Record compilation and sandbox execution telemetry
634+ (e.g., ` sanitizers_used: ASan+UBSan ` , ` assertions_disabled: true ` ,
635+ ` build_profile: release ` ) to provide empirical execution evidence for
636+ ` /mantis-critic ` .
637+
567638 - If reproduction succeeds (` repro_status ` is evaluated as ` "reproduced" `
568639 or ` "statically_confirmed" ` ) and the finding's current ` "status" ` is
569640 ` "PROVISIONALLY_VALID" ` : BEFORE upgrading, scan the finding's
0 commit comments