ultrarouter docs
Concepts

Discovery

How ultrarouter finds a workflow worth learning from your own traffic — the two a-ha moments, the channel ladder, and the law that a proposed objective never teaches.

Flywheel does not start with a form. It starts with your traffic. The moment you change the base URL and key, ultrarouter watches the calls you already make and works toward two realisations: what you are running (the structural a-ha) and which one workflow is worth learning from (the semantic a-ha). You confirm one thing — what "it worked" means for that workflow — and nothing is learned until you do.

Before any traffic arrives, discovery can start from what you have already published: your public website. When you give (or we infer) a site URL, we fetch and redact it and feed it to the discovery analyzer as untrusted input — its own neutralised data envelope, never an instruction — to propose the workflows you run and a provisional definition of good for each. At minute zero these arrive as proposals in the collecting state for you to confirm, edit or skip; a hostile website can steer nothing but a proposal you confirm. If we cannot reach an analyzer model, we make no proposal and say so — never a fabricated one.

This page explains the two a-ha moments, the ladder a signal climbs before it can be trusted, and the single hard rule underneath all of it: a proposed objective never teaches.

The two a-ha moments

1. The structural a-ha — "so this is what I'm running"

Shortly after your traffic starts flowing, the Learn onboarding shows a picture of your account assembled from nothing but your requests — no configuration, no tagging. It has four parts:

  • An inventory of your call types, ranked by the share of spend each one accounts for over the window, with a request count and an archetype hypothesis (a prior, never a fact — shown as such, or omitted when it is below confidence).
  • Contract-derived evaluator drafts — starting points for how each call type could be checked, derived from its shape, offered for you to edit rather than imposed.
  • Mechanical and next-turn defect counts, each with its n — tool-call, schema and test failures the traffic already reveals, so the count is grounded and you can see how many observations it rests on.
  • The outcome channels detected in your traffic, each with its rung on the ladder below — so you can see, per channel, whether a real signal is available yet or only possible.

The structural a-ha answers three questions at once: what am I spending on, what breaks, and what could I even measure? It is diagnostic. It never claims a workflow or an improvement — it is the ground the semantic a-ha is built on.

2. The semantic a-ha — "this is the workflow to improve, and here's the bundle"

Once enough signal has accrued past the noise gate, ultrarouter proposes derived workflow candidates — groupings of your call types into a workflow, each call typed by its role (intermediate / terminal / reviewer) — and recommends one. For the recommended workflow it assembles a complete, inspectable bundle:

  • One definition of what "it worked" means for the workflow, plus at most two alternatives shown beside it, each flagged for whether it is teach-eligible.
  • "Why we suggested this" — the reason the recommendation exists, in plain words.
  • An estimate of resolved outcomes per week with its n, its interval and the window it covers — an estimate, labelled as one, never a headline number.
  • The channel and the join the objective needs — and, when the join is not yet wired, the missing source, named rather than hidden.
  • A separate value axis, so how often a workflow resolves is never confused with how valuable resolving it is.
  • Provenance chips on every field — From your traffic, Drafted, or Yours — reflecting where each value actually came from (see below).
  • A one-sentence preview: Store X when Y happens; learn Z; apply it to calls W — shown at confirmation and again on any material change, so you always see the whole proposal in one line before you accept it.

A collecting state ("still gathering examples") or a nothing learnable, because X state is honest output, not a bug — but it is also a failure of the a-ha: the goal is to reach a real proposal, and when the product cannot, it says why plainly instead of dressing a diagnostic up as progress.

Provenance is never dressed up

Every field the proposal shows carries a chip reflecting its real origin:

ChipOriginMeaning
From your trafficstructuralDerived deterministically from your calls.
DrafteddraftedAn LLM suggestion — a starting point, never authoritative.
YourscustomerA value you entered or confirmed.

A Drafted field can never be re-labelled From your traffic. That is why accepting the top suggestion with one click grounds no external claim: a one-click acceptance of an LLM draft is recorded as a Yours confirmation of a Drafted value, not as evidence that the value was correct. Review actions — Confirm, Edit, Merge, Split, Decline — are product telemetry, never a correctness label; the only correctness signal comes from blind, pre-proposal intent capture and an adjudicated set, not from what you happened to click.

The channel ladder

An outcome channel earns trust one rung at a time, and only receipts move it up:

possible → configured → observed → qualified
  • possible — the shape suggests this channel could exist.
  • configured — a source for it has been wired.
  • observed — real events have actually arrived through it.
  • qualified — enough real events have arrived, cleanly, to rely on.

A schema, a tool name, or a code scan can suggest a channel is possible; none of them ever advances a rung. Availability is proven by events that arrived, not by evidence that they could. Learning eligibility for a given use is derived as the intersection of the rung with confirmation, consent, provenance and exposure — so a channel that is only possible teaches nothing, and even a qualified proxy channel is allowed to rank candidates but never to teach.

Proposed never teaches

This is the law the whole surface is built to protect. A proposal is a draft. It is inert. Nothing you see on the Learn screen — no derived workflow, no drafted objective, no suggested field — can influence a single request until you confirm it.

It is not a runtime check that could be bypassed; it is a type boundary that makes the alternative impossible to express. The compiler that turns an objective into a live trigger accepts only a confirmed plan, and a confirmed plan has exactly one way to come into existence — the audited confirm service. A confirmed field's origin is typed to exclude drafted, so an LLM-drafted value is not even assignable into a confirmed plan; a proposed objective reaching the compiler is a compile error, not a refusal that has to fire at runtime. The confirm service reads the confirmed values you authorised — never the draft's proposed values — which is why editing any suggestion changes what you review but can never change what a confirmed plan teaches.

Every learning consumer downstream keys on the confirmed objective version, read from the versioned config snapshot, and re-checks confirmation, consent, learning use, source binding and exposure at the moment it consumes — never the proposal rows. There is no path from a proposal to a lesson that skips your confirmation.

The six card states

On the Flywheel screen, one card tracks where a workflow's discovery stands, and every state offers exactly one next action. The state is derived from the ledger and the plan rows — never a writable flag — so it can only reflect reality:

StateWhat it means
collectingStill gathering examples; no proposal yet.
proposal_readyA proposal exists and is waiting for your review.
confirmed_no_joinYou confirmed a workflow, but its outcome source is not wired yet.
resolvingConfirmed and joined; real outcomes are arriving.
staleThe confirmed plan has drifted from your current traffic — review the diff.
nothing_learnableNothing worth learning was found, and the card says why.

When a confirmed plan drifts from the current traffic-derived draft, the card shows a per-field diff — the confirmed value beside the current one — with the verbs Accept, Keep mine, and Explain, plus the refreshed one-sentence preview. At most one material diff surfaces per workflow per week, and only one proposal is pending at a time, so the screen never floods you.

What is live today, and what you will see next

Live now: the discover → assist loop (a changed input digest produces one proposal and enqueues one bounded analysis pass, reserved against a spend cap before any model call), the plan projection and review routes (GET /v1/flywheel/plan, POST /v1/flywheel/plan/:id/review), the two a-ha payloads, the six card states, the diff, the coded Decline menu, and "describe it in your words" (bounded to a small number of attempts per day and a short length, with the limit shown to you rather than silently swallowing the input).

Not yet wired — and described here as what you will see, never as a current state: live confirmation of a learned change against a holdout, the portable knowledge export you own, and the adoption of a lever into live traffic. Discovery finds the workflow and confirms the objective; turning a confirmed objective into a tested, live-confirmed improvement is the correction-to-application-to-live loop, published as it ships.

Next steps