# Overdeck K3s migration tooling

This directory contains phase-scoped, receipt-driven K3s migration tools. Normal repository users run the phase package launcher; root-side helpers are implementation details and must not be invoked manually except through a documented recovery command.

## Phase 0

`phase0-discover.sh` performs read-only repository, host, and cluster inventory.

## Phase 1 — qualification-first control-plane baseline

Primary files:

- `phase1-control-plane.sh` — local-only workstation entrypoint.
- `phase1-control-plane.py` — qualification, apply, backup, and recovery orchestrator.
- `remote/phase1-server.py` — ephemeral checksum-verified root helper for server inspection, transactional configuration, and backup staging.
- `verify-backup.py` — decrypted TAR validation and non-live isolated restore materialization.
- `restore-control-plane.sh` — explicit decrypt-and-materialize wrapper; never activates a live restore.
- `upgrade-plan.py` and `upgrade-control-plane.sh` — digest-locked, plan-only upgrade scaffold.
- `systemd/` — hardened recurring encrypted backup user service and timer.
- `lib/phase1_common.py` — shared stdlib-only safety, archive, SSH, locking, and retention helpers.
- `test/fixtures/debian3-20260811-server-state.json` — sanitized live topology fixture from the third owner run.
- `test/` — unit, failure-injection, systemd, backup/restore, and full fake-cluster transaction tests.

### Transaction order

`--mode apply` always executes:

```text
complete qualification
  -> verified encrypted pre-change backup
  -> transactional managed configuration
  -> post-converge health/identity proof
  -> verified encrypted post-change backup
  -> recurring timer installation
  -> transaction finalization
```

It cannot publish Git changes. The external phase package launcher reads the final receipt and performs Git publication only when `status=success` and `git_publication_allowed=true`.

### Modes

- `--mode qualify` or `--mode plan`: run complete qualification and create a verified pre-change backup, but do not publish K3s configuration or install the timer.
- `--mode apply`: qualification plus the transactional apply sequence above.
- `--mode backup`: scheduled encrypted backup, restore proof, API checks, and retention.
- `--mode recover`: explicit rollback or finalization of a named unfinished server transaction.

### Important contracts

- `/usr/local/bin/k3s`-style outer launcher and `/var/lib/rancher/k3s/data/.../bin/k3s` runtime are separate roles.
- The agent token may be absent, regular, or a symlink resolving exactly to the server token.
- Archive TARs never contain symlinks, devices, FIFOs, or unlisted payload files.
- A pre-change backup may legitimately predate the three Phase 1 canonical files.
- A post-change or scheduled backup must contain the complete canonical file set.
- K3s upgrades, datastore conversion, cluster reset, and live restore are out of scope.

References:

- `docs/specs/2026-08-10-k3s-control-plane-baseline-design.md`
- `docs/reports/2026-08-11-k3s-phase1-rederivation.md`
- `docs/runbooks/k3s-control-plane-backup-restore.md`
- `docs/runbooks/k3s-phase1-agent-instructions.md`

## Phase 2 — one-command enrollment plan and dry-run

Primary files:

- `enroll-node.sh` — owner-facing workstation command; live apply is hard-disabled.
- `enroll-node.py` — identity/preflight collection, deterministic plan, durable ledger and registry previews.
- `lib/phase2_common.py` — plan, safety, secret scanning, ledger and atomic registry-pair contracts.
- `remote/phase2-candidate.py` — ephemeral read-only candidate inspector.
- `remote/phase2-server.py` — ephemeral read-only Phase 1 control-plane contract inspector.
- `validate-enrollment-receipt.py` — independent zero-mutation receipt authorization.
- `test/fixtures/phase2-debian4.json` — sanitized OS + Tailscale-ready candidate fixture.
- `test/phase2-enrollment.test.sh` and `test/test_phase2_*.py` — deterministic, failure-injection and helper tests.

Phase 2 emits the complete future 17-step transaction but performs no host, Kubernetes, token or tracked-registry mutation. A successful candidate preview uses `execution=none` and is absent from build, E2E and fallback orders. Live canary enrollment remains a separate Phase 3 package bound to one reviewed plan digest.

References:

- `docs/specs/2026-08-11-k3s-node-enrollment-design.md`
- `docs/runbooks/k3s-node-enrollment.md`
- `docs/runbooks/k3s-phase2-agent-instructions.md`
- `docs/reports/2026-08-11-k3s-phase2-implementation.md`
- `docs/mockups/k3s-phase2-enrollment.html`
