Skip to content

Phases hand back typed results, not prose - #69

Merged
yavorpanayotov merged 4 commits into
juxt:mainfrom
panayotovk:typed-phase-handoffs
Aug 20, 2026
Merged

Phases hand back typed results, not prose#69
yavorpanayotov merged 4 commits into
juxt:mainfrom
panayotovk:typed-phase-handoffs

Conversation

@yavorpanayotov

Copy link
Copy Markdown
Collaborator

Why

The loop runs each phase in its own subagent. Each phase hands back a result. Until now that result was prose, so the loop had to read it and work out what it meant. This makes the result typed. The loop reads a field instead of reading a paragraph. The routing and the done check get simpler and easier to trust, with less room to misread a result. It also lays the groundwork for moving these checks into the CLI later, where code can run them instead of the model.

What it does

Every phase now returns a small JSON record instead of prose. weed returns a verdict and its divergences. propagate returns the coverage counts. The loop reads those fields to decide what to do next. A clean verdict moves on, a code bug goes back to the code, and whether the loop is done becomes a plain check over the fields.

Implementation

  • Six schemas: one per phase result, plus the ledger.
  • Each skill returns its record, with a worked example to follow.
  • The routing table and the convergence check read the typed fields.

Tests

  • The test suite has a small dependency-free validator: valid records pass, malformed ones are caught, and convergence is proven as a function of the fields.
  • A live test spawns each real agent and confirms its output matches its schema.

Potential next steps

Right now the loop reads the records itself, and the validator that checks them lives in the tests, not the live loop. A possible next step is to run that check inside the loop too, first as a small script the loop calls on each hand-off, and later as part of the CLI, alongside the routing and the done check. That would be the point where these checks stop being the model's judgement and become code.

Each loop phase returned prose the orchestrator had to re-read and interpret. A
prose read is a model step, so the routing and the convergence check inherited
the model's non-determinism. This turns the contract between a phase and the
loop into typed data.

Add a JSON Schema per phase result (distill, weed, tend, propagate, witness) and
one for the ledger, under skills/allium/references/schemas/. driving-the-loop
gains section 12: a routing table that is a lookup on the typed fields, and
convergence stated as a boolean over them. The phases stay probabilistic inside;
the control flow around them becomes deterministic. Section 7 now carries a
typed result record between phases, and section 8's ledger is itself typed.

Required fields are only the decision-bearing ones (verdict, divergences,
obligations, uncovered_obligations, generated_tests). Redundant and informational
fields are optional, so a phase can never fail the contract on a field the loop
does not route on.
Each skill gains a "Typed result" section: when running as the loop subagent,
return a single JSON object conforming to the phase's schema and nothing else,
with a worked example to mirror. Interactively the skills still speak prose; the
typed record is the machine hand-off, not the conversation. The agent shells
return the record, and the VS Code agents are regenerated to match.

The witness returns its verdict as the JSON hand-off as the loop subagent, and
keeps the human summary line only for interactive use. propagate's generated
test hashes are now a first-class field of its record, the same baseline the
witness re-derives.
…ormance

A dependency-free validator for the JSON-Schema subset the records use, plus a
handoffs group. Offline and deterministic: valid fixtures validate, malformed
records are caught (bad enum, missing field, wrong type, unexpected property),
and convergence is proven as a pure function of the typed fields. This is the
part of the contract a test settles rather than an eval.

Live (--live): spawn each phase agent and assert its real output conforms to the
schema. Stochastic input, deterministic assertion. The witness conformance rides
the existing tamper probe's spawn. Running this eval is what surfaced that
propagate, tend and witness omitted required fields or returned prose; the fix
was relaxing the schemas to the decision-bearing fields and giving each skill a
worked example. All five agents now return conforming records.
@yavorpanayotov
yavorpanayotov merged commit 527cd52 into juxt:main Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant