Skip to content

mtcollins1_boot: WIF-trusted recurring effect via auth pattern selection, with an operator maintenance hold - #12101

Merged
briansrls merged 26 commits into
mainfrom
session/proud-dove-705
Sep 24, 2026
Merged

briansrls merged 26 commits into
mainfrom
session/proud-dove-705

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Operator ruling 2026-09-23: mtcollins1_boot is a recurring automated effect. It runs under workload identity with no per-run approval, and the change is made through the model rather than by deleting the gate. Head 6514b685fa7, reworked after side-chat reviews 5286225278, 5287596716 and 5288466573 and review 70369. Do not file the ruling before this PR is reviewed at its final head.

⚠️ Operator action required: every boot REFUSES until this one tap

The operator's standing consent is attested outside the diff (decision A). File it once, in a session on srv1, with the submission MAC key path set:

GUNBC_APPROVAL_SUBMISSION_MAC_KEY_FILE=<srv1 path to the approval submission MAC key> \
  ./target/release/gunbc run --source-root dag --source-root src/v2 \
  --entry dag/gunbc/machine_intake/mtcollins1_standing_ruling.dag --function mtcollins1_boot_standing_ruling_file
  • What gets approved: one typed ruling, the Mt. Collins destructive controller effect (mtcollins1_boot_standing_ruling), covering both destructive roots, mtcollins1_boot_wet and host_reset_return_wet. The ntfy request shows its words.
  • What the decision is bound to: the SHA-256 (pure FIPS, not FNV) of one injective tag:length:value encoding of the complete ruling: text, effect, every root, scope verb, tree and service, every path segment, action and interlock.
  • One digest, two uses: that digest is both the approval's intent hash and the escalation-id suffix (mtcollins1-standing-ruling-<sha256>), so a revised or once-denied ruling is fileable under its own id.
  • Derived census: the census's standing authorization and both census rows are derived from the same value.
  • Until the tap: every boot refuses, typed, before the unit hold. There is no fallback to a per-run approval.
  • Editing the words: changing even one character voids the consent until the operator taps again.
  • Provenance the tap confirms: operator chat ruling 2026-09-23, "we technically don't even need my approval - would you mind getting rid of that step or making WIF just trust this workflow".

1. Selection (§3d)

  • Census row: mtcollins1_boot_wet is a census row declared honestly:
    • EveryProvision (recurring, unattended);
    • IrreversibleEffect: a power cycle destroys RAM and the running session;
    • MintsNoCredential;
    • bound to a dedicated workload identity.
  • No relabel: it is NOT relabelled ReversibleByReapply (wall 5). The operator's ruling is a typed StandingDestructiveAuthorization. It discharges only the irreversibility ground of the witness obligation; a wide credential, billing or break-glass still owes a per-instance witness.
  • Where the consent lives: the record names its interlock and its confirmation_read. It is not the consent itself; the consent is the tap above.
  • Selection: with the ruling, the effect selects FederatedScopedGrant. Without it, NoAdmissiblePattern (claimed).

2. Binding: dedicated pool/provider/SA (decision A: dedicated pool, heal-publisher precedent)

  • Why not the repo pool: gunbc.auth.mtcollins1_boot_federation. The repo-wide github_wif_provider cannot pin workflow, ref or job, and WIF principals are pool-scoped (gunbc#10887).
  • Provider condition: pins repository_id, repository_owner_id, workflow_ref == gunb-ai/gunbc/.github/workflows/fleet-converge.yml@refs/heads/main, ref == refs/heads/main, event_name == workflow_dispatch, environment == mtcollins1-boot. One pin list is projected both to the CEL string and to the admission fold the witness evaluates.
  • Accessor cells: the SA holds exactly two, each version-conditioned: bmc-mtcollins1-gunbc v2 and fleet-automation-ssh-key v1. The submission MAC key is gone from this route.

3. Approval loop removed from the boot

The per-run filing, polling, grant handling, grant-keyed claim slot, approval window and its expired arm, and the submission-MAC fetch are all removed. fleet-converge.yml is regenerated from its authority.

4. Interlock: operator maintenance hold, as ONE boundary (wall 3)

  • The hold: gunbc.machine_intake_mtcollins1_maintenance_hold gives the unit one std.durable_exclusive_hold slot, held in the srv1 store. The operator uses mtcollins1_maintenance_hold_take / mtcollins1_maintenance_hold_release (with GUNBC_MTCOLLINS1_MAINTENANCE_REASON set to take it).
  • The proof: UnitHoldProof is sole_constructor and is minted only in the live acquire's FileHoldAcquired arm. Supplied outcomes feed only the pure refusal fold.
  • Gated writes: every Mt. Collins BMC write takes the proof (SOL, media attach, boot device, power). The operations beneath are admit_callers-sealed.
  • Root census: privileged_effect_interlocks.hold_owning_roots lists exactly two roots, both hold-owning:
    • mtcollins1_boot_wet;
    • host_reset_return_wet. Per decision A it now takes the same srv1 hold, and refuses off the store host or while held.
  • Deleted entries: four unconsumed operator entries (netboot/cdrom handoff, denied-admission control, absent-image control) reached this unit's power or media with no interlock. They are deleted.
  • SOL: the SOL write now happens under the hold. This dissolves the side chat's "pre-approval SOL mutation": there is no approval stage left, and the SOL follows the gate that replaced it.

5. Executable bytes and runner (walls 1, 2)

  • Pinned bytes: the boot job checks out ${{ github.sha }} only. The build job's checkout takes github.sha first when mode == mtcollins1_boot, before expected_revision is considered.
  • Fixed runner: runs-on is srv1's literal labels, and concurrency is gunbc-host-mutation-srv1.
  • Job-level gate: if requires inputs.host == 'srv1'. A host=srv2 dispatch never starts the job: no OIDC exchange, no secret fetch.

6. Provisioner reads before it grants (wall 4)

heal_publisher_provision is generalized to one DedicatedFederation record, and the boot binds its own record. The protocol:

  1. Read and classify the pool, its whole provider population (showDeleted), each provider's issuer, mapping and condition, and the SA.
  2. Anything existing-but-different halts with nothing granted. Adoption is a separate path.
  3. Create only what was absent.
  4. Re-read, and require everything to be present and matching.
  5. Only then bind impersonation and write the secret cells.

Out-of-band IAM for the grant administrator (NOT applied here)

Run gunbc run --source-root dag --source-root src/v2 --entry dag/gunbc/auth/mtcollins1_boot_federation_provision.dag --function mtcollins1_boot_federation_provision_with_supplied_token with the grant administrator's own token file. It creates and binds, in order:

  1. Pool projects/582015116396/locations/global/workloadIdentityPools/github-mtcollins1-boot.
  2. Provider .../providers/github-mtcollins1-boot-oidc, with the condition above.
  3. SA mtcollins1-boot@gunbai-secrets.iam.gserviceaccount.com (no keys).
  4. On the SA: roles/iam.workloadIdentityUser → principalSet://iam.googleapis.com/projects/582015116396/locations/global/workloadIdentityPools/github-mtcollins1-boot/*.
  5. On bmc-mtcollins1-gunbc: roles/secretmanager.secretAccessor → the SA, condition resource.name == "projects/582015116396/secrets/bmc-mtcollins1-gunbc/versions/2".
  6. On fleet-automation-ssh-key: the same, condition .../fleet-automation-ssh-key/versions/1.

The new pool/provider reads have not yet been exercised against the live API; their first run is this provisioning.

Evidence (local aarch64 interpreter; ruling files re-run at 6514b685fa7)

Invocation, per file:

./target/release/gunbc run --source-root dag --source-root src/v2 --entry <file> --claim-run
Witness Pass/fail
test.claim.machine_intake.mtcollins1_standing_ruling_witness_test 6/0. Five claims take SUPPLIED digests (DESIGN §3): the own-approval control (SHA-256 family; absent, pending and denied refuse); a boot-only approval cannot confirm the two-root ruling and the id moves; verb, tree, service, path and interlock each change the encoding; separator redistribution does not collide; canonical re-encode. ONE inhabitance claim runs the real standing_ruling_request -> standing_ruling_digest -> sha256_hex over the production ruling and asserts the route (intent digest == escalation-id suffix) and the answer (== an independent SHA-256 of the 1369-char encoding, e13583e1…6568).
test.claim.machine_intake.mtcollins1_unit_hold_forged_probe_witness_test 4/0: SoleConstructorViolation on UnitHoldProof and StandingRulingConfirmation; ConstructorCallAdmissionRefused on the four sealed writes and on mtcollins1_boot_under_live_unit_hold (the skip-the-read mutation); class-scoped harness control
test.claim.machine_intake.mtcollins1_maintenance_hold_witness_test 6/0: RED boot under operator hold; second writer refused; OIDC subject REDs (other workflow/ref/event/environment/none)
test.claim.authorization_pattern_selection_witness 18/0, incl. every ruling root is a conforming census row with an interlock row
mtcollins1_boot_run_witness_test 12/0, incl. wall-1 and wall-2 REDs
host_reset_return_witness_test 53/0
heal_publisher_provision_witness_test 13/0, incl. RED existing provider with another condition halts before any grant
gha_job_projection_witness_test 5/0
workflow_dispatch_input_witness_test 30/0
mtcollins1_boot_authorization_witness_test 1/0
  • Generated artifacts: generated_artifact_gate main_wet on this head leaves the tree byte-identical.
  • Mutations (applied, run, reverted):
    • FileHoldOccupied => acquired: hold REDs FAIL.
    • Dropping the environment pin: subject RED FAILs.
    • Removing the oob_boot_handoff seal: sealed-call RED FAILs.

Inhabitance-claim cost receipt (exact head)

  • Run: required floor run 35852820957 at 1cf802b1801 (job 107154400326), artifact required-ci-measurement-receipt, for …the_production_ruling_digest_is_the_sha256_of_its_encoding_and_the_request_carries_it.
  • Result: pass; 4,199,697 eval steps; 3,281 ms CPU; wall 3,290 ms (under the 8 s limit); admitted at the enrolment margin as declared expensiveness.
  • Admission: a typed floor_cost_debt admission, under its own one-member drop gunbc.rung_drop.mtcollins1_standing_ruling_digest_new_witness_eval_step_cost. The App Attest drop is untouched.
  • Floor totals at that head: 472 planned, 459 passed, 0 failed, 0 over-cost refusals.

Provisioner split and the interpreter defect it surfaced

  • What moved: the provisioning binding moved out of gunbc.auth.mtcollins1_boot_federation into gunbc.auth.mtcollins1_boot_federation_provision.
  • What prompted it: the interpreter defect below. While the binding sat in the federation module, gunbc.fleet_converge_workflow's closure contained gunbc.auth.heal_publisher_provision.
  • Why the split stands on its own: it is the shape the heal publisher already uses. gunbc.auth.heal_publisher_federation holds the federation facts that emission reads, and gunbc.auth.heal_publisher_provision holds the out-of-band provisioning entry. My first cut fused the two, which made workflow emission depend on the grant administrator's provisioner. So the split is not reverted when the defect is fixed. Only the claim that "the workflow's closure must not contain the provisioner" is defect-driven; the layering is not.
  • Defect repro (dispatched separately by eager-owl-205). A module containing only the following fails with NoSuchVariable { name: "FleetConvergeYamlArtifact" }:
    import gunbc.generated_artifact { artifact_path, FleetConvergeYamlArtifact }
    import gunbc.auth.heal_publisher_provision { heal_publisher_impersonation_cell }
    fn b() -> ProcessExit { exit_failure(reason: concat("FC=", artifact_path(a: FleetConvergeYamlArtifact))) }
    
    It reproduces with main's own heal_publisher_provision. Drop the second import and the same module prints FC=.github/workflows/fleet-converge.yml. HealPublisherWorkflowYamlArtifact evaluates fine in the same closure.

Residue

  • Old repo-wide grant stays: the repo-wide convergence SA still reads the BMC credential for other modes (fan observe). The boot no longer uses that path.
  • Environment claim is job-grain only by review: another job in fleet-converge.yml at main declaring the same environment would be admitted.
  • Unsealed service calls: the seals cover the gunbc wrappers. A new direct ipmi / megarac service call would be a new root that is not caught mechanically.
  • Misplaced homes (follow-ups): DedicatedFederation lives in the heal module, and mtcollins1_boot_authorization is now misnamed.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 2 commits September 23, 2026 00:59
…n selection, with an operator maintenance hold

The census now carries the boot as a row and the selection derives FederatedScopedGrant for it.
The per-run approval stage (file request, poll, grant, claim slot, submission MAC fetch) is removed.
The boot runs as its own fleet-converge job under a dedicated WIF pool/provider/SA with two
version-pinned accessor cells. It takes the unit's durable exclusive hold before any BMC write
and refuses typed under an operator maintenance hold.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…names the mtcollins1-boot job

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SOURCE HOLD at exact head f5d09c9d987a25ae7d31546ae2325383aa9124c7.

The dedicated pool/provider/SA, job-grain environment, pinned secret versions, and durable unit hold are the right direction. Five load-bearing walls remain.

  1. The WIF identity is pinned, but the executable code is not. Both the build job and the privileged mtcollins1-boot job check out ${{ github.event.inputs.expected_revision || github.ref }}. expected_revision is a caller-supplied workflow input and is not among the provider claims. A dispatch from the trusted workflow/ref can therefore select another repository revision, build its release-bins, and hand that artifact to the job that later obtains the BMC and fleet credentials. The boot subject still records GITHUB_SHA, so it can name main while executing bytes from the supplied revision. claim_executor is also taken from the same artifact it “verifies”; it is not independent provenance, and it executes before WIF in the same persistent job/runner. For this mode, bind checkout/build/runtime bytes to the event SHA, or consume an independently attested artifact whose source revision is joined to that SHA. Add a RED in which an arbitrary expected_revision cannot change any executable byte used by the WIF job.

  2. The job reaches WIF and both secrets on a caller-selected host before the source-level srv1 refusal. runs-on uses the host input, while the job-level if checks only the mode. Thus host=srv2|srv3|srv4 schedules there, exchanges OIDC, materializes the fleet key and BMC credential, and only later lets mtcollins1_boot_wet reject the host. Pin this job structurally to srv1 (and preferably its concurrency group), or put a host==srv1 condition at job grain before scheduling/authentication. The RED must show a non-srv1 dispatch never reaches OIDC or either secret read.

  3. The maintenance hold is not a source-level prerequisite for actuation. mtcollins1_boot_actuate is an effectful callable function that performs SOL/attach/bootdev/power without acquiring a hold. mtcollins1_boot_under_unit_hold accepts a supplied BootHoldAcquired, which is forgeable in this substrate, and mtcollins1_attach_diskless_image has been weakened from requiring scoped authorization to accepting an ordinary subject. The live acquire and every BMC mutation need one effect-owning entrypoint/arm; supplied store outcomes may feed pure admission tests, but no effectful helper may accept evidence-shaped admission as authority. Add a reachability census/control over every callable path to SOL, attach, boot selection, and power.

  4. The federation provisioner grants access before classifying pre-existing security subjects. A 409 becomes SubjectAlreadyPresentUnverified, but provision_dedicated_federation still binds the whole pool to the service account and grants its secret reads, then refuses only at bound_verdict_for. A pre-existing provider with a broader/different condition can therefore receive the BMC and fleet-key grants during a run that correctly ends red. Read and classify the existing pool/provider/account—especially provider count, issuer, mapping, and condition—before writing impersonation or Secret Manager policy; otherwise halt without widening access.

  5. The interlock does not make a power cycle reversible. The authorization authority defines reversibility as whether the world can be put back, not whether the operation is repeatable. A power cycle destroys the current RAM/session state; a maintenance hold prevents collision with declared hands-on work but does not restore that state. The statement that this unit is intake-only and disposable is currently prose, not a typed/observed premise consumed by selection. Either carry a load-bearing unit-role/current-state standing that makes restoration-by-reapply true, or add/select an explicit recurring-destructive-under-interlock policy. Do not set ReversibleByReapply merely because IrreversibleEffect + EveryProvision exposes that the present candidate field has no admissible pattern.

Accepted in the current source: the claim pin set and its REDs; separating the boot into its own environment-bearing job; the two version-conditioned accessor cells; deleting the approval-submission key; typed occupied/lost/unreadable hold refusals; operator release refusing boot-owned holds; and moving SOL acquisition after the live interlock in the intended route.

Do not apply the IAM bindings while wall 4 remains. At this read GitHub reports the PR non-mergeable and the exact head has no check runs yet; those are landing conditions after the source walls.

gunbc-ci-auto-heal and others added 5 commits September 23, 2026 02:47
fleet_converge_workflow.dag: keep both additions (mtcollins1-boot job; main's credential prelude producer).
fleet-converge.yml regenerated from the merged authority, not hand-resolved. Two Job literals gain the
environment field.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1. Executable bytes: the boot job checks out github.sha only; the build job takes the event sha
   first for this mode. No dispatch input selects bytes the WIF job runs.
2. srv1 structurally: fixed runs-on labels and concurrency, and a job-level host == srv1 condition.
3. One boundary: UnitHoldProof is sole_constructor, minted only in the live acquire's
   FileHoldAcquired arm. Mt. Collins BMC writes take the proof, and oob_boot_handoff, megarac attach
   and the SOL ops are admit_callers-sealed. host_reset_return takes the same srv1 hold (decision A).
   Four unconsumed operator entries are deleted. Forged-proof and sealed-call REDs come from a probe.
4. Provisioner: read and classify pool, whole provider population and account before any write.
   An existing differing subject halts with nothing granted. Create only absent subjects, re-read,
   then bind.
5. No relabel: the boot is IrreversibleEffect. A typed StandingDestructiveAuthorization (the operator
   ruling, conditional on a rostered interlock) discharges only the irreversibility witness ground.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…dule's closure is too deep for a zero-row control)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Main's EFFECTS-1 cut (#11993) deleted the uses-net clauses in five files this branch also edits. Resolved
to this branch's content with the same clauses removed, and the same cut applied to the new
mtcollins1_boot_federation entry. fleet-converge.yml regenerated from the merged authority.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…0369, decision A); annotations to module-item grain

- gunbc.machine_intake_mtcollins1_standing_ruling: the ruling's words are the approval request's purpose
  and their content hash is its intent hash. Every boot reads the stored decision before the unit hold
  and refuses if it is absent, pending, denied or for other words. StandingRulingConfirmation is
  sole_constructor, minted only by that live read. The hold-owning path requires it and is
  admit_callers-sealed to the boot entry. One-time filing entry: mtcollins1_boot_standing_ruling_file.
- StandingDestructiveAuthorization now names its confirmation_read, not an author-written ruled_by.
- REDs: absent, pending, denied, one-character edit. The skip-the-read mutation is refused at compile
  time in the probe.
- Move annotations out of declaration bodies (actions.dag Job, iam_admin service, host_reset_return_run).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

Review 70369 addressed at 186f2cf (decision A from eager-owl-205). The standing ruling is no longer attested by an author-written row. Its exact words are filed once through the approval loop: they are the request's purpose, and their content hash is its intent hash. Every boot reads the stored decision on srv1 before the unit hold and refuses, typed, if the decision is absent, pending, denied or for other words. StandingRulingConfirmation is sole_constructor and is minted only by that live read. The hold-owning path requires it and is admit_callers-sealed to the boot entry, so a forged row yields a selection and no effect. The census record now names confirmation_read instead of ruled_by, and the comment states the rung honestly: the static check is only that the interlock and the confirmation route are named against the site. REDs: absent, pending, denied, one-character edit. The skip-the-read mutation is refused at compile time (forged-proof probe). — sent from proud-dove-705

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SOURCE HOLD at exact head 186f2cf.

The five original walls are materially improved, and I accept most of the re-cut:

  • checkout, build and privileged runtime are pinned to the event SHA for mtcollins1_boot;
  • the WIF job is fixed to srv1 at job level, so another host never reaches OIDC or secret materialization;
  • the live maintenance-hold acquisition and BMC effects form one caller-sealed production boundary, and the Mt. Collins host-reset route acquires the same hold;
  • the dedicated federation provisioner classifies existing pool/provider/service-account state before it writes impersonation or secret grants;
  • the effect remains explicitly irreversible, with a separate standing-destructive authorization pattern under the physical-safety interlock rather than a reversibility relabel.

Two defects remain in the one-time standing-consent construction.

  1. THE CONSENT CANNOT ACTUALLY BE RENEWED AFTER THE TEXT CHANGES OR AFTER A DENIAL.

mtcollins1_boot_standing_ruling_escalation_id is one fixed value, while the source promises that editing one character voids the old consent “until the operator taps again.” The approval store deliberately files generation 1 under ExpectSlotAbsent; a second filing under the same escalation id reports the slot occupied rather than replacing what was shown to the operator. A denial is likewise terminal for that escalation id.

Therefore the current behavior is:

old text approved
→ text changes
→ live read correctly refuses revision mismatch
→ filing the new words under the fixed id cannot create a new request
→ every boot is permanently wedged

Derive a versioned escalation id from the ruling revision/digest, or carry an explicit ruling epoch/version that changes with the approved text. The old decision must remain immutable under its old id, and the new wording must file into a distinct absent slot.

Required control:

approval for revision A + source revision B
→ B refuses A
→ B's filing targets a distinct id and can be filed

Also cover a denied revision A followed by an intentionally new revision B.

  1. THE “EXACT WORDS” BINDING USES A NON-CRYPTOGRAPHIC STRUCTURAL HASH.

standing_ruling_request sets intent_hash with content_hash_of_value(text). In this repository that mints the FNV-1a-64 structural family; request_revision_of serializes that value. This is suitable as a structural identity/fingerprint, but it is not an authorization-grade commitment to operator-visible words. An author able to choose replacement text can deliberately search for a collision and reuse the durable approval while changing the words. The one-character mutation proves ordinary drift detection, not collision resistance.

Use a cryptographic SHA-256 digest over one canonical standing-ruling preimage, and carry it as the request's Sha256Hash intent. The preimage should include at least the full ruling text and the load-bearing subject/scope/interlock identity; deriving the versioned escalation id from that same digest avoids a second computation and closes issue 1 at the same boundary.

Required controls:

  • the request intent is the SHA-256 family, never Fnv1a64Structural;
  • one-character text change changes both revision and versioned escalation id;
  • scope/interlock change also changes the approved preimage;
  • old approval cannot confirm the new request, while the new request remains fileable.

The forged-proof, maintenance-hold, authorization-selection, host-reset, federation-classification and workflow-pin receipts are otherwise accepted. The current floor/witness CI red is separately attributable to the latent main consumer type error being repaired by #12120; this source hold does not depend on that inherited failure.

gunbc-ci-auto-heal and others added 2 commits September 23, 2026 07:19
…est-versioned, read on every BMC route (review 5287596716)

- fleet_converge_job_kinds is the one job roster: the workflow's jobs map over it and each job's
  id and needs are drawn from it. The roster and trigger claims read it and the dispatch inputs,
  not the built workflow (519k -> roster reads). Boot-run wall claims read the job's steps and
  fields; no YAML render.
- Standing ruling: one canonical preimage (text, effect, scope action, interlock). SHA-256 (pure
  FIPS, extdeps.crypto.sha2), not FNV. One digest is the intent hash and the escalation-id suffix,
  so a revised or once-denied ruling is fileable under its own id.
- No route skips the ruling: unit_hold_acquire (the proof's only mint) takes the ruling
  confirmation and is sealed to the two roots. Sealed: the ruling read, the boot actuation and the
  SOL steps. host_reset_return reads the ruling (StandingRulingUnconfirmed refusal).
- REDs: A approved cannot confirm B; A denied leaves B fileable; scope and interlock changes change
  the digest; family is SHA-256. The probe covers outside calls to actuation, acquire and read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#12093 (boot diagnostic bundle) was built on the per-run approval flow. Resolved by porting its
conclude/bundle structure onto the standing-ruling + unit-hold boot: every terminal arm still
uploads a bundle, the before-SEL read is taken after the ruling confirms and before the hold, and
the receipt names the standing ruling instead of a per-run escalation id. fleet-converge.yml
regenerated from the merged authority.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SOURCE HOLD at exact head 96690ffd52bd31b9730bf923df038e681753fe3d, superseding review 5287596716.

The two defects from that review are repaired in their direct form:

  • the ruling now uses a typed SHA-256 digest rather than the structural FNV family;
  • that same digest versions the escalation id, so revision A cannot confirm revision B and a denied A does not occupy B's slot.

The five earlier WIF/interlock walls remain accepted: event-SHA bytes, srv1 job grain, one live hold-owning effect boundary, classify-before-grant, and no reversibility relabel.

Two authorization-boundary defects remain.

1. The SHA-256 preimage is neither complete over AuthorizationScope nor injective

standing_ruling_preimage includes only:

text
effect_subject
scope.action
interlock

It omits scope.verb and scope.resource (the namespace tree and full path). The new “scope change” witness changes only action while leaving verb and resource byte-identical, so it does not discriminate this omission.

This is load-bearing, not metadata. request_revision_of is only the serialized intent_hash; once that revision agrees, grant_from_approved_decision constructs the grant from the CURRENT request's scopes and subject. Therefore an old approval can confirm a request whose resource or verb changed while its action stayed constant, and the resulting grant carries the changed current scope.

The preimage also is not canonical/injective despite its annotation. It concatenates unrestricted string fields with newline-labelled separators but performs no escaping or length-prefixing. For example these two distinct rulings serialize identically before the unchanged action/interlock suffix:

A: text="T\neffect=E1", effect_subject="E2"
B: text="T",             effect_subject="E1\neffect=E2"

That reuses an approval without finding a SHA-256 collision; it exploits an ambiguous preimage.

Required repair: one canonical, injective encoding—canonical JSON through the existing authority or unambiguous length-prefixed fields—over the complete typed ruling:

operator-visible text
effect subject
scope verb
scope resource tree/service and every path segment
scope action
interlock identity

Use its one SHA-256 for both intent and escalation id, as this head already does.

Required controls:

  1. same action, different verb -> different digest/id;
  2. same action, different resource path/tree -> different digest/id;
  3. separator/newline redistribution between adjacent fields cannot preserve the encoding;
  4. encode/decode or canonical re-encoding proves one ruling has one byte representation;
  5. old approval cannot confirm any of those changed requests.

2. The newly authorized host_reset_return effect is outside the request's typed scope and outside the census authorization row

The current operator-visible ruling text and runtime StandingRuling.effect_subject authorize BOTH mtcollins1_boot and host_reset_return. host_reset_return_wet reads this ruling, obtains the same StandingRulingConfirmation, acquires the unit hold and may set boot selection and power-cycle the unit.

But the request still carries only:

resource: gunbc-standing-ruling / mtcollins1 / boot
action: gunbc.standing-ruling.mtcollins1-boot

and privileged_effect_census independently re-authors mtcollins1_boot_standing_authorization.effect_subject as boot-only. Its one PrivilegedEffectSite is mtcollins1_boot_wet; host_reset_return_wet appears only as an InterlockRoot beneath that site's hold roster. Thus the cryptographically approved runtime ruling, the typed enforcing scope, and the selection/census record are three spellings that already disagree about which destructive effects are authorized.

Choose one coherent construction:

  • separate boot and host-reset standing rulings, scopes, confirmations and census rows; or
  • one shared typed Mt. Collins destructive-effect ruling whose scope explicitly covers both roots, with the runtime request and StandingDestructiveAuthorization derived from the SAME value/digest, and with host reset represented in the privileged-effect census rather than only as a hold-owning root.

Required REDs:

  1. a boot-only approval cannot authorize host reset;
  2. changing the root/effect population changes the digest and escalation id;
  3. the runtime ruling and census authorization cannot disagree on subject, full scope or interlock;
  4. every destructive root consuming the confirmation is represented by the authorization census at the same grain.

Accepted remainder: caller sealing, sole-constructor confirmation and hold proof, host-reset live acquisition/release, boot diagnostics integration, the centralized workflow job roster, and the local clean-tree claim receipts as reported.

Do not file the one-time standing ruling at this head: its current approval would be durably under-bound in the two ways above. Exact-head CI is still running; this source hold is independent of that landing state.

…ive encoding of the complete ruling (review 5288466573)

- The ruling is one typed value, the Mt. Collins destructive controller effect, covering both roots
  (mtcollins1_boot_wet, host_reset_return_wet) with its typed scope. The request, digest, escalation
  id, the census StandingDestructiveAuthorization and both census rows are derived from it.
  host_reset_return_wet is a census PrivilegedEffectSite with its own interlock row.
- Preimage: tag:length:value per field (lists count-first) over text, effect, every root, verb,
  tree and service, every path segment, action and interlock. One SHA-256 is the intent and the id
  suffix.
- Controls: a boot-only ruling moves the digest and id, and its approval cannot confirm the two-root
  ruling. Verb, tree, service, path and interlock each change the encoding. Separator redistribution
  across fields and path segments does not collide. Re-encoding is one byte form. Census roots equal
  ruling roots.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

APPROVE at exact head 1ce25ecce49559c21945241276f724712b8c2bed, superseding REQUEST_CHANGES review 5288466573.

Both held authorization walls are closed.

  1. The cryptographic preimage is now complete and injective. One typed StandingRuling carries the operator-visible text, effect subject, full destructive-root population, complete scope and interlock. standing_ruling_preimage encodes every value as tag:length:value, encodes list cardinality before list members, and covers: text; effect; every root; scope verb; namespace-tree kind and ServiceOpTree service; every resource-path segment; action; and interlock identity. Separator-looking content therefore cannot move across field or list boundaries without changing the bytes. SHA-256 over that one canonical encoding is used for both AuthorizationRequest.intent_hash and the escalation-id suffix. The prior FNV/partial-scope and ambiguous-concatenation defects are gone.

  2. One authority now covers both destructive roots. mtcollins1_boot_standing_ruling names exactly mtcollins1_boot_wet and host_reset_return_wet. The runtime request/digest/id derive from it; standing_authorization_of derives the census authorization from it; both root-specific PrivilegedEffectSite rows derive their common effect, ruling and interlock from it; and both sites have interlock rows at their own grain. The two-way census/root checks refuse either a missing ruling root or an extra census site. A boot-only approval consequently has a different digest and escalation id and cannot confirm the two-root ruling.

The executed controls are appropriately discriminating: verb, namespace-tree kind, service, path length/content, interlock, root population and text all move the encoding; separator redistribution does not preserve it; reassembling the same typed value yields the same bytes; and both roots select federation and conform only under the standing ruling. The previously accepted walls remain intact: event-SHA bytes, srv1 job gate before OIDC/secrets, one live hold-owning actuation boundary, classify-before-grant federation provisioning, explicit irreversibility, caller seals and sole-constructor evidence.

No further source blocker remains. A future second standing-ruling family should identify census discharge by a typed ruling identity/digest rather than the current text comparison, but with this head's single constructor and two-way root census that is not a present defect.

At approval time compiler and clippy are green; exact-head floor and emit-build are still running. Land after the required floor completes green. Do not file the durable one-time ruling until this exact source head is the landed authority and the operator-facing filing step is run against it.

…0459)

UnitHoldOwner = OperatorMaintenance { reason } | BootRun { run_id } | HostResetReturn { attempt }. It is
rendered to and decoded from the durable owner string in one place; the decode refuses a foreign or
detail-less owner. The operator release names each kind (a host-reset holder is no longer called a
boot run). unit_hold_release returns UnitHoldReleasedCleanly | UnitHoldLeftHeld { cause } in place of
an empty-string flag.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

Review 70459 addressed at 37ea4c8. The holder kind is now a declared sum, UnitHoldOwner = OperatorMaintenance { reason } | BootRun { run_id } | HostResetReturn { attempt }. It is rendered to and decoded from the durable owner string in one place (unit_hold_owner_ref / decode_unit_hold_owner), and the decode refuses a foreign or detail-less owner. mtcollins1_maintenance_hold_release matches each kind, so a host-reset-return holder is named as one rather than as a boot run. unit_hold_release returns a typed UnitHoldReleasedCleanly | UnitHoldLeftHeld { cause } in place of the empty-string flag. New claim: every kind round-trips, and a foreign or detail-less owner is refused. Local: maintenance_hold 7/0, boot_run 12/0, host_reset_return 53/0. — sent from proud-dove-705

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

APPROVE at exact head 37ea4c82291a7d74719a4893a8bb7090fbc8fbe3, superseding my approval at 1ce25ecce49559c21945241276f724712b8c2bed.

The delta is one commit over the approved head and is confined to the maintenance-hold authority plus its witness.

The holder model is now coherent:

  • UnitHoldOwner = OperatorMaintenance | BootRun | HostResetReturn is the one typed population.
  • unit_hold_owner_ref is the one renderer; decode_unit_hold_owner is the one decoder.
  • Every admitted arm carries a non-empty detail.
  • An unknown tag or a recognized tag with no detail becomes UnitHoldOwnerUnrecognized; it is never guessed into an authorized holder kind.
  • The operator-release path matches the decoded constructor. A boot holder is named as a boot, a host-reset holder is named as host reset-return, and only OperatorMaintenance reaches the release transaction. This closes the prior two-valued classification that mislabeled every non-maintenance holder as a boot run.

The release fold is also improved without changing its effect semantics. The former empty-string sentinel is replaced by:

UnitHoldReleasedCleanly
UnitHoldLeftHeld { cause }

unit_hold_release then preserves the original step result on a clean release and combines a typed release failure with the original step outcome when the slot remains held. Every file_hold_release_commit arm remains exhaustively classified.

The new witness establishes all three render/decode/label round trips, an unknown owner refusal, and an empty-detail refusal. The reported clean-tree maintenance_hold 7/0, boot_run 12/0, and host_reset 53/0 receipts are consistent with the exact delta.

No previously approved WIF, standing-consent, census-root, sole-constructor, caller-seal, or live-hold boundary moved. I found no new source blocker.

Land only after the required exact-head floor completes green. At review time clippy was green while compiler, floor, and emit-build were still in progress.

gunbc-ci-auto-heal and others added 2 commits September 23, 2026 10:38
…erlock symbol

The two ruling claims that digested the real ruling with the pure SHA-256 measured 4.2M and 5.5M eval
steps against the 72.3k new-witness budget (about 100k steps per 64-byte block). Per DESIGN §3 they
now supply digests: they are about the request built from a digest and the encoding it is taken over.
The SHA-256 primitive's evidence is test.claim.sha256_fips_witness_test. The alternate-interlock control
cited a nonexistent module (CITED-MODULE-ABSENT); it now names an existing declaration.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…under the interpreted-crypto drop

the_production_ruling_digest_is_the_sha256_of_its_encoding_and_the_request_carries_it runs
standing_ruling_request over the production ruling (standing_ruling_digest -> sha256_hex of the
canonical encoding bytes). It asserts the route (intent digest == escalation-id suffix) and the answer
(== an independent SHA-256 of the same 1369-character encoding). DESIGN §3 pairing obligation: every
other ruling claim supplies its digest. The identity is admitted with a typed floor_cost_debt admission
and added to the population of gunbc.rung_drop.app_attest_interpreted_crypto_new_witness_eval_step_cost
(same ground: interpreter-realized SHA, retired by the natively emitted crypto closure); no parallel
drop. docs/design-rung-drops.md regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SOURCE HOLD at exact head 1cf802b180147d5736f86f19785d9a5c8ebc2dbb.

The witness recut itself is correct. Supplying digests to the interface-focused claims and retaining exactly one inhabitance claim that calls standing_ruling_request over the production ruling is the right DESIGN §3 pairing shape. That claim asserts both the route (the request intent digest is also the escalation-id suffix) and the answer; the pinned e13583e1…6568 value is the SHA-256 of the current 1,369-byte canonical encoding. The replacement of the nonexistent gunbc.other_hold citation is also sound. No previously approved WIF, unit-hold, consent, or census boundary moved.

Three drop-authority issues remain.

1. This is a new drop, not growth of the App Attest drop

The governing authority in v2.workflow.floor_eval_step_cost_drop is explicit: growing a drop's own list is a new drop, and a newly expensive witness gets its own declared list rather than a row appended to another drop's population. This head appends the Mt. Collins ruling claim to floor_eval_step_cost_drop_interpreted_crypto_rows, whose declared rung drop is app_attest_interpreted_crypto_new_witness_eval_step_cost.

That creates both problems the rule exists to prevent:

  • the bounded App Attest population has silently grown from its declared incident;
  • the module, data value and RungDrop.identity still say app_attest, while the subject now includes an unrelated Mt. Collins authorization claim.

The file also still says “All ten members” after adding the eleventh member, which is the immediate prose symptom of the authority widening.

A simple rename is not enough, because it would retroactively broaden the historical drop and its declared population. The fastest correct path is a one-member drop of its own, for example:

floor_eval_step_cost_drop_mtcollins1_standing_ruling_digest_rows
mtcollins1_standing_ruling_digest_new_witness_eval_step_cost

It should reuse the existing shared membership mechanism and may name the same primitive-level cause, but it needs its own list, RungDrop identity, declaration date, roster entry and generated projection. That is not a parallel authority for SHA-256; it is a separate bounded loss incident under the one shared policy.

An atomic replacement of the old App Attest drop by a newly declared generic interpreted-crypto drop could also be coherent, but it would need a new identity/date and an explicit retirement of the old drop. Merely renaming the current module while keeping the appended population is not enough.

2. The inherited restoration trigger does not restore this claim

The current drop's trigger says all members execute on the native gunbc-test route named by approval_device_redemption::ecdsa_verification_realization_frontier. That is the App Attest ECDSA route. It does not establish that the Mt. Collins standing-ruling claim executes standing_ruling_request -> standing_ruling_digest -> sha256_hex natively.

MachineWidth<N> reification may be a prerequisite shared by both, but a trigger is sufficient only when satisfying it actually restores the named evidence. The new one-member drop must name the native claim/instrument that executes the production standing-ruling digest route, not merely a neighboring App Attest crypto frontier.

Required trigger shape:

native emission can execute the standing-ruling digest closure
AND this exact inhabitance identity runs through standing_ruling_request
AND it measures under the new-witness budget, or moves to that explicitly named native row

3. measured_by does not name a receipt for this identity

The new row cites required-floor run 35844351667 at head 37ea4c8. The current identity did not exist at that head; that run measured the two predecessor claims which each happened to compute the same SHA-256. It is useful causal evidence, but it is not this row's measurement receipt.

The exact-head floor is already running. If it proves this identity over the budget and above the enrolment margin, cite that run/artifact and its own identity line in the new drop. If the live reading no longer occupies the admission, delete the typed admission and drop row instead. The source cannot presently say that the old run measured this identity.

I accept the clean-tree 6/0 standing-ruling result as semantic evidence. The PR body should also update its table from 5/0 to 6/0 and describe the new inhabitance identity after the source repair.

At review time clippy is green; compiler, floor and emit-build are still running. This source hold is independent of those pending checks.

… exactly (review 5290215172)

- gunbc.rung_drop.app_attest_interpreted_crypto_new_witness_eval_step_cost and its rows are reverted
  to their prior population and text.
- New gunbc.rung_drop.mtcollins1_standing_ruling_digest_new_witness_eval_step_cost with its own list
  floor_eval_step_cost_drop_mtcollins1_standing_ruling_digest_rows (shared membership mechanism; same
  MechanicallyPreventable -> Mitigatable rung and diagnosis). Its own trigger: native emission of the
  standing-ruling digest closure AND this identity executing it on a named native instrument or floor
  route within the new-witness budget; the App Attest ECDSA route does not restore it.
- Measured on the exact-head floor: run 35852820957 at 1cf802b (job 107154400326), verdict pass,
  over budget, admitted at the enrolment margin. Run 35844351667 is causal context only.
  docs/design-rung-drops.md regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SOURCE HOLD at exact current head 545fc9022b74af4b2bd71860245bce14e340fa98, superseding the requested but non-current/non-resolvable bc7d0e22e4e spelling.

The substantive repair to review 5290215172 is correct:

  • gunbc.rung_drop.app_attest_interpreted_crypto_new_witness_eval_step_cost is restored to its prior ten-member App Attest population and prior trigger; the Mt. Collins identity is no longer appended to it.
  • floor_eval_step_cost_drop_mtcollins1_standing_ruling_digest_rows is a separate one-member population joined through the existing shared membership fold.
  • gunbc.rung_drop.mtcollins1_standing_ruling_digest_new_witness_eval_step_cost has its own identity, declaration date, subject, MechanicallyPreventable -> Mitigatable rung, replacement, population and restoration trigger.
  • Its trigger names the exact standing-ruling composition and requires this exact identity to execute on a named native route; it explicitly says the App Attest ECDSA route does not restore it.
  • Run 35852820957 is real exact-identity evidence: the witnesses workflow ran at parent head 1cf802b1801, concluded success, and published the required-ci-measurement-receipt artifact. The older 35844351667 receipt is correctly labelled causal context for predecessor claims, not measurement of the current identity.

No cost reading was copied into the typed admission reason

Confirmed. The FloorCostDebtTypedAdmission.reason contains no run id, eval-step count, CPU time, wall time, threshold reading or copied receipt value. It carries only:

  • the diagnosis: interpreted SHA-256 word folds over the production ruling encoding;
  • the structural workload description (about twenty-two blocks);
  • why the digest cannot be supplied: this is the one inhabitance claim of the route;
  • the owner and native-closure remedy.

The block count is a property of the authored input/composition, not the floor's cost reading, and it does not decide admission. The measurement citation is kept in the separate EvalStepCostDropMeasurement.measured_by row, which names the run/job/artifact and explicitly says the standing figure is read from that artifact and never copied into source.

Remaining source wall: the admission authority still says this is all App Attest

src/v2/workflow/floor_cost_debt_admission.dag still introduces floor_cost_debt_typed_admissions with:

  • THE APP ATTEST INTERPRETED-CRYPTO ROWS;
  • Each identity below evaluates real P-384 field arithmetic or a real SHA-384...;
  • the App Attest native ECDSA frontier as the terminal shape;
  • All ten members....

But the first row below that authority is now the Mt. Collins SHA-256 standing-ruling identity. It evaluates neither P-384 nor SHA-384, has a different owner, and—by the new drop's correct trigger—is explicitly not restored by the App Attest ECDSA route.

That leaves the exact meaning fork this delta otherwise repairs: typed row says Mt. Collins, enclosing authority says App Attest. Separate the Mt. Collins admission into its own explanatory paragraph/section and narrow the existing paragraph to the ten App Attest rows. The row's existing reason can stay as written.

The shared-drop module header should be corrected in the same edit. src/v2/workflow/floor_eval_step_cost_drop.dag still says Four bounded populations and enumerates an older subset, while the module now carries seven independently declared lists including App Attest and Mt. Collins. This is the root explanation of the shared-membership mechanism; it should describe the current population classes without copying their sizes as cost readings.

No semantic redesign is required. After those authority comments agree with the typed populations, rerun the admission/drop roster resolution, generated rung-drop projection and exact-head required floor. The current head's clippy is green; compiler, floor and emit-build were still running at review time.

…raph; drop header names the seven lists (review 5290889114)

- floor_cost_debt_admission: app_attest_interpreted_crypto_typed_admissions (paragraph narrowed to
  exactly those ten) and mtcollins1_standing_ruling_digest_typed_admissions (its own paragraph; reason
  unchanged), concatenated by floor_cost_debt_typed_admissions.
- floor_eval_step_cost_drop header: the seven independently declared lists, each with its drop, and no
  figures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

APPROVE at exact head 10a2bc81e60cbcd85beff5e783662af08c00f462, superseding REQUEST_CHANGES review 5290889114.

The two remaining authority-prose findings are closed.

Typed admission authority

The App Attest and Mt. Collins incidents are now separate declared populations:

  • app_attest_interpreted_crypto_typed_admissions is introduced by a paragraph explicitly scoped to exactly its ten P-256/P-384/SHA-384 identities;
  • mtcollins1_standing_ruling_digest_typed_admissions has its own paragraph, one identity, owner, real route and distinct native restoration capability;
  • floor_cost_debt_typed_admissions composes the two lists through concat, preserving the prior combined consumer population without placing the Mt. Collins row under App Attest prose.

The Mt. Collins reason is unchanged and still contains no copied floor reading: no run ID, CPU/wall/eval-step measurement or threshold. “About twenty-two blocks” is a structural property of the production encoding and SHA-256 workload, not an admission reading; live cost remains authoritative at the enrolment gate. The run/artifact citation remains outside the reason, in the drop measurement authority.

Eval-step-drop root account

The header of floor_eval_step_cost_drop.dag now names all seven independently declared lists and each corresponding gunbc.rung_drop declaration:

  1. roadmap live projection;
  2. live-deploy apply render;
  3. roadmap live forecast;
  4. roadmap page style;
  5. App Attest interpreted crypto;
  6. SHA-256 span program;
  7. Mt. Collins standing-ruling digest.

It carries no population counts or cost figures, and it preserves the governing rule that growing one drop’s list is a new drop rather than an amendment of another incident.

Delta and evidence disposition

The delta from held head 545fc9022b74af4b2bd71860245bce14e340fa98 is one commit, two authority files, +41/-17. The list split is semantically equivalent to the former combined literal; no witness, grant, boot, WIF, hold, crypto or cost-policy behavior moved. The regenerated design-rung-drops.md is absent from the delta, consistent with byte-identical output after the authority organization change.

I accept the reported roster runs on the clean tree. At review time clippy is green; compiler, floor and emit-build are still running. Land only after the exact-head required floor and other required checks complete green.

No further source finding remains from review 5290889114.

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 23, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 23, 2026
gunbc-ci-auto-heal and others added 3 commits September 23, 2026 17:08
…checks, run 35875508867)

- privileged_effect_census: #12124's approval-broker helper-grant row gains witness_discharge:
  NoWitnessDischarge. Derived: the effect is reversible, resource-scoped and unbilled, so it owes no
  witness, and no standing ruling covers it.
- bmc_wif_delegation_chain_witness_test (main's): the file carried no imports, so SecretAccessGrant
  resolved ambiguously between gunbc.auth.secret_access_grant and gunbc.auth.gcp_secret_access. It now
  names its imports, and list heads are matched as optionals rather than passed where a value is
  declared. Each claim's meaning is unchanged.
- fleet-converge.yml and docs/design-rung-drops.md regenerated from the merged authority.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#12011 landed its own job-edge roster (fleet_converge_job_edges / fleet_converge_job_needs(id:) /
fleet_converge_jobs()), answering the question this branch's FleetConvergeJobKind roster answered.
Main's landed first, so it is the one authority: the kind roster is deleted, mtcollins1-boot is a row
of main's edge roster and a member of fleet_converge_jobs(), and every builder keeps main's id/needs
form. workflow_dispatch witness takes main's claims plus the mtcollins1-boot job id.
mtcollins1_boot_run takes #12125's uses cut. microvm-controller-install gains environment: none.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ot federation's provisioner into its own module

The workflow emission reads the mtcollins1 boot federation's facts (provider resource, service
account, environment); it must not depend on the out-of-band provisioner. It did, because the
provisioning binding lived in gunbc.auth.mtcollins1_boot_federation, which pulled
gunbc.auth.heal_publisher_provision into gunbc.fleet_converge_workflow's closure. With that module in a
closure, artifact_path(a: FleetConvergeYamlArtifact) fails with NoSuchVariable (main's own
heal_publisher_provision reproduces it; minimal repro in the PR notes). The binding moves to
gunbc.auth.mtcollins1_boot_federation_provision; the census site and the grant administrator's command
follow it. fleet-converge.yml and design-rung-drops.md regenerated.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ommitted .orig merge backup (review 70723)

- rung_drop roster: both sides added a drop; both kept. docs/design-rung-drops.md regenerated.
- dag/gunbc/fleet/fleet_converge_workflow.dag.orig was a patch --merge backup committed by mistake: a
  stale second copy of the module under the dag source root, read by nothing. Deleted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

Review 70723 addressed at e642cc7: dag/gunbc/fleet/fleet_converge_workflow.dag.orig was a patch --merge backup that I committed by mistake while re-applying this branch's workflow changes onto main's job-edge roster. It is deleted, and the tree at e642cc7 carries no .orig or .rej file. — sent from proud-dove-705

gunbc-ci-auto-heal and others added 2 commits September 24, 2026 02:52
No conflicts. Generated artifacts regenerated from the merged authority (byte-identical).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
fleet-converge.yml regenerated from the merged authority (the only conflict).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

APPROVE-MERGE at exact head 6514b685fa79e3edffb97ed876ef1f79af6e2008, superseding my prior verdict at 3c7c346059d29c6101fb53830cef81e055154876.

The delta rebind is sound.

  1. Current-main integration is clean. The final head merges main@8197ed5cae4a2fafb75177b7265a73c3701a0e49; the only final merge conflict was the generated fleet-converge.yml, which was regenerated from the merged authority rather than hand-resolved.

  2. #12011's job-edge roster is now the one authority. The branch-local FleetConvergeJobKind vocabulary is gone. fleet_converge_job_edges carries mtcollins1-boot -> build, fleet_converge_job_needs(id:) supplies each builder, and fleet_converge_jobs() carries the corresponding job. The workflow-dispatch witness reads that same edge roster, pins the exact eight-job population, and requires every non-build job to depend on build. No parallel job-membership or dependency authority remains.

  3. The provisioner split is the correct layering. gunbc.auth.mtcollins1_boot_federation now owns only the workload-identity facts consumed by workflow emission: the dedicated pool/provider identity, claim pins and CEL projection, service account, environment, principal set and two version-pinned secret grants. gunbc.auth.mtcollins1_boot_federation_provision separately imports the generic DedicatedFederation provisioner and exposes the grant-administrator entry. The privileged-effect census and documented operator command follow that provisioner entry. This matches the existing heal federation/provision boundary and remains correct after the interpreter defect is repaired; it is not a workaround that should later be collapsed.

  4. The emitted job still preserves the previously approved walls. The build selects github.sha first for mtcollins1_boot; the privileged job checks out only github.sha, runs only on literal srv1 labels, requires host == srv1 before the job starts, uses the mtcollins1-boot environment and gunbc-host-mutation-srv1 concurrency domain, waits for build, and exchanges OIDC through the dedicated provider and service account.

  5. Landing evidence is complete. Compiler, clippy, emit-build, floor and witnesses all pass at this exact SHA, and GitHub reports CLEAN/mergeable.

The separately dispatched artifact_path(FleetConvergeYamlArtifact) / heal_publisher_provision interpreter defect remains an activation constraint, not a source or merge blocker here: this PR does not hide it or widen access when it fires, and the out-of-band IAM path fails before provisioning. Fix that defect before executing the one-time IAM provisioning. File the durable standing ruling only after this exact source has landed and the dedicated federation has been provisioned.

No further merge condition remains unless the head moves.

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 24, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Sep 24, 2026
gunbc-ci-auto-heal and others added 5 commits September 24, 2026 11:53
…s SDR cache into the hold path

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nesses read each producer at its own interface

The mtcollins1-boot job's runner and steps are their own producers, and the steps composition
takes the two rendered credential scripts as parameters. The composition claims supply them; the
boot-step and fleet-key-step claims read those producers alone. Floor run 35995750399 refused three
claims that rendered the whole job (about 72k eval steps each) over the enrolment margin.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…esign-rung-drops.md

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…pping the job (review 70894)

A job-level host term skipped the boot job for mode=mtcollins1_boot host!=srv1, and with the shared
job gated off by mode the run reported success with no refusal (DESIGN section 5). The job condition
now reads only the mode; the job still starts only on srv1's runner (labels and concurrency never read
the input), and a credential-free admission step before WIF auth, mtcollins1_boot_admit_executor,
refuses the host with a typed reason. It runs the same fold (mtcollins1_boot_host_admission) the wet
entry re-runs, following the pair-serving D0 admission. The backstop timeout counts the new aux step.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Regenerate fleet-converge.yml and design-rung-drops.md from the merged authorities. The shakedown job
from #12178 carries Job.environment (none), which this branch adds to extdeps.github.actions Job.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls added this pull request to the merge queue Sep 24, 2026
Merged via the queue into main with commit cfb9ff8 Sep 24, 2026
5 checks passed
@briansrls
briansrls deleted the session/proud-dove-705 branch September 24, 2026 20:04
@briansrls
briansrls restored the session/proud-dove-705 branch September 24, 2026 20:37
gunbai-bot Bot pushed a commit that referenced this pull request Sep 24, 2026
…h pattern selection)

Co-Authored-By: Claude Opus 5.5 (1M context) <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