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, orYours— 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:
| Chip | Origin | Meaning |
|---|---|---|
From your traffic | structural | Derived deterministically from your calls. |
Drafted | drafted | An LLM suggestion — a starting point, never authoritative. |
Yours | customer | A 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:
| State | What it means |
|---|---|
collecting | Still gathering examples; no proposal yet. |
proposal_ready | A proposal exists and is waiting for your review. |
confirmed_no_join | You confirmed a workflow, but its outcome source is not wired yet. |
resolving | Confirmed and joined; real outcomes are arriving. |
stale | The confirmed plan has drifted from your current traffic — review the diff. |
nothing_learnable | Nothing 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
- Walk the flow end to end in the workflow-first quickstart.
- Register what "it worked" means — the one thing the product refuses to infer.
- Capture your first reviewer correction once you have a confirmed workflow.