M3: adapt deploy template to the split + composed-layer canary #3

Merged
vnprc merged 2 commits from agent/deploy-archetypes-split into master 2026-07-17 23:01:07 +01:00
Member

Part of the archetypes/profiles repo split — Refs allod/strategy#18. This is M3: adapting the public deploy template to the split and wiring the generic composed-layer canary. Depends on M2 (it pins the post-flip framework at 0ebda69).

Changes (Interface Contract 3):

  • Rename the framework input profilesarchetypes (URL unchanged), and add a separate profiles definitions input (allod/profiles, pinned 8e0b9a0). Redirect the framework's own inputs at the three data repos: archetypes.inputs.{profiles,secrets,inventory}.follows.
  • nixosConfigurations / vmFacts now re-export from archetypes.
  • Add checks.<system>.composed-layer = archetypes.lib.composedLayerCheck { pkgs; expectedProfiles = profiles; } — the generic canary. pkgs comes from nixpkgs.follows = "archetypes/nixpkgs", so the template pins no divergent nixpkgs.
  • Add tests/empty-profiles/ — a minimal empty-contract profiles fixture for the sabotage tests.
  • Rewrite the README: the "operator fork changes exactly three input URLs (profiles, secrets, inventory) and nothing else" charter, now enforceable by diff.

An operator fork changes exactly those three data URLs; vm/nexus arrive through archetypes' own lock (nix flake update archetypes).

Risk

R2 Medium — adapts a template nothing operational builds from directly, but it pins the pattern operators fork, so a wrong follows shape here would propagate into every future fork. Mitigated by the canary + two sabotage fixtures below. Rollback is a plain revert to the pre-split adapter shape.

Validation

nix flake check     # canary green; nixosConfigurations (allod-dev/privacy-1/nexus/installer) evaluate

Both sabotage runs demonstrably fail — the canary counts as validated only once they do:

  • Sabotage 1 (lost redirect): nix build .#checks.x86_64-linux.composed-layer --override-input archetypes/profiles path:./tests/empty-profilesfails, canary message names both store paths and the dropped-follows cause.
  • Sabotage 2 (dropped definitions): nix eval .#nixosConfigurations.allod-dev.…toplevel.drvPath --override-input profiles path:./tests/empty-profiles --override-input archetypes/profiles path:./tests/empty-profilesthrows machine 'allod-dev' selects missing dev profile definition 'allod-dev'.

Stranger-accessible: every flake.lock input URL is public https://forge.anarch.diy/allod/*.git (no ssh://), so a fresh clone evaluates and checks green with only repo read access.

Note on Sabotage 1: the plan sketched an older allod/profiles git rev, but that repo has only fresh history (LICENSE → populate; the LICENSE-only commit has no flake). The tests/empty-profiles fixture is the self-contained equivalent — a valid but distinct profiles flake — and exercises the same mismatch.

Part of the archetypes/profiles repo split — `Refs allod/strategy#18`. This is **M3**: adapting the public deploy template to the split and wiring the generic composed-layer canary. Depends on M2 (it pins the post-flip framework at `0ebda69`). Changes (Interface Contract 3): - Rename the framework input `profiles` → `archetypes` (URL unchanged), and add a separate `profiles` definitions input (`allod/profiles`, pinned `8e0b9a0`). Redirect the framework's own inputs at the three data repos: `archetypes.inputs.{profiles,secrets,inventory}.follows`. - `nixosConfigurations` / `vmFacts` now re-export from `archetypes`. - Add `checks.<system>.composed-layer = archetypes.lib.composedLayerCheck { pkgs; expectedProfiles = profiles; }` — the generic canary. `pkgs` comes from `nixpkgs.follows = "archetypes/nixpkgs"`, so the template pins no divergent nixpkgs. - Add `tests/empty-profiles/` — a minimal empty-contract profiles fixture for the sabotage tests. - Rewrite the README: the "operator fork changes exactly three input URLs (`profiles`, `secrets`, `inventory`) and nothing else" charter, now enforceable by diff. An operator fork changes exactly those three data URLs; `vm`/`nexus` arrive through `archetypes`' own lock (`nix flake update archetypes`). ## Risk R2 Medium — adapts a template nothing operational builds from directly, but it pins the pattern operators fork, so a wrong `follows` shape here would propagate into every future fork. Mitigated by the canary + two sabotage fixtures below. Rollback is a plain revert to the pre-split adapter shape. ## Validation ``` nix flake check # canary green; nixosConfigurations (allod-dev/privacy-1/nexus/installer) evaluate ``` **Both sabotage runs demonstrably fail** — the canary counts as validated only once they do: - **Sabotage 1 (lost redirect):** `nix build .#checks.x86_64-linux.composed-layer --override-input archetypes/profiles path:./tests/empty-profiles` → **fails**, canary message names both store paths and the dropped-`follows` cause. - **Sabotage 2 (dropped definitions):** `nix eval .#nixosConfigurations.allod-dev.…toplevel.drvPath --override-input profiles path:./tests/empty-profiles --override-input archetypes/profiles path:./tests/empty-profiles` → **throws** `machine 'allod-dev' selects missing dev profile definition 'allod-dev'`. **Stranger-accessible:** every `flake.lock` input URL is public `https://forge.anarch.diy/allod/*.git` (no `ssh://`), so a fresh clone evaluates and checks green with only repo read access. Note on Sabotage 1: the plan sketched an older `allod/profiles` git rev, but that repo has only fresh history (LICENSE → populate; the LICENSE-only commit has no flake). The `tests/empty-profiles` fixture is the self-contained equivalent — a valid but distinct profiles flake — and exercises the same mismatch.
Rename the framework input profiles -> archetypes and add a separate profiles
definitions input, redirecting the framework's profiles/secrets/inventory inputs
at the three data repos via follows. Add the generic composed-layer canary
(checks.<system>.composed-layer via archetypes.lib.composedLayerCheck) plus the
tests/empty-profiles sabotage fixture, and update the README.
Author
Member

Per request: replacing the hard-coded system list [ "x86_64-linux" "aarch64-linux" ] in the composed-layer check with inventory.lib.supportedPlatforms, so the template derives its platforms from the inventory source of truth instead of hard-coding architecture strings (matching how archetypes and secrets generate their checks). Follow-up commit incoming.

Per request: replacing the hard-coded system list `[ "x86_64-linux" "aarch64-linux" ]` in the composed-layer check with `inventory.lib.supportedPlatforms`, so the template derives its platforms from the inventory source of truth instead of hard-coding architecture strings (matching how archetypes and secrets generate their checks). Follow-up commit incoming.
Replace the hard-coded [ x86_64-linux aarch64-linux ] system list with
inventory.lib.supportedPlatforms, so the template derives its checked platforms
from the inventory source of truth rather than hard-coding architecture strings
(matching how archetypes and secrets generate their checks).
vnprc approved these changes 2026-07-17 23:01:01 +01:00
vnprc merged commit 796014829b into master 2026-07-17 23:01:07 +01:00
vnprc deleted branch agent/deploy-archetypes-split 2026-07-17 23:01:07 +01:00
Sign in to join this conversation.
No description provided.