Files
felhom.eu/documentation/tests/VALIDATION-n100-rehearsal-2026-07-18.md
T
admin aa9c08f0dd docs(rehearsal): N100 S8 wrap — VALIDATION, map flips, ROADMAP R-30..R-39, R-3 draft
The 2026-07-18 N100 rehearsal ran the complete final-product flow on real metal
in one pass: RESET -> generic pairing ISO v1.20.0 -> customer self-bind -> day-0
-> managed-floor lift -> escrow ceremony -> offsite snapshots. No code changed;
every finding is recorded and ranked, none fixed.

VALIDATION-n100-rehearsal-2026-07-18.md — run context, a UTC-normalised timeline
built from the hub events stream / hub DB / controller log / bootstrap + agent
journals, per-ledger verdicts for S1-S8 + ledgers 8 and 9, 12 findings, the
not-exercised list, and 7 discrepancies against the brief.

Headline wall-clocks: bind -> credential 26 s; bind -> controller running the
current version 2 min 44 s; managed floor 0.143.0 -> 0.145.0 in 5 s unattended
(initiated_by: auto-floor); escrow ceremony -> offsite enabled 12 s; drive enrol
30.3 s. No post-bind leg stalled, which is the immediacy row's real-onboarding
proof.

Capability map (10 citations added):
- Bare-metal Felhom ISO           PARTIAL     -> PROVEN-LIVE (F1 closed on metal)
- Customer self-bind (slice 1)    IMPLEMENTED -> PROVEN-LIVE (customer_selfbind)
- Guest RAM resize (R-24)         IMPLEMENTED -> PROVEN-LIVE (shrink AND grow)
- Customer RESET                  two real firings + verified external teardown
- Escrow ceremony                 first live wizard firing
- Immediacy row                   "real-onboarding proof pending" cleared
- Publish train                   box-side floor lift proven on a fresh install
- Customer claim                  R-4 gmail half (Inbox under p=quarantine)
- Offsite orphan guard            staged live leg fired on its own
- DR tier by default              candidate PROVEN-LIVE upgrade WITHDRAWN (R-39)
Not flipped, as instructed: customer-performs-restore, BYO, DLNA, multi-user.

ROADMAP — collapsed R-1 (appliance half done, Peti half survives), R-21
(physically closed), R-24, R-27 slice 1, R-4. New ranked items:
  P2-HIGH  R-39 PBS DR applied-but-dead   R-30 liveness from the wait channel
           R-31 async offsite + status    R-32 RESET base-dir purge
           R-33 bootstrap quiet-poll
  P2       R-34 backup lifecycle          R-35 config-apply session survival
           R-36 post-RESET offsite prompt R-27c console-passphrase bind
  P3       R-37 post-RESET health card    R-38 installer GRUB slice
Plus a pre-invite checklist (golden 0.145.x rebuild, freemail.hu, C6, R-11).

R-39 is NEW and was not on the brief: the PBS DR descriptor auto-provisions and
the agent converges state=applied, but pvesm reports 401 Unauthorized/inactive
and a direct probe 401s on every endpoint including /version while WG is healthy.
The hub minted a second token secret two minutes after the agent applied the
first and consumed_at is still NULL; the converged state machine will not
re-apply, and the agent's verify loop cannot read the credential to notice it
(non-root read of a file it writes through a root wrapper). Rank is provisional
pending Viktor.

R-3 draft: all four [REFINE] slots filled, self-bind made the default path with
"send the link BEFORE the customer sees the console", the measured wall-clock
table added, and interim operator workarounds for R-31/R-36/R-39. C6 (renumbered
C7) is marked as the single unexecuted step and keeps the doc a DRAFT.

Evidence bundle: 180:~/n100-rehearsal/ (10 files + MANIFEST.md), collected before
the box was unplugged for travel. Secrets read only to run probes; recorded as
lengths and metadata, never values.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
2026-07-18 19:56:17 +02:00

302 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VALIDATION — N100 rehearsal: RESET → generic ISO → self-bind → customer zero, 2026-07-18
> Supervised run of `runbooks/RUNBOOK-rehearsal-v3.md` (S1S8). Viktor at the box as customer zero;
> CC collected the evidence afterwards (Phase A) before the N100 was unplugged for travel. **No
> production code changed by this run** — this document, the capability-map flips, and the ROADMAP
> items are its outputs. Every finding below is **recorded and ranked, never fixed here.**
>
> **Headline — read this first.** The complete final-product flow ran **end to end on real metal in
> one pass**: blank hardware → zero-touch install → self-registration → **customer self-bind** →
> credential delivery → day-0 → managed-floor lift → drive enrolment → escrow ceremony → offsite
> snapshots. The chain from **bind to a running current-version controller took 2 min 44 s**, and the
> managed floor lifted the controller **0.143.0 → 0.145.0 in 5 seconds, unattended**. Three things
> did not go to plan and are the run's real value: **(1)** the offsite repo came up **ORPHANED**,
> which S7 defines in advance as a finding; **(2)** the **PBS DR tier is silently non-functional** —
> descriptor applied, token rejected `401`, and the agent's own verify loop cannot read the
> credential to notice; **(3)** pushing the offsite config **restarted the controller and logged the
> customer out mid-flow**. Net: **core objectives green, 11 ranked items, one of them new and
> unforecast.**
---
## Run context
| | |
|---|---|
| Hardware | Intel **N100** (AlderLake-N), 16 GB; the same physical box as `VALIDATION-n100-baremetal-2026-07-16` |
| Host | `demo-felhom`, PVE **9.2.2** (kernel 7.0.2-6-pve), guest **9201** (`demo-felhom`) |
| Customer | `demo-felhom`, domain demo-felhom.eu — reborn clean-slate on this run |
| Versions | controller **0.145.0** · agent **0.90.0** · hub **v0.66.0** · ISO scripts **v1.20.0** · host-install **1.17.0** |
| Preparation | **RESET ×2** (host-delete-first): `demo-vm-felhom` 15:49:57, `demo-felhom` 16:08:51 — both with all five legs `ok` and escrow acked |
| Media | safety ISO first, then the real **universal pairing ISO v1.20.0**, `--loader mkimage`, Secure Boot **OFF** (mkimage is unsigned — the documented slice-B constraint) |
| Evidence | `180:~/n100-rehearsal/` (10 files + `MANIFEST.md`) |
> **⚠ Timezone.** The PVE host journal is **CEST (+0200)**; the guest, the controller and the hub are
> **UTC**. **Every timestamp in this document is UTC.** Subtract 2 h from any `journalctl` line
> before comparing it with a controller or hub timestamp. This split is live-captured in
> `timezones.txt` and is itself worth a ruling (see *Observations*).
---
## Timeline (wall-clocks, all UTC)
Sourced from the hub events stream, the hub DB, the controller log, the bootstrap journal and the
agent journal — **not** from expectation. Where the brief and the evidence disagreed, the evidence
is recorded and the disagreement is called out under *Discrepancies*.
| UTC | What happened | Evidence |
|---|---|---|
| 15:49:57 → 15:50:06 | **RESET #1** — customer `demo-vm-felhom`; legs `claim/db_purge/descriptor/hetzner/pbs` all `ok`, escrow acked | `hub-state.txt` `customer_resets` id=1 |
| 16:05:24 | `host_stale` + `node_stale` — "no report for 30m" | events |
| 16:08:51 → 16:08:59 | **RESET #2** — customer `demo-felhom`; all five legs `ok`, escrow acked (8 s) | `customer_resets` id=2 |
| **16:17:14** | **Blank metal first boot.** `felhom-bootstrap` in **PAIRING** mode; registers as an unclaimed appliance the same second | `bootstrap-journal.txt`; `appliance_registrations.first_seen` |
| 16:17:14 → 16:28 | 30 s pairing-poll loop; **every iteration exits 1****52** systemd `FAILED`/`Failed to start` lines on the customer-visible console | `bootstrap-journal.txt` |
| 16:28:55 | Operator mints + emails the **self-bind link**; 7-day TTL (expires 2026-07-25 16:28:55) | `selfbind_tokens` `created_at`/`emailed_at`/`expires_at` |
| **16:29:55** | **Customer self-binds** — token consumed, `attempts=0`, `locked=0`; `appliance_bound` source **`customer_selfbind`** | `selfbind_tokens.consumed_at`; events |
| 16:30:21 | `appliance_credential_delivered` (**26 s** after bind) | events; `appliance_registrations.delivered_at` |
| 16:30:40 | Hub `hosts` row created — `demo-felhom-8363b5` | `hosts.created_at` |
| 16:30:49 | Agent **0.90.0** daemon start; fast-tick armed | `agent-journal.txt` (18:30:49 CEST) |
| 16:30:51 | WG keypair generated → **registered with hub**`10.77.0.2/32` → tunnel applied (**~2 s** end to end) | agent journal |
| 16:30:54 | Poke listener up, WG-confined `10.77.0.2:51822` | agent journal |
| 16:32:28 | `controller_started` **0.143.0** (the golden's version) | events |
| 16:32:29 | **Managed-floor update initiated — `initiated_by: auto-floor`** | `update-state.json` |
| 16:32:32 | **Day-0 provision SUCCESS** — done-flag written, unit disabled, bootstrap secrets scrubbed | `bootstrap-journal.txt` |
| **16:32:34** | **Floor update complete: 0.143.0 → 0.145.0 in 5 s**; new container created | `update-state.json`; `docker inspect .Created` |
| 16:32:39 | `controller_started` **0.145.0** | events |
| 16:33:24 | `node_recovered` — "Reports resumed (was stale for 27m)" | events |
| 16:41:41 | Drive init starts — `/mnt/hdd_1`, `/dev/sdb`, ext4 | controller log |
| 16:41:42 | Agent wipe gate: `storage_wipe``customer_confirmable`, **allowed=false**, `pending_confirmation` | agent journal |
| 16:41:51 | Wipe gate: **allowed=true**, `customer_confirmed` (9 s of customer thinking time) | agent journal |
| 16:42:19 | Device formatted ext4 | agent journal |
| 16:42:21 | Mount ensured → bound into guest → storage path registered → FileBrowser mounts synced. **Init 30.3 s** (F6 working) | controller log + agent journal |
| **16:50:22** | **RAM shrink 11675 → 8192 MB**, live cgroup, no reboot | controller log + agent `local-api: guest-memory resized` |
| 16:45:51 | Agent consumes a one-time **PBS** token secret (`secret_len=36`) and applies the descriptor | agent journal |
| 16:45:53 | `pbsdr: converged state=applied` | agent journal |
| **16:47:52** | **Hub mints a NEW PBS token secret — `consumed_at` is still NULL** | `host_pbs_secrets` |
| 16:47:55 → | Agent PBS verify loop: `cannot read token secret … permission denied`**repeats every ~15 min, indefinitely** | agent journal |
| 16:54:58 | Config-refresh: hub `config_version=11 != applied=10`**controller self-restarts** | controller log |
| 16:55:02 | Controller 0.145.0 restarts (container `StartedAt` 16:54:59Z — a **real restart**, not a reload) | controller log; `docker inspect` |
| 16:55:05 | `offsite-apply`: Storage Box target configured, *pending key escrow* | controller log |
| 16:56:29 | **Escrow ceremony started** via the wizard | controller log |
| 16:56:39 | Recovery code claimed (one-shot, not logged) | controller log |
| **16:56:41** | Hub-verified → `EscrowState` auto-confirmed → offsite runs enabled (**12 s** ceremony → confirmed) | controller log |
| 16:58:12 | First offsite run starts | controller log |
| **16:58:14** | **ORPHAN GUARD FIRES**`offbox_repo_orphaned`, run skipped, card shown | controller log + events |
| 16:59:26 | Operator-confirmed reset: move-aside `/home/felhom-repo``.orphaned-20260718` | controller log |
| 16:59:32 | Fresh repo initialised; `offbox_repo_reset` | controller log + events |
| 16:59:38 → 16:59:50 | Backup run: 0 apps toggled, 0 snapshots, 7 s | controller log |
| **17:02:17** | **RAM grow 8192 → 12288 MB**, live cgroup, no reboot | controller log + agent journal |
| 17:05:15 | Calibre-Web deployed; deploy-page memory math now reads `total=12288MB` (**the grow rippled**) | events + controller log |
| 17:06:40 | Immich deployed | events |
| 17:11:16 | BookStack deployed (first start attempt failed `exit 1` 17:11:36; healthy by 17:12:03) | events + controller log |
| 17:13:38 → 17:14:22 | **Offsite run: 2 apps backed up, 1 skipped, 2 snapshots, 38 s** | controller log |
| 17:13:42 | Snapshot **`243ad08c`** — calibre-web | `restic-and-pool.txt` |
| 17:13:46 | Snapshot **`6df12205`** — immich | `restic-and-pool.txt` |
### Derived wall-clocks (the numbers R-3 needs)
| Leg | Wall-clock |
|---|---|
| Blank-metal boot → registered as unclaimed appliance | **< 1 s** (same second) |
| Self-bind link minted → customer consumed it | 1 min 0 s |
| **Bind → credential delivered** | **26 s** |
| Bind → agent enrolled + WG tunnel up | 56 s |
| **Bind → controller running the CURRENT version** | **2 min 44 s** |
| Credential delivered → day-0 provision SUCCESS | 2 min 11 s |
| **Managed-floor lift 0.143.0 → 0.145.0** | **5 s**, unattended |
| Drive enrol (confirm → usable, incl. mkfs) | 30.3 s |
| **Escrow ceremony → offsite runs enabled** | **12 s** |
| Boot → day-0 SUCCESS (incl. ~11.7 min waiting for the operator to send the link) | 15 min 18 s |
---
## Per-ledger verdicts
| Ledger | Verdict | Evidence |
|---|---|---|
| **S1** — stop apps, shut down, hub DOWN | **PASS** | `host_stale`/`node_stale` 16:05:24 |
| **S2** — the one BIOS visit (boot order, SB off, State-After-G3) | **PASS** (human leg) | Viktor at the box; SB-off is required by `--loader mkimage` |
| **S3** — the F1 moment: mkimage GRUB boots where stock GRUB threw `relocation 0x0` | **PASS** | The box reached first boot at 16:17:14 on the real board — **F1 is closed on physical hardware** |
| **S4** — unattended install → pairing mode → appears under Unclaimed appliances | **PASS** | `bootstrap-journal.txt` "PAIRING mode … registered — appliance token stored (0600)"; `appliance_registrations` id=3 `status=registered` |
| **S5** — the bind + the four-minute event composition, **no ~15-min stall between legs** | **PASS — and this is the immediacy proof** | Every post-bind leg is seconds apart: bind 16:29:55 → credential 16:30:21 → agent 16:30:49 → WG 16:30:51 → controller 16:32:28 → floor-lifted 16:32:39. **No leg stalled.** F5 auto-sizing landed the guest at **11675 MB** |
| **S6** — customer zero: claim → password → escrow ceremony → storage → **RAM grow *and* shrink** → deploy → enable offsite | **PASS on every leg, with two findings attached** | Ceremony 16:56:29→16:56:41; wipe gate pending→confirmed 16:41:42→16:41:51; **shrink 11675→8192 at 16:50:22 and grow 8192→12288 at 17:02:17, both live with no reboot**; 3 apps deployed. Findings: the config push logged the customer out (F3); offsite provisioning is **Save-triggered**, answering S6's open question |
| **S7** — first snapshot into a brand-new repo; **"if an orphan card appears, that's a finding"** | **FINDING — the orphan card appeared** | `offbox_repo_orphaned` 16:58:14. Recovered by the operator-confirmed move-aside 16:59:26→16:59:32; the run then produced **2 snapshots / 48.717 MiB** at 17:13:4246. The *guard* worked exactly as designed — the finding is that it had to |
| **S7 (operator gauges)** | **PARTIAL** | Restic tab: Viktor's screenshots. **PBS DR tab was not captured, and the reason now matters — see F2** |
| **S8** — wrap: evidence, VALIDATION doc, map flips, ROADMAP, R-3 | **DONE** — this document | `180:~/n100-rehearsal/MANIFEST.md` |
| **Ledger 8** — immediacy legs, first live firing on a real onboarding | **PASS** | See S5. The "real-onboarding proof pending" note on the immediacy row can be cleared |
| **Ledger 9** — R-24 guest RAM resize, the *apply* (not just the refusals) | **PASS, both directions** | Shrink **and** grow, live cgroup, no reboot, and the new total rippled into the deploy page's memory math at 17:05:15 |
---
## Findings (recorded and ranked — not fixed)
Ranked as proposed for the ROADMAP; IDs assigned in `backlog/ROADMAP.md`.
### F1 — Liveness presence lags reality by ~30 min (→ R-30, P2-HIGH)
The box was powered off at the start of the run, yet the hub carried it as healthy until the
staleness threshold expired at **16:05:24** ("no report for 30m"), and cleared only at **16:33:24**
("was stale for 27m"). The host-delete guard compounds this: RESET refuses while any host row
exists, so a stale-but-"online" host stalls a forced teardown. **Direction:** derive presence from
Dir-2 long-poll connectedness (~90 s grace), decoupled from notification hysteresis; agent/ep0
analog later.
### F2 — PBS DR tier is provisioned-but-dead, and cannot self-report it (→ R-39, P2-HIGH, **NEW — not in the brief**)
This was not forecast by the brief and is the run's most serious finding. Three facts:
1. The descriptor **was** auto-provisioned: the agent consumed a one-time token secret at 16:45:51
and reached `converged state=applied` at 16:45:53. `storage.cfg` holds a complete `pbs:
felhom-pbs` stanza (namespace `demo-felhom`, token `felhom@pbs!demo-felhom`, encryption key,
fingerprint).
2. **The storage is non-functional.** `pvesm status` → `felhom-pbs: error fetching datastores - 401
Unauthorized`, `inactive`. A direct probe with the stored credential returns **401 on every
endpoint including `/version`** — so this is authentication failure, not ACL scope. The transport
is healthy (WG handshake 9 s old, 27.9 ms RTT, `/version` reachable), so the token itself is
rejected server-side.
3. **The hub minted a second secret at 16:47:52 — two minutes after the agent applied the first —
and `consumed_at` is still NULL** ~55 min later. The agent will not pick it up: it has already
converged to `state=applied`, and its 15-minute verify loop cannot even read the credential to
detect the failure (`open /etc/pve/priv/storage/felhom-pbs.pw: permission denied` — the agent
runs non-root, writes the file through a root sudo wrapper, then tries to read it directly).
Net: a mint/consume race leaves the box on a stale secret, a converged state machine prevents
re-application, and a permission bug blinds the only loop that could notice. **The DR tier would
have failed silently on the first real restore.** This also explains why the S7 PBS DR gauge was
worth capturing — it would have shown the fault.
### F3 — Config apply restarts the controller and drops customer sessions (→ R-35, P2)
The offsite config push bumped `config_version` 10→11 at 16:54:58; the controller self-restarted
(container `StartedAt` 16:54:59Z) and came back at 16:55:02. In-memory sessions died with it, so
customer zero was force-logged-out mid-flow. **Direction:** hot-apply the offbox target, or persist
sessions across restart.
### F4 — Offsite provisioning is synchronous, with no status affordance (→ R-31, P2-HIGH)
Save runs the Hetzner sync in-request; the request can hit the nginx 504 while succeeding
server-side, so the operator cannot distinguish failed from slow, and a retry races the first
attempt. **Direction:** reuse the awaiting-card/poll idiom. Interim mitigation belongs in R-3:
**click once, wait, verify.**
### F5 — RESET destroys custody but not the ciphertext; the pool accumulates unattributed bytes (→ R-32, P2-HIGH)
The RESET ledger records `"hetzner":"ok"` — the sub-account **was** destroyed. But a Hetzner
sub-account is an access-control object, not a data object: deleting it leaves its directory intact.
Re-enabling offsite recreated a sub-account over the **same** `/home`, which still held the previous
lifecycle's repo — under a key destroyed by that same RESET. Hence S7's unexpected orphan card.
Measured on the pool box tonight:
| Path | Size | Status |
|---|---|---|
| `/home/felhom-repo` | **49 M** | live, attributed (2 snapshots, 48.717 MiB) |
| `/home/felhom-repo.orphaned-20260717` | **1.4 G** | unattributed, key destroyed — from the 07-17 incident |
| `/home/felhom-repo.orphaned-20260718` | **3.0 M** | unattributed, key destroyed — from tonight |
**Ruling from the run:** because RESET destroys custody, leftover ciphertext is unrecoverable **by
design**, so RESET gains a main-account purge of the customer base dir (the operator ack already
covers it). The move-aside guard **stays** for reinstall-without-RESET, where custody survives and
the card's promise is true. The operator Restic tab should show per-customer directory bytes against
attributed snapshot bytes so dead data cannot hide.
### F6 — Bootstrap pairing-poll spams the customer-visible console (→ R-33, P2-HIGH)
Each 30 s poll is a separate `felhom-bootstrap.service` run that exits 1, so systemd prints
`Failed to start …` on the console the customer is watching. **52 FAILED lines in ~11 minutes**,
while nothing was actually wrong — the box was correctly waiting to be bound. **Direction:** poll
*inside* the script (scripts v1.21) and reword the first-boot noise.
### F7 — Design-v2 gates are unenforced; one has been red for 16 releases
**Already ranked as R-29** (committed `2eccda4`, 2026-07-18) — the brief asked for a new ID, but the
finding already has one, including the `docker_run_volume_path_gate` /
`internal/appexport/estimate.go` attribution. **No new ID minted.**
### F8 — Backup data lifecycle is unmanaged (→ R-34, P2)
Apps with snapshots but no active backup (disabled or uninstalled) are invisible and undeletable.
**Direction:** an "inactive backups" section on Távoli mentés — name / size / last snapshot /
restorable, with an explicit double-confirmed per-app delete via `restic forget --tag` + nightly
prune. **RULING: the offsite toggle NEVER offers deletion — policy and destruction stay decoupled.**
### F9 — Post-RESET re-enroll leaves offsite "enabled but unprovisioned", silently (→ R-36, P2)
The hub knows the state and says nothing. Provisioning is **Save-triggered** (`configs.go`
`applyOffsite`) — confirmed live tonight, which answers S6's open question — and the re-enroll
auto-re-issue correctly skips unprovisioned targets (`handler.go`). **Direction:** flash it on the
customer page. Interim: an R-3 step. **Related:** auto-mint the self-bind link on customer
create/RESET so the console banner's "e-mailben kapott link" is always already true.
### F10 — Console-passphrase bind (→ R-27c, P2)
Viktor's direction, with the session's security constraints: passphrase issued at customer creation;
spray-hardened global-lookup endpoint (per-appliance + per-IP caps, constant-time, single generic
failure, alerting); accent-free wordlist for console keymaps; the web capability-link path
**RETAINED**; claim-by-email **RETAINED** as the delivery-channel proof. The self-bind email gains
the public universal-ISO download link + two-line instructions (the DIY case). **Secret-bearing
per-customer ISOs are ruled OUT.**
### F11 — Post-RESET health card shows stale pre-RESET warnings (→ R-37, P3)
Should read „RESET óta nincs adat".
### F12 — Installer GRUB menu offers interactive installers (→ R-38, P3)
Single default „Felhom telepítés" entry; interactive installers **REMOVED** (safety: wrong-disk
manual installs); felhom background. Squashfs/theme rebranding explicitly deferred.
---
## Observations (not findings — no ID minted)
- **Host/guest timezone split.** The PVE host runs CEST while the guest, controller and hub run UTC.
Nothing is broken, but every cross-tier correlation needs a manual 2 h shift, which is exactly the
kind of friction that produces wrong incident timelines under pressure. Flagged for a ruling
rather than ranked unilaterally.
- **The escrow awaiting-card window was 12 seconds.** Ceremony → hub-confirmed took 16:56:29 →
16:56:41, so the „megerősítésre vár, legfeljebb 15 perc" card rendered only briefly. The card is
correct and its ≤15-minute promise is honest, but capturing *both* states on screen is a matter of
luck at this speed.
- **BookStack skipped its first offsite run** — `no recovery unit found on any connected drive`
(17:13:42). This is the expected pre-first-nightly-dump state; the nightly job is scheduled
2026-07-19 04:15 CEST. **Watch item, not a finding** — it becomes one only if it still skips
afterwards.
- **BookStack's first start attempt failed** (`exit 1`, 17:11:36) and succeeded on retry by
17:12:03. Self-corrected; noted for pattern-watching only.
- **`felhom-samba` was not running** on the reborn box — sharing was not exercised this run
(consistent with *What was NOT exercised*).
---
## What was NOT exercised (explicit)
- **C6 — a customer performs a restore unassisted.** The single open script step in R-3, and still
**MISSING as evidence**. Remains remote-doable on the reborn box from vacation (the dashboard is
remote).
- **freemail.hu deliverability.** The gmail half is evidenced (claim email → Inbox under
`p=quarantine`); freemail.hu is Viktor's open half.
- **Sharing smoke on the reborn box** — R-7/R-7b were proven on the pre-RESET box; `felhom-samba` was
not deployed here.
- **R-19 WAN-outage drill.**
- **The PBS DR operator gauge** — not captured, and F2 means it would have shown a fault.
- **BookStack's offsite unit** — watch item, see *Observations*.
- **SMB positive auth with the real household password** — carried over from R-7b, unchanged.
---
## Discrepancies vs the Phase-A brief (live evidence wins)
1. **"expect ~11675 MB ballpark" — the final `pct config` reads 12288 MB.** Both are right at
different times: F5 auto-sized the guest to **11675 MB**, then customer zero **shrank it to 8192**
(16:50:22) and **grew it to 12288** (17:02:17). The brief described the F5 value; the box ended
above it because the grow was the last resize. Not a fault — and it is what completes ledger 9.
2. **"2.6 GB pool vs ~0 attributed" — measured 1.4 G + 3.0 M unattributed against 49 M attributed,
across TWO orphaned directories, not one.** The F5 ruling is unaffected; the numbers are.
3. **"felhom-pbs entry present" — present but `401 Unauthorized` / `inactive`.** The brief treated
the PBS descriptor as done; it is provisioned but dead. See F2.
4. **"RESET ×2 … second + third live firings" — the ledger holds exactly two rows, both tonight**
(`demo-vm-felhom` 15:49:57, `demo-felhom` 16:08:51), on **two different customers**. Any earlier
firing is not in `customer_resets`. Described here as tonight's two firings rather than as
ordinals.
5. **"keep the name R-29 if the number is free" — it is not free.** R-29 was committed earlier the
same day (`2eccda4`) for the design-v2 gate rot, which is also exactly the brief's item 5. The
liveness item therefore takes **R-30**, and no new ID was minted for the red-gate item.
6. **The brief's tip `a03e142` is two commits behind** `bbaa844`; Viktor's R-3 draft landed as
`runbooks/RUNBOOK-onboarding-draft-v3.md`, not `DRAFT-R3-onboarding-runbook.md`.
7. **F2 has no counterpart in the brief at all** — it was found by probing the box rather than by
following the finding list.
---
## Evidence bundle
`180:~/n100-rehearsal/` — see `MANIFEST.md` there for the per-file map. Secrets were read only to
run probes and are recorded as lengths and metadata, never as values.