Skip to content

microVM guest runner bootstrap - #11671

Merged
briansrls merged 14 commits into
mainfrom
session/merry-bee-648
Sep 19, 2026
Merged

briansrls merged 14 commits into
mainfrom
session/merry-bee-648

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

Auto-opened by session-dashboard for session merry-bee-648.
Pushing to session/merry-bee-648 advances this PR.

Worker attestation

Before flipping this PR to ready for review, confirm each item:

  • Title describes the change (not the session id or branch).
  • PR body summarises what and why (replace the TODO below).
  • Tests run: name the command (e.g. npm test, cargo test) and the result.
  • If this closes a work item, the body contains a Closes #N directive.
  • No commits on this branch are surprises (no fork/cherry-pick I did not make).
  • No secrets / credentials / large binaries staged.

Summary

TODO: replace this paragraph with one or two sentences naming the change and its motivation. Reviewers read this first.

Test plan

  • TODO: list the commands that ran (or "no tests changed; relied on CI") and the outcome.

Brian Searls and others added 3 commits September 19, 2026 01:50
…drive contract, serial guest observations, manager-owned poweroff

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…m coproduct resolved as an alias

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…st mint and staging

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 19, 2026 03:33
…nsole reader consumed by the boot probe, RunnerListening has no emitter

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68146 in 2873dda:

  1. Sector size as bare Int. Removed jit_drive_sector_bytes. The drive content is now measured in UTF-8 bytes (jit_drive_utf8_size, via std.bytes) against a ByteSize, not as a character count.
  2. Upstream fact in the product layer. Added extdeps.virtualization.firecracker firecracker_block_sector_size, cited to firecracker v1.16.1 (SECTOR_SIZE = 1 << SECTOR_SHIFT in virtio/block/virtio/mod.rs; "the tail bits are not exposed" in device.rs). gunbc.runner_microvm consumes it.
  3. Reader with no consumer. Added guest_console_observations / guest_console_carries. runner_microvm_boot_probe now judges live boots through guest_agent_boot_verdict, which requires the agent's GuestBooted marker via that reader (new arm BootConsoleLacksGuestBooted). It is a layer over boot_probe_verdict, not inside it, because runner_observed_version_check runs that verdict over the committed Mt. Collins capture, which predates the marker. New witness: a_live_boot_requires_the_agents_guest_booted_marker. I also removed the annotation's claim that a host already joins the attempt tuple. It now says that is the lifecycle controller's job, and that the controller is not built yet.
  4. RunnerListening emittable. Split the kinds. The emitter takes GuestEmittedEvent = GuestBooted | RunnerStarted | RunnerExited. GuestObservationKind = GuestEmitted { event } | RunnerListening is what the reader returns, so guest_observation_emit_command(event: RunnerListening, ..) has no constructor.
  5. Four Bool predicates. Deleted. The witness now compares guest_observation_kind_label over the whole folded console, in order, using the emitter's own line builder.

— sent from merry-bee-648

… row; drop the unconsumed return-code row

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68174 in 8b221c9:

  1. Nickname of the jitconfig argument. actions_runner_jitconfig_env_name now derives from the cited row: concat(actions_runner_input_env_prefix, actions_runner_jitconfig_argument). Upstream compares both the prefix and the argument name with StringComparison.OrdinalIgnoreCase (CommandSettings.cs v2.337.0), so ACTIONS_RUNNER_INPUT_jitconfig is read exactly as the uppercased form would be. I did not add a second, uppercased spelling. The drive-content witness now asserts the derived name.
  2. Unconsumed return-code row. Deleted actions_runner_retryable_error_return_code. The reasoning stays in the annotation, which now says why no row is declared.

— sent from merry-bee-648

…racker_block_sector_size

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68195 in bab7700. the_credential_drive_is_whole_sectors_of_one_assignment now takes the sector from byte_size_count(b: firecracker_block_sector_size) instead of a literal 512. It also asserts that jit_drive_newline_sector() is exactly one sector long, so the annotation on that function now describes a check that actually runs, and a change to the cited sector size reds the witness if the padding source does not follow it.

— sent from merry-bee-648

…xtdeps variant

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68215 in 4d4e4cb. Added ExecStopPostIgnoringFailure { command } to extdeps.systemd.unit_file SystemdServiceDirective, serialized as ExecStopPost=-. It is the same shape as the existing EnvironmentFileIfPresent: a second variant, not a flag. The guest agent uses it, and the hand-spelled "-" in guest_runner_exited_emit_command is gone. The rendered unit is unchanged, so the_credential_arrives_by_environment_file_and_every_program_is_absolute still asserts ExecStopPost=-/usr/bin/echo ... runner-exited.

gunbc.spark.pair_serving_realization tolerated_exec_line is the same concept on a different, unrelated surface. I left it untouched here rather than migrate a serving module inside a guest-bootstrap PR. It is a candidate for its own consolidation onto these variants.

— sent from merry-bee-648

… real drive order

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68234 in de16687.

  • Added extdeps.virtualization.firecracker firecracker_drive_guest_device(drives, drive_id) -> String?. It maps a drive's position in drives to its virtio-blk guest name (vda, vdb, ...). The mapping is cited to Firecracker attaching drives in configuration order and to Linux virtio_blk's naming. It is also observed on this fleet's aarch64 hardware: the Mt. Collins run booted root=/dev/vda and read its credential off /dev/vdb. An unattached drive, or one past the 26th, gets no name rather than a guessed one.
  • New witness the_credential_device_is_where_the_vm_config_puts_the_credential_drive applies it to the real runner_microvm_vm_config, both bare and after attach_workspace_drive, and requires the result to equal jit_drive_guest_device. Prepending or reordering a drive now reds instead of silently pointing the tolerant EnvironmentFile=- at the rootfs. Controls: the root drive maps to /dev/vda, and an unattached id maps to nothing.

Stated honestly in the annotation: this reaches rung 2 (a witness), not structural derivation. The unit is rendered with no drive list in hand, and deriving inside it would need a fabricated device name for the no-drive case, which I would not accept. Moving the unit to render from the attempt's configuration belongs with the lifecycle controller that will hold that configuration.

— sent from merry-bee-648

Brian Searls and others added 2 commits September 19, 2026 07:12
…tch before the record literal

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…osed action set as a coproduct

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68281 in a5385f4. SuccessAction and FailureAction now carry SystemdUnitStateAction, a coproduct of systemd.unit(5)'s full closed set. That is 17 arms: none plus the reboot, poweroff, exit, soft-reboot, kexec and halt families with their -force/-immediate strengths. It is rendered by systemd_unit_state_action_wire, the same shape as SystemdExitType and SystemdKillMode in this module. The guest agent's end action is UnitActionPoweroffForce, so a misspelled action no longer has a constructor. Modeling the whole upstream set also avoids the one-arm-coproduct-as-alias resolution I hit earlier. None of the new constructor names collide anywhere else in the corpus.

— sent from merry-bee-648

Brian Searls and others added 2 commits September 19, 2026 08:19
…nce builder; .dag read them as interpolation

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ne drive list; fix witness brace interpolation

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68308 in 5dcfb4e. You were right that this was authorship, not a ceiling.

  • runner_microvm_drives is now the one drive list, and runner_microvm_vm_config attaches it.
  • The /dev/vdb literal is deleted. jit_drive_guest_device() now returns a JitDriveDeviceResolution (JitDriveDevice { device } | JitDriveNotAttached { cause }), derived by firecracker_drive_guest_device over that list.
  • runner_guest_agent_unit(image, credential_device) renders EnvironmentFile=- from the argument. The image build resolves the device first and refuses with exit_failure if the drive is not attached, rather than rendering a guessed device.
  • The witness oracle is now the hardware observation (/dev/vdb, as the Mt. Collins guest read it), not a copy of a production row. It checks the resolution, the rendered unit, and the real config before and after attach_workspace_drive. Prepending a drive now moves the derived name and reds that pin.

Same commit: the previous head's floor refused on my witness string "{EXIT_CODE}". .dag interpolates {IDENT} inside string literals, not only ${IDENT}. The witness now joins the brace, name and brace as separate pieces, as extdeps.systemd.unit_file systemd_environment_reference already does.

— sent from merry-bee-648

…d sentinel

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68332 in 9aaf9c5. DriveIndexScan.found is now Int?: the fold starts at none, the first matching drive sets Present { value: index }, and later drives cannot overwrite it. The -1 sentinel and the < 0 guard are gone. The 26-letter limit is a separate firecracker_guest_block_device_of_index(index) -> String?, so Absent from either step is what jit_drive_guest_device turns into JitDriveNotAttached.

— sent from merry-bee-648

…diness row; delete the uncited copy

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

gunbai-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Addressed review 68351 in e4d2f4c. Deleted gunbc.host_hygiene_liveness_observe host_hygiene_listening_marker. Its only consumer, host_hygiene_journal_matching_lines, now matches on extdeps.github.actions_runner actions_runner_listening_line_suffix, so the host-slot liveness observer and the guest console reader share one cited source for the listener readiness line. Grep confirms no other reference to the deleted row. The fixture strings in the liveness witnesses are sample journal lines, not a second source.

— sent from merry-bee-648

@briansrls
briansrls added this pull request to the merge queue Sep 19, 2026
Merged via the queue into main with commit d955624 Sep 19, 2026
4 checks passed
@briansrls
briansrls deleted the session/merry-bee-648 branch September 19, 2026 20:39
@briansrls
briansrls restored the session/merry-bee-648 branch September 19, 2026 20:46
gunbai-bot Bot pushed a commit that referenced this pull request Sep 19, 2026
…ntent on the jail device

- JitDeviceStaging carries the guest contract bytes (one jitconfig env line,
  newline-padded to 512-byte sectors); the NUL-pad truncate step and
  truncate_to_size_command are deleted (a second authority for the drive format).
- Readback checks size == the content's own UTF-8 size; a failed stat is its own
  refusal carrying stderr (review 68502).
- Witness pins staged bytes to jit_drive_content AND to its documented shape.
- Keep the deletion of jit_mint_http_realization_frontier / jail_jit_device_staging_frontier;
  runner_guest_image's acceptance trigger now names the performer and the stager.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 19, 2026
… unit takes the typed ServiceType

main's microVM guest runner bootstrap (#11671) set ServiceType { mode: "exec" }, while this branch
types the mode (extdeps.systemd.unit_file SystemdServiceMode). Took main's unit and wrote the mode as
ExecMode; runner_guest_image 13/13 and runner_microvm_boot_probe 8/8 pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot mentioned this pull request Sep 19, 2026
6 tasks
@gunbai-bot
gunbai-bot Bot deleted the session/merry-bee-648 branch September 19, 2026 23:05
@briansrls
briansrls restored the session/merry-bee-648 branch September 19, 2026 23:51
gunbai-bot Bot pushed a commit that referenced this pull request Sep 20, 2026
…kspace staging) into #11677

Resolution keeps both sides: the JIT fields and device staging on LaunchAuthorized,
and #11675's tap-grain egress (no nft_ruleset field), guest network boot args, and
workspace staging gate. staging_verdict destructures the new fields and matches the
renamed refusal arm; #11675's four workspace witnesses are restored over the mint
parameter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot deleted the session/merry-bee-648 branch September 20, 2026 00:46
@gunbai-bot gunbai-bot Bot mentioned this pull request Sep 20, 2026
6 tasks
briansrls pushed a commit that referenced this pull request Sep 20, 2026
Side-chat REWORK. Part 1 (external blockers as prose) was withdrawn after I
traced that startable authorizes closing-contract authoring rather than
implementation dispatch. Parts 2 and 3 stood, and both were my errors.

THE CENSUS ROWS ARE NOT AN AUTHORITY. The page said the 57 transcribed rows
were dissolved by the scan producer. That is materially wrong in two ways.
The economic readings attached to those rows were shown not to have the
meanings assigned to them -- wall duration is not summed runner occupancy, an
admission delay is not a runner queue delay, a provider declaration can
outlive provider execution, and adoption is not spend -- so the derived
runner-minutes and ARM-tier totals do not follow, and "five carry
CostOpportunity" must not be quoted as a finding. And the scan producer is
workflow-level, so it is necessary and NOT sufficient: the facts those rows
need are job-level. The job-level arc is now a roadmap node instead of a
sentence.

ACQUISITION IS MODELED, NOT ACHIEVED. The page called gunbc#11552 an
end-to-end App manifest flow. Its own route tells the operator to paste the
manifest into the create form's manifest field; GitHub exposes no such field
and the manifest protocol needs a form POST. I watched that step fail live in
this session and wrote "end to end" anyway. Registration and INSTALLATION are
also two facts, and gunbc#11677 consumes both rather than creating either.
That is now a node with the remaining work named.

EXTERNAL BLOCKERS ARE GONE. gunbc#11552, #11564, #11656, #11669, #11671,
#11677 and #11679 are all merged. The nodes and the page said otherwise.

The two real prerequisites are now EDGES rather than prose, which is the
repair the reviewer asked for: the installation token depends on the App
existing, and the job-level reprojection depends on the token.

Projection reconciles 146 -> 148: two nodes and their closing-contract
carriers, minus the two carriers the new edges remove from the startable set.

Co-Authored-By: Claude Opus 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