ultraresearch

SkillDev tools

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.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the ultraresearch skill

What this skill tells your AI

The instructions your AI receives, as published by toongri/oh-my-toong-playground in skills/ultraresearch/SKILL.md and read by ahel’s review.

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 that serves as 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 a 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:

  1. 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.
  2. Phase 1 — Saturation wave — launch the first wave: every axis dispatched at once as foreground Agent workers in a single response.
  3. 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.
  4. Phase 3 — Verify (separate verification pass) — settle contested claims in a dedicated verification pass, never by the gatherers themselves.
  5. 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)

The substrate is fixed-member: a wave's entire membership is dispatched in one response, and the barrier collect waits for every one of those workers to return — there is no mechanism to add a worker to a wave already in 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.
  • Symptom vs question. For multi-faceted runs, the user's question names a solution shape ("is there a library that does X?"); their pain names a symptom ("we only find out at PR/merge time"). Decompose BOTH: the stated symptom is its own axis with its own worker, alongside the solution-shaped axes. An answer that settles the question while leaving the symptom unaddressed has answered the wrong thing. For a Scoped pre-work CLEAR single-fact ask that includes a pain statement, fold that symptom into the one fact axis, launch one worker for that axis, and launch no extra symptom worker.

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. Practitioner discourse is librarian territory, not browsing-gated: engineering-blog postmortems, site:reddit.com OR site:news.ycombinator.com discussions, and "how teams handle " accounts answer the workflow and symptom axes that official docs cannot — a run whose axes include a workflow or symptom axis assigns at least one librarian to this territory.
  • Browsing (hermes, load 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:

  1. Barrier collect: wait for every worker in the wave to return.
  2. 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).
  3. Deduplicate new markers against expansion-log.md (every lead ever seen, not just confirmed ones, or rejected leads resurface each wave).
  4. Spawn the next wave: one expansion worker per new unchecked lead, all dispatched in one response.
  5. Record the wave in expansion-log.md: workers spawned, markers gained, leads opened/closed, and any OPEN CHAIN carried over.

Negative-result pivot

A wave verdict of the form "no tool provides X" is itself a lead, not a dead end: it converts the axis from tool-selection into practice-hunting. Before that axis may count toward convergence, spawn the next wave's workers on how practitioners cope without X — workflow conventions, CI checks, postmortems, discussion threads. A DEAD END marker that closes a tool claim leaves the underlying user need open; only the practice-hunting pass closes it.

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.
  • Practice-shaped claims (what teams do, rather than what a tool documents) satisfy the primary-source criterion with the practitioner's own first-party account — a postmortem, a talk, an issue thread written by the team itself. They enter synthesis labeled as practice ("teams report doing X"), never restated as tool capability; without this class the gate's primary-source criterion would structurally exclude the entire workflow axis, since no standard or first-party doc can exist for what practitioners do around a tool's gap.

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 rendering REPORT.html and before the final chat response is sent, so the HTML rendering and the response both reflect the corrected table rather than the pre-fix draft.

The coverage table also carries a workers column, sourced from expansion-log.md: for each requirement item, the workers actually assigned to it across all waves. An axis no worker was ever assigned to cannot be covered — material that was never gathered by anyone cannot have covered anything, so a covered-with-zero-workers row is the same defect as a blank Status. Staffing the log cannot resolve counts as zero: a log that records workers only in aggregate proves nothing about any single axis, so an unresolvable row is downgraded exactly as an unstaffed one is, and the fix is the per-axis attribution the expansion-log schema requires (see Epistemic-instrumentation artifacts), not a benefit-of-the-doubt covered. Declaring an axis staffs it: the Phase 1 wave assigns at least one worker to every declared axis, and the workers column is where a silently unstaffed axis surfaces.

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

PostureSelected whenEmits
explicit researchthe user explicitly demanded research (/ultraresearch <question>)terminal REPORT.md + REPORT.html (self-contained), citing SYNTHESIS.md
pre-work CLEARinvoked by a caller to ground facts while a human is in the loop answering the decisions; the goal/decisions are clear, only the facts are missinggrounded 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.)

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
25
Forks
1
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
ultraresearch
Source
github.com/toongri/oh-my-toong-playground