Export the microVM QMP socket path constructor beside the launcher that removes it #27

Open
opened 2026-08-22 01:17:20 +01:00 by allod-agent · 0 comments
Member

The string that decides where a microVM's QMP control socket lives is written in allod/archetypes, while the code that recursively removes the resulting directory lives in allod/nexus. Export the path constructor from allod/nexus beside that removal, so one repository owns both the convention and the rm -rf that acts on it.

Primary goals:

  • One owner for the path and the code that deletes it — the constructor sits next to the post-stop hook whose blast radius it decides, rather than a repository away.
  • No behaviour change — the rendered socket path stays byte-identical and every current assertion keeps its meaning. This is placement, not policy.
  • A named home if the layout ever becomes settable — whoever makes the root configurable finds one constructor to parameterize instead of a literal to hunt for.

Current state and specifics

allod/archetypes owns the literal. On the agent/microvm-host-guest-join branch, flake.nix:106 defines microvmQmpSocketRoot = "/run/allod/microvm-qmp", flake.nix:900 renders each guest's microvm.socket from it, and flake.nix:877 asserts that nexus.microvm.hostPlaintextRoot is not nested inside it.

allod/nexus hardcodes nothing. It derives the directory from whatever the guest declared — qmpDirectory = builtins.dirOf qmpSocket at nix/microvm/host.nix:84 — and the per-VM post-stop hook removes it recursively at nix/microvm/launcher.nix:340, alongside the prepared credential directory and the staging directory.

This closes no current gap, and the issue should not be read as one. Contract 8 already prevents silent drift of the split. Nexus duplicates no literal, so there is no second copy to fall out of sync. The overlap assertion compares the archetypes literal against itself, both sides sourced from one string in one file. The behavioural witness that the removal touches nothing but what the launcher prepared already exists in checks/microvm/isolation.nix, subtest "post-stop removes only what the launcher prepared", which stops one of two running guests and asserts the sibling's QMP socket, the sibling's prepared credential, the rollback slot, the volume image and the plaintext mount all survive.

What the move buys is locality. A reader auditing the recursive delete would see the convention that decides its target in the same file, instead of inferring it from an assertion in another repository.

Trigger

Take this up when a second consumer needs to know the QMP root, or when the socket layout stops being a fixed value. The pull request allod/archetypes#39 declined to make it configurable on the grounds that a fixed value cannot be misaimed; that reasoning stops holding the moment it is settable, and at that point the constructor's location decides how many places have to change together. Absent either condition the current split is correct, and this is a recorded alternative rather than pending work.

Scope

In: exporting a path constructor from allod/nexus beside the launcher, having the allod/archetypes join consume it, and keeping the rendered socket path byte-identical across the move.

Out: making the QMP root configurable, which allod/archetypes#39 ruled against. Out: any change to the removal hook or its isolation check. Out: the overlap assertion's placement, which follows the constructor rather than being decided separately.

Recorded from the owner review of allod/archetypes#39, which ruled this a defensible follow-up rather than a blocker. Part of allod/strategy#20.

The string that decides where a microVM's QMP control socket lives is written in `allod/archetypes`, while the code that recursively removes the resulting directory lives in `allod/nexus`. Export the path constructor from `allod/nexus` beside that removal, so one repository owns both the convention and the `rm -rf` that acts on it. Primary goals: - **One owner for the path and the code that deletes it** — the constructor sits next to the post-stop hook whose blast radius it decides, rather than a repository away. - **No behaviour change** — the rendered socket path stays byte-identical and every current assertion keeps its meaning. This is placement, not policy. - **A named home if the layout ever becomes settable** — whoever makes the root configurable finds one constructor to parameterize instead of a literal to hunt for. ### Current state and specifics `allod/archetypes` owns the literal. On the `agent/microvm-host-guest-join` branch, `flake.nix:106` defines `microvmQmpSocketRoot = "/run/allod/microvm-qmp"`, `flake.nix:900` renders each guest's `microvm.socket` from it, and `flake.nix:877` asserts that `nexus.microvm.hostPlaintextRoot` is not nested inside it. `allod/nexus` hardcodes nothing. It derives the directory from whatever the guest declared — `qmpDirectory = builtins.dirOf qmpSocket` at `nix/microvm/host.nix:84` — and the per-VM post-stop hook removes it recursively at `nix/microvm/launcher.nix:340`, alongside the prepared credential directory and the staging directory. **This closes no current gap, and the issue should not be read as one.** Contract 8 already prevents silent drift of the split. Nexus duplicates no literal, so there is no second copy to fall out of sync. The overlap assertion compares the archetypes literal against itself, both sides sourced from one string in one file. The behavioural witness that the removal touches nothing but what the launcher prepared already exists in `checks/microvm/isolation.nix`, subtest "post-stop removes only what the launcher prepared", which stops one of two running guests and asserts the sibling's QMP socket, the sibling's prepared credential, the rollback slot, the volume image and the plaintext mount all survive. What the move buys is locality. A reader auditing the recursive delete would see the convention that decides its target in the same file, instead of inferring it from an assertion in another repository. ### Trigger Take this up when a second consumer needs to know the QMP root, or when the socket layout stops being a fixed value. The pull request allod/archetypes#39 declined to make it configurable on the grounds that a fixed value cannot be misaimed; that reasoning stops holding the moment it is settable, and at that point the constructor's location decides how many places have to change together. Absent either condition the current split is correct, and this is a recorded alternative rather than pending work. ### Scope In: exporting a path constructor from `allod/nexus` beside the launcher, having the `allod/archetypes` join consume it, and keeping the rendered socket path byte-identical across the move. Out: making the QMP root configurable, which allod/archetypes#39 ruled against. Out: any change to the removal hook or its isolation check. Out: the overlap assertion's placement, which follows the constructor rather than being decided separately. Recorded from the owner review of allod/archetypes#39, which ruled this a defensible follow-up rather than a blocker. Part of allod/strategy#20.
Sign in to join this conversation.
No description provided.