Skip to content

Dispatch and the belt bind the deployed revision instead of refusing on drift from the fleet ref - #10611

Merged
briansrls merged 1 commit into
mainfrom
dispatch-ignores-convergence
Sep 5, 2026
Merged

briansrls merged 1 commit into
mainfrom
dispatch-ignores-convergence

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

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 via gunbc converge landed 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/main itself, 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_observe gains LocalTreeRevision (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 consumes LocalTreeRevision; it binds the revision into the launch identity and refuses only when HEAD cannot be read. LaunchRevisionDrift, its wire label deployed_revision_drifted, its reason, exemplar, 409 arm and band row are deleted. deployed_revision_unobserved survives: an attempt with no code to name has no identity.
  • gunbc.roadmap_belt_actuate: the host observer and the tick execution standing read local_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_frozen re-pinned 8b884d701d7a356e → 20ca8a8cde2f7e84 (the contract digest is derived from the refusal vocabulary, so removing an arm changes it by design; the receipt CLI would otherwise refuse with Rlm1ContractDigestDrift forever).
  • gunbc.fleet_desired_admission consumes the typed local read instead of the deleted Option one.
  • Witnesses: drift fixtures become unobserved fixtures; the fold witness is now discriminating against the deleted arm (an observed revision passes whatever the fleet ref says, because the fold never sees the fleet ref); band-row count 23→22, refusal-label count 21→20. roadmap_launch_admission_witness_test also had a stale BeltTickReceipt literal missing commit_pass since 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 on roadmap_serve, roadmap_launch_deployment_cli, roadmap_belt_tick_cli, fleet_desired_admission.
  • claim_batch --hermetic over 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-existing witness_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

…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
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-05T20:59:54.608306Z ec3626a PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

@briansrls
briansrls merged commit 2f382a1 into main Sep 5, 2026
4 checks passed
@briansrls
briansrls deleted the dispatch-ignores-convergence branch September 5, 2026 21:32
briansrls added a commit that referenced this pull request Sep 5, 2026
…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>
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