## Why
When the loop drives a big goal it can run for many ticks. If it stops converging, with tests not improving and weed still dirty, there is no signal until it hits an iteration cap. The loop now records each tick and warns as soon as it stalls, instead of at the cap.
## What it does
Each tick it appends a line to a trace file with the test counts, the weed verdict, the open questions, and which subagent ran and why. If a tick improves none of those, it flags a stall rather than waiting for the cap. A hook records how long each subagent call took. The final report shows the trace.
## Implementation
- One trace entry per tick in `.allium-loop/<slug>.trace.jsonl`, built from the phases' typed records.
- The stall rule is simple counting over the trace, so the model applies it directly. The threshold is a config value.
- A hook times each subagent call into `.allium-loop/timings.jsonl`. It runs where hooks are supported and does nothing elsewhere.
- Each entry records which phase ran and why, so a wasted call is visible.
## Tests
- Offline: trace entries validate, malformed ones are caught, and the stall rule is proven over trajectories.
- The hook has unit tests in CI, plus a live check that spawns a real subagent and confirms a timing line lands.
## Potential next steps
The model applies the stall rule today, with the deterministic version pinned in the tests. It could move into a script or the CLI later, which would also be the natural home for the timing.
## 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.
## Why
The loop keeps getting stronger. 3.10 moved each phase into its own subagent. 3.11 fanned distill out across services. Each phase runs isolated and hands back a short result. This is the next step. The loop should be able to stand behind that result and prove it. Witness gives it that. It confirms the run's own answer against ground truth, and it leaves a record the loop can show for it.
## What it does
This adds a new phase called witness. It runs at the convergence gate in its own subagent. It rebuilds the result from ground truth the run cannot fake. It reads the test runner's own exit status. It hashes each generated test and compares it to the hash propagate recorded. It reads the reconciliation line and the weed verdict. It checks the open questions. If any of that was faked, the witness fails and the loop keeps working. The loop converges only when the witness passes.
It stays cheap. It re-runs the fast deterministic tools and reads output the phases already produced. It never re-runs propagate, distill, or weed. So it costs one light pass per run.
## Implementation
- New witness skill and agent. Same dual entry as the other phases.
- Propagate records the generated test hashes in the ledger. That is the baseline the witness checks.
- The loop docs gate convergence on the witness verdict.
- Witness writes a record to `.allium-loop/<slug>.witness.json`.
- Tests cover it, including a live probe that weakens a test and confirms the witness catches it.
- Version bump to 3.12.0.
* distil: fan-out orchestration to keep source out of the main context
For a large codebase, map it into bounded contexts and dispatch one subagent
per context that reads only its slice and returns distilled fragments, never
raw source. The orchestrator assembles the fragments and never holds the whole
codebase in one window. Small codebases still run inline.
* Bump plugin version to 3.11.0
Make each skill the single source of truth; Claude Code agents become thin preload shells. Add distill and propagate agents for per-phase loop isolation. Generate VS Code agents from the canonical skills. Pin the interaction-mode contract offline and add a live parking probe.
The canonical site moved from juxt.github.io/allium to
allium-lang.org. Update the README link and the homepage/websiteURL
fields in both plugin manifests. Metadata only, no version bump.
Claude-Session: https://claude.ai/code/session_01D6FTVnDrei6nNse624pG3w
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
/allium now drives the whole spec→tests→code loop to convergence. The separate /allium:loop command and standalone loop skill are removed — folded into the allium entry-point skill, with the driver procedure in skills/allium/references/driving-the-loop.md. Minor release 3.6.0 → 3.7.0.
Frame Allium's skills as an agentic loop — gather context → take action →
verify → repeat — and position the spec+tests+weed signal as the
verification phase that makes a self-driving loop trustworthy.
- New reference skills/allium/references/recommended-loops.md with the
loop framing, the convergence invariant (whole-loop, two feedback arcs),
spec-first (Loop A) and code-first (Loop B) walkthroughs, the red-step
before implementation, autonomous-run guardrails, and the implement prompt.
- README: prominent "The Allium loop" section after "How it works".
- allium router SKILL.md: recommended-sequencing note so the LLM suggests
the next phase, plus the reference in the References list.
- Bump both plugin manifests 3.5.0 -> 3.6.0 (minor: additive docs/guidance).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Minor bump for the CLI install notice added in #51: new backward-compatible
behaviour (first-run install prompt, install offer, marker files), no breaking
changes.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Minor bump for new backwards-compatible features added since v3.3.0:
LSP server wiring via lspServers (#48) and Codex support / .codex-plugin
manifest (#41). Updates both the Claude and Codex plugin manifests.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Wire allium-lsp in plugin.json for live .allium diagnostics (#39)
Add an lspServers entry so the Claude Code plugin connects the
allium-lsp language server to .allium files, giving Claude checker
diagnostics, go-to-definition and hover immediately after each edit
without a separate `allium check` invocation.
Note in the README that allium-lsp is not bundled and must be
installed separately (and be on PATH), consistent with official
marketplace LSP plugins.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Fix allium-lsp invocation and install note
The language server calls createConnection(ProposedFeatures.all), which
requires a transport flag on argv, so it must be launched as
`allium-lsp --stdio` (per allium-tools CONTRIBUTING). Add args: ["--stdio"]
to the lspServers entry; without it the server errors on startup.
allium-lsp is not published to npm (the bare and @juxt-scoped names both
404), so drop the `npm install -g allium-lsp` instruction and point to the
allium-tools repo for installing the server onto PATH instead.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>