Repository navigation
Dispatch and the belt bind the deployed revision instead of refusing on drift from the fleet ref - #10611
Conversation
…se on drift from the fleet ref The launch admission's revision gate compared the deployed tree to refs/fleet/desired and refused on inequality, and the belt tick shared it. Desired advances on every green merge and a deploy takes minutes, so the gate held only in the gap between two merges: three consecutive srv1 deploys landed drifted before dispatch could run, and while drifted the tick refused verify, review, audit and publication too. Convergence decides which version of the control software runs; the worker checks out origin/main itself and publication targets main, so drift was never a fact about the attempt. fleet_desired_observe gains LocalTreeRevision (the deployed tree's own HEAD, read locally), which launch admission, the dispatch preflight axis, the tick execution standing and fleet_desired_admission consume; FleetRevisionStanding stays the converge CLI's and the deployed-tree report's fact. The LaunchRevisionDrift refusal, its wire label deployed_revision_drifted and its band row are deleted; an unreadable HEAD still refuses (deployed_revision_unobserved) because an attempt with no code to name has no identity to bind. The launch-admission contract digest changes with its vocabulary, so rlm1_contract_digest_frozen is re-pinned to the digest the module now computes. Operator ruling 2026-09-05: dispatch shouldn't care about convergence. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019iXPtAqzPaNBZbaaM5rxrY
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ec3626a835
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| remote: instance.admitted_revision.remote, | ||
| ref_name: instance.admitted_revision.ref_name, | ||
| ), | ||
| revision: local_tree_revision(repo: instance.repo_root), |
There was a problem hiding this comment.
Preserve per-instance admission refs
For actuating instances with operator-controlled admission refs, this replacement bypasses the explicit launch grant rather than merely tolerating fleet deployment lag. macbook_local_dashboard_instance uses refs/gunbc/local-admitted, and srv2_deploy_dashboard_instance uses refs/gunbc/srv2-admitted; both are documented as refs the operator must advance deliberately. With either ref absent or stale, a readable HEAD now passes this stage, allowing an eligible POST dispatch to spawn work anyway. Limit the drift relaxation to the fleet-managed source, or otherwise retain comparison against these local admission refs.
Useful? React with 👍 / 👎.
…ses every dispatch (#10617) harness_observe_backend folded the replica roster into one standing and answered with the first non-serving replica's, so with .232 unreachable and .225 advertising the model, dispatch on srv1 refused at provider selection (measured 2026-09-05, first dispatch after #10611). The roster's point is that attempts spread across it, so the reading was all-or-nothing over a set. harness_backend now observes each replica once and keeps both halves: HarnessBackendRoster carries the serving addresses and the declined replicas with their typed standing, so what is down is counted and never absorbed. Selection and the belt preflight admit when any replica serves and refuse naming every replica's cause when none does. Each harness entry point binds its backend URL at process start from the serving set (harness_serving_backend_url; the seed spreads attempts within it) and exits with the roster's refusal before the first POST when nothing serves. harness_wire gains the pure pick over an arbitrary roster, witnessed against the deleted behaviour: a one-element roster is chosen whatever the seed says. Claude-Session: https://claude.ai/code/session_019iXPtAqzPaNBZbaaM5rxrY Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Why
The launch admission's revision gate refused whenever the deployed tree differed from
refs/fleet/desired, and the belt tick shared the gate. Desired advances on every green merge and a deploy round trip takes ~12 minutes, so the gate held only in the gap between two merges. Measured today on srv1: three consecutive deploys viagunbc convergelanded already drifted before dispatch could run (deployed_revision_drifted), and while drifted the tick refused verify, review, audit and publication as well. Convergence lag became a whole-pipeline outage.Convergence decides which version of the control software runs. The worker checks out
origin/mainitself, the belt verifies against main, publication opens a PR against main. Drift was never a fact about the attempt.Operator ruling, 2026-09-05: dispatch shouldn't care about convergence.
What
gunbc.fleet_desired_observegainsLocalTreeRevision(Observed { revision } | Unobserved { cause }): the deployed tree's own HEAD, read locally, compared to nothing.FleetRevisionStanding(converged / drifted / unobserved) stays the converge CLI's and the deployed-tree report's fact.gunbc.roadmap_launch_admission: the revision gate consumesLocalTreeRevision; it binds the revision into the launch identity and refuses only when HEAD cannot be read.LaunchRevisionDrift, its wire labeldeployed_revision_drifted, its reason, exemplar, 409 arm and band row are deleted.deployed_revision_unobservedsurvives: an attempt with no code to name has no identity.gunbc.roadmap_belt_actuate: the host observer and the tick execution standing readlocal_tree_revision; the old rationale block is rewritten to record why the drift refusal was wrong.gunbc.dispatch_preflight: the revision axis names the deployed revision and refuses only unreadable.gunbc.roadmap_launch_deployment_cli: preflight fact arms follow;rlm1_contract_digest_frozenre-pinned8b884d701d7a356e → 20ca8a8cde2f7e84(the contract digest is derived from the refusal vocabulary, so removing an arm changes it by design; the receipt CLI would otherwise refuse withRlm1ContractDigestDriftforever).gunbc.fleet_desired_admissionconsumes the typed local read instead of the deletedOptionone.roadmap_launch_admission_witness_testalso had a staleBeltTickReceiptliteral missingcommit_passsince Harness thinking on the Spark engines, the roadmap's commit→verify→publish phase, and the round-strip dashboard #10443 and did not compile; fixed in passing.Verified
gunbc compile --target dag: 0 blocking onroadmap_serve,roadmap_launch_deployment_cli,roadmap_belt_tick_cli,fleet_desired_admission.claim_batch --hermeticover every test in the four changed witness files: preflight 6/6, serve 16/16, launch admission 52/52, belt actuate 101/108 — the 7 failures are the pre-existingwitness_exec_*route gaps (hermetic route has no arm for Check), untouched here.Not in this PR
Deploy-on-desired-advance from the fabric (the disaggregated converge trigger) — that is the live-deploy remodel's seam.
🤖 Generated with Claude Code
https://claude.ai/code/session_019iXPtAqzPaNBZbaaM5rxrY