docs(R-7b): CORRECTION — offsite leg + restore round-trip ARE live-proven
The prior revision claimed the demo box had no offsite target and that both legs
were unexercised. All three clauses were false on a box that had run a successful
offsite backup minutes earlier.
Evidence: offsite snapshots e0b9d723 (Viktor 12:18:16Z) and 4e2b15ec, tagged
felhom-offbox,_shares, each carrying the payload dir (manifest + passdb.tar, 0600)
plus both share folders. Restore round-trip through the real routes returned a
deleted probe byte-identical and a deleted DEFINITION with its original flags,
without overwriting the two pre-existing files. R-7b is fully PROVEN-LIVE.
Root cause in new REPORT section 7b: the check read a GUESSED settings key
('offbox_target') where the real tag is 'offbox' (settings.go:96), got None for
every field, and read that as 'not configured' instead of 'wrong key'.
This commit is contained in:
@@ -2,8 +2,12 @@
|
||||
|
||||
## felhom-controller v0.145.0 — R-7b: share data enters the live backup runs (Model B′) + samba liveness — 2026-07-18
|
||||
|
||||
**Class:** Implementation. **Shipped:** controller **v0.145.0**, deployed and live-validated on demo
|
||||
guest 9201.
|
||||
**Class:** Implementation. **Shipped:** controller **v0.145.0**, deployed on demo guest 9201 and
|
||||
**fully PROVEN-LIVE** (tier-2 leg, offsite leg, restore round-trip, samba liveness).
|
||||
|
||||
> **Revised 2026-07-18** after a close-out runbook: the prior revision wrongly claimed the demo box
|
||||
> had no offsite target and that the offsite leg + restore round-trip were unexercised. Both are now
|
||||
> live-proven with snapshot evidence; the faulty verification method is dissected in §7b.
|
||||
|
||||
## 1. Baselines (re-confirmed at session start)
|
||||
|
||||
@@ -160,21 +164,90 @@ rather than assuming showed `scheduler.Every` waits a full interval before its f
|
||||
hit the deliberate `prev == ""` first-observation guard — a test-timing artifact, not a defect. The
|
||||
clean re-run above is the real proof.
|
||||
|
||||
### NOT live-exercised — stated explicitly
|
||||
**Offsite `_shares` leg — PASS (live).** The demo box HAS a working offsite target: Hetzner Storage
|
||||
Box `u629488-sub1.your-storagebox.de:23`, repo `/home/felhom-repo`, `escrow_state: escrowed`,
|
||||
`quota_gb: 50`. Viktor's manual run at **2026-07-18T12:18:16Z** produced snapshot **`e0b9d723`**
|
||||
(tags `felhom-offbox,_shares`) carrying exactly the designed three paths — the payload staging dir
|
||||
plus both share folders. A second run I triggered through the „Távoli mentés" button endpoint
|
||||
(`POST /backup/offbox/run`) produced **`4e2b15ec`** at 12:25:52. Inside it:
|
||||
|
||||
```
|
||||
-rw-r--r-- 1000 1000 39 …/shares/dokumentumok/r7b-restore-probe.txt ← uid 1000 preserved
|
||||
-rw------- 0 0 418 …/data/shares-payload/_shares-manifest.json
|
||||
-rw------- 0 0 855040 …/data/shares-payload/passdb.tar ← credential present
|
||||
```
|
||||
The payload dir rides as `drwx------`; both payload files as `0600`. `shares_last_status: ok`,
|
||||
`shares_last_count: 2`.
|
||||
|
||||
**Restore round-trip (Scenario D) — PASS (live, through the real routes).** Probe created (uid 1000,
|
||||
md5 `8824dcb5b33cf3583c391860d427bfd0`) → captured in `4e2b15ec` → then **damaged**: probe deleted
|
||||
from the share folder, and the `dokumentumok` DEFINITION deleted via the real „Megosztás" endpoint
|
||||
(`POST /sharing/shares/delete`), which correctly removed it from the registry and from `smb.conf`
|
||||
while leaving the folder and its other files intact. Then `POST /backup/shares/restore` →
|
||||
`POST /backup/shares/place`:
|
||||
|
||||
```
|
||||
[shares] restore placed: 1 file(s), 1 definition(s) re-added, 1 kept, 0 refused, credential=true
|
||||
[samba] applying samba stack: shares=2 config_changed=true
|
||||
```
|
||||
- probe back, **md5 identical**, uid 1000 and original mtime preserved;
|
||||
- **only 1 file written** — `r7.txt` and `r7b-live.txt` already existed and were NOT overwritten, so
|
||||
the missing-only merge is proven on live data, not just in a fake;
|
||||
- `dokumentumok` back with its **original** flags (`read_only=false`, `offsite=true`,
|
||||
`created_at 2026-07-18T09:55:58Z` — the original stamp, not a fresh one);
|
||||
- `filmek` reported **kept** (existing-wins) and its flags/mtime untouched;
|
||||
- `smb.conf` re-rendered: `[global] [filmek] [dokumentumok]`;
|
||||
- **0 refused**, and nothing written outside the registered roots (only `backups/` changed mtime —
|
||||
the scratch, which was removed after successful placement).
|
||||
|
||||
**Credential leg — PASS for continuity; positive auth is a HUMAN leg.** After the restore the passdb
|
||||
account is present and enabled (`Unix username: felhom`, flags `[U]`) with **`Password last set: Sat,
|
||||
18 Jul 2026 09:55:58 UTC`** — the original stamp, unchanged, proving the credential path did not
|
||||
regress. Negative control: `smbclient -U felhom%WRONG` → `NT_STATUS_LOGON_FAILURE`, so smbd is
|
||||
genuinely authenticating. A positive `net use \\FELHOM\dokumentumok` with the real household password
|
||||
remains **Viktor's leg** — that password is never persisted by design, so I cannot hold it.
|
||||
|
||||
**R-7b is therefore fully PROVEN-LIVE:** tier-2 leg, offsite leg, restore round-trip, and samba
|
||||
liveness all exercised on the demo box through real endpoints.
|
||||
|
||||
### Still NOT live-exercised — stated explicitly
|
||||
|
||||
- **The offsite `_shares` restic leg** and **the „Megosztások" restore round-trip (Scenario D)**. The
|
||||
demo box has **no offsite target configured** (`offbox_target` empty — no Storage Box credentials,
|
||||
no escrow), and the run gate refuses offsite work until the repo password is escrowed. Configuring
|
||||
one is operator/Viktor territory ("first offsite run = Viktor"). Both are unit-covered and
|
||||
red-proofed (red-proofs 2, 3, 4), but neither has touched a real restic repo.
|
||||
- **Scenario E's OFF direction** was not live-toggled — disabling sharing on the demo box would down
|
||||
the stack and churn customer state. Unit-tested in both directions with red-proof 5.
|
||||
- **Scenario F on a genuinely disconnected drive** (unit-tested; the live shares are on healthy drives).
|
||||
- **Scenario C's quota degradation live** — the repo is at 2.6 MB of a 50 GB quota, so the gate cannot
|
||||
trip without fabricating state. Unit-covered with red-proof 3.
|
||||
|
||||
## 7b. Root cause — why the previous REPORT claimed the opposite, and what the correct check is
|
||||
|
||||
The previous revision of this report asserted "no offsite target configured (`offbox_target` empty —
|
||||
no Storage Box credentials, no escrow), and the run gate refuses offsite work until the repo password
|
||||
is escrowed." Every clause was false, on a box that had run a successful offsite backup minutes
|
||||
earlier. **What I actually checked:** I read
|
||||
`/var/lib/docker/volumes/felhom-controller-data/_data/data/settings.json` with a Python one-liner
|
||||
doing `o = d.get('offbox_target') or {}` and printing `o.get(k)` for six fields. **What it returned:**
|
||||
`None` for all six. **Why that was wrong:** the JSON key is `offbox`, not `offbox_target` — pinned at
|
||||
`internal/settings/settings.go:96`, `Offbox *OffboxTarget \`json:"offbox,omitempty"\``. My `.get()`
|
||||
silently produced a missing key, the `or {}` fallback turned that into an empty dict, and every field
|
||||
read back `None`. I then interpreted "all fields None" as "not configured" — when a dict whose
|
||||
*every* field is None is overwhelming evidence that the KEY is wrong, not that the values are empty.
|
||||
I also asserted the escrow gate's behaviour without ever reading the gate's input (`escrow_state` was
|
||||
`escrowed`). **The correct check — the one Phase A used:** resolve the persisted key from the struct
|
||||
tag at source (`grep 'Offbox \*OffboxTarget' internal/settings/settings.go`), print the JSON's
|
||||
top-level keys before indexing into it, and corroborate against the running system's own surfaces
|
||||
rather than a guessed schema — here `restic snapshots --tag _shares` through the controller's own
|
||||
restic environment, the `/backups/remote` page, and this release's own `shares_last_*` fields, any
|
||||
one of which would have contradicted the claim instantly. **The rule going forward:** a live-state
|
||||
claim in a REPORT gets verified the way campaigns verify one — through the system's own surface, from
|
||||
at least two independent angles, with a negative result treated as a hypothesis to disprove rather
|
||||
than a finding to publish.
|
||||
|
||||
## 8. Handoff
|
||||
|
||||
- **Viktor: raise the managed-update floor to v0.145.0** (supersedes the earlier 0.144 note) so the
|
||||
N100 rehearsal's day-0 box converges onto the honest version.
|
||||
- **Viktor: the offsite leg + restore round-trip need a live leg** on a box with an escrowed offsite
|
||||
target. That is the one part of R-7b whose real-world behaviour rests on tests alone.
|
||||
- **Viktor: the SMB positive-auth leg** — `net use \FELHOM\dokumentumok` with the real household
|
||||
password, to close the credential path end-to-end. Continuity is proven (passdb account enabled,
|
||||
password-last-set stamp unchanged by the restore, wrong password correctly rejected), but the
|
||||
password is never persisted by design so the positive test needs a human.
|
||||
- R-7 slice-2 remainder is unchanged (avahi/`.local`, app-folder presets, per-share users, recycle bin).
|
||||
|
||||
Reference in New Issue
Block a user