Phase 3a — Render and reconcile: the supervisor says what it would do
30 AUG AT 08:08 PM

Phase 3a — Render and reconcile: the supervisor says what it would do

0 LOVES 4 VIEWS
A renderer turns a declaration into the complete 19-flag command line, and a reconciler logs what it would do — spawning nothing. The entire config boundary, verified at zero risk.

Prove the declaration before launching from it

Phase 2 wrote declarations and said, plainly, that nothing read them. A declaration is a claim about a bridge that has never been checked against the bridge. This phase turns one into a command line and proves it is right before anything is launched from it.

A renderer reads the agent plus its active revision and produces the complete 19-flag set a bridge would be launched with; a reconciler logs the actions it would take. The two production declarations are then diffed against what the live bridges are actually running — so a mis-bucketed flag or a wrong value surfaces as a readable table, instead of as a bridge that will not come up.

This phase spawns nothing. No exec, no fork, no process-spawning import in the package, no process created by any code path — including the tests. That is not caution, it is the seam: the entire config boundary can be verified at zero risk, and the next phase then only has to get spawning right.

Named explicitly so they could not be smuggled in: starting or killing anything, re-adoption of running bridges, the launchd plist, backoff and give-up, rotation of the log files this phase names, and the cutover itself.

⭐ And this phase is the acceptance test for Phase 2. Phase 2 could only assert its own rules against itself. This is the first time the declarations meet the processes they claim to describe.

What the diff actually proves

A “19 of 19 clean” headline would have been available here, and it would have overclaimed. The evidentiary weight is not spread evenly across the flags, so the phase says where it actually falls:

  • Bucket A — six flags — is the real test. These come out of config_json. If a declaration is wrong, this is where it shows.
  • Bucket C — four flags — is expected to differ. Matching would be meaningless; the diff proves only that derivation happens at all.
  • Bucket B — nine flags — is a transcription check. If the deploy constants were copied from the live command lines, they match by construction. What it does prove is completeness: that all nineteen are accounted for and none was accidentally sourced from the database.

So the honest claim is “six of six on the half that came from the database, four of four intentionally regularised, nine of nine accounted for” — not nineteen of nineteen.

The subtler problem: argv is not a flag set. One live bridge passed 7 of the 19 flags on its command line and the other passed 10. A rendered set is always 19. Compared as raw argv, the first differs from a render in 12 places and the second in 9 — nearly all spurious, because a flag left at its default is not a flag that disagrees.

The comparison is therefore between effective sets: the binary’s documented defaults, overlaid with what the process actually passed, with three computed defaults resolved first — an empty -api-base means the websocket host with a scheme glued on, an empty -mcp-env means the main env file, and an empty gate-state means a temp file. Comparing an explicit value against a process that passes nothing is otherwise just comparing two spellings of the same thing.

⚠ And the parser has to handle both spellings, because the live command lines mix -flag=value and --flag value in the same invocation. A parser that handled only one would silently drop half of one bridge’s real arguments and produce a clean-looking diff that checked nothing. That is the single most plausible way this phase could have certified a false pass, so it got a dedicated test using the real argv.

Pushing Tin — managing a bridge fleet from inside the product
Pushing Tin — managing a bridge fleet from inside the product
Aug 29, 2026 Pushing Tin
← Back to Pushing Tin