Repository navigation
Conversation
… to a relation WIP commit before merging main -- full message on the PR.
…r_workflow #8702 (mine) deleted a 14-line annotation block and reverted a CI step name that another session had authored in #8657. I did not write those deletions. My branch predated #8657, squash-merge takes the branch's version of every touched file wholesale, and the result presented as if I had authored the removal. WHAT WAS LOST: - the annotation explaining why the behavioral receipt is NOT a step here -- that #8647 collapsed the step ladder into one invocation, that re-adding steps would rebuild the ladder that PR removed, and that the per-PR phase now decides from what it can OBSERVE rather than from a trigger name. That last paragraph records a BEHAVIOURAL difference, not a relocation, and it is the kind of thing a future reader needs and cannot re-derive. - the step name "Required CI: parse, regen, regen determinism, behavioral receipt, witness floor", reverted to a form omitting the receipt phase. WHY NOTHING CAUGHT IT. Three properties compounded: 1. squash-merge of a stale branch presents a revert as an authored deletion; 2. the generated-artifact drift gate is UNGUARDED -- DESIGN names it in the floor cut's declared rung drop -- so the module and .github/workflows/ witnesses.yml disagreed on main with nothing to notice; 3. the merge was clean, five reviews approved the diff, and CI passed. I found it only by chasing a 20-byte mismatch while byte-comparing an emitted artifact in an unrelated branch. That comparison is exactly the check CI is currently missing. THE REPAIR NEEDS NO REGENERATION, which matters under the fleet stop-the-line rule: the committed artifact still carries the correct text, so restoring the module makes the two agree again. witnesses.yml emitted 1457 == committed 1457 (was 1437 vs 1457 on main) the_live_witness_floor_job_closes_its_capabilities -> true in-body annotations -> 0 THE GENERAL HAZARD, recorded because it is not specific to this file: a long-lived branch plus squash-merge is a silent-revert machine. Every hour a branch sits unmerged, its copy of each touched file becomes a stale snapshot that will overwrite whatever landed meanwhile, and no conflict, review, or green CI will say so while the drift gate is down. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Verification against current main, and one cross-PR dependency worth stating. Re-verified after merging
The Cause: my own merged #8702 reverted that line from a stale branch. Fixed in #8737, which restores the module text so it agrees with the committed artifact again — no regeneration needed. Merge order: #8737 before this PR. If this one lands first the drift simply persists unchanged (this branch neither causes nor worsens it), but the reverse order means #8737's byte-identity proof is measured against a tree this PR has already touched. This branch touches — sent from eager-crane-282 |
|
CI failure at The failing phase is the witness floor:
Main's own floor confirms it, by headSha:
Main has been red since #8701 and remains red; every open PR that merges main inherits it. #8738 ( Merge order, unchanged apart from the new head: #8738 → #8737 → this PR. (#8737 restores the annotation block my earlier #8702 clobbered via a stale branch; the |
|
Rebased onto current main ( One further change, to close a hazard rather than to add content: this branch now also merges Verified after the merge: — sent from eager-crane-282 |
|
Superseded by #8796, which carries this work unchanged along with the rest of the srv3 stack and the fleet-converge capability binding. Consolidated at the operator's request (too many open PRs). Verified before closing: every declaration, module and witness file this PR introduced is present on Nothing is dropped. Review history stays here; the diff to review is now #8796. |
Corrected body. I briefly replaced this PR's description with text belonging to a different branch — the annotation restore, now #8735. The diff here was never the restore; this body now describes what is actually in it.
Extends the merged #8702 closure to
fleet-converge.yml— the workflow that actually carries the hand-written cargo resolve circuit.The role model was wrong, and binding a second workflow proved it
#8702 shipped
StepCapabilityRoleas a three-variant coproduct: provides or consumes or neutral. The fleet prelude does not fit:setup-rust-toolchaininstalls cargo, rustc and rustfmt in one action.Squeezing that into the coproduct would have required marking the rustc-consuming step
Neutral— hiding a real dependency to fit my model, which is the failure this whole program is about. So the role became a record of two lists, and neutral became the empty relation rather than a distinct variant.Worth stating plainly: a model that fits one specimen is not yet a model. The first bound job happened to need exactly one capability and I generalised from it.
The constraint this writes down
Two prelude steps consume a capability an earlier one installs, and until now that fact lived only inside a diagnostic string:
The dependency was real, load-bearing, and invisible to everything except a human reading the error it would print if it broke. It is now structural.
Single authority
ci_prelude_bound_steps_with_checkoutis one list of rows carrying both theStepand its capability role.ci_prelude_steps_with_checkoutandci_prelude_annotations_with_checkoutare both projections of it, so they cannot drift. Three inline step literals were extracted to named functions so both projections share one authority.Evidence
Eight witnesses, each falsified by a different wrong implementation:
truetruetruetruetruetruetruetrueThe middle three are new claims made expressible by the record model — a step declaring both lists would always close if provides were granted before consumes was checked, which is the vacuous answer.
fleet-converge.ymlemission byte-identical at 18736. Emission refuses rather than fabricating YAML when closure fails.Rung
Two jobs bound. Other workflow emitters can still assemble bare
Steps and bypass closure entirely — that remains the next trigger.🤖 Generated with Claude Code