Day 70 — Stage VI gate
Day 70 — Stage VI gate
Stage VI · ~4h (integration)
Goal: Prove fleet habits: a flake-defined lab that deploys remotely, is tested, built in CI, and supported by a cache story—with Disko/impermanence/backup notes complete enough that a new host of an existing role is boring.
Why this day exists
Stage VI without a gate is a pile of demos. Exit only when the boring path works: clone → build/check → deploy → rollback plan → restore state plan.
Gate bar (explicit)
| # | Requirement | Evidence |
|---|---|---|
| H1 | Remote deploy works (deploy-rs or Colmena) | Transcript + remote nixos-version |
| H2 | ≥2 hosts or 1 remote + documented second role path | Hive/nodes |
| H3 | Shared baseline + ≥1 role module | Tree layout Day 61 |
| H4 | Flake checks ≥3 meaningful, green locally | nix flake check |
| H5 | CI runs Nix build/check on PR/push | Actions/GitLab URL |
| H6 | Binary cache push/pull or file-store proof | Day 53/66 |
| H7 | Disko layout for at least one host type | Committed module |
| H8 | Impermanence proof or written skip | Day 58 |
| H9 | Backup restore drill done | Day 69 RESTORE.md |
| H10 | SB/TPM dossier exists | Day 68 |
| H11 | TF boundary sketch exists | Day 63 |
| H12 | Dossier GATE-VI.md self-scored |
This day |
Stretch: image boot (Day 62) linked from gate dossier.
Theory — Reference architecture
┌────────── CI (GHA) ──────────┐
│ nix flake check / build │
│ cachix push │
└─────────────┬────────────────┘
│ substitutes
┌────────────┐ deploy-rs/colmena v
│ laptop/dev │ ───────────────────► edge host (remote VM)
│ flake.dev │ ───────────────────► core host (optional)
└────────────┘
│
├─ modules/profiles/baseline.nix
├─ modules/roles/web.nix
├─ hosts/*/disko.nix
├─ tests/*.nix
└─ RESTORE.md / BOUNDARY.md / SECUREBOOT-TPM.md
Worked example — gate dossier skeleton
# GATE-VI.md
## Inventory
| Host | Role | Deploy tool | IP | Disko | Persist |
|------|------|-------------|----|-------|---------|
## Commands that must work
```bash
nix flake check -L
deploy .#edge # or colmena apply --on edge
ssh edge cat /etc/roleCI
- Workflow:
- Latest green URL:
Cache
- Substituter:
- Push method:
State
- Backup tool:
- Last restore drill date:
- Link RESTORE.md
Scores
| ID | Pass? | Notes |
|---|---|---|
| H1 |
…
---
## Lab — gate protocol (multi-step)
Suggested workspace: promote your fleet flake; notes `~/lab/90daysofx/02-nixos/day70`
### Step 1 — Freeze scope
No new tools today. Only glue and proof.
### Step 2 — Remote deploy proof
```bash
# change a harmless etc file text with timestamp
deploy .#edge # or colmena
ssh edge cat /etc/day70
Step 3 — Checks green
nix flake check -LFix or quarantine with written reason (not silent delete).
Step 4 — CI green
Ensure main branch workflow green; link it.
Step 5 — Cache proof
Cold-ish machine or nix store delete careful path on lab only—prefer second VM pull through cache.
Step 6 — Role composition review
New host checklist written:
- Copy
hosts/_template
- Set disko device
- Enable roles
- Add to colmena/deploy nodes
- Apply
- Attach backup paths
Step 7 — Fill GATE-VI.md
Score H1–H12 ruthlessly.
Step 8 — Tag
git tag -a stage-vi-gate -m "Stage VI fleet habits gate"Step 9 — Rollback drill (required)
On the remote host, after a successful deploy:
ssh edge 'ls /nix/var/nix/profiles/system*'
# switch to previous generation once, then back
ssh edge 'sudo /nix/var/nix/profiles/system-N-link/bin/switch-to-configuration switch'
# or boot-menu / nixos-rebuild --rollback depending on setupRecord: how long until SSH returned, whether services flapped, whether magic-rollback would have helped.
Step 10 — Retrospective (short)
Three things that will break in Stage VII/VIII; put them in BACKLOG-stage-vii.md.
House defaults freeze (record yours)
By Day 70 you should stop re-picking tools every week. Fill and commit:
| Concern | Your default | Runner-up | Why |
|---|---|---|---|
| Pinning | flakes + lock | ||
| Secrets | sops-nix / agenix | ||
| Deploy | deploy-rs / Colmena | ||
| Cache | Cachix / Attic / file | ||
| Images | nixos-generators format | ||
| Backup | restic / borg / zfs | ||
| Tests | nixosTest + pkg checks | ||
| Disks | Disko layout family | ||
| Persist | full / partial / skip |
This table is part of the gate dossier—not optional flavor text.
Acceptance ceremony (30 minutes)
Run in order; paste outputs into GATE-VI.md:
# 1. Metadata
nix flake metadata
git rev-parse HEAD
git describe --tags --always
# 2. Checks
nix flake check -L
# 3. Package (Stage V still alive)
nix build .#cooltool -L || nix build .#default -L
# 4. Host eval
nix build .#nixosConfigurations.edge.config.system.build.toplevel -L
# 5. Deploy
deploy .#edge # or: colmena apply --on edge
# 6. Live proof
ssh edge 'hostname; nixos-version; cat /etc/role 2>/dev/null || true'
# 7. Backup pointer
test -f RESTORE.md && head -n 20 RESTORE.mdIf any step fails, the gate fails—fix or document a time-boxed exception with a ticket ID.
What “new host is boring” means
You pass the spirit of Stage VI when this checklist is mechanical:
- Allocate VM/metal (TF or console)
- Set
disko.devices.disk.main.device
- Import
profiles.baseline+ role(s)
- Add SSH bootstrap key
- Add node to deploy/colmena inventory
- First deploy
- Attach backup paths for that role’s state
- CI already covers shared modules—no new workflow required
If step 3 still means “copy 400 lines from edge,” return to Day 61.
Theory — Deploy path proof matrix
| Path | Command / tool | Proven? |
|---|---|---|
| Local rebuild | nixos-rebuild switch --flake |
|
| Remote deploy | deploy-rs / colmena | |
| Image path | generators / disko install story | |
| Test path | nix flake check subset |
Gate requires honesty: blank cells need a written “not used” with reason.
Theory — Impermanence / Disko status
Even if optional in your lab:
| Topic | Status |
|---|---|
| Disko config exists / N/A | |
| Persist list written | |
| Backup of state dirs | |
| New host install notes |
“We use default ext4 installer” is a valid status if documented.
Worked example — gate freeze commit message
day70: stage VI gate
- deploy tool: …
- shared modules: roles/…
- checks: list
- cache: …
- known debt: …
Lab — cross-host dry run
If you only have one machine, still write:
- How a second host reuses
modules/roles
- What differs (hardware, secrets, networking.hostName)
- How inventory assigns roles
Lab — CI badge honesty
If CI exists, paste latest green URL or log hash into the dossier. If not, write the blocker (secrets, runners, time) and the minimal check you run locally instead.
Common gotchas
| Symptom / mistake | What to do |
|---|---|
| “Works on my laptop only” | Fail H1/H5 |
| Checks skipped in CI | Fail H5 |
| Deploy without backup story | Fail H9 |
| Secret docs missing | Fix before claiming gate |
| Tool zoo (deploy-rs+colmena+tf+k8s) unfinished | Narrow; finish boring path |
| Impermanence half-broken SSH | Fix keys before scoring pass |
| Gate scored green without remote | Invalid—H1 is remote |
| Stage V package abandoned | Rebuild once; prove cache still helps |
| Rollback never practiced | Do Step 9 before tag |
Checkpoint
- H1–H12 scored in
GATE-VI.md
- Remote deploy demonstrated
- Rollback drill recorded
- CI URL recorded
- House defaults table frozen
- New-host checklist exists
- Acceptance ceremony outputs attached
- Tag
stage-vi-gate(or equivalent milestone)
- Ready for Stage VII internals without fleet shame
Commit
git add .
git commit -m "day70: stage VI gate dossier"Write three personal gotchas before continuing.
Tomorrow
Day 71 — Evaluator: thunks, infinite recursion, and tracing tricky evals (Stage VII begins).