Implementation plan for the #12 split — audit, isolation hardening, box + templates #14

Closed
dan-claude-bot wants to merge 1 commit from docs/issue-12-implementation-plan into main
dan-claude-bot commented 2026-07-13 21:02:09 +00:00 (Migrated from github.com)

Plan of record for the #12 split — #15 audit → #16 isolation hardening → #17 box + templates — as docs/issue-12-implementation-plan.md. Nothing executable lands here; this PR is the review gate on the order and shape of the work before any of it is written. Re-pinned to main @ 0982a2d after #13 merged.

The shape

Three stages, one per issue, strictly ordered:

  1. Stage 0 — audit (#15), no code: probe every edge of the stated isolation contract live (egress, host, LAN, sibling, DNS enumeration, inbound, IPv6) and pin the four Incus behaviors the later stages lean on — whether bridge ACLs actually catch intra-bridge sibling traffic (the analysis's central, never-reproduced claim), @internal as an ACL destination on bridge networks, incus copy preserving user.* keys, and dns.mode=none semantics. Results land as comments on #15. If the sibling probe fails to block, #16's diagnosis is wrong and gets redesigned before code.
  2. Stage 1 — isolation hardening (#16), own PR: explicit sibling drop (renumber-proof — @internal or a subnet derived by masking the gateway CIDR), security.mac_filtering/ipv4_filtering, dns.mode=none, IPv6-off promoted to stated contract, and tests/isolation.sh — the repo's first test. Zero CLI changes. Lands on the current tool, so the test stands guard over the rename that follows.
  3. Stage 2 — box + templates (#17), own PR: template dirs with a strict allowlist box.env parser (not sourced — that's the enforcement of "a template cannot express a different network"), metadata stamped on instances at launch, box_user() with the legacy fallback, dual-tag matching in resolve_box() so pre-rename boxes and their snapshots never fall out of list/shell/--from, the profile split into a placement contract (box-net: NIC + root disk only), and the full rename sweep including install.sh.

Stage 2 is additionally gated on three maintainer answers (#17's open questions: CLI-name compat, default template, repo/binary naming) — the plan tables them with recommendations and defaults, so one comment settles it.

Why this order

The isolation test is the only artifact that can prove the rename didn't regress the thing the tool exists for. Building it first, against today's names, means stage 2 inherits a tripwire instead of a hope. And the audit exists because the analysis's central claims read fine and were never run.

#13's merge simplified stage 2: every verb now resolves through resolve_box(), so dual-tag matching is one function instead of per-verb edits, and the incus escape hatch answers root access in templated boxes without a flag.

Closes nothing; implements nothing. #15/#16/#17 carry the work.

🤖 Generated with Claude Code

Plan of record for the #12 split — **#15 audit → #16 isolation hardening → #17 box + templates** — as `docs/issue-12-implementation-plan.md`. Nothing executable lands here; this PR is the review gate on the *order and shape* of the work before any of it is written. Re-pinned to `main` @ `0982a2d` after #13 merged. ## The shape **Three stages, one per issue, strictly ordered:** 1. **Stage 0 — audit (#15)**, no code: probe every edge of the stated isolation contract live (egress, host, LAN, sibling, DNS enumeration, inbound, IPv6) and pin the four Incus behaviors the later stages lean on — whether bridge ACLs actually catch intra-bridge sibling traffic (the analysis's central, never-reproduced claim), `@internal` as an ACL destination on bridge networks, `incus copy` preserving `user.*` keys, and `dns.mode=none` semantics. Results land as comments on #15. If the sibling probe fails to block, #16's diagnosis is wrong and gets redesigned *before* code. 2. **Stage 1 — isolation hardening (#16)**, own PR: explicit sibling drop (renumber-proof — `@internal` or a subnet derived by masking the gateway CIDR), `security.mac_filtering`/`ipv4_filtering`, `dns.mode=none`, IPv6-off promoted to stated contract, and `tests/isolation.sh` — the repo's first test. Zero CLI changes. Lands on the *current* tool, so the test stands guard over the rename that follows. 3. **Stage 2 — `box` + templates (#17)**, own PR: template dirs with a strict allowlist `box.env` parser (not `source`d — that's the enforcement of "a template cannot express a different network"), metadata stamped on instances at launch, `box_user()` with the legacy fallback, dual-tag matching in `resolve_box()` so pre-rename boxes and their snapshots never fall out of `list`/`shell`/`--from`, the profile split into a placement contract (`box-net`: NIC + root disk only), and the full rename sweep including `install.sh`. Stage 2 is additionally gated on three maintainer answers (#17's open questions: CLI-name compat, default template, repo/binary naming) — the plan tables them with recommendations and defaults, so one comment settles it. ## Why this order The isolation test is the only artifact that can prove the rename didn't regress the thing the tool exists for. Building it first, against today's names, means stage 2 inherits a tripwire instead of a hope. And the audit exists because the analysis's central claims read fine and were never run. #13's merge simplified stage 2: every verb now resolves through `resolve_box()`, so dual-tag matching is one function instead of per-verb edits, and the `incus` escape hatch answers root access in templated boxes without a flag. Closes nothing; implements nothing. #15/#16/#17 carry the work. 🤖 Generated with [Claude Code](https://claude.com/claude-code)

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/box#14
No description provided.