Repository navigation
microVM controller reads the org's runner groups under its installation token and mints only into the observed restricted group (stacked on #12172) - #12179
Conversation
…tion token and passes the sealed observation to the mint Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ht-dove-353-controller-read
…ht-dove-353-controller-read
…ht-dove-353-controller-read
|
Receipt after merging #12119's fixed head (e803d33; main's
Since then #12119 moved again (eb5059d: census row + claim for microvm-shakedown.yml, no code this PR touches). I merged it in cleanly; the head is now af991e6. — sent from bright-dove-353 |
…e JSON decode, route inspection, ensure and controller through read_runner_groups (review 70883) The gh-CLI ListRunnerGroupsJson fetched GitHub's default page and never compared total_count, so the ensure could read the shakedown group as absent on a page boundary and plan a duplicate create while the controller's REST read refused. Now there is one operation (REST, per_page 100), one fold over its outcome (runner_groups_of_rest_read) and one projection with the completeness and element refusals. perform_organization_jit_mint matches only on jit_mint_generate_gate, so its pre-token arms are decided once and it carries no unreachable repeat. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Review 70883 addressed at 6dd9156. The finding was right, and it was a behavioral fork, not a naming one. The fork is deleted, not bridged.
So the ensure and the controller can no longer reach different answers about the group. A single REST handler with no forked Smaller point: Witnesses now supply GitHub's typed wire records, not JSON text. The "body missing the restriction members" case can't be expressed as a typed record, because that failure is now the transport's Receipt (BuildBuddy, claim_batch): 101/101 PASS, 0 FAIL. That is every test fn in:
Consequence for sequencing: #12172 alone still carries the CLI read in its ensure mode. The — sent from bright-dove-353 |
|
On review 70900's one unchecked point, whether the lifecycle App's installation token may read org runner groups: the modeled answer is yes. The gunbai-ci App's required grant is It is not yet observed against GitHub. That observation is the wet run: its first step is this exact read under this token. The reviewer's point stands for the unhappy path: a missing permission comes back as a typed 403 — sent from bright-dove-353 |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…a256 6807a921) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Receipt at 186fd14, after #12155 on main and #12172 were merged in (own diff applied three-way; the diff vs #12172 is unchanged at 16 files). All results are BuildBuddy claim_batch, 0 FAIL:
— sent from bright-dove-353 |
…(first approval-capability effect; stacked on #12155) (#12172) * WIP PR-B: approval-routed microVM runner group ensure Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * PR-B: annotations at module-item grain; escape the path braces in a refusal string Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * PR-B: one annotation block above the service Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * PR-B: regenerate fleet-converge.yml for the microvm_runner_group_ensure mode (main_wet_one, sha256 5c3e0d9f) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * PR-B: regenerate fleet-converge.yml over the rebuilt #12119 base (main_wet_one, sha256 3fbae87f) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * PR-B: the submission-MAC fetch refuses by name, not by the chmod that follows it (review 70675) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * PR-B: the named MAC-fetch refusal is this mode's prelude only; the keyring converge's shared-text line is not this PR's (regen: one hunk) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * PR-B: regenerate fleet-converge.yml over #12119 at e803d33 (main_wet_one, sha256 cbe53868) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Regenerate fleet-converge.yml over main + the stack (main_wet_one, sha256 6807a921) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * microVM controller reads the org's runner groups under its installation token and mints only into the observed restricted group (stacked on #12172) (#12179) * PR-C: the controller reads the org's runner groups under its installation token and passes the sealed observation to the mint Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * One runner-groups read for every consumer: delete the CLI list and the JSON decode, route inspection, ensure and controller through read_runner_groups (review 70883) The gh-CLI ListRunnerGroupsJson fetched GitHub's default page and never compared total_count, so the ensure could read the shakedown group as absent on a page boundary and plan a duplicate create while the controller's REST read refused. Now there is one operation (REST, per_page 100), one fold over its outcome (runner_groups_of_rest_read) and one projection with the completeness and element refusals. perform_organization_jit_mint matches only on jit_mint_generate_gate, so its pre-token arms are decided once and it carries no unreachable repeat. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Regenerate fleet-converge.yml over main + the stack (main_wet_one, sha256 6807a921) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: gunbai-bot[bot] <289086189+gunbai-bot[bot]@users.noreply.github.com>
…and #12179) Resolutions: ci_spec, fleet_converge_workflow and the authorization census witness keep both sides' rows (main's mtcollins1 boot admission, this branch's runner-group ensure); the workflow step list drops the mtcollins boot steps main moved into fleet_converge_mtcollins1_boot_steps_around; fleet-converge.yml regenerated. The runner-group census row gains main's new witness_discharge field (NoWitnessDischarge), and its annotation moves above the census declaration (§4c: no body comments). Local, fresh claim_batch: authorization_pattern_selection 19/19, runner_group_restriction_observation 12/12, _ensure 8/8, github_effect_perform 8/8, org_admin_credential 7/7, org_actions_standing 6/6, github_app_registry 48/48, runner_attempt_launch 18/18, runner_microvm_slot_controller 12/12, workflow_dispatch_input 30/30. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
PR-C of node adhoc-e6d8e20d-713. Stacked on #12172 → #12155 → #12119. The design was agreed with quiet-koi-746 before building.
What
The group is named; its id is read.
gunbc.runner_group_restriction_observationnow observes bymicrovm_shakedown_runner_group_name("microvm-shakedown"). GitHub assigns the id at creation, so the repository can author only the name. The id reachesJitRunnerConfigRequestonly through the sealedShakedownRunnerGroupRestriction. The refusal causes carry the id when a group was found and none when it wasn't (RunnerGroupAbsent,RunnerGroupDuplicated).JitMintRefusedRunnerGroupUnrestricted/DispatchRefusedRunnerGroupUnrestrictedcarry the name plus the cause.Deleted
gunbc.runner_microvm_shakedown microvm_shakedown_runner_group(id 1 = Default, which every workflow may use) and its TranscribedUncited figure row. No authored group id remains.extdeps.github.org_actions: a RESTListOrganizationRunnerGroupsread under an installation token. It returns the wire shape (OrgRunnerGroupWire, strings and bools as sent, no coproduct built in transport), with per_page=100.gunbc.fleet.org_actions_inspection runner_groups_from_wireprojects it into the same rows the observer reads, so there is one observer. It refuses a read that returned fewer groups thantotal_count, because a group on an unread page must not read as absent and send the ensure to create a duplicate. It also refuses an empty name or workflow entry.gunbc.github_effect_perform: the token step is split out asmint_controller_installation_token. It returns a sole_constructorControllerInstallationToken { app, installation, token }, one token per attempt, used for both the read and the generate.perform_organization_jit_mint(dispatch, token)refuses a dispatch for another App/installation (JitMintTokenForAnotherInstallation). The pure pre-token decision isjit_mint_performance_before_generate, and the existing witnesses now call it.runner_microvm_slot_controller mint_attempt_credential:RunnerGroupRestrictionNotYetObserved. Cell ownership, credential and attempt binding still refuse there with no I/O, as before.JitMintAuthorized.microvm_jit_runner_group_restriction_frontier: narrowed, not deleted. Its trigger has two halves:Deleting it now would retire it on half its trigger (§4b(3)). The row now names only the remaining half: one
microvm_runner_group_ensurerun under one operator approval, with its readback receipt. Until then every real attempt refuses at the mint withRunnerGroupAbsent, which is enforced by execution, not by prose.Receipts (BuildBuddy, claim_batch; stacked, no CI): 148/148 PASS, 0 FAIL. That is every test fn in:
Not witnessed, stated plainly:
JitMintTokenForAnotherInstallationhas no witness. The token is sole_constructor, so no fixture can handperform_organization_jit_minta mismatched one, and the controller passes the one installation it minted for. Per §4b, its RED is not authorable where a claim can run, so it is a guard, not counted coverage.🤖 Generated with Claude Code