Conversation
The terminal view over live supervisor runs lived in the loops repo, where it
carried its own hand-joined copy of the on-disk layout:
[join(root, '.agent', 'supervisor'), join(root, '.loops', 'supervisor')]
agent-runtime owns and exports that contract, and agent-runtime is what WRITES
the state the view renders. A reader versioning independently of its writer
drifts; keeping the two in one package makes drift impossible by construction.
Moved verbatim except where a hand-joined path became a call into the contract:
src/tui/top-model.ts read the layout into a TopSnapshot, render an ANSI frame
src/tui/top-app.ts keypress/mouse loop, steer and cancel controls
src/tui/bin.ts agent-runtime-top [root] [--once] [--no-color]
Three fixes fall out of consuming the contract rather than copying it:
- The view read only `journal.jsonl`, the retired bare-event file. This repo's
own `createFileRunContext` writes `spawn-journal.jsonl`, so the view showed
zero workers for every current run. Both names are read, newest first.
- Worker tails are keyed by file stem, which the writer puts through
`safeWorkerFile`; a label that stem alters never found its own events.
- `<label>.inbox.ndjson` was read as if it were a control-event log.
Steers go through `writeWorkerSteer` — the snapshot already carries the label
the layout keys inboxes by, so no id-to-label resolution sits in between.
run-layout gains the accessors the view needs so it never joins a path itself:
`legacySupervisorRunsRoot` (enumerating pre-rename runs), `supervisorWorkersDir`,
`workerControlLogFile`. The layout doc already named those files; nothing
exported them. The existing writers now use them too.
Zero new dependencies: raw ANSI and node:readline, as before.
Proof: a real `createSupervisor().run` journalled by `createFileRunContext`,
then `node dist/tui/bin.js <root> --once` renders its three workers, token
bars, latency histogram, and the steer appended by `writeWorkerSteer`.
state.json and the spawn journal have different producers and their ids need not agree: the journal's root is the runtime's runId, which defaults to a value unrelated to the supervisor id the state file records. Only the spawned branch carried a second guard for that. The metered, settled, and cancelled branches checked state.id alone, so every driver event minted a worker named for the runId — one that never settles, sorts first as RUNNING so it is the default-selected row, holds the driver's spend where the driver's own totals then read zero, and captures steers into an inbox nothing reads. The journal's root is now recovered from its own parentless root spawn and either id counts as root in all four branches. The regression pins the mismatch case the original proof was constructed to avoid.
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — 79bc444c
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: drewstone_author · 2026-08-01T08:08:11Z
tangletools
left a comment
There was a problem hiding this comment.
🟡 Value Audit — sound-with-nits
| Verdict | sound-with-nits |
| Concerns | 3 (1 medium-concern, 1 low, 1 weak-concern) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 115.5s (2 bridge agents) |
| Total | 115.5s |
💰 Value — sound-with-nits
Promotes the supervisor-run TUI from an external pi extension into the runtime that writes its state, co-locating reader and writer so they can't drift — a sound move that also surfaced and fixed a real phantom-worker bug.
- What it does: Extracts the htop-style supervisor/worker terminal view (1,380 lines, zero third-party deps) from the
loopspi extension into agent-runtime as a./tuisubpath export plus anagent-runtime-topbin. It reads the.agent/supervisor/<id>run layout the runtime owns and renders live runs/workers with spend, token, and latency bars; it writes back via two operator controls — steer a worker (throu - Goals it achieves: Eliminate reader/writer version skew: the TUI is the reader for a layout the runtime writes, and a separately-versioned reader is exactly the failure that bit this stack (cli-bridge's Python bridge vs its npm client). By consuming the SAME
run-layout.tshelpers the writers use, the contract has one definition instead of a hand-joined copy. The payoff is concrete — wiring the reader to the writer - Assessment: Sound and in the grain of the codebase. The central architectural argument is correct and self-proving: the phantom-worker bug was found BY connecting the two halves, which is the strongest possible evidence that co-location is the right move. The fix (recover the journal's own root id from its parentless
label:'root'spawn at top-model.ts:319-322 and treat either id as root) is correct and prec - Better / existing approach: none — this is the right approach. The only inconsistency with the change's own thesis is noted below.
- Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 2
- Bridge warning: opencode/kimi-for-coding/k2p7: opencode: opencode error
🎯 Usefulness — sound-with-nits
A well-wired, zero-dependency extraction of the supervisor TUI that consumes the owned run-layout contract; observability and steer are fully live, but the cancel control writes a file no reader in this repo consumes.
- Integration: Fully reachable. package.json:97-101 exports the
./tuisubpath and package.json:107 registers theagent-runtime-topbin; tsdown.config.ts:24-25 builds both entry points; vitest.config.ts:20-22 and typedoc.json:20 wire test/doc resolution; scripts/gen-primitive-catalog.mjs:80 lists the surface. The reader consumes the OWNED layout helpers imported at src/tui/top-model.ts:17-22 (`supervisorRunsR - Fit with existing patterns: Fits cleanly. Zero third-party deps (raw ANSI + node:readline), matching other dependency-free modules. Follows the established bin pattern (mcp/bin, loop-runner-bin in tsdown.config.ts). No competing supervisor viewer exists — grepping src outside tui for TUI/renderTop/loadTopSnapshot returned nothing. The extraction rationale is real: a separately-versioned reader would skew from the on-disk lay
- Real-world viability: Reader is defensively built: corrupt journal lines and half-written files are skipped (src/tui/top-model.ts:296-298, 1008-1012); the state.json-vs-journal root-id disagreement is handled and proven by a test against the real FileSpawnJournal (tests/tui/top-model.test.ts:24-64). The steer path is durable (best-effort control log + durable inbox append, run-layout.ts:170-185). The weak spot is the c
- Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
🔎 Heuristic Signals
🟡 Cruft: magic number added src/tui/top-app.ts
- timer = setInterval(draw, 1000)
💰 Value Audit
🟡 Cancel write hand-joins a path, breaking the PR's own 'no hand-joined paths' rule [against-grain] ``
The PR's stated principle (top-model.ts:1-13, top-app.ts:1-13) is that the reader becomes a CONSUMER of the owned layout helpers, not a copier of path joins — and the read side plus the steer write both honor this (steer calls
writeWorkerSteer). But the cancel control still hand-joins:join(supervisor.stateDir, 'cancel.request.json')at src/tui/top-app.ts:395, with no correspondingcancelRequestFile(dir)helper promoted from run-layout.ts. To stay consistent with the change's grain, promot
🎯 Usefulness Audit
🟠 Cancel control writes a file no reader owns — contradicts the PR's owned-layout premise [problem-fit] ``
src/tui/top-app.ts:393-406 hand-writes
cancel.request.jsonvia rawwriteFileSync(join(supervisor.stateDir, 'cancel.request.json')). This path is NOT part of the ownedrun-layoutcontract (no helper, no export in src/runtime/index.ts), directly contradicting the PR thesis that 'hand-joined paths are replaced by the owned helpers.' Grep across the whole repo finds NO reader ofcancel.request.json— the only match is the TUI's own write. The real cancellation paths are in-process: the super
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
Extracts the htop-style supervisor/worker TUI from the
loopspi extension into agent-runtime as a./tuisubpath plus anagent-runtime-topbin.Why here
The TUI reads the
.agent/supervisor/<id>run layout that agent-runtime owns and publishes (supervisorRunsRoot,supervisorRunDir,workerInboxFile,writeWorkerSteer). A reader shipped separately from its writer version-skews against the layout it renders — the exact failure that cost this stack hours when cli-bridge's Python bridge required a field the npm client did not send. Reader and writer now ship together.It also arrives free of baggage: zero third-party dependencies (raw ANSI +
node:readline), and zero pi imports across 1,380 lines. It was trapped in a pi extension by history, not by design.Extraction, not redesign
Names preserved exactly —
loadTopSnapshot,renderTopFrame,renderTopFrameWithLayout,TopSnapshot,RenderOptions,RenderTarget,RenderedTopFrame— plusrunTopAppandrenderTopOnceas entry points. Hand-joined paths are replaced by the owned helpers, which is the point: a copy of the layout contract becomes a consumer of it.Wiring the reader to its writers exposed that they disagreed
Four bugs, all real, all found by connecting the two halves rather than by reading:
The blocking one, caught by adversarial review after my own proof missed it:
state.jsonand the spawn journal have different producers and their ids need not agree. The journal's root is the runtime'srunId, which defaults to a value unrelated to the supervisor id the state file records. Only thespawnedbranch guarded for that;metered,settled, andcancelledcheckedstate.idalone. So every driver event minted a worker named for therunId— one that never settles, sorts first as RUNNING so it is the default-selected row, holds the driver's spend while the driver's own totals read $0, and captures steers into an inbox nothing will ever read.Measured on the default path:
workers 4 / live 1where the truth was3 / 0.The journal's root is now recovered from its own parentless root spawn, and either id counts as root in all four branches. A regression pins the mismatch case — the one my original proof was constructed to avoid.
Proof
A real
createSupervisor().runover three workers, journalled by the runtime's owncreateFileRunContext, then the built bin pointed at that directory. No hand-written journal lines; the supervisor wrotespawn-journal.jsonlitself and the steer came fromwriteWorkerSteer.Gates
tsc 0 · biome clean (540 files) · 2244 passed / 6 skipped across 198 files · docs freshness OK · typedoc 0 warnings ·
publintvalidates the new./tuiexport and bin against a realpnpm pack· built artifact load-checked.loops follow-up (not in this PR)
Sequence after
refactor/pi-through-bridgelands: deletesrc/top.ts,src/top-model.ts,tests/top-model.test.ts; pointpnpm topat the bin; drop the knip entry. Two visible changes — the header readsSUPERVISOR TOP, and the shell key's exported env vars are renamedLOOPS_*→AGENT_*.