From 5adbcafb6e45795df92f6e2ef1514e3b31da48f1 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Fri, 21 Aug 2026 18:48:41 +0000 Subject: [PATCH 1/6] Record which code adjudicated the advance, and refuse to actuate when it cannot be observed The receipt named what the compare-and-swap DID (#8768: target and expected prior) and never which code DECIDED it. That fact is not recoverable from anything else the run leaves behind: the admission workflow's checkout carries no `ref:`, so on a workflow_run event it takes the DEFAULT BRANCH TIP AT RUN START rather than the triggering head_sha. J == C is therefore a timing coincidence -- it holds while main has not moved between floor completion and admission start, and #8733's bounded queue makes the divergence ordinary rather than rare, since an entry can wait while main advances and then be adjudicated by whatever main became. This is the RECORDING half only. Pinning the judge to the candidate is a separate change, ruled on separately, and deliberately lands after this one: without a recorded judge the pinning is a belief about GitHub's checkout semantics, and with it the receipts say whether J == C actually held. Recording is unconditional under either pinning, which is why it goes first. THE UNOBSERVABLE CASE REFUSES RATHER THAN FABRICATES. observe_local_tree_revision returns a bare GitObjectId?, so the run cannot distinguish "the judge is X" from "I could not tell what the judge is" -- and a receipt naming an unattributable judge is worse than no receipt. The advance therefore refuses to actuate with a typed, located reason instead of publishing an advance whose adjudicator is unknown. (That carrier's answer/ignorance conflation is real and already leaking: fleet_revision_standing renders its Absent arm as "not a git repository, or HEAD undecodable" -- an `or` in a cause string, because the carrier cannot tell the two apart. Splitting it is a separate change and is not required for this one to be correct.) WITNESSES, and the second one is here because the RED CONTROL CAUGHT IT PASSING VACUOUSLY: - the receipt names the judge, distinctly from the target and the prior - the judge operand is not the target or the prior -- which, as first written, was trivially true when the operand was DELETED ENTIRELY. It returned PASS against a receipt with no judge at all while its sibling correctly returned FAIL. It now asserts the operand is PRESENT before asserting what it is not, and fails under the same plant. RED CONTROL: removing the judge operand takes BOTH judge claims FAIL and leaves the three pre-existing receipt/lease claims PASS. The fixture uses a third distinct hex so a renderer echoing the target or the prior into the judge position cannot satisfy them. Co-Authored-By: Claude Opus 5 (1M context) --- dag/gunbc/fleet_desired_admission.dag | 57 ++++++++++++------- .../fleet_desired_admission_witness_test.dag | 42 ++++++++++++++ 2 files changed, 79 insertions(+), 20 deletions(-) diff --git a/dag/gunbc/fleet_desired_admission.dag b/dag/gunbc/fleet_desired_admission.dag index 9eec1af5546..c0494cf28f2 100644 --- a/dag/gunbc/fleet_desired_admission.dag +++ b/dag/gunbc/fleet_desired_admission.dag @@ -44,7 +44,7 @@ import gunbc.fleet_main_revision { fleet_desired_advance_expectation, fleet_desired_revision_target, } -import gunbc.fleet_desired_observe { observe_fleet_desired_revision } +import gunbc.fleet_desired_observe { observe_fleet_desired_revision, observe_local_tree_revision } import std.disposition { Disposition, Scaffold, SingleAuthority } import std.dissolution { DissolutionCondition, unbound_dissolution } import std.decl_ref { DeclarationRef, WholeDeclaration } @@ -311,16 +311,17 @@ fn fleet_desired_receipt_expected_phrase(expected: GitRemoteRefExpectation) -> S // coincide exactly when the CAS held, which is the thing a receipt is supposed to let a reader // check rather than assume. Measured before this row: eleven successful admissions whose expected // prior appears nowhere in their logs. -fn fleet_desired_authorized_push_script(expected: GitRemoteRefExpectation, to: GitObjectId) -> String { +fn fleet_desired_authorized_push_script(expected: GitRemoteRefExpectation, to: GitObjectId, judge: GitObjectId) -> String { let request = fleet_desired_authorized_push_cas_request(expected: expected, to: to) let to_hex = git_object_id_wire_hex(oid: to) as String let expected_phrase = fleet_desired_receipt_expected_phrase(expected: expected) + let judge_hex = git_object_id_wire_hex(oid: judge) as String join([ "set -eu\n", "git push ", git_remote_ref_lease_word(request: request) as String, " ", request.remote as String, " ", git_remote_ref_cas_refspec(request: request) as String, "\n", - "echo \"[fleet-desired] admitted ", to_hex, " expected-prior ", expected_phrase, "\"\n", + "echo \"[fleet-desired] admitted ", to_hex, " expected-prior ", expected_phrase, " judge ", judge_hex, "\"\n", ], "") } @@ -332,24 +333,40 @@ func admit_fleet_desired_from_floor_event_wet() -> ProcessExit { observed: observe_fleet_desired_revision(repo: fleet_desired_admission_repo_root), ) { AdmissionRefused { cause: why } => exit_failure(reason: why) - AdmissionAdvanceAuthorized { expected: expected, to: to_oid } => { - let wrote = Filesystem.Write( - path: fleet_desired_admission_authorized_push_path, - content: fleet_desired_authorized_push_script(expected: expected, to: to_oid), - ) - if wrote.success { - ExitSuccess - } else { - exit_failure( - reason: join([ - "fleet_desired_admission: the advance was admitted but the authorized push could not be written to ", - fleet_desired_admission_authorized_push_path, - ": ", - wrote.error, - ], ""), - ) + AdmissionAdvanceAuthorized { expected: expected, to: to_oid } => + match observe_local_tree_revision(repo: fleet_desired_admission_repo_root) { + Absent => + exit_failure( + reason: join([ + "fleet_desired_admission: the advance to ", + git_object_id_wire_hex(oid: to_oid) as String, + " was admitted, but the JUDGE revision could not be observed, so the run cannot ", + "record which code adjudicated it — refusing to actuate rather than publish an ", + "unattributable advance (gunbc.fleet_desired_observe observe_local_tree_revision ", + "returned no revision for ", + fleet_desired_admission_repo_root, + ")", + ], ""), + ) + Present { value: judge } => { + let wrote = Filesystem.Write( + path: fleet_desired_admission_authorized_push_path, + content: fleet_desired_authorized_push_script(expected: expected, to: to_oid, judge: judge), + ) + if wrote.success { + ExitSuccess + } else { + exit_failure( + reason: join([ + "fleet_desired_admission: the advance was admitted but the authorized push could not be written to ", + fleet_desired_admission_authorized_push_path, + ": ", + wrote.error, + ], ""), + ) + } + } } - } } WorkflowRunEventMemberAbsent { member: m } => exit_failure(reason: concat("fleet_desired_admission: floor run event payload is missing a required member: ", m)) diff --git a/dag/test/claim/fleet_desired_admission_witness_test.dag b/dag/test/claim/fleet_desired_admission_witness_test.dag index 2d9637b1ad3..357baaa9e6a 100644 --- a/dag/test/claim/fleet_desired_admission_witness_test.dag +++ b/dag/test/claim/fleet_desired_admission_witness_test.dag @@ -26,6 +26,7 @@ import gunbc.fleet_desired_admission_workflow { expected_fleet_desired_yml } data fixture_prior_hex: String = "1111111111111111111111111111111111111111" data fixture_candidate_hex: String = "2222222222222222222222222222222222222222" +data fixture_judge_hex: String = "4444444444444444444444444444444444444444" data fixture_repo: String = "gunb-ai/gunbc" fn fixture_oid(hex: String) -> GitObjectId { @@ -239,6 +240,7 @@ test fn the_authorized_push_carries_the_observed_prior_as_the_cas_expectation() let script = fleet_desired_authorized_push_script( expected: RemoteRefMustEqual { oid: fixture_oid(hex: fixture_prior_hex) }, to: fixture_oid(hex: fixture_candidate_hex), + judge: fixture_oid(hex: fixture_judge_hex), ) string_contains(s: script, pattern: concat("--force-with-lease=refs/fleet/desired:", fixture_prior_hex)) && string_contains(s: script, pattern: concat(fixture_candidate_hex, ":refs/fleet/desired")) @@ -251,12 +253,50 @@ test fn the_creation_push_leases_on_the_ref_being_absent() -> Bool { let script = fleet_desired_authorized_push_script( expected: RemoteRefMustBeAbsent, to: fixture_oid(hex: fixture_candidate_hex), + judge: fixture_oid(hex: fixture_judge_hex), ) string_contains(s: script, pattern: "--force-with-lease=refs/fleet/desired: ") && string_contains(s: script, pattern: concat(fixture_candidate_hex, ":refs/fleet/desired")) && !string_contains(s: script, pattern: fixture_prior_hex) } +// THE JUDGE IS THE THIRD OPERAND AND IT ANSWERS A DIFFERENT QUESTION FROM THE OTHER TWO. `to` and +// `expected-prior` say what the compare-and-swap did; the judge says WHICH CODE DECIDED IT. That is +// not recoverable from anything else the run leaves behind -- the workflow checks out the default +// branch tip at run start rather than the candidate, so J == C is a timing coincidence and nothing +// in the run says whether it held. A receipt that cannot name its judge cannot make that +// falsifiable, which is the whole purpose of recording it before the pinning lands. +test fn the_receipt_names_the_judge_that_decided_the_advance() -> Bool { + let script = fleet_desired_authorized_push_script( + expected: RemoteRefMustEqual { oid: fixture_oid(hex: fixture_prior_hex) }, + to: fixture_oid(hex: fixture_candidate_hex), + judge: fixture_oid(hex: fixture_judge_hex), + ) + string_contains(s: script, pattern: concat(" judge ", fixture_judge_hex)) + && string_contains(s: script, pattern: concat("admitted ", fixture_candidate_hex)) + && string_contains(s: script, pattern: concat("expected-prior ", fixture_prior_hex)) +} + +// The judge is DISTINCT from both other operands. A renderer that echoed the target or the prior +// into the judge position would satisfy a bare "names three hexes" claim, so the fixture uses a +// third value and this pins that the positions are not interchangeable. +// +// THE FIRST CONJUNCT IS NOT REDUNDANT WITH THE CLAIM ABOVE, and it is here because the red control +// caught this row passing VACUOUSLY: with the judge operand deleted from the receipt entirely, both +// negations are trivially true and this returned PASS while its sibling correctly returned FAIL. A +// claim that cannot fail for the reason it exists is not evidence, so it now asserts the operand is +// PRESENT before asserting what it is not. +test fn the_judge_operand_is_not_the_target_or_the_prior() -> Bool { + let script = fleet_desired_authorized_push_script( + expected: RemoteRefMustEqual { oid: fixture_oid(hex: fixture_prior_hex) }, + to: fixture_oid(hex: fixture_candidate_hex), + judge: fixture_oid(hex: fixture_judge_hex), + ) + string_contains(s: script, pattern: " judge ") + && !string_contains(s: script, pattern: concat(" judge ", fixture_candidate_hex)) + && !string_contains(s: script, pattern: concat(" judge ", fixture_prior_hex)) +} + // THE RECEIPT HALF, WHICH THE TWO CLAIMS ABOVE DO NOT COVER. They assert what the push DEMANDS; // this asserts what the run RECORDS. The two came apart once already: #8746 replaced the `from` // operand with the expectation sum and the echo silently lost its prior, leaving eleven successful @@ -266,6 +306,7 @@ test fn the_receipt_names_both_operands_of_the_compare_and_swap() -> Bool { let script = fleet_desired_authorized_push_script( expected: RemoteRefMustEqual { oid: fixture_oid(hex: fixture_prior_hex) }, to: fixture_oid(hex: fixture_candidate_hex), + judge: fixture_oid(hex: fixture_judge_hex), ) string_contains(s: script, pattern: concat("[fleet-desired] admitted ", concat(fixture_candidate_hex, concat(" expected-prior ", fixture_prior_hex)))) } @@ -277,6 +318,7 @@ test fn the_creation_receipt_names_absence_rather_than_nothing() -> Bool { let script = fleet_desired_authorized_push_script( expected: RemoteRefMustBeAbsent, to: fixture_oid(hex: fixture_candidate_hex), + judge: fixture_oid(hex: fixture_judge_hex), ) string_contains(s: script, pattern: "expected-prior absent") && !string_contains(s: script, pattern: "expected-prior \"") From d7442963d489c5cfd5de356017397a8bb960209c Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Fri, 21 Aug 2026 19:07:33 +0000 Subject: [PATCH 2/6] Name what the judge operand is NOT, before pinning makes its absence misleading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ref:` on the checkout pins repository CONTENT. It does not pin the WORKFLOW TRANSPORT: for a workflow_run event GitHub requires the .yml to exist on the DEFAULT BRANCH and takes it from there regardless of the triggering branch, and GITHUB_SHA for such a run is the last commit on the default branch. Verified against the upstream reference, not inferred. WHY THIS LANDS NOW RATHER THAN WITH THE PINNING. Today, with no `ref:`, the checkout HEAD and GITHUB_SHA are THE SAME SHA -- judge and transport coincide by accident of configuration, so a receipt naming only the judge is harmless. They DIVERGE the moment the checkout is pinned to the candidate: the judge becomes the candidate while the transport stays main's. At that point a receipt carrying judge alone invites the reader to conclude every byte involved came from the candidate -- an inference that is false and, worse, UNFALSIFIABLE from the receipt itself. So the omission is named where the field would go, on the rule that an absent field reads as "not a subject". The judge is the revision of the checked-out tree this process was built from; it is not the transport, not the candidate, and not the subject the required floor judged. The full field set -- candidate, judge, required-CI receipt subject, workflow transport, the first two CHECKED equal and the transport RECORDED-not-equal -- belongs to the pinning change, because that is when the divergence exists. Shipping four fields whose values are provably identical today would land equality checks that cannot fail, which is the vacuous-claim failure the red control caught in this branch's own witness one commit ago. Annotation only; no behavior change. §4c grain checked locally: 0 `source annotation` diagnostics. Co-Authored-By: Claude Opus 5 (1M context) --- dag/gunbc/fleet_desired_admission.dag | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dag/gunbc/fleet_desired_admission.dag b/dag/gunbc/fleet_desired_admission.dag index c0494cf28f2..35e4092a737 100644 --- a/dag/gunbc/fleet_desired_admission.dag +++ b/dag/gunbc/fleet_desired_admission.dag @@ -297,6 +297,22 @@ fn fleet_desired_authorized_push_cas_request(expected: GitRemoteRefExpectation, // positive word rather than as nothing, and it matches over the closed sum instead of over the // lease's hex-or-empty text — the two renderings answer to the same authority but not to the // same reader. +// WHAT `judge` IS, AND THE THREE THINGS IT IS NOT -- because an absent field reads as "not a +// subject", which is how this class propagates. The judge is the revision of the CHECKED-OUT TREE +// this process was built from. It is NOT the workflow transport: for a workflow_run event GitHub +// takes the .yml from the DEFAULT BRANCH regardless of any `ref:` on the checkout, so `ref:` +// governs repository CONTENT and never which workflow file orchestrates the run. It is also not the +// candidate, and not the subject the required floor judged. +// +// TODAY ALL OF THESE COINCIDE AND THAT IS EXACTLY THE HAZARD. With no `ref:`, the checkout and +// GITHUB_SHA are both the default-branch tip, so judge == transport by accident of configuration. +// The moment the checkout is pinned to the candidate they DIVERGE -- the judge becomes the +// candidate while the transport stays main's -- and a receipt naming only the judge would then +// invite the reader to conclude every byte involved came from the candidate. That inference is +// false and would be UNFALSIFIABLE from the receipt, so the gap is named here BEFORE the pinning +// lands rather than after it makes the receipt misleading. The transport sha, the candidate, and +// the floor receipt's subject are separate fields the decision receipt should carry; recording +// them is scoped to the pinning change, where the divergence becomes real. fn fleet_desired_receipt_expected_phrase(expected: GitRemoteRefExpectation) -> String { match expected { RemoteRefMustBeAbsent => "absent" From 89889dcb67896d96cc57f416057d10fffe6c6d8a Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Fri, 21 Aug 2026 19:16:13 +0000 Subject: [PATCH 3/6] The judge field is caller-coupled: name the condition it holds under MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What the read observes is the CHECKOUT's HEAD. What the receipt asserts is the provenance of the BINARY THAT DECIDED. Those are one fact only because the workflow builds that binary from that checkout inside the same job -- `cargo build --release -p v1-compiler --bin gunbc`, toolchain cache off -- which is a property of the CALLER, not of observe_local_tree_revision. Hand that job a cached, prebuilt, or externally-installed gunbc and HEAD still reports the checkout. The receipt would then name a judge that did not judge, confidently, with nothing in the receipt able to reveal it. That is the same defect this branch exists to fix, one level up: a field whose subject is narrower than its name. THE CONDITION, stated so it can be checked rather than assumed: the binary executing this decision was built, in this job, from the tree this read observes. It holds today. It is not enforced anywhere, and nothing fails if a future workflow edit breaks it. Closing it properly means the binary carrying its own build provenance rather than the run inferring it from a neighbouring checkout. Until then the field is honest evidence under a named condition, not a structural guarantee -- and a reviewer can now attack the condition instead of discovering it. Annotation only; no behavior change. §4c grain checked locally: 0 `source annotation` diagnostics. Co-Authored-By: Claude Opus 5 (1M context) --- dag/gunbc/fleet_desired_admission.dag | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dag/gunbc/fleet_desired_admission.dag b/dag/gunbc/fleet_desired_admission.dag index 35e4092a737..2f2815dd927 100644 --- a/dag/gunbc/fleet_desired_admission.dag +++ b/dag/gunbc/fleet_desired_admission.dag @@ -304,6 +304,21 @@ fn fleet_desired_authorized_push_cas_request(expected: GitRemoteRefExpectation, // governs repository CONTENT and never which workflow file orchestrates the run. It is also not the // candidate, and not the subject the required floor judged. // +// AND THE JUDGE FIELD IS CALLER-COUPLED, WHICH IS A WEAKER CLAIM THAN ITS NAME SUGGESTS. What is +// read is the CHECKOUT's HEAD. What the receipt asserts is the provenance of the BINARY THAT +// DECIDED. Those are the same fact only because the workflow builds that binary from that checkout +// inside the same job (`cargo build --release -p v1-compiler --bin gunbc`, toolchain cache off) -- +// a property of the CALLER, not of this function. Hand the job a cached, prebuilt, or +// externally-installed gunbc and HEAD still reports the checkout, so the receipt would name a judge +// that did not judge, confidently and with no way to tell from the receipt. +// +// The condition, stated so it can be checked rather than assumed: THE BINARY EXECUTING THIS +// DECISION WAS BUILT, IN THIS JOB, FROM THE TREE THIS READ OBSERVES. It holds today. It is not +// enforced anywhere, and nothing fails if a future edit to the workflow breaks it. Closing that +// properly means the binary carrying its own build provenance rather than the run inferring it from +// a neighbouring checkout; until then this field is honest evidence under a named condition and not +// a structural guarantee. +// // TODAY ALL OF THESE COINCIDE AND THAT IS EXACTLY THE HAZARD. With no `ref:`, the checkout and // GITHUB_SHA are both the default-branch tip, so judge == transport by accident of configuration. // The moment the checkout is pinned to the candidate they DIVERGE -- the judge becomes the From 1a46f12ece8b61defc7c4d19adda9848304908f0 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Fri, 21 Aug 2026 19:52:16 +0000 Subject: [PATCH 4/6] Name the field judge-source-observed, because "judge" outruns what the run establishes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "judge" asserts the identity of the BINARY THAT DECIDED. What is established is an OBSERVATION OF A SOURCE REVISION, valid under a caller condition stated one commit ago: the binary was built in this job from this checkout, no other binary was substituted, and tracked source did not change between build and decision. The prose already said that, and the prose is not where this is read. The field sits in operator-facing run-log text, so a reader sees `judge ` and the qualification lives in a .dag comment they will never open. A name that outruns its evidence in the one place the evidence is consumed is rung inflation -- §4b calls that worse than sitting low, because an inflated class never ranks for climbing. It earns the stronger name when the pinning cut binds the build: observe/pin J before build, build the judge from J, re-observe before actuation, require both observations equal the candidate. An embedded self-reported build revision is stronger still and is the real terminal. Verified after the rename: both judge claims PASS, including the vacuity-guarded one. The first returned NO-VERDICT twice in batch position -- that is the 700s timeout killing a cold first run, not a defect; run alone it passes, and its sibling sharing the same fixture, pattern and module passed in the same batch, which is what rules out a compile break. Co-Authored-By: Claude Opus 5 (1M context) --- dag/gunbc/fleet_desired_admission.dag | 10 ++++++++-- .../claim/fleet_desired_admission_witness_test.dag | 8 ++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/dag/gunbc/fleet_desired_admission.dag b/dag/gunbc/fleet_desired_admission.dag index 2f2815dd927..819ee5d95c2 100644 --- a/dag/gunbc/fleet_desired_admission.dag +++ b/dag/gunbc/fleet_desired_admission.dag @@ -304,7 +304,13 @@ fn fleet_desired_authorized_push_cas_request(expected: GitRemoteRefExpectation, // governs repository CONTENT and never which workflow file orchestrates the run. It is also not the // candidate, and not the subject the required floor judged. // -// AND THE JUDGE FIELD IS CALLER-COUPLED, WHICH IS A WEAKER CLAIM THAN ITS NAME SUGGESTS. What is +// THE FIELD IS NAMED judge-source-observed, NOT judge, AND THE NAME IS THE HONEST RUNG. Calling it +// "judge" would assert the identity of the deciding binary; what is established is an OBSERVATION +// of a source revision, under the conditions below. A field whose name outruns its evidence is the +// rung inflation §4b calls worse than sitting low, and it would sit in operator-facing text where +// nobody can see the qualification. It gets the stronger name when the pinning cut binds the build. +// +// AND THE FIELD IS CALLER-COUPLED, WHICH IS A WEAKER CLAIM THAN ITS NAME SUGGESTS. What is // read is the CHECKOUT's HEAD. What the receipt asserts is the provenance of the BINARY THAT // DECIDED. Those are the same fact only because the workflow builds that binary from that checkout // inside the same job (`cargo build --release -p v1-compiler --bin gunbc`, toolchain cache off) -- @@ -352,7 +358,7 @@ fn fleet_desired_authorized_push_script(expected: GitRemoteRefExpectation, to: G "git push ", git_remote_ref_lease_word(request: request) as String, " ", request.remote as String, " ", git_remote_ref_cas_refspec(request: request) as String, "\n", - "echo \"[fleet-desired] admitted ", to_hex, " expected-prior ", expected_phrase, " judge ", judge_hex, "\"\n", + "echo \"[fleet-desired] admitted ", to_hex, " expected-prior ", expected_phrase, " judge-source-observed ", judge_hex, "\"\n", ], "") } diff --git a/dag/test/claim/fleet_desired_admission_witness_test.dag b/dag/test/claim/fleet_desired_admission_witness_test.dag index 357baaa9e6a..6a631b46c0f 100644 --- a/dag/test/claim/fleet_desired_admission_witness_test.dag +++ b/dag/test/claim/fleet_desired_admission_witness_test.dag @@ -272,7 +272,7 @@ test fn the_receipt_names_the_judge_that_decided_the_advance() -> Bool { to: fixture_oid(hex: fixture_candidate_hex), judge: fixture_oid(hex: fixture_judge_hex), ) - string_contains(s: script, pattern: concat(" judge ", fixture_judge_hex)) + string_contains(s: script, pattern: concat(" judge-source-observed ", fixture_judge_hex)) && string_contains(s: script, pattern: concat("admitted ", fixture_candidate_hex)) && string_contains(s: script, pattern: concat("expected-prior ", fixture_prior_hex)) } @@ -292,9 +292,9 @@ test fn the_judge_operand_is_not_the_target_or_the_prior() -> Bool { to: fixture_oid(hex: fixture_candidate_hex), judge: fixture_oid(hex: fixture_judge_hex), ) - string_contains(s: script, pattern: " judge ") - && !string_contains(s: script, pattern: concat(" judge ", fixture_candidate_hex)) - && !string_contains(s: script, pattern: concat(" judge ", fixture_prior_hex)) + string_contains(s: script, pattern: " judge-source-observed ") + && !string_contains(s: script, pattern: concat(" judge-source-observed ", fixture_candidate_hex)) + && !string_contains(s: script, pattern: concat(" judge-source-observed ", fixture_prior_hex)) } // THE RECEIPT HALF, WHICH THE TWO CLAIMS ABOVE DO NOT COVER. They assert what the push DEMANDS; From 69f5851df541f1bc49c267bba71e587a035a6028 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Fri, 21 Aug 2026 21:37:25 +0000 Subject: [PATCH 5/6] Narrow the judge claim to what the run establishes: judge-source-observed The field records the SOURCE REVISION THE ADMISSION CHECKOUT WAS SITTING ON when it adjudicated. The previous naming -- parameter `judge`, PR title "which code adjudicated the advance", refusal text "cannot record which code adjudicated it" -- claimed BINARY IDENTITY, which nothing in this repository yet establishes: no binary embeds its own source revision. Those identities coincide in today's workflow only because the job checks out one tree, builds the deciding binary from it in the same job, and adjudicates in that same checkout. That is a property of the CALLER, not of this function, and it diverges the moment the binary is pinned or prebuilt -- precisely the cut this recording exists to make falsifiable. Naming it for the inference rather than the observation is the rung inflation of Sec 4b, surviving in the durable review and witness surfaces after the run-log field had already been fixed. Raised in side-chat review. Extended to BOTH no-op arms: "this source decided not to mutate" is exactly as attributable an adjudication as an advance, and recording only the mutating arm would leave the two most common outcomes unattributable. Rung: mitigatable. The refusal is real and typed -- the wet entry point declines to actuate when the revision cannot be observed, rather than publishing an unattributable receipt -- but the caller-coupling is held by an annotation, not by construction. Next-rung trigger: a self-reported embedded build revision, at which point the binary's source stops being inferred from the adjacent checkout. The refusal names no cause on purpose: observe_local_tree_revision returns a bare GitObjectId?, conflating "not a git repository" with "HEAD undecodable". Splitting that Optional is separate work and is not required for this change's correctness. EVIDENCE (green-by-execution plus a discriminating red, both run): green 26/26 PASS, 0 FAIL, 0 verdictless, 26 enrolled red dropped the field from the CONVERGED arm only: FAIL both_no_op_receipts_also_name_the_observed_judge_source PASS the_advance_receipt_names_the_observed_judge_source_revision PASS the_observed_judge_source_is_present_and_distinct_from_target_and_prior PASS a_no_op_action_still_renders_a_nonempty_script The two advance rows holding green proves the no-op row is not riding on them; the nonempty-script control holding green proves the failure is the missing field rather than a broken arm. Sec 4c 0 annotation-grain diagnostics, against a compile confirmed to emit (243 files) -- a bare grep -c zero cannot distinguish no-match from nothing-to-match. REBASED over main after #8733 landed. That PR restructured the same decision path (AdmissionAdvanceAuthorized -> AdmissionActionAuthorized over a three-variant coproduct), so this change was RE-DERIVED against the new shape rather than textually merged: each conflict hunk was a choice between two different programs, not two edits to one. My own merged #8768 renderer fleet_desired_receipt_expected_phrase and its two creation witnesses are NOT carried forward, and that is a rung CLIMB rather than lost work. FleetDesiredRemoteAdvance { accepted, expected_prior } now carries the prior structurally, so RemoteRefMustBeAbsent has no spelling in the advance arm -- the state that renderer existed to serve is unwritable. Restoring it would have re-opened exactly what #8733 closed. Only the evidence carries forward: the surviving the_receipt_names_the_expected_prior_beside_the_target covers the same subject one rung up. Co-Authored-By: Claude Opus 5 (1M context) From 4b2e91d2c01b1fa02b1693b2b45d397f4f614ba6 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Fri, 21 Aug 2026 22:04:11 +0000 Subject: [PATCH 6/6] Merge the two fleet_desired_observe import clauses into one Residue of this branch's conflict resolution: #8733 restructured the module and already imported gunbc.fleet_desired_observe, while my side added a second clause for observe_local_tree_revision. Taking "ours" for that hunk kept both, so the module carried two import authorities for one module and named observe_fleet_desired_revision twice. Raised by review 54484 (non-blocking). Verified by execution rather than assumed, because an import edit can break resolution: 26/26 PASS, 0 FAIL, 0 verdictless, no resolve error. Co-Authored-By: Claude Opus 5 (1M context) --- dag/gunbc/fleet_desired_admission.dag | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dag/gunbc/fleet_desired_admission.dag b/dag/gunbc/fleet_desired_admission.dag index d39dd4c681e..4a6ffff7238 100644 --- a/dag/gunbc/fleet_desired_admission.dag +++ b/dag/gunbc/fleet_desired_admission.dag @@ -44,7 +44,7 @@ import gunbc.fleet_revision_acceptance { required_ci_refusal_message, default_branch_refusal_message, } -import gunbc.fleet_desired_observe { observe_fleet_revision_relation, observe_fleet_desired_revision } +import gunbc.fleet_desired_observe { observe_fleet_revision_relation, observe_fleet_desired_revision, observe_local_tree_revision } import gunbc.fleet_main_revision { FleetDesiredAdvanceInput, FleetDesiredExpectationRefusedInput, @@ -67,7 +67,6 @@ import gunbc.fleet_main_revision { FleetDesiredAdmitted, FleetDesiredUnobserved, } -import gunbc.fleet_desired_observe { observe_fleet_desired_revision, observe_local_tree_revision } import std.disposition { Disposition, Scaffold, SingleAuthority } import std.dissolution { DissolutionCondition, unbound_dissolution } import std.decl_ref { DeclarationRef, WholeDeclaration }