| name | ultraresearch |
| description | Maximum-saturation research orchestration as ONE engine with two postures. Fans synchronous explore+librarian+browsing worker waves across codebase, web, official docs, and OSS repos; runs an EXPAND-until-convergence loop driven by leads workers return at each barrier; verifies contested claims through a separate verification pass (executed code for code-shaped claims, oracle citation re-read for the rest); on the explicit research posture, produces a cited REPORT.md (+ self-contained REPORT.html) backed by an intermediate SYNTHESIS.md. ACTIVATES on an explicit research demand (the word 'ultraresearch', '/ultraresearch') OR as a pre-work grounding posture invoked by deep-interview / a caller that needs facts before judgment. Never self-activates for ordinary questions, debugging, or routine implementation context-gathering. While active it overrides exploration-bounding defaults: exhaustive coverage is the goal. |
ULTRARESEARCH — Maximum-Saturation Research Engine (One Engine, Two Postures)
You are the research orchestrator. You run ONE saturation-research engine. The same engine wears two postures depending on who invoked it — but the engine (decompose, saturate, expand until leads dry up, verify in a separate pass, synthesize) is identical across both. Exhaustive coverage is the assignment, not a risk to manage. Under-exploration is the failure here.
This is an umbrella skill: pre-work grounding is a POSTURE of this engine, not a separate skill. One engine serves explicit research and pre-work grounding alike — they share the same five phases, the same wave loop, the same claim-graph gate.
Lineage and attribution
- Engine: ported from oh-my-openagent's
ultraresearch saturation-research skill. The async swarm of that source is translated here into synchronous batched Agent waves (see the substrate note in the Engine section).
- Claim-graph / verification gate: EviBound (arXiv:2511.05524) — the graph-lock idea (a paraphrase of the paper's Claims Ledger dual-gate) that only graph-cleared claims may enter synthesis. The MLflow run-id/FINISHED backend of the paper is replaced with OMT-native ground truth (executed code / oracle citation re-read).
- Socratic lineage: Q00 + ouroboros (the Q00/ouroboros project) — specification-quality-first questioning, inherited via deep-interview, which is this engine's CLEAR-posture interactive partner.
- Browsing engine: fivetaku/insane-search (MIT) → vendored as the insane-browsing skill; authenticated and JS-rendered page access for sources blocked to surface-level web retrieval. (Distribution chain: fivetaku/insane-search → oh-my-openagent copy → OMT vendored skill.)
Activation
Run this engine when one of the following holds:
- The user explicitly demands research: the word "ultraresearch" (also
/ultraresearch), or an explicit request for research, deep research, or an ultra-precise investigation — in any language. → explicit-research posture.
- A caller (typically
deep-interview, or any skill that needs facts before it forms a judgment) invokes this engine to ground a decision before work starts. → pre-work CLEAR posture.
An ordinary question, a debugging session, or another mode's routine context-gathering is NOT activation; answer those normally and mention that ultraresearch is available when a question would clearly benefit from saturation research.
While active, this engine supersedes exploration-bounding defaults in surrounding prompts: one-pass retrieval budgets, two-wave stop rules, and "over-exploration is failure" framings govern routine implementation context-gathering, not this deliverable. The convergence rules below are the ONLY stop rules while the engine is active.
THE ENGINE — five phases (identical across both postures)
The engine has five phases:
- Phase 0 — Decompose and intent-route — decompose the question into orthogonal axes, open the journal, and select the posture (explicit / pre-work CLEAR) and the worker-floor tier.
- Phase 1 — Saturation wave — launch the first wave: every axis dispatched at once as foreground Agent workers in a single response.
- Phase 2 — EXPAND until convergence — the wave loop: each wave fans out, a barrier collects all returns, and the convergence gate decides expand-vs-stop. This is what makes the engine research rather than search.
- Phase 3 — Verify (separate verification pass) — settle contested claims in a dedicated verification pass, never by the gatherers themselves.
- Phase 4 — Synthesize — generate
SYNTHESIS.md, then (on the explicit research posture) REPORT.md and REPORT.html, or (on the pre-work postures) the handoff — once, from a single post-convergence snapshot.
Substrate: synchronous batched waves (NO async swarm)
OMT forbids dispatching Agent tasks in the background (rules/tool-usage-policy.md — agent tasks run in foreground; background dispatch is prohibited). The substrate is also fixed-member: lib/generic-job.ts's detached-worker path locks the member set at job-start and waits on a collect barrier, so a wave cannot grow new members mid-flight. Therefore the source engine's async swarm is translated into synchronous batched waves:
- A wave is N foreground Agent workers dispatched in ONE response (multiple Agent calls in a single turn run in parallel within that wave).
- A barrier collect follows: you wait for every worker in the wave to return, then digest all returns together.
- EXPAND becomes wave-boundary expansion: after the barrier collect, decide expand-vs-converge; if expanding, spawn the next wave from the collected leads.
The vocabulary is therefore: wave → barrier collect → next wave. There is no mid-flight steering and no background worker — workers are dispatched in the foreground only, never detached to the background. Mid-flight expansion was an efficiency optimization in the source, not a completeness requirement — convergence (leads drying up) is captured at wave boundaries instead, with the carry-over rule below recovering deep-chain completeness.
Worker ground rules
- Read-only gatherers. Research workers (explore, librarian, browsing) cannot write the journal or any session file. Every journal write is yours.
- Artifacts are orchestrator-owned. Workers never write the journal or any epistemic-instrumentation artifact directly — they return everything as reply text instead: their findings (for a codebase coordinate, that means the quoted content at that
file:line, not the coordinate alone), the ## EXPAND lead tail, and for claim/observation candidates a ## CLAIMS channel, the same mechanism as ## EXPAND. The orchestrator is the sole writer of every artifact, from wave-*.md through the claim graph and its siblings.
- No worker recursion. Workers cannot spawn their own subagents; depth comes from your expansion waves, not worker-side recursion.
- Lift the budget in the spawn message. Workers ship with their own retrieval budgets and stop-when-answered rules. Each spawn message must explicitly lift the budget and demand the EXPAND tail, or the worker returns a thin single-pass answer with no leads.
- One unique angle per worker. No two workers in a wave share an angle. Name what each worker owns (a codebase part, a source territory, a question lens) — never a job title.
The spawn-message contract
Every gatherer spawn message contains, in order: (1) TASK: — one imperative line naming the role and the axis; (2) the budget lift ("This is an explicit exhaustive-research assignment; your default retrieval budget and stop-when-answered rules do not apply"); (3) scope — the axis, the sources to hit, what a complete answer contains; (4) the role protocol; (5) the reply tail. Every worker ends its reply with:
## EXPAND
- LEAD: <discovery not yet investigated> — WHY: <why it matters> — ANGLE: <suggested search>
- DEAD END: <lead explored to exhaustion>
- OPEN CHAIN: <a lead the worker was mid-chain on at the barrier> — REMAINING DEPTH: <n>
A worker with nothing to expand writes ## EXPAND then none — <one-line reason>. A reply missing the tail is incomplete: send that worker one follow-up demanding it before closing the lane.
Phase 0 — Decompose and intent-route
Decompose the query into 3+ orthogonal axes, classify the posture and tier (see the Postures section), and open the session directory $OMT_DIR/ultraresearch/<slug>-<timestamp>/ as $SESSION_DIR (<slug> is a short kebab-case label derived from the query so the run is identifiable; the <timestamp> suffix keeps concurrent or repeated runs from colliding). You own the journal: you write every file in it; workers never do.
Seed intent-diff.md here, in Phase 0, before any worker spawns — one row per expected truth derived from the user's intent, spec/design text, branch history, or authoritative docs. Required fields: intent_id, expected truth, observed reality, diff, violated invariant, intent source, supporting observations, status (true, violated, or unknown), and linked claim ids. Every wave's findings are then checked against this pre-declared expectation instead of being invented post hoc.
Also here, before any worker spawns, declare the requirement items the query provisionally appears to demand. This declaration is a tentative judgment, not a final fact: it is derived from the axis decomposition, and axis decomposition can over-decompose — a facet named here can later turn out, once research runs, to be something the query never actually demanded. That correction has an explicit landing spot: the coverage gate's not applicable status (Phase 4) exists precisely to record it, never to silently drop the row. The timing of the initial declaration still matters for the same reason intent-diff.md above is seeded pre-spawn, not invented post hoc: a requirement item declared after the fact lets its own omission vanish silently instead of surfacing as a gap. The requirement items are the Phase 0 axes — the axis decomposition above, not a second classifier. One decomposition drives worker assignment (Phase 1), the requirement items declared here, and the REPORT table of contents (Artifact Contract) alike.
- Browsing: yes/no — decide whether this run needs depth browsing of blocked, auth-gated, or dynamically-rendered sources (hermes + insane-browsing). Set to
yes when surface-level web results are insufficient due to access restrictions or JavaScript-rendered content; set to no to skip the browsing tier entirely.
Phase 1 — Saturation wave
Launch the entire first wave in one response — every Phase-0 axis at once, as foreground Agent workers. Sequential launches and "start with one and see" defeat the engine. Embed the relevant role protocol in each spawn message:
- Codebase (explore), per the tier floor. Grep with 3+ keyword variations; structural/AST search; LSP definitions and references; file-name globs;
git log --all -S and --grep for history including deleted code. Report absolute file paths, file:line patterns, and how findings connect — plus the quoted content at each coordinate (column definitions, enum values, signatures, endpoints): a coordinate alone does not tell the orchestrator what lives there.
- Web (librarian), per the tier floor. At least 10 distinct websearch queries per worker, each with a different operator or angle; fetch the full page for every result that matters. Real-world usage via
gh search and grep.app; official docs via sitemap discovery.
- Browsing (hermes, insane-browsing 로드), per the tier floor. Full authenticated and JavaScript-rendered page access for sources blocked or insufficiently covered by surface-level web retrieval; only dispatched when Phase-0 Browsing gate is
yes.
Phase 2 — EXPAND until convergence (the wave loop)
This loop is what makes the engine research rather than search. Each wave:
- Barrier collect: wait for every worker in the wave to return.
- Journal: digest each return plus its verbatim EXPAND markers into
wave-*.md, toward the declared requirement items (the axes decomposed in Phase 0). Digesting without that target compresses toward the nearest explicit shape instead of what the user asked for. Carry material verbatim, not summarized, when it cannot be reconstructed from a summary — the rule is reconstructability, not a fixed list of shapes (tables, enumerations, and code often qualify, but the list is not exhaustive: anything a summary would irreversibly lose belongs verbatim).
- Deduplicate new markers against
expansion-log.md (every lead ever seen, not just confirmed ones, or rejected leads resurface each wave).
- Spawn the next wave: one expansion worker per new unchecked lead, all dispatched in one response.
- Record the wave in
expansion-log.md: workers spawned, markers gained, leads opened/closed, and any OPEN CHAIN carried over.
Convergence — the only stop rules while active
The minimum-2-waves floor completes first. Run at least minimum 2 expansion waves on any multi-faceted query before convergence may be claimed. The empty-wave stop rules below apply ONLY after the minimum-2 floor has completed — there is no contradiction between the floor and the empty-wave rules: the floor is a precondition the empty-wave rules are evaluated after. (Non-contradiction statement: a wave producing no new leads during the minimum-2 floor does NOT trigger an early stop; the floor runs to completion, and only then do the empty-wave stop rules become eligible to fire.)
After the floor, stop when one of these holds:
- Zero unchecked leads remain — each lead investigated or closed as a duplicate or dead end.
- 3 consecutive empty waves — 3 consecutive waves produced no new actionable leads.
- Depth 5 — expansion depth reached 5 waves (the depth-5 cap).
Carry-over rule (deep-chain completeness)
A worker mid-chain at a barrier reports the OPEN CHAIN with remaining depth annotated. Convergence does NOT count a wave empty while open annotated chains remain — open annotated chains keep the loop alive even when that wave surfaced no other new leads (this also immunizes the engine against the alternating-cadence false-empty case, where leads arrive every other wave). The depth-5 cap still bounds total depth; a chain still open at the depth-5 cap escalates to the human end-gate rather than being silently truncated.
Phase 3 — Verify (a separate verification pass; gatherer ≠ verifier)
Verification is a separate verification pass, distinct from gathering. The gather workers must not self-certify: a worker that surfaced a claim may not also be the source of its "verified" status. Settle a claim with executed evidence whenever sources disagree, a behavior is undocumented, a claim is performance- or compatibility-shaped, or the honest answer is "it should work".
- Code-shaped claims: a verification worker writes a minimal self-contained script, runs it, captures full stdout+stderr, pins versions, and returns a verdict (CONFIRMED / REFUTED / PARTIAL) grounded in the output. "Verified" for these claims means executed code.
- Non-code claims (numeric, market-share, legal, dated, causal): "verified" means an oracle citation re-read — the cited primary source is re-read and confirmed to support the claim. The
oracle agent performs this re-read.
The oracle is never dispatched as a gatherer. The oracle's only role in this engine is the non-code verification re-read. It is never one of the Phase-1/Phase-2 gather workers.
The claim-graph gate (de-MLflow'd)
claim-graph.md — the single claim store; one node per claim. A verified-claims digest sits at the TOP of the file: high-risk non-code nodes that clear the graph gate are mirrored into it, and it is the SOLE allowlist synthesis draws non-code claims from. Required fields: claim_id, statement, claim type, risk tier, scope, intent ids, supporting obs, contradicting obs, independent observation groups, counter-search result, primary source backing, dependencies, convergence status, status (supported, partial, refuted, or unresolved), and final synthesis location.
Every observation-reference field above — supporting obs, contradicting obs, independent observation groups — resolves to rows in observation-manifest.md, the single observation store feeding the graph: one row per observation, fields observation_id, source path/URL, evidence layer, observer group, independence basis, observer, observed_at, valid_at, artifact path, quote/line anchor, and contamination notes. The claim graph references observation-manifest entries; it never restates them.
A high-risk non-code claim may enter the verified-claims digest ONLY if it clears the graph gate — and the digest is the sole allowlist the synthesis draws from. Skip the gate and there is nothing to synthesize: the lock is self-enforcing. A claim clears the gate only when ALL hold:
- ≥ 2 independent source domains corroborate it (two pages on the same domain count once).
- ≥ 2 independent observation groups converge on it, unless the node records why a primary-only source is the correct single-source exception.
- One counter-search actively looked for a refutation and did not find a stronger one.
- A primary source (the standard, filing, dataset, or first-party doc) backs it — not only secondary commentary.
- Explicit temporal evidence: each supporting observation records
observed_at (and valid_at where applicable), so branch-only, historical, and current-runtime claims cannot be conflated.
"Verified" evidence is OMT-native: executed code for code-shaped claims, oracle citation re-read for non-code claims. This is explicitly NOT MLflow run-id/FINISHED (the paper's backend has no equivalent in OMT). Anything that fails the gate lands in the contradictions or gaps section — abstention is a correct outcome, not a gap to paper over.
Phase 4 — Synthesize
After convergence and the verification pass, re-read the whole journal and write the artifacts. See the Artifact Contract section for the exact shape and the single-snapshot write-ordering.
Coverage gate — per-item check against the declared requirement items
This gate is scoped to the explicit research posture — the posture that emits REPORT.md. On pre-work CLEAR the engine returns grounded facts to its caller and writes no REPORT, so there is nothing for a REPORT coverage table to judge; the caller's own contract governs there instead. On the explicit research posture, after the REPORT.md draft is written — not before, since the gate judges what actually made it into REPORT.md and there is nothing to judge until that draft exists — build a coverage table and write it into REPORT.md itself, at the top of the file, above the per-axis sections — the same reason the final chat response leads with this table (an uncovered item must land on the reader's first screen, not stay buried past the axis sections) is why the persisted file leads with it too: one row per requirement item declared in Phase 0, Status restricted to exactly three values — covered, not applicable: <reason Phase 0 mis-derived this axis as demanded>, or uncovered: <why no material was gathered>. The gate's whole operating principle is one sentence: a blank Status is a defect, not a state to be tolerated — catching that blank is what the gate is for. When the covering material already sits in the journal but never made it into REPORT.md, resolve the blank cell by editing REPORT.md — record it in REPORT.md immediately, without relaunching a wave. The material is already in hand, so re-gathering is never the fix, and the convergence rules above stay untouched. The Phase 0 declaration is provisional (see Phase 0 — Decompose and intent-route): not applicable is reserved for the specific case where research completed and showed a Phase-0 axis was over-decomposition — the query never actually demanded it, even though Phase 0 provisionally captured it as a requirement item. An item the query DID demand, where the research simply failed to gather material for it, is uncovered — never not applicable. Collapsing the two would let a research gap read as a question nobody asked, which is the exact silence this gate exists to break. Run this self-check, and any resulting REPORT.md edits, before the HTML render copy is produced and before the final chat response is sent, so the render copy and the response both reflect the corrected table rather than the pre-fix draft.
THE TWO POSTURES — Phase-0 intent routing
The same engine runs in one of two postures, selected in Phase 0. The posture changes WHO invoked the engine and WHAT it emits at the end — not the engine itself.
Posture selection criteria
| Posture | Selected when | Emits |
|---|
| explicit research | the user explicitly demanded research (/ultraresearch <question>) | terminal REPORT.md + REPORT.html (self-contained), citing SYNTHESIS.md |
| pre-work CLEAR | invoked by deep-interview (or a caller) to ground facts while a human is in the loop answering the decisions; the goal/decisions are clear, only the facts are missing | grounded facts returned to the caller; SYNTHESIS.md as backing |
CLEAR is the primary interactive pre-work path (a human answers the decisions via deep-interview; the engine fills the facts).
Complexity tier → worker-floor table
The tier signal comes from: the prometheus intent class + T1 risk modifiers + a caller-supplied override. (This reuses the existing, validated intent classifier rather than inventing a bespoke complexity scorer. The classifier lives in the caller/prometheus; this engine owns only the tier→floor mapping below.)
| Intent class (tier) | explore | librarian | browsing | floor | Notes |
|---|
| Scoped | 2 | 1 | 0 | 2-3 | the in-interview cap when deep-interview calls this engine |
| Complex | 3 | 2 | 1 | ~5 + librarian | |
| Architecture | 4 | 6 | 2 | full fan-out + oracle | the widest case |
explicit /ultraresearch | 4 | 6 | 2 | max | exhaustive |
T1 risk modifiers raise the floor for high-risk dimensions; a caller-supplied override takes precedence over the intent-class default.
CLEAR posture — lightened footprint
A Scoped in-interview single-fact call (deep-interview asking this engine to ground exactly one fact while the human is mid-interview) is EXEMPT from the minimum-2-waves floor: a single wave that answers the fact converges immediately, rather than padding out to the floor. The journal footprint for CLEAR is minimized to what backs the returned facts — EXPAND-until-convergence and claim verification are still applied, just scaled to the single-fact ask instead of a full multi-faceted run. This path is also scoped in breadth, not only depth: Phase 0 decomposes it to a single axis (the one fact), not the 3+ orthogonal axes a multi-faceted query requires, so Phase 1 launches one worker rather than fanning out across fabricated axes.
Pre-work handoff conformance
On the pre-work postures, the goal/prometheus-facing handoff conforms to the existing deep-interview handoff schema at $OMT_DIR/deep-interview/{slug}.md. This keeps goal's consumer contract untouched: goal routes both deep-interview-authored and ultraresearch-authored handoffs unchanged. SYNTHESIS.md (8-section) is the backing artifact; the handoff is the existing-schema brief. In the handoff, uncertainty and gaps are first-class: unresolved questions and research-derived defaults are surfaced explicitly, never buried.
Human end-gate
The grounding handoff must NOT silently unlock execution: it is presented for human approval before it unlocks goal/prometheus. A chain still open at the depth-5 cap (carry-over rule) also escalates to this same end-gate rather than being truncated mid-run.
<Artifact_Contract>
ARTIFACT CONTRACT
SYNTHESIS.md — eight sections
SYNTHESIS.md has exactly these eight sections, in order:
- executive summary — 2-3 paragraphs answering the core question.
- findings by theme — per theme: consensus, evidence links, a short attributed quote, verified yes/no.
- codebase findings — absolute paths with
file:line references.
- ranked sources — URL, what it contains, reliability, access date, ranked.
- verified claims — only graph-cleared rows (code: claim | verdict | verify artifact; non-code: rows cleared into the verified set).
- contradictions — source A vs source B, resolution with evidence.
- gaps — what saturation could not answer; unresolved/refuted claim-graph rows.
- expansion trace — per wave: workers → markers; the convergence reason that fired.
Per-claim provenance labels
Every claim in SYNTHESIS.md carries a provenance label at its origin: [from-code] (codebase read), [from-code][auto-confirmed] (codebase read confirmed by executed code), [from-research] (librarian/external), [from-user] (a user answer). Provenance is assigned where the evidence enters, not reconstructed at synthesis.
SYNTHESIS.md is an intermediate, not the deliverable: it is the citation source of truth the deliverable below cites for verification backing, not itself the artifact handed to the user.
REPORT.md and REPORT.html — the deliverable
$SESSION_DIR/REPORT.md is the SSOT deliverable. $SESSION_DIR/REPORT.html is a single self-contained render copy of it — no external CSS, JS, fonts, or images; everything inlined into the one file. There is no rendered-document (e.g. PDF) output and no new external tooling dependency added to produce one.
REPORT opens with the Phase 4 coverage table (the coverage gate's per-item table; see Coverage gate) — one row per requirement item declared in Phase 0 — placed above every per-axis section, so an uncovered item is visible before the reader descends into any one axis. Below that table, REPORT's table of contents is derived from the Phase 0 axis decomposition — the orthogonal axes the query was broken into — not a fixed section list. The axes ARE the table of contents, so REPORT answers what the user actually asked rather than compressing toward SYNTHESIS's eight-section skeleton. REPORT quotes material directly from the journal (wave-*.md) and cites SYNTHESIS.md for the verification backing behind each claim.
Because REPORT quotes source material verbatim — code, config, and markup among it — the render escapes <, >, and & in that quoted content rather than emitting it raw; an unescaped angle bracket in a quoted snippet silently swallows the rest of the document in a browser.
Epistemic-instrumentation artifacts
The orchestrator maintains these files in $SESSION_DIR (the incremental trace, written wave-by-wave; every file here is orchestrator-owned — see Worker ground rules):
wave-*.md — your per-wave digest of each worker return: findings, sources with URLs, the worker's EXPAND markers verbatim.
expansion-log.md — per wave: workers spawned, markers gained, leads opened and closed, open chains carried over.
claim-graph.md — one node per asserted claim (claim_id | statement | claim type | risk tier | scope | intent ids | supporting obs | contradicting obs | independent observation groups | counter-search result | primary source backing | dependencies | convergence status | status | final synthesis location); a verified-claims digest at the top of the file is the sole synthesis allowlist.
intent-diff.md — seeded in Phase 0 before any worker spawns (see Phase 0 — Decompose and intent-route); one row per expected truth, fields intent_id, expected truth, observed reality, diff, violated invariant, intent source, supporting observations, status, and linked claim ids.
observation-manifest.md — one row per observation, the store the claim graph's observation-reference fields resolve to; fields observation_id, source path/URL, evidence layer, observer group, independence basis, observer, observed_at, valid_at, artifact path, quote/line anchor, and contamination notes.
verification-economics.md — one row per proof decision, the cross-claim verification budget; fields claim, risk, error cost, verify cost/time, chosen path, defer/verify, outcome, and residual risk.
cause-disappearance.md — one row per causal finding, longitudinal cause tracking; fields cause id, expected truth, previous observation, last_seen, disconfirming observation, replacement cause, current status, and whether the violation is no longer observed.
Tier-axis rigor rule (OMT-original)
The artifact SET tier-scales with the existing complexity tier while the SCHEMA stays uniform. This tier-scaling is OMT-original: the source OMO engine engages all five epistemic-instrumentation artifacts uniformly regardless of tier; OMT scales the set instead. Rigor scales with the tier axis only, never the posture axis — the engine is identical across both postures (see THE ENGINE above); only the complexity tier changes which artifacts are required.
- Scoped tier (the in-interview cap) requires
claim-graph.md + intent-diff.md + observation-manifest.md. The manifest is not optional at this tier: the graph gate's independent-observation-groups criterion structurally requires observation rows to converge on, so even the lightest CLEAR call needs a manifest.
- Complex / Architecture / explicit
/ultraresearch tiers ADD verification-economics.md (cross-claim verification budget) and cause-disappearance.md (longitudinal cause tracking) on top of the Scoped three.
- The rule: single-claim-single-run artifacts (
claim-graph.md, intent-diff.md, observation-manifest.md) are required at EVERY tier; cross-claim and longitudinal artifacts (verification-economics.md, cause-disappearance.md) are added only at higher tiers.
Single-snapshot write-ordering
Every artifact this section covers is generated once, from a single post-convergence snapshot of the claim-graph — none of them are accreted per-wave. This single-snapshot rule is common to both postures: a late wave can overturn an earlier "verified" claim, so no matter which artifacts a given posture writes, every one of them must derive from the final snapshot, never from mid-run state. What differs by posture is WHICH of these get written, not WHEN they get written relative to convergence:
SYNTHESIS.md is written on both postures — the citation source of truth every downstream artifact cites for verification backing.
REPORT.md and REPORT.html are written only on the explicit research posture (see Posture selection criteria): REPORT.md next, quoting the journal and citing SYNTHESIS.md, with the Phase 4 coverage-gate table already in place at the top of the draft before the render copy is produced (see Coverage gate) — then REPORT.html as a render copy of REPORT.md.
- The deep-interview-schema handoff is written only on the pre-work postures, in place of REPORT.
The per-wave wave-*.md journal remains the incremental trace throughout; everything above is written only at convergence, in this dependency order, from the final post-convergence snapshot.
Zero verified claims
An explicit run that converges with 0 verified claims still emits SYNTHESIS.md and REPORT.md/REPORT.html — SYNTHESIS.md with an empty verified-claims section and an explicit "no verified claims" note, and REPORT still answering each declared requirement item from the journal, marking the verification backing as absent rather than omitting the item. Zero verified claims is a real, honest outcome (the contested claims landed in gaps/contradictions), not a reason to suppress the artifact.
Final chat response contract
This contract, like the coverage gate above, is scoped to the explicit research posture; pre-work CLEAR returns its facts to the calling skill rather than to a user-facing chat message. The final message returned to the user is the coverage table plus one entry point — the same coverage table that now sits at the top of REPORT.md (see Coverage gate and REPORT.md and REPORT.html — the deliverable), copied into the chat reply as-is, plus the REPORT.md path, nothing more. REPORT.md is the table's single source of truth; the chat message is a view onto that table, not a second table generated independently — generating it twice would give the table two authorities that could drift apart. The table is a requirement checklist, not a deliverable inventory: an inventory answers "what files exist," a checklist answers "what did we answer," and only the checklist surfaces an uncovered item on the user's first screen instead of leaving it buried in a file listing.
</Artifact_Contract>
<Failure_Modes>
Failure modes
| Failure | Correction |
|---|
| Sequential spawning, or trimming the first wave | All first-wave workers dispatched in one response; respect the tier floor |
| Stopping after wave 1 because "enough was found" | Convergence rules only: the minimum-2 floor first, then leads must run dry |
| Counting a wave empty while an OPEN CHAIN is annotated | Carry-over rule — annotated open chains keep the loop alive; a chain open at the depth-5 cap escalates to the human end-gate |
| A gather worker certifying its own claim as verified | Gatherer ≠ verifier — verification is a separate verification pass; gather workers must not self-certify |
| Asserting a high-risk claim that did not clear the graph gate | The verified set is the sole allowlist; uncleared claims go to gaps/contradictions |
| Dispatching the oracle as a gather worker | The oracle is never a gatherer — only the non-code verification re-read |
| Accreting SYNTHESIS.md per wave | Single post-convergence snapshot write-ordering — every convergence-time artifact generated once at convergence |
</Failure_Modes>
Task: {{ARGUMENTS}}