0d463a859e
gates / gates (push) Successful in 6m12s
- closed: R-922 R-255 R-266 R-333 R-577 R-554 R-562 (controller 0.308.0 on demo-hp, demo-felhom, Tester 1), R-288 (map 212 KB -> 48 KB, detail per section) - R-521 narrowed to F7; R-388 design in 08 §8.1 (two questions for the operator) - privacy draft: why the registered address stays (S1); 02 module map: setup wizard deleted - STATUS + REPORT-answers-2026-10-12.md; docs.md routing line names capability-map-detail/ Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
257 lines
47 KiB
Markdown
257 lines
47 KiB
Markdown
# 00 — Felhom Capability Map
|
||
|
||
> **How to read this document.** Two kinds of statement appear, and where this document marks them it
|
||
> marks them like this — the same wording as `07-backup-architecture.md:11-17`, carried here on
|
||
> 2026-08-22 (R-376) so a reader meets one convention and not eight:
|
||
>
|
||
> - **[DESIGN]** — a decision taken. Not derived from code; the code may not implement it yet.
|
||
> - **[FACT]** — an observed property, carrying a `file:line`, a live command output or a citation.
|
||
>
|
||
> **Statements in this document are NOT yet all marked.** Marking them wholesale is a large judgement
|
||
> exercise and a wrong mark is worse than none, so only what a session touches is marked (R-376).
|
||
> **An unmarked statement therefore means "not yet classified", never "observed".** That ambiguity is
|
||
> exactly what cost this project three sessions in August 2026: the hot/bulk placement decision sat
|
||
> unmarked beside a marked `[FACT]`, and was read as an observation and reported as a defect.
|
||
|
||
> **What this is:** the single cross-component truth table of what the Felhom platform can do
|
||
> **today**, at what confidence level, with verifiable evidence. Rows are *scenarios* (user- or
|
||
> operator-visible outcomes), not modules — a scenario spans agent + controller + hub + catalog,
|
||
> and this is the only doc that shows that view.
|
||
>
|
||
> **What this is NOT:** a roadmap. Planned work lives in `documentation/backlog/ROADMAP.md` and is
|
||
> referenced from gap rows by ID (`→ R-n`). A row here never claims future behavior.
|
||
>
|
||
> **Status enum (strict):**
|
||
> | Status | Meaning |
|
||
> |--------|---------|
|
||
> | **PROVEN-LIVE** | Exercised end-to-end on real infrastructure; MUST cite a campaign/drill/validation doc in `documentation/audits/` or `documentation/tests/`. No citation → not PROVEN-LIVE. |
|
||
> | **IMPLEMENTED** | Shipped + unit/red-proof tested, but the real flow has not been exercised live (or not on the surface that matters — noted per row). |
|
||
> | **PARTIAL** | Some legs live, some missing/unvalidated — the note says which. |
|
||
> | **MISSING** | Does not exist. Present-tense fact; if planned, the row points at a roadmap ID. |
|
||
>
|
||
> **Shape (since 2026-10-12, R-288 with R-290 folded in — `09` §3 decisions 214 and 229).** One
|
||
> row per capability, and the row is short on purpose — a row nobody can finish is a row nobody
|
||
> re-reads, and that is how this map went stale:
|
||
>
|
||
> | Column | Holds |
|
||
> |---|---|
|
||
> | **ID** | the capability's id, linking to its **detail entry** — the full former row text, moved verbatim into `capability-map-detail/<section>.md` |
|
||
> | **Capability** | the scenario, one line (the former first cell) |
|
||
> | **Component** | what delivers it, with the version that was proven (historical, not current fleet state) |
|
||
> | **Status** | ONE word from the enum above |
|
||
> | **Scope** | a few words: where it was proven, what it does not cover, or how the word was arrived at |
|
||
> | **Evidence** | dated pointers: a file under `documentation/` as `path (YYYY-MM-DD)` — the date in the file's name, else its last commit — or a register id for a gap |
|
||
>
|
||
> **Rules of the shape:**
|
||
> - **Every PROVEN-LIVE row cites a file under `documentation/` that exists**, or says
|
||
> ***(evidence not on file — not re-verifiable)*** and names what the old text cited instead (a
|
||
> sibling repo's `REPORT.md`, a task file). Such a row keeps its status — nothing read contradicts
|
||
> it — but nobody can re-check it from this repository. **This conflicts with the enum's own rule
|
||
> above ("No citation → not PROVEN-LIVE")**: the 2026-10-12 restructure was told not to move a
|
||
> status without contradicting evidence, so the conflict is flagged here, not resolved. Each such
|
||
> row is a candidate to re-walk or to lower — an operator decision.
|
||
> - **Words outside the enum were normalised on 2026-10-12**, and the Scope cell says so:
|
||
> *written BUILT* and *written UNIT-PROVEN* → IMPLEMENTED; *written PROVEN* (a run on real
|
||
> infrastructure, not called PROVEN-LIVE) → PROVEN-LIVE. A row whose own status text said one of
|
||
> its legs is IMPLEMENTED only was **LOWERED** to PARTIAL, as the enum defines it; its Scope cell
|
||
> says *LOWERED … by its own words*. No status was raised.
|
||
> - **The argument lives in the detail file or the audit, never in the row.** A correction is
|
||
> written, dated, under the entry it corrects in `capability-map-detail/`.
|
||
>
|
||
> **Update rule (end-of-session checklist item):** if a task changed any capability's status,
|
||
> update the row in the same session — the status word, the Scope words, and a dated pointer to the
|
||
> new evidence file — and put the reasoning in the audit (or, for a correction, under the row's
|
||
> detail entry). A PROVEN-LIVE claim is subject to the cardinal rule like any other claim.
|
||
>
|
||
> *Verified 2026-07-16 against evidence corpus @ felhom.eu tip `4b18cc5` by CC (capability-map audit);
|
||
> see REPORT.md for the per-row verdict table.* *Restructured 2026-10-12 from commit `1b45bb4d`: every
|
||
> evidence path in the table was checked to exist that day; the statuses themselves were carried,
|
||
> not re-walked.*
|
||
|
||
---
|
||
|
||
## A. Provisioning & day-0
|
||
|
||
| ID | Capability | Component | Status | Scope | Evidence |
|
||
|---|---|---|---|---|---|
|
||
| <a id="a1"></a>[A1](capability-map-detail/A.md#a1) | Appliance day-0 install: golden image → first boot → auto-confirm (zero clicks) → claimable box | installer, agent, hub, golden | **PROVEN-LIVE** | nested VM; customer hardware pending (R-1) | `audits/DRILL-day0-vm-2026-07-12.md` (2026-07-12); `audits/DRILL-day0-take2-2026-07-12.md` (2026-07-12) |
|
||
| <a id="a2"></a>[A2](capability-map-detail/A.md#a2) | BYO install: `--mode byo`, mandatory caps, host-mutation disclosure, coexistence guards | installer v1.15+, agent | **PARTIAL** | demo box only; first real BYO run owed | `pilot/DRILL-GL6-2026-07-08.md` (2026-07-08); R-1 |
|
||
| <a id="a3"></a>[A3](capability-map-detail/A.md#a3) | The installer is PUBLISHED, not pushed — the artifact that runs as root on a virgin box is served from a version-controlled ref, and rolling back is one act | scripts v1.23.0 + `manifests/webpage.yaml` (R-110, operator ruling option (b)) | **PROVEN-LIVE** | HTTP against the real URL | *(evidence not on file — not re-verifiable)*: the row cites `scripts/CHANGELOG.md` v1.23.0 and a REPORT.md, both outside `documentation/` (2026-08-03) |
|
||
| <a id="a4"></a>[A4](capability-map-detail/A.md#a4) | Bare-metal Felhom ISO (blank hardware → zero-touch auto-install → first-boot `host-install`); selectable UEFI loader; universal secret-free / operator-bind mode | scripts v1.19.0 (`scripts/iso/`) + hub v0.62.0 + assistant container | **PROVEN-LIVE** | N100 (2026-07-18) and HP t740 (2026-07-21) | `tests/VALIDATION-n100-rehearsal-2026-07-18.md` (2026-07-18); `audits/SPIKE-baremetal-iso-2026-07-16.md` (2026-07-16) |
|
||
| <a id="a5"></a>[A5](capability-map-detail/A.md#a5) | Box survives a wrong-NIC install: hub-unreachable first boot → legible Hungarian console screen (NIC table + remedy) + NIC sweep self-heal (bounded DHCP + hub probe per NIC, success-only persist), and the baked root password is operator-knowable (`<iso>.rootpw.txt`) | scripts v1.24.0 (`felhom-bootstrap.sh`, `build-felhom-iso.sh`) | **PROVEN-LIVE** | nested drill; metal proof pending | `audits/SPIKE-firstboot-nic-sweep-2026-07-22.md` (2026-07-22) |
|
||
| <a id="a6"></a>[A6](capability-map-detail/A.md#a6) | Customer claim: one-time emailed code → customer sets own password (bcrypt, operator never sees it) | controller v0.122, hub v0.50 | **PROVEN-LIVE** | drill VM; no non-operator human yet (R-3) | `audits/DRILL-day0-vm-2026-07-12.md` (2026-07-12) |
|
||
| <a id="a7"></a>[A7](capability-map-detail/A.md#a7) | Customer binds their own appliance (self-service): operator-sent 7-day tokenized capability link → public two-factor `/bind/<token>` (console pairing code + retrieval passphrase) → hub stages the bind, no operator | hub v0.66.0 + ISO scripts v1.20.0 | **PROVEN-LIVE** | customer-zero, on metal | `tests/VALIDATION-n100-rehearsal-2026-07-18.md` (2026-07-18) |
|
||
| <a id="a8"></a>[A8](capability-map-detail/A.md#a8) | Escrow ceremony: customer-facing wizard, one-shot R claim, operator zero-knowledge | controller v0.127, agent v0.88/0.89 | **PROVEN-LIVE** | drill VM, endpoint-exact; browser wizard first fired 2026-07-18 | `audits/SPIKE-controller-escrow-2026-07-13.md` (2026-07-13); `tests/VALIDATION-n100-rehearsal-2026-07-18.md` (2026-07-18) |
|
||
| <a id="a9"></a>[A9](capability-map-detail/A.md#a9) | One name per secret on every surface — „Beállító kód" (the setup code) and „Tulajdonosi jelmondat" (the owner passphrase) — and the re-enrol mail points at a page a rebuilt box shows | controller v0.211.0, hub v0.104.0 + v0.105.0 (R-295, R-323) | **IMPLEMENTED** | written BUILT: source-read; no customer has typed the passphrase | R-295; R-323 |
|
||
| <a id="a10"></a>[A10](capability-map-detail/A.md#a10) | The offsite repository password can be RECOVERED from the sealed escrow with the customer's recovery code | hub v0.94.0, agent v0.125.0, controller v0.195.0 | **PROVEN-LIVE** | demo-felhom, real endpoints | `audits/DRILL-r201-offsite-recovery-2026-08-04.md` (2026-08-04); `audits/RECON-offsite-dr-chain-2026-08-04.md` (2026-08-04) |
|
||
| <a id="a11"></a>[A11](capability-map-detail/A.md#a11) | DR tier by default: PBS + WireGuard base infra on every install, hub-controlled activation | installer v1.15, agent v0.86, hub v0.51 | **PROVEN-LIVE** | demo/drill fleet only | `audits/DRILL-day0-take2-2026-07-12.md` (2026-07-12) |
|
||
| <a id="a12"></a>[A12](capability-map-detail/A.md#a12) | A customer's file survives a machine rebuild and comes back — the whole off-site story, end to end | hub v0.94.0, agent v0.125.0, controller v0.197.0 | **PROVEN-LIVE** | the success path; the failure path is not claimed (R-379, R-380) | `audits/DRILL-r201-night-run-2026-08-04.md` (2026-08-04); `audits/DRILL-r356-hot-only-restore-2026-08-22/` (2026-08-22); `audits/DRILL-r356b-driveless-db-restore-2026-08-22/` (2026-08-22) |
|
||
| <a id="a13"></a>[A13](capability-map-detail/A.md#a13) | The customer's own UNAIDED recovery journey, end to end | controller v0.206.0, hub v0.98.0, agent v0.127.0 | **PROVEN-LIVE** | fifth walk, scoped — read what it does not claim | `tests/walk5-r201-2026-08-07/journal.md` (2026-08-07); `audits/CAMPAIGN-11-recovery-journey-2026-08-05.md` (2026-08-05) |
|
||
| <a id="a14"></a>[A14](capability-map-detail/A.md#a14) | A random night of household actions while random things go wrong — twelve rounds, unattended | controller v0.245.0, agent v0.131.0, hub v0.116.0, golden 0.245.0, ISO 1.28.0 | **PROVEN-LIVE** | nested box, twelve chaos rounds | `audits/DRILL-chaos-night-2026-09-17.md` (2026-09-17) |
|
||
| <a id="a15"></a>[A15](capability-map-detail/A.md#a15) | A stranger's FIRST HOUR on a fresh install — download → install → claim → two apps → use → backup → remove → restore, plus a power cut and a mistyped code | controller v0.242.0, agent v0.130.0, hub v0.112.0, golden 0.242.0, installer ISO 1.26.1 | **PARTIAL** | every mechanism passed; the unaided journey failed before the first app | `audits/DRILL-fresh-install-0242-2026-09-14.md` (2026-09-14); `audits/DRILL-new-household-2026-09-30.md` (2026-09-30) |
|
||
| <a id="a16"></a>[A16](capability-map-detail/A.md#a16) | Off-site app-data capture covers the paths an app declares MANDATORY — on BOTH drive layouts | controller v0.197.0 | **PROVEN-LIVE** | both drive layouts | `audits/DRILL-r201-offsite-recovery-2026-08-04.md` (2026-08-04) |
|
||
| <a id="a17"></a>[A17](capability-map-detail/A.md#a17) | Recurring offsite (PBS) whole-guest backups actually LAND, and RESTORE — local daily + offsite weekly as scheduled work | agent v0.97–0.103, controller v0.174/0.175, hub v0.76.0, host-install 1.20.0 | **PROVEN-LIVE** | demo-hp | `audits/SPIKE-r82-phase0-2026-07-26.md` (2026-07-26) |
|
||
| <a id="a18"></a>[A18](capability-map-detail/A.md#a18) | Restore-proof is UNATTENDED — the scheduler covers EVERY tier, follows the BACKUP rather than the clock, and a failure is heard | agent v0.104.0 → v0.121.0, hub v0.77.0 → v0.91.0 | **PROVEN-LIVE** | — | *(evidence not on file — not re-verifiable)*: the row cites per-repo CHANGELOGs and the spec `backlog/SPEC-r85-phase4-5-2026-07-26.md` — a spec, not a run record |
|
||
| <a id="a19"></a>[A19](capability-map-detail/A.md#a19) | A restore-test can never fill the box's disk: it sizes the restore first (uncompressed), keeps off the tested guest's pool when it can, refuses what does not fit, and retries a failed clean-up on a timer | agent v0.133.0 (RELEASED, NOT DELIVERED), hub v0.124.0 | **IMPLEMENTED** | written BUILT: the refusal proven on demo-hp 2026-09-24; the full-test path not live | `audits/r672-2026-09-24/` (2026-09-24); R-672 |
|
||
| <a id="a20"></a>[A20](capability-map-detail/A.md#a20) | Customer RESET (middle lifecycle tier: host delete < RESET < customer Delete): one operator action → pre-first-install; all operational state destroyed, identity + basic config survive | hub v0.61.0, felhom-tenantsync v1.1.0 | **PROVEN-LIVE** | two real firings | `tests/VALIDATION-n100-rehearsal-2026-07-18.md` (2026-07-18) |
|
||
| <a id="a21"></a>[A21](capability-map-detail/A.md#a21) | Customer DELETE cascade (top lifecycle tier): one guided operator action → `hosts → RESET → residue → purge`; host rows deleted (custody DEMOTED), full external teardown (Hetzner repo destroyed, PBS namespace/token revoked, tunnel + zone removed), then the customer record and ALL escrow ciphertext purged | hub v0.69.0 | **IMPLEMENTED** | written UNIT-PROVEN: live leg pending | hub unit tests `hub/internal/web/customer_delete_test.go` (outside `documentation/`) |
|
||
| <a id="a22"></a>[A22](capability-map-detail/A.md#a22) | Uninstall: KEPT-vs-WIPED statement, secret purge, enrolled-drive handling | installer | **PARTIAL** | GL6-F2 open | `pilot/DRILL-GL6-2026-07-08.md` (2026-07-08); R-9 |
|
||
|
||
## B. Apps & catalog
|
||
|
||
| ID | Capability | Component | Status | Scope | Evidence |
|
||
|---|---|---|---|---|---|
|
||
| <a id="b1"></a>[B1](capability-map-detail/B.md#b1) | Deploy an app from the catalog (env config, memory guard, health-aware progress) | controller, catalog (~52 apps, images pinned) | **PROVEN-LIVE** | — | `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07); `audits/RERUN-p1p3-2026-07-06.md` (2026-07-06) |
|
||
| <a id="b2"></a>[B2](capability-map-detail/B.md#b2) | App lifecycle: start/stop/restart/update/logs/remove/redeploy | controller | **PROVEN-LIVE** | the actions; remove-with-data re-proven 2026-09-13 | `audits/R442-2026-09-13/` (2026-09-13); `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07) |
|
||
| <a id="b3"></a>[B3](capability-map-detail/B.md#b3) | Update is GUARDED: it refuses without a restorable backup, backs up first when the copy is stale, and HOLDS an app that does not come up — on ANY backup tier, and the release itself arrives by the managed floor | controller v0.237.0 + v0.238.0 + v0.238.1 + v0.239.0, hub v0.112.0 | **PROVEN-LIVE** | — | `audits/slice4-2026-09-13/` (2026-09-13); `audits/rulings-r472-r475-2026-09-13/` (2026-09-13) |
|
||
| <a id="b4"></a>[B4](capability-map-detail/B.md#b4) | A failed update is UNDONE by the box itself — the previous version back with its data from seconds before the update; the app is held only if that undo fails too | controller v0.263.2 (the undo), v0.264.0 + hub v0.120.0 (the mail) | **PROVEN-LIVE** | scratch 9202 | `audits/undo-live-2026-09-23/README.md` (2026-09-23) |
|
||
| <a id="b5"></a>[B5](capability-map-detail/B.md#b5) | The catalog holds only TESTED steps — an image move without a proven test record (bench + box, digests the registry still serves) is refused at push time | catalog `6db08a5` (test-record gate, `ladder.py`) | **PROVEN-LIVE** | written PROVEN: the catalog gate against the live registry | `audits/DRILL-night-2026-09-23.md` (2026-09-23) |
|
||
| <a id="b6"></a>[B6](capability-map-detail/B.md#b6) | A box behind climbs ONE tested step per press, each with its own definition (`09` §3 decision 14) | controller v0.268.0 + catalog `5ed599c` | **PROVEN-LIVE** | — | `audits/ladder-2026-09-24/partD/10-romm-two-steps.json` (2026-09-24) |
|
||
| <a id="b7"></a>[B7](capability-map-detail/B.md#b7) | A file app comes back WHOLE from the second drive — its files by four rules (never delete, never overwrite a newer file, bring back what is missing, keep an older replaced file beside it), then its settings and database (`09` §3 decision 26) | controller v0.269.0 (`backup/tier2_whole.go`) | **PROVEN-LIVE** | — | `audits/night-2026-09-24/A1/21-readback.json` (2026-09-24) |
|
||
| <a id="b8"></a>[B8](capability-map-detail/B.md#b8) | A crash-looping or out-of-memory app is STOPPED by the box, the household and operator are told, and Start gives one more try (decision 28) | controller v0.269.0, hub v0.123.0 | **PROVEN-LIVE** | — | `audits/night-2026-09-24/A3/21-gokapi-page-event.txt` (2026-09-24) |
|
||
| <a id="b9"></a>[B9](capability-map-detail/B.md#b9) | A held app whose page says support is informed can only be removed KEEPING its data (decision 27) | controller v0.269.0 | **PROVEN-LIVE** | — | `audits/night-2026-09-24/A2/10-held-no-copy-keep-data.json` (2026-09-24) |
|
||
| <a id="b10"></a>[B10](capability-map-detail/B.md#b10) | The box runs the exact TESTED image of a floating tag, and an installed app keeps its image until a guarded Update moves it (`09` §6.4 part 6, box half) | controller v0.269.1 (`stacks/digest.go`) | **PROVEN-LIVE** | — | `audits/night-2026-09-24/B/21-floating-tag-0.269.1.json` (2026-09-24) |
|
||
| <a id="b11"></a>[B11](capability-map-detail/B.md#b11) | Automatic updates at night — the update leg (`09` §6.4 part 7) | controller v0.271.0 | **PROVEN-LIVE** | scratch 9202, six simulated nights; demo boxes in Part D | `audits/DRILL-night-2026-09-25.md` (2026-09-25) |
|
||
| <a id="b12"></a>[B12](capability-map-detail/B.md#b12) | What `restart` and `update` do to a deployed app whose compose file the catalog already moved | controller v0.235.0 | **PROVEN-LIVE** | HISTORY: the behaviour up to v0.234.0; changed 2026-09-06 — current behaviour is B17 | `audits/SPIKE-app-update-2026-09-01.md` (2026-09-01) |
|
||
| <a id="b13"></a>[B13](capability-map-detail/B.md#b13) | Whether the box UPGRADES an app by itself, with nobody pressing anything | controller | **PROVEN-LIVE** | answer: yes, only when an app fails to come back (measured 2026-09-01) | `audits/SPIKE-app-update-2026-09-01.md` (2026-09-01) |
|
||
| <a id="b14"></a>[B14](capability-map-detail/B.md#b14) | Whether an app UPGRADE can be undone | controller + catalog | **PROVEN-LIVE** | answer: no, once a migration has run | `audits/SPIKE-app-update-2026-09-01.md` (2026-09-01) |
|
||
| <a id="b15"></a>[B15](capability-map-detail/B.md#b15) | Protected infra stacks can't be stopped/removed from UI | controller | **PROVEN-LIVE** | — | `audits/CAMPAIGN-nomercy-2026-07-06.md` (2026-07-06); `audits/RERUN-p1p3-2026-07-06.md` (2026-07-06) |
|
||
| <a id="b16"></a>[B16](capability-map-detail/B.md#b16) | What VERSION a box is running, and whether it is behind the catalog | controller v0.234.0 + catalog `69761cf` | **PROVEN-LIVE** | the record and the rendered badge | `tests/VALIDATION-update-slice12-2026-09-02.md` (2026-09-02) |
|
||
| <a id="b17"></a>[B17](capability-map-detail/B.md#b17) | An app's VERSION is frozen to what the customer has; only a deliberate Update moves it, while template CORRECTIONS still arrive | controller v0.235.0 | **PROVEN-LIVE** | two real catalog pushes, real 15-minute cycle | `tests/VALIDATION-update-slice3-2026-09-06.md` (2026-09-06) |
|
||
| <a id="b18"></a>[B18](capability-map-detail/B.md#b18) | Catalog sync (git, 15 min) + orphan lifecycle + validation choke point (bad `backup:` block degrades to legacy, loudly) | controller v0.132, catalog | **PROVEN-LIVE** | — | `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07) |
|
||
| <a id="b19"></a>[B19](capability-map-detail/B.md#b19) | Lemez-egészség felügyelet: per-disk SMART kártya („Lemezek állapota") + degradáció-riasztás (Rendben/Figyelmeztetés/Hiba/Nincs adat) | agent v0.94.0→v0.95.0, controller v0.169.0→v0.171.0→v0.215.0, hub v0.73.1 | **PARTIAL** | LOWERED from PROVEN-LIVE by its own words: the Hiba-from-counters path is unit-only (R-332) | `audits/SPIKE-smart-coverage-2026-07-25.md` (2026-07-25); `audits/DIAG-smart-passed-trap-2026-08-14.md` (2026-08-14) |
|
||
| <a id="b20"></a>[B20](capability-map-detail/B.md#b20) | App crashes → customer notified (one event per transition, no flapping spam) | controller v0.120, hub v0.48 | **IMPLEMENTED** | crash→customer mail never live-confirmed | `audits/CAMPAIGN-3-2026-07-11.md` (2026-07-11) |
|
||
| <a id="b21"></a>[B21](capability-map-detail/B.md#b21) | Post-deploy optional config (API keys etc.) with restart | controller, catalog `.felhom.yml` | **IMPLEMENTED** | config-save + restart in no campaign | `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07) |
|
||
| <a id="b22"></a>[B22](capability-map-detail/B.md#b22) | Backup classification: 13 bind-bearing apps carry mandatory/optional/excluded classes | catalog, controller v0.132–133 | **PROVEN-LIVE** | — | `audits/SPIKE-backup-classification-2026-07-14.md` (2026-07-14); `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15) |
|
||
|
||
## C. Protection & recovery (the product promise)
|
||
|
||
> **Coupling (2026-07-28, S-1).** The **failure → recovery matrix** in
|
||
> `07-backup-architecture.md` §8 is authoritative for *which failure has which recovery route, who
|
||
> can invoke it, and what its measured RTO is*. This section stays authoritative for *per-capability
|
||
> status*. **Neither restates the other** — rows below carry a `→ 07 §8 row n` pointer instead of
|
||
> repeating the route. Where a row's status and the matrix's status differ in wording, the matrix is
|
||
> about the **failure** and the row is about the **mechanism**; that is not a contradiction, and both
|
||
> cite the same evidence.
|
||
>
|
||
> The matrix's blank RTO/RPO cells are deliberate: no number is estimated anywhere. The two counts of
|
||
> Tier-2 app coverage that used to disagree (9/43/1 vs 7/45/1) were **settled 2026-08-31 by measurement
|
||
> at catalogue `459766cb1639`: A = 7 · B = 45 · C = 1** (`07-backup-architecture.md` §6.2, which also
|
||
> records which prior count was wrong and why). Take the number from there, not from memory.
|
||
>
|
||
> *Since 2026-10-12 a row's `→ 07 §8 row n` pointer sits in its detail entry, not in the row.*
|
||
|
||
| ID | Capability | Component | Status | Scope | Evidence |
|
||
|---|---|---|---|---|---|
|
||
| <a id="c1"></a>[C1](capability-map-detail/C.md#c1) | Whole-guest backup lands OFF the guest's own physical device; a single-drive box is recorded DEGRADED rather than silently normal (installer Case A/B) | agent v0.113, host-install v1.22.0 | **PROVEN-LIVE** | — | `audits/E2D-fresh-vm-2026-07-29.md` (2026-07-29) |
|
||
| <a id="c2"></a>[C2](capability-map-detail/C.md#c2) | Nightly DB dumps (postgres/mariadb autodiscovery), atomic writes | controller v0.118 | **PROVEN-LIVE** | — | `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07); `audits/CAMPAIGN-6E-2026-07-15.md` (2026-07-15) |
|
||
| <a id="c3"></a>[C3](capability-map-detail/C.md#c3) | Tier-2 secondary-drive copy: class-driven legs, v2 relpath layout, NAS-target exclusion, safe-remove boundary | controller v0.135 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6E-2026-07-15.md` (2026-07-15); `audits/CAMPAIGN-6C-2026-07-14.md` (2026-07-14) |
|
||
| <a id="c4"></a>[C4](capability-map-detail/C.md#c4) | Offsite (restic → Hetzner Storage Box): mandatory class only, raw-data quota, enlargement gate, retention regrouping | controller v0.134, agent, hub | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15); `audits/VALIDATION-offbox-storagebox-2026-07-09.md` (2026-07-09) |
|
||
| <a id="c5"></a>[C5](capability-map-detail/C.md#c5) | Offsite restore: local-preferred scratch, unit-only default, full two-step, missing-only place-to-live | controller v0.134/134.1/135 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15); `audits/DIAG-immich-restore-round2-2026-07-19.md` (2026-07-19) |
|
||
| <a id="c6"></a>[C6](capability-map-detail/C.md#c6) | Manual `.fab` export/import: class-scoped capture, browser up/download, tunnel-proof chunking | controller v0.125/128/130/136 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15); `audits/CAMPAIGN-6B-2026-07-14.md` (2026-07-14) |
|
||
| <a id="c7"></a>[C7](capability-map-detail/C.md#c7) | Guest-loss DR: PBS restore with full-fidelity layout from archive, restore-test verification | agent v0.75/0.76, PBS | **PROVEN-LIVE** | — | `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07); `pilot/DRILL-GL6-2026-07-08.md` (2026-07-08) |
|
||
| <a id="c8"></a>[C8](capability-map-detail/C.md#c8) | PBS-DR secret self-heal on reused-peer re-provision | hub v0.56 | **IMPLEMENTED** | scoped to one host | `audits/SPIKE-pbsdr-selfheal-2026-07-15.md` (2026-07-15) |
|
||
| <a id="c9"></a>[C9](capability-map-detail/C.md#c9) | Box survives an unattended app or guest-network failure (a dead app member, a boot-orphaned app, a dead DHCP client) — it is noticed, and where safe it is repaired | controller v0.156.0→v0.190.0, agent v0.92.1 | **PROVEN-LIVE** | demo box; boot-orphan leg 6 of 6 hard resets | `audits/DIAG-bootrecon-drive-absent-2026-08-02.md` (2026-08-02) |
|
||
| <a id="c10"></a>[C10](capability-map-detail/C.md#c10) | Crash/power-loss mid-backup/mid-migration → self-heal on next run | controller, agent | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15); `audits/CAMPAIGN-6E-2026-07-15.md` (2026-07-15) |
|
||
| <a id="c11"></a>[C11](capability-map-detail/C.md#c11) | An app can be withdrawn from the catalog without orphaning the customers running it (available / hidden / abandoned) | controller v0.158.1, catalog metadata | **PROVEN-LIVE** | guest 9201, real endpoints | *(evidence not on file — not re-verifiable)*: the row cites TASK-F Part 1 and `felhom-controller/REPORT.md` (2026-07-21), both outside `documentation/` |
|
||
| <a id="c12"></a>[C12](capability-map-detail/C.md#c12) | Box survives a site/network change (relocation, different subnet, DHCP re-lease) with the control plane intact | agent v0.96.0 (island NIC), host-install v1.19.0, controller (unchanged), bootstrap | **PROVEN-LIVE** | — | `audits/SPIKE-island-bridge-2026-07-25.md` (2026-07-25) |
|
||
| <a id="c13"></a>[C13](capability-map-detail/C.md#c13) | The customer is warned BEFORE a filesystem fills — per filesystem, in Hungarian, naming the drive and the free space, edge-triggered | controller v0.191.0/.1/.2, hub v0.89.0 (R-167, decision D-c) | **PROVEN-LIVE** | guest 9201, a real filesystem | *(evidence not on file — not re-verifiable)*: the row cites `felhom-controller/REPORT.md` (2026-08-02); `audits/SPIKE-r165-mp1-merge-2026-08-02.md` is cited as context only |
|
||
| <a id="c14"></a>[C14](capability-map-detail/C.md#c14) | A failed per-app Tier-1 backup reaches the OPERATOR — EVERY failing app, in ONE mail per run, and every failure recorded whether or not it is mailed | controller v0.194.0, hub v0.90.1 (R-158 → R-167 → R-182) | **PROVEN-LIVE** | guest 9201 | *(evidence not on file — not re-verifiable)*: the row cites `felhom-controller/REPORT.md` (2026-08-03), outside `documentation/` |
|
||
| <a id="c15"></a>[C15](capability-map-detail/C.md#c15) | A local backup is bounded by the box's FREE SPACE, not by a partition set at build time — the appliance ships ONE data volume, and a capture that would exhaust it is refused per app rather than allowed to stop the container runtime | golden `build-golden.sh` v3.0.0, agent v0.120.0, controller v0.193.1 | **PROVEN-LIVE** | both halves | `audits/SPIKE-r165-phase0-2026-08-03.md` (2026-08-03) |
|
||
| <a id="c16"></a>[C16](capability-map-detail/C.md#c16) | Soft-quota: usage bar, pre-push enlargement block, customer notification | controller v0.109/134, hub v0.41/55 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15); `audits/CAMPAIGN-6E-2026-07-15.md` (2026-07-15) |
|
||
| <a id="c17"></a>[C17](capability-map-detail/C.md#c17) | A customer (not the operator) performs a restore via UI alone | all | **MISSING** | as evidence | `audits/DIAG-immich-restore-2026-07-19.md` (2026-07-19); R-3 |
|
||
|
||
## D. Storage & devices
|
||
|
||
| ID | Capability | Component | Status | Scope | Evidence |
|
||
|---|---|---|---|---|---|
|
||
| <a id="d1"></a>[D1](capability-map-detail/D.md#d1) | A second drive appearing is OFFERED as the backup target; accepting moves it; registration and the drive gate confer no role by themselves | controller v0.186.0, agent v0.113 | **PROVEN-LIVE** | — | `audits/SESSION-C-2026-07-29.md` (2026-07-29) |
|
||
| <a id="d2"></a>[D2](capability-map-detail/D.md#d2) | Drive wizard: scan/format/mount/enroll, incl. legacy-boot LVM-root hosts | controller, agent v0.87 | **PROVEN-LIVE** | — | `audits/DISPOSITION-ia-finding2-systemdisks-2026-07-13.md` (2026-07-13); `audits/storage-lifecycle-acceptance-2026-06-15.md` (2026-06-15) |
|
||
| <a id="d3"></a>[D3](capability-map-detail/D.md#d3) | Data migration between drives (all / per-app), crash-safe | controller | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6C-2026-07-14.md` (2026-07-14); `audits/storage-lifecycle-acceptance-2026-06-15.md` (2026-06-15) |
|
||
| <a id="d4"></a>[D4](capability-map-detail/D.md#d4) | NAS (NFS/SMB-client) verify-before-commit, uid-1000 probe, categorized Hungarian errors, DSM-validated | controller v0.113–117, agent v0.81/84/85 | **PROVEN-LIVE** | — | `audits/SPIKE-nas-verify-2026-07-11.md` (2026-07-11); `audits/SPIKE-nas-dsm-2026-07-11.md` (2026-07-11) |
|
||
| <a id="d5"></a>[D5](capability-map-detail/D.md#d5) | Network storage (NAS) is browse + bulk-media only — it may NOT host an app's data namespace | controller v0.187.0 | **PROVEN-LIVE** | — | `audits/R108-network-app-namespace-2026-07-30.md` (2026-07-30) |
|
||
| <a id="d6"></a>[D6](capability-map-detail/D.md#d6) | A Tier-1/Tier-2 app restore works from the DRIVE ALONE — the recovery unit carries the app's secrets (D5) | controller v0.188.0 | **PROVEN-LIVE** | — | `audits/D5-drive-alone-restore-2026-07-30.md` (2026-07-30) |
|
||
| <a id="d7"></a>[D7](capability-map-detail/D.md#d7) | A restore SAYS what it returned, and refuses what it cannot do — the four restore-surface truth defects from the 2026-08-21 drill | controller v0.226.0 (R-353, R-357, R-358, R-360, R-396) | **PARTIAL** | LOWERED from PROVEN-LIVE by its own words: three of four live; R-357 implemented only | `audits/evidence-r353-r360-live-2026-08-30/live-validation.txt` (2026-08-30) |
|
||
| <a id="d8"></a>[D8](capability-map-detail/D.md#d8) | The box PROVES its own off-site copy still HOLDS something — a backup that is intact and EMPTY is caught without a person | controller v0.231.0 (R-87) + hub v0.110.0 | **PARTIAL** | LOWERED from PROVEN-LIVE by its own words: the scheduled firing is implemented only | `tests/r87-offsite-proof-2026-08-31/` (2026-08-31) |
|
||
| <a id="d9"></a>[D9](capability-map-detail/D.md#d9) | The off-site store is VERIFIED on a cadence — something checks that the customer's backups are still readable | controller v0.228.0 (R-359, R-397, R-399) | **PARTIAL** | LOWERED from PROVEN-LIVE by its own words: the scheduled firing is implemented only | `tests/r359-integrity-2026-08-30/` (2026-08-30) |
|
||
| <a id="d10"></a>[D10](capability-map-detail/D.md#d10) | USB drive enrollment + unplug detection + recommission | controller, agent | **PROVEN-LIVE** | — | `audits/storage-lifecycle-acceptance-2026-06-15.md` (2026-06-15); `audits/CAMPAIGN-4-2026-07-13.md` (2026-07-13) |
|
||
| <a id="d11"></a>[D11](capability-map-detail/D.md#d11) | Decommission (migrate-first and anyway-paths), eject | agent, controller | **PROVEN-LIVE** | — | `audits/storage-lifecycle-acceptance-2026-06-15.md` (2026-06-15) |
|
||
| <a id="d12"></a>[D12](capability-map-detail/D.md#d12) | Boot ordering: automount + networking survive reboot; appliance self-heal watchdog | agent v0.85 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-4-2026-07-13.md` (2026-07-13); `audits/CAMPAIGN-6A-2026-07-14.md` (2026-07-14) |
|
||
|
||
## E. Access, networking & household use
|
||
|
||
| ID | Capability | Component | Status | Scope | Evidence |
|
||
|---|---|---|---|---|---|
|
||
| <a id="e1"></a>[E1](capability-map-detail/E.md#e1) | Remote access via Cloudflare Tunnel + Traefik (per-app subdomains) | cloudflared, traefik | **PROVEN-LIVE** | — | `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07) |
|
||
| <a id="e2"></a>[E2](capability-map-detail/E.md#e2) | LAN access when internet is down (lan_resolver) | agent | **IMPLEMENTED** | never drilled as a customer experience | R-19 |
|
||
| <a id="e3"></a>[E3](capability-map-detail/E.md#e3) | Phone photo backup | immich (classified) | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15) |
|
||
| <a id="e4"></a>[E4](capability-map-detail/E.md#e4) | Documents/OCR | paperless-ngx (classified) | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6C-2026-07-14.md` (2026-07-14) |
|
||
| <a id="e5"></a>[E5](capability-map-detail/E.md#e5) | Files from Windows Explorer / Mac Finder (SMB server) | controller v0.145.0 + `felhom-samba:1.0.0` | **PROVEN-LIVE** | — | *(evidence not on file — not re-verifiable)*: the row cites `felhom-controller` REPORT.md (v0.144.0, outside `documentation/`), the design `controller/sharing.md` and the transport verdict `audits/SPIKE-lan-discovery-2026-07-18.md` — none is a run of the shipped server |
|
||
| <a id="e6"></a>[E6](capability-map-detail/E.md#e6) | Media to TV via DLNA | — | **MISSING** | — | R-6; R-8 |
|
||
| <a id="e7"></a>[E7](capability-map-detail/E.md#e7) | File access via browser | FileBrowser (infra app, auto-mount sync) | **IMPLEMENTED** | browse/download through FileBrowser in no doc | `audits/storage-lifecycle-acceptance-2026-06-15.md` (2026-06-15); R-75 |
|
||
| <a id="e8"></a>[E8](capability-map-detail/E.md#e8) | Indítópult (app launcher) — one-tap grid of the household's openable apps | controller v0.163.0 | **IMPLEMENTED** | live click-through pending | R-72 |
|
||
| <a id="e9"></a>[E9](capability-map-detail/E.md#e9) | Indítópult megosztás (vendég link) — capability URL `/s/<token>` serves a standalone read-only guest launcher (no account, no admin session); optional per-share password; QR | controller v0.165.0 | **IMPLEMENTED** | — | R-15 |
|
||
| <a id="e10"></a>[E10](capability-map-detail/E.md#e10) | Forgot dashboard password → instant reset code | controller v0.123, hub | **PROVEN-LIVE** | — | `audits/DRILL-day0-take2-2026-07-12.md` (2026-07-12) |
|
||
| <a id="e11"></a>[E11](capability-map-detail/E.md#e11) | The dashboard in English — the household picks its language; Hungarian unchanged | controller v0.247.0 (spike) → v0.250.0 (slice 1, R-556 CLOSED) | **PARTIAL** | every dashboard template live; other surfaces open | `audits/i18n-slice1-2026-09-17/C/live/` (2026-09-17); `audits/i18n-2026-09-17/live/` (2026-09-17) |
|
||
| <a id="e12"></a>[E12](capability-map-detail/E.md#e12) | The box tells visitors apart — a stranger's wrong passwords lock only the stranger (dashboard, setup gate, apps that read the visitor from the right) | controller v0.286.1, catalog router resets | **PARTIAL** | — | `audits/visitors-2026-10-01/A/L2-demo-hp-real-tunnel.txt` (2026-10-01); R-779 |
|
||
| <a id="e13"></a>[E13](capability-map-detail/E.md#e13) | The family gate — a permanent door with each family member's own login in front of an app (Grimmory with its e-reader exceptions, MeTube with none) | controller v0.287.0, catalog `family_gate:`, golden 0.287.0 | **PROVEN-LIVE** | written PROVEN: on scratch 9202; not yet a phone over the real internet | `audits/family-gate-2026-10-02/A/items.txt` (2026-10-02) |
|
||
| <a id="e14"></a>[E14](capability-map-detail/E.md#e14) | Multiple household users / per-person accounts | — | **MISSING** | — | R-15 |
|
||
| <a id="e15"></a>[E15](capability-map-detail/E.md#e15) | A second login step for the dashboard (a TOTP code or a passkey) | — | **MISSING** | — | R-811 |
|
||
| <a id="e16"></a>[E16](capability-map-detail/E.md#e16) | The household can leave Felhom, or outlive it — the box runs without the hub, the household owns its domain, tunnel and off-site account, and can export everything | — | **MISSING** | as a written answer | R-810 |
|
||
| <a id="e17"></a>[E17](capability-map-detail/E.md#e17) | The host agent cannot reach root without the operator key: exact sudo patterns, no agent-written file installed where root reads it without a content check, the agent binary only by an operator-signed update checked as root | agent v0.146.1 (R-861; delivered by a step bundle, R-880) | **PROVEN-LIVE** | both demo boxes; three named residuals | `audits/hub-safety-2026-10-05/partF/` (2026-10-05) |
|
||
| <a id="e18"></a>[E18](capability-map-detail/E.md#e18) | WireGuard base infra always-on; OOB operator access (felhom-sshd, /32 peer) | agent v0.72, hub v0.35 | **IMPLEMENTED** | — | `audits/SPIKE-oob-wg-operator-peer-2026-07-05.md` (2026-07-05); `audits/SPIKE-felhom-sshd-2026-07-05.md` (2026-07-05) |
|
||
| <a id="e19"></a>[E19](capability-map-detail/E.md#e19) | The operator can see WHERE a managed host is — its LAN address and its WireGuard address, on the host page | agent v0.119.0, hub v0.85.0 | **PROVEN-LIVE** | — | `audits/host-addresses-visible-2026-07-31.md` (2026-07-31) |
|
||
| <a id="e20"></a>[E20](capability-map-detail/E.md#e20) | The operator can see whether a managed host's guests still have working networking — and how often the watchdog had to repair them | agent v0.92.0 (emitter, 2026-07-21), hub v0.104.0 (reader, 2026-08-13) | **IMPLEMENTED** | not proven live | R-319 |
|
||
| <a id="e21"></a>[E21](capability-map-detail/E.md#e21) | Break-glass management-plane recovery | agent v0.71, hub v0.84 | **IMPLEMENTED** | — | `runbooks/break-glass.md` (2026-07-31); `audits/hub-safety-2026-10-05/partB/` (2026-10-05) |
|
||
|
||
## F. Notifications & monitoring
|
||
|
||
| ID | Capability | Component | Status | Scope | Evidence |
|
||
|---|---|---|---|---|---|
|
||
| <a id="f1"></a>[F1](capability-map-detail/F.md#f1) | An ABSENT backup-target drive raises its OWN alarm, paired with a matching recovery | agent v0.116.0, controller v0.184.1+, hub v0.81.0 | **PROVEN-LIVE** | — | `audits/R116-v0116-2026-07-30.md` (2026-07-30) |
|
||
| <a id="f2"></a>[F2](capability-map-detail/F.md#f2) | Health-degradation email (edge-triggered, cooldowns, Hungarian) via hub → Resend | controller, hub | **IMPLEMENTED** | the health trigger never fired a mail live | `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15); R-4 |
|
||
| <a id="f3"></a>[F3](capability-map-detail/F.md#f3) | Event catalog: app_start_failed, dead-app, offbox_enlarge_blocked, claim/reset codes, critical severity | controller, hub v0.31/48/50/55 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15); `audits/DRILL-day0-vm-2026-07-12.md` (2026-07-12); `audits/DRILL-day0-take2-2026-07-12.md` (2026-07-12) |
|
||
| <a id="f4"></a>[F4](capability-map-detail/F.md#f4) | Prefs safety: empty-email wipe guard | controller v0.137 + hub v0.71.0 | **IMPLEMENTED** | red-proofed 2026-07-15 / 2026-07-22 | unit red-proofs in the controller and hub repos (outside `documentation/`) |
|
||
| <a id="f5"></a>[F5](capability-map-detail/F.md#f5) | Paired recovery notifications + prefs seeding at claim + priority headers (power-outage audit F11/F12/F14-light) | hub v0.71.0 | **IMPLEMENTED** | recovery leg partial until a live staleness cycle | R-69 |
|
||
| <a id="f6"></a>[F6](capability-map-detail/F.md#f6) | System + container metrics (SQLite, Chart.js, 30-day downsampling) | controller | **IMPLEMENTED** | validated in no campaign | `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07) |
|
||
| <a id="f7"></a>[F7](capability-map-detail/F.md#f7) | Always-on debug rings + on-demand log-bundle pulls with TTL/custody | controller v0.116, agent v0.83, hub v0.46 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-3-2026-07-11.md` (2026-07-11) |
|
||
| <a id="f8"></a>[F8](capability-map-detail/F.md#f8) | Operator alerting (Healthchecks → monitoring@felhom.eu) | k3s, Resend | **IMPLEMENTED** | no corpus validation doc | operator infra; no evidence document |
|
||
| <a id="f9"></a>[F9](capability-map-detail/F.md#f9) | Backup-deadline alerting (`expected_backup_missed`) is ANCHORED — absence of signal is UNKNOWN, not failure | hub v0.75.0 | **IMPLEMENTED** | — | `audits/DIAG-backup-missed-2026-07-26.md` (2026-07-26); R-82 |
|
||
| <a id="f10"></a>[F10](capability-map-detail/F.md#f10) | A box that is not always on (off at its backup time) makes the missed night up once when it comes back; the household sees a banner; the operator gets the missed-backup alarm, down or not | controller v0.295.0, hub v0.134.0, agent v0.145.0 | **PARTIAL** | catch-up and banner live; R-872 alarm by tests; suspend not measured | `audits/catchup-2026-10-05/partA/` (2026-10-05); R-872 |
|
||
|
||
## G. Fleet & operator (hub)
|
||
|
||
| ID | Capability | Component | Status | Scope | Evidence |
|
||
|---|---|---|---|---|---|
|
||
| <a id="g1"></a>[G1](capability-map-detail/G.md#g1) | Customer/host management: 8-tab detail, scoped auto-refresh, safe stale-host deletion, capability chips | hub v0.47–0.53 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-4-2026-07-13.md` (2026-07-13); `audits/DRILL-day0-take2-2026-07-12.md` (2026-07-12) |
|
||
| <a id="g2"></a>[G2](capability-map-detail/G.md#g2) | Config/state change round-trips in seconds (hub↔box immediacy; 15-min cycle stays the backbone): box→hub out-of-cycle report (Dir 1) + hub→box `GET /api/v1/wait` long-poll wake (Dir 2) | controller v0.139/140, hub v0.58/0.63 | **PROVEN-LIVE** | — | `audits/SPIKE-immediate-sync-transport-2026-07-16.md` (2026-07-16); `tests/VALIDATION-n100-rehearsal-2026-07-18.md` (2026-07-18) |
|
||
| <a id="g3"></a>[G3](capability-map-detail/G.md#g3) | Customer right-sizes guest RAM from the controller (agent-enforced bounds, live cgroup apply, no reboot) | agent v0.90.0 + controller v0.143.0 (R-24) | **PROVEN-LIVE** | grow and shrink, on metal | `tests/VALIDATION-n100-rehearsal-2026-07-18.md` (2026-07-18) |
|
||
| <a id="g4"></a>[G4](capability-map-detail/G.md#g4) | Publish train: MinAgent floors, gated auto-Reissue, version channels, floor-field-LAST rules | hub v0.45/0.53, agent | **PARTIAL** | — | `runbooks/publish-train-rules.md` (2026-09-13); R-23 |
|
||
| <a id="g5"></a>[G5](capability-map-detail/G.md#g5) | Agent self-update: A/B slots, crash-loop auto-rollback, operator-signed | agent v0.70+ | **PROVEN-LIVE** | demo | `audits/SPIKE-agent-selfupdate-2026-07-05.md` (2026-07-05) |
|
||
| <a id="g6"></a>[G6](capability-map-detail/G.md#g6) | Controller self-update: anonymous registry, no credentials in guest | controller v0.112 | **PROVEN-LIVE** | demo; the file found is the floor-driven self-update leg | `audits/DRILL-day0-take2-2026-07-12.md` (2026-07-12) |
|
||
| <a id="g7"></a>[G7](capability-map-detail/G.md#g7) | Offsite provisioning: Hetzner API, sub-account per customer, host-key pinning, credential re-issue | hub v0.37–0.39 | **PROVEN-LIVE** | — | `audits/VALIDATION-offsite-provisioning-e2e-2026-07-09.md` (2026-07-09); `audits/SPIKE-hetzner-api-provisioning-2026-07-09.md` (2026-07-09) |
|
||
| <a id="g8"></a>[G8](capability-map-detail/G.md#g8) | Per-customer offsite fill + staleness + freeze lever | hub v0.41 | **IMPLEMENTED** | no live-fired leg | `audits/CAMPAIGN-offsite-overnight-2026-07-10.md` (2026-07-10) |
|
||
| <a id="g9"></a>[G9](capability-map-detail/G.md#g9) | Box-level Storage Box aggregate (total fill, Σ quotas, oversubscription alert) | hub v0.64.0 (R-5) | **IMPLEMENTED** | data pipeline live; UI render and alert mail not | hub v0.64.0 code and unit tests (outside `documentation/`) |
|
||
| <a id="g10"></a>[G10](capability-map-detail/G.md#g10) | Operator sees PBS DR datastore fill at a glance (Offsite "PBS DR" tab + dashboard gauge) | hub v0.65.0 + tenantsync v1.2.0 (R-5) | **IMPLEMENTED** | data pipeline live; UI render and alert mail not | hub v0.65.0 code and unit tests (outside `documentation/`) |
|
||
| <a id="g11"></a>[G11](capability-map-detail/G.md#g11) | The hub reports LOSS OF VISIBILITY into either off-site store (not just how full it is) | hub v0.106.0 (R-339) | **IMPLEMENTED** | deliberately not proven live | R-340 |
|
||
| <a id="g12"></a>[G12](capability-map-detail/G.md#g12) | Secrets hygiene: bearer in k8s Secret, no secrets in git, single-quote credential store | hub v0.53, conventions | **IMPLEMENTED** | — | the 2026-07-13 hub closing bundle (no evidence document) |
|
||
| <a id="g13"></a>[G13](capability-map-detail/G.md#g13) | Operator login password changeable from UI | hub v0.54 | **IMPLEMENTED** | — | hub v0.54 (2026-07-13; no evidence document) |
|
||
| <a id="g14"></a>[G14](capability-map-detail/G.md#g14) | The operator sees boxes left behind: per-customer controller floors with their age (and which a global raise cannot move), each box's agent against the vouched one, a 7-day "agent behind" alarm and a "floor raise skipped boxes" mail | hub v0.135.0 (R-604, R-530) | **IMPLEMENTED** | the page live; the alarm and the mail unit-proven | `audits/hub-safety-2026-10-05/partD/` (2026-10-05) |
|
||
| <a id="g15"></a>[G15](capability-map-detail/G.md#g15) | The hub database survives the loss of DooPlex: a nightly consistent copy, encrypted, on ep0; restore-tested weekly; an alarm when either stops | hub v0.136.0 (R-173), `scripts/hub-db-backup/`, homelab-manifests rules | **PROVEN-LIVE** | — | `audits/hub-db-offsite-2026-10-05/` (2026-10-05); `audits/dooplex-survival-2026-10-09/` (2026-10-09) |
|
||
| <a id="g16"></a>[G16](capability-map-detail/G.md#g16) | Gitea (all code), the operator's password manager (Vaultwarden, since 2026-10-09 afternoon, R-923) and DooPlex's secrets survive the loss of DooPlex: a nightly encrypted copy on ep0; restore-tested weekly; an alarm when either stops; a failure mail | `scripts/dooplex-offsite/` (R-232), homelab-manifests rules | **PROVEN-LIVE** | — | `audits/dooplex-survival-2026-10-09/` (2026-10-09) |
|
||
| <a id="g17"></a>[G17](capability-map-detail/G.md#g17) | The operator surface refuses a cross-site form post on BOTH login paths (session token; Basic auth + `X-Felhom-Operator`) | hub v0.135.0 (R-135) | **PROVEN-LIVE** | — | `audits/hub-safety-2026-10-05/partA/live.txt` (2026-10-05) |
|
||
| <a id="g18"></a>[G18](capability-map-detail/G.md#g18) | Box operating-system security updates (Proxmox host, guest Debian, Docker engine) | agent v0.143.0, hub v0.133.0 | **PARTIAL** | kernel lane missing | `audits/os-guest-lane-2026-10-04/` (2026-10-04); `audits/os-host-lane-2026-10-04/` (2026-10-04); `audits/os-docker-crash-2026-10-04/` (2026-10-04) |
|
||
| <a id="g19"></a>[G19](capability-map-detail/G.md#g19) | An ENGLISH-SPEAKING household's first hour: download, install, pair, bind, claim, two apps | controller v0.259.0 + hub v0.119.0 + ISO 1.29.0 + the whole catalog | **PROVEN-LIVE** | walked on 0.258.0 with one blocker; fixed, the walk not repeated | `audits/DRILL-first-hour-en-0258-2026-09-20.md` (2026-09-20); `audits/i18n-closing-2026-09-21/live/` (2026-09-21) |
|
||
| <a id="g20"></a>[G20](capability-map-detail/G.md#g20) | A deletion of a customer's off-site history is NOTICED within a day | hub v0.111.0 (R-431) | **IMPLEMENTED** | not yet proven live | R-431 |
|
||
|
||
## H. Business & legal (outside the platform — added 2026-10-03)
|
||
|
||
> Not platform capabilities, but what must exist before a household pays. Listed here so the coupling rule
|
||
> (every roadmap item names the row it flips) has a row to point at.
|
||
|
||
| ID | Capability | Component | Status | Scope | Evidence |
|
||
|---|---|---|---|---|---|
|
||
| <a id="h1"></a>[H1](capability-map-detail/H.md#h1) | Website legal pages: ÁSZF, adatkezelési tájékoztató, impresszum | website | **MISSING** | — | R-813; R-809 |
|
||
| <a id="h2"></a>[H2](capability-map-detail/H.md#h2) | Customer contract and data-processing agreement | — | **MISSING** | — | R-809 |
|
||
| <a id="h3"></a>[H3](capability-map-detail/H.md#h3) | Billing and invoicing | — | **MISSING** | — | R-809 |
|