Repository navigation
Managed-host cut 5 (re-derived): fan and KVM observations over ManagedHost - #13689
Merged
Merged
Conversation
Move the BMC-stack observation bodies off the mtcollins1 procedure root onto ManagedHost (fan, family-selected) and AdmittedMegaRacHost (KVM). Keep the fleet-converge entries as thin unit bindings. Do not restore served-UI: that AMI-bundle-derived path left public gunbc in f956099. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
Author
|
Required gate receipt on this head (
Dashboard review 78449 (cursor, dashboard-only) approved this head; no REQUEST_CHANGES. Operator lands; this lane does not merge. |
This was referenced Oct 13, 2026
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Oct 15, 2026
…nericized on explicit subject + executor params Subject/medium/attempt/receipts become explicit parameters; the mtcollins1_ measured readings stay as mtcollins1_ receipt rows. Executor side keyed by executor host per #13416. census_boot_medium computes artifact identity only. DONE: the 5 census modules' procedure roots genericized (census_image, census_image_publish, census_medium_readback, census_member_readback); the mtcollins1_ receipt rows retained; discriminating controls wired (a mismatched medium-vs-image binding refuses at census_medium_qualification before any effect). NOT DONE: 14 consumer files (ci_spec, fleet_converge_workflow, mtcollins1_boot_run, runner_throughput_qualification_route, 10 witness tests) still reference the old names and must be re-pointed at the genericized roots + new param surfaces; the type-check (remote gunbc loop) has not been run on the whole tree; terminal receipt (witness runs + red-same-path + corpus sweep) outstanding. Refs: managed-host-untangle cut 4b-ii; precedents #13248 (4a), #13416 (4b-i), #13261 (3), #13689 (5).
gunbai-bot Bot
added a commit
that referenced
this pull request
Oct 16, 2026
…s genericized (#14065) * Managed-host cut 4b-ii (WIP): census image/medium/member readbacks genericized on explicit subject + executor params Subject/medium/attempt/receipts become explicit parameters; the mtcollins1_ measured readings stay as mtcollins1_ receipt rows. Executor side keyed by executor host per #13416. census_boot_medium computes artifact identity only. DONE: the 5 census modules' procedure roots genericized (census_image, census_image_publish, census_medium_readback, census_member_readback); the mtcollins1_ receipt rows retained; discriminating controls wired (a mismatched medium-vs-image binding refuses at census_medium_qualification before any effect). NOT DONE: 14 consumer files (ci_spec, fleet_converge_workflow, mtcollins1_boot_run, runner_throughput_qualification_route, 10 witness tests) still reference the old names and must be re-pointed at the genericized roots + new param surfaces; the type-check (remote gunbc loop) has not been run on the whole tree; terminal receipt (witness runs + red-same-path + corpus sweep) outstanding. Refs: managed-host-untangle cut 4b-ii; precedents #13248 (4a), #13416 (4b-i), #13261 (3), #13689 (5). * census: re-point consumers to the genericized mtcollins1_census_* params - census_capture_program(machine, console_device, halt_command, stages) - census_seeded_image_input(image_stem, volume_id, user_data_body, grub_kernel_cmdline, nocloud_dir, program_file, program_content) - census_medium_readback(medium, image); census_medium_readback_from_answers(+image) - census_member_readback(medium, image_stem, volume_id); census_pin_gate(+image_stem, volume_id); census_member_readback_from_readings(+image_stem, volume_id) - mtcollins1_boot_run passes mtcollins1_census_image to the two readback gates * census member readback wet entry: restore mtcollins1_ receipt name The wet entry is the mtcollins1 RECEIPT producer (reads mtcollins1_boot_medium, mtcollins1_census_image_stem, mtcollins1_census_volume_id; writes the mtcollins1 receipt path) -- not a generic derivation root. Keep the mtcollins1_ prefix for consistency with mtcollins1_census_image_publish_wet and with the fleet-converge.yml:1250 + ci_spec.dag:1093 consumers (the .yml consumer is outside the required v2-bootstrap gate). * census medium readback: restore module declaration to the file's rule position gunbc requires module name = file path (the rule position). The genericization this cut applies to the FUNCTIONS (census_*), not the module/file: the plan defers module naming until after cuts 2-6 expose the axes, and the scope adjustment only removes mtcollins1 constants + makes params explicit. Restoring the declaration so the file path and module name agree again. * census readback: executor+subject params and two executed discriminating controls Addresses review 80603 (REQUEST_CHANGES) + manager msg 3fb13889: - census_readback_refusal + before_filing/before_attach take (subject, host) params; the refusal text now names the SUBJECT and the EXECUTOR that took the leg, not one baked-in host (DESIGN 3 meaning fork, DESIGN 5 no fabricated output). - census_medium_readback takes (medium, image, host, attempt): the recorded host and the SSH attempt identity are parameters, not the srv2 / mtcollins1 constants; boot_run + the witness thread the mtcollins1 labels. - Two EXECUTED discriminating-control test fns on a constructed second subject (supplied values, not mtcollins1's rows): control_a a non-mtcollins1 subject derives its own image+medium plan (own stem/digest, distinct build key); control_b a medium whose stem does not match its image refuses at census_medium_qualification before any leg. - Each control was run RED once against a deliberately broken variant (a derivation that ignores the supplied stem; a gate with the stem check dropped): both DID-NOT-HOLD outcome=Fail, while the controls themselves HELD. Scratch reds removed; only the two green controls are committed. Verified on the remote runner (gunbc @ da13ad3 + this diff, 28GiB cgroup, 24GiB budget): //test/claim/machine_intake/mtcollins1_census_medium_readback_witness:all = 19 held, 0 did not hold (control_a + control_b both HELD). * machine_intake: parameterize the pinned-image expected digest in census_regression_on Close the meaning fork in census_regression_on (review 80729): the generic subject input (pinned_image) was judged against mtcollins1's hardcoded expected digest, so a non-mtcollins1 pinned image would be judged against the wrong digest. The expected digest is now an explicit parameter, and the mtcollins1 wet entry passes its own mtcollins1_census_hermetic_pinned_rebuild_digest. The generic function now takes only its subject and the expected digest, keeping the mtcollins1-specific fact (the pinned rebuild digest) as the caller's receipt row. * census image: the seed's early command and seed file cannot disagree Close the silent medium review 80811 names (DESIGN §5: correctness by construction, not validation; §4b: silent wrongness is not a rung). census_image_derivation took live_commands and nocloud_dir/program_file as independent parameters. The user-data's early command (where the installer runs the program from) came from live_commands; the seed file (where the program actually rides) came from nocloud_dir/program_file. Those could disagree and still yield CensusImageDerived -- a runnable image whose autoinstall invokes a path that is not the seeded program. On main that mismatch was unwritable: derivation always used mtcollins1_census_live_commands, which closed over the same module constants as the seeded input. The early command is now BUILT inside the derivation from the seed's location (census_program_on_medium(nocloud_dir, program_file)), so the command the installer runs and the file the seed carries are one fact, not two parameters a caller can cross. A path mismatch is unwritable, not a validation. mtcollins1_census_live_commands is kept as the measured receipt row (the payload the derivation builds for mt. collins' seed dir and program file); it no longer feeds the derivation. * census readback: the refusal names the host that ran the leg, from the receipt Close review 80825 (DESIGN 5: correctness by construction, not validation; no plausible output is fabricated). census_readback_refusal took its own host parameter, untied from the readback's. Only CensusMediumReadbackAgreed recorded which host it ran on; the two unreadable variants the renderer prints a host for -- CensusMediumReadbackRecordUnreadable and CensusMediumReadbackImageUnreadable -- did not, so the renderer printed whatever host the caller handed it. A caller that passes different hosts to the two functions gets a refusal blaming a host that never ran the leg; the "no fabricated output" comment above the renderer was prose the code did not enforce. The executor host is now stored in the two unreadable readback variants, populated at construction (census_record_standing / census_measure_join / the producer's refused SSH-context arm), where the producer's host is the single source that also names the executor the leg ran on. census_readback_refusal and its before_filing / before_attach wrappers take the host from the receipt, not as a second input a caller can cross -- one fact, not two parameters. census_record_standing takes the host so the record-stage refusal names the same executor the measure stage would. Witnesses re-pointed: the refusal checks now exercise the host recorded in the receipt. * control (a): route the second subject through the real census_image_derivation Close review 80832 (DESIGN 5: done means a real consumer green by execution plus a discriminating input that goes red when the behavior is wrong; DESIGN 3 pairing: assert the route, not only the answer). control_a claimed a non-mtcollins1 subject "derives" its own image, but second_subject_image hand-built CensusImageDerived via census_seeded_image_input and never called census_image_derivation. A derivation that ignored image_stem (or the other subject params) and always used the mtcollins1 constants would have left the control green -- it tested a re-derivation of the same input, not the genericized derivation it claimed to prove. The second subject's image is now the REAL census_image_derivation applied to its own facts (its stem and volume id name the artifact; the envelope and seed location are the shared census shape). The control asserts the derived input carries the second stem (not mtcollins1's), its own image name, and a build key distinct from mtcollins1's -- so a derivation that ignored the subject's stem goes RED here. * census image: the seed's early commands have one author Close review 80838 (DESIGN 2/3: authored duplication is a meaning fork; minimization holds only if each fact lives in exactly one place). The 80811 fix built the user-data payload from (nocloud_dir, program_file) inside census_image_derivation so the early command and seed file cannot cross, but it left an independently authored twin with the same UbuntuAutoinstallLiveCommands shape at the mtcollins1_census_live_commands receipt row. Two sources that can drift; the inhabitance witness only detected disagreement after the fact. census_live_commands(nocloud_dir, program_file) is now the single helper that builds the payload, consumed by both the derivation and the receipt row, so the early-command fact stays single-authority and the two cannot drift. * census readback: the receipt's host is derived from the leg's target Close review 80844 (DESIGN 5: no plausible output is fabricated; DESIGN 3: a materially different contract needs a materially different name). census_medium_readback took a free host parameter and stamped it into the receipt and the unreadable arms, while the legs actually ran on export.target. A caller could pass a host the producer never contacted and get a refusal naming that host -- contradicting the module's own contract that the receipt names the host that actually took the leg, one fact, not two inputs a caller can cross. The effectful producer no longer takes host: it derives it from the qualified medium's own exporter target address (known_hosts_host_field(export.target.address)), which is the SSH target the legs run on. The receipt and the unreadable arms now name the host the leg actually ran on -- it cannot name a different one. The host parameter stays only on the supplied-answers fold (census_medium_readback_from_answers), where it is a witness boundary value the witness supplies and asserts. Producer call sites (boot_run, witness) re-pointed. * census readback: control (c) -- the refusal names the subject and the host its receipt recorded Close review 80853 (DESIGN 5: done means a real consumer green by execution plus a discriminating input that goes red when the behavior is wrong). The refusal subject/host parameterization (the answer to baked-in mtcollins1/srv2 naming) had no discriminating control: every refusal claim called with mtcollins1_census_machine and never asserted that the second subject's label -- or a non-srv2 receipt host -- appears in the rendered text. A renderer that ignored its subject parameter and hardcoded mtcollins1, or ignored the receipt host and hardcoded srv2, would have stayed green. control_c is the discriminating control: a not-census refusal for the second subject names that subject (and not mtcollins1), and a record-unreadable refusal with a non-srv2 receipt host renders that host (and not srv2) -- so the text names the subject it was given and the host its receipt recorded. It is pure (renders a constructed readback), so a renderer that drops the parameters goes RED here. * census image / boot_run: cite the symbol, drop the unused import Close review 80870. - census_image.dag: the census_live_commands comment cited "the derivation (line 219)" -- a positional pointer that any edit above the line silently invalidates (DESIGN 3: cite the symbol, not the position). Replaced with the symbol census_image_derivation. - mtcollins1_boot_run.dag: the import line added operator_host_srv2, but nothing in the file uses it (grep -c returns 1, the import itself). Left over from moving the executor host into the readback receipt, where the host is now derived from the export target. Removed the unused import. * machine_intake: census_member_readback takes the attempt identity as an input Side-chat HOLD on #14065 (b220363): the generic census_member_readback and census_member_mapped_attributes called prepare_fleet_ssh_agent_context under the captured mtcollins1 row (census_member_readback_attempt_raw) and owned a mtcollins1-named scratch prefix. The fleet-SSH attempt identity owns the paths that materialize the public selector and the verified known_hosts anchor, so a second or concurrent subject would have run under mtcollins1's attempt identity: two subjects alias one attempt-owned materialization, and a receipt cannot say whose attempt prepared the SSH context. The medium readback already takes its attempt; the member readback did not. DESIGN §3/§5: one fact, not two inputs a caller can cross, and no fabricated receipt. - census_member_readback and census_member_mapped_attributes take `attempt: NonEmptyStr` and prepare their context under it. - The scratch prefix is a fact OF the attempt: census_member_workspace_prefix_of / _template_of derive it, replacing the two mtcollins1 prefix data rows (deleted). - CensusMemberReadbackAttempt now carries `attempt`, and the receipt renders it, so a receipt names the attempt whose context it answers for. census_member_attempt_of, render_workspace_outcome and render_census_member_attempt thread it. - The mtcollins1 wet wrapper supplies census_member_readback_attempt_raw, and the mtcollins1 receipt output path stays there. Witness controls (each demonstrated RED once against a broken variant, see PR): - a_second_subject_attempt_owns_its_receipt_and_its_namespace: a second subject under its own attempt stores that attempt, admits its own disjoint namespace, and renders neither mtcollins1's attempt identity nor mtcollins1's namespace. - an_unsafe_attempt_identity_refuses_at_admission_before_any_agent_or_remote_work: the producer admits the caller's attempt before the agent; a non-safe-segment identity refuses with admission's own words and requests no workspace, and the report entry refuses the same way. member witness: 21 claim(s), 21 held, 0 did not hold. --------- Co-authored-by: Brian Searls <briansearls1@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ManagedHost, KVM observer is MegaRAC-scoped overAdmittedMegaRacHost.gunbc.fleet_fan_converge_routes fan_observation_authority_for_family(same peripheral family dispatch as the existing converge routes). A host whose BMC family was never observed refusesFanHostFamilyUnobservedand is never defaulted to either policy.ManagedHostFoundUnderDeclaredDropis matched, not dropped (currentManagedHostLookup).mtcollins1_fan_observeandmtcollins1_kvm_observer_observestay as thin unit bindings (workflow surface is cut 7). Credential source is unchanged (GUNBC_MTCOLLINS1_BMC_CREDENTIAL_FILE).MegaRacServedUiRead/megarac_ui_bundle_observe. Public gunbc deleted AMI-bundle-derived content inf956099fcbe(moved to gunbc-private). Restoring it would re-introduce that content.Conformance
gunbc.machine_intake_fan_observe,gunbc.machine_intake_megarac_kvm_observer_observe); noUnobservedauthored in an upstream module.admit_callersnow name the generic probe (megarac_kvm_observer_observe/megarac_kvm_observer_release).Test plan
claim_batchdag/test/claim/machine_intake/fan_observe_witness_test.dag— 4/4 PASS, exit 0 (seedclaim_batchbuilt from this branch,CTRL_BUILD_MODE=local,CARGO_TARGET_DIR=/tmp/cargo-target-still-swift-683)claim_batchdag/test/claim/machine_intake/megarac_kvm_observer_observe_witness_test.dag— 14/14 PASS, exit 0claim_batchdag/test/claim/machine_intake/bmc_stack_observation_forged_probe_witness_test.dag— 4/4 PASS, exit 0 (sole-constructor + outside-caller seals; no served-UI probe)witnessesjob on this PRmtcollins1_fan_observe/mtcollins1_kvm_observer_observeon srv1; no fleet-converge dispatch from this PRMade with Cursor