CAMPAIGN-11: R-228 (set-aside history invisible) + campaign doc F7/F9/F10/F11 sections
The move-aside is correct and verified byte-for-byte; what follows it is not. settings.json records orphaned_renamed_to and OrphanedRenamedTo has zero references in any template or handler — 12.5 MB of deliberately retained customer data at a path the box knows and never shows. Fifth instance of the project's seam-built-but-never-wired pattern. Campaign document gains the F7/F9/F10/F11 write-ups: F7 split (set-aside PASS, afterwards FAIL), F9 partial (R-215's gate proven live on a narrower shape), F10 NOT INJECTED (harness — three self-healing attempts), F11 PASS. No product code changed.
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
supersession) PASSED on its central question. Phase 2 (eleven injected faults) and Phase 4 (an
|
||||
unattended soak) ran overnight on 2026-08-05/06 and are reported here for the first time.**
|
||||
|
||||
**Findings: R-214 … R-223 from Phases 1 and 3** (seven since fixed and shipped), **plus R-224 … R-227
|
||||
from Phase 2.** **Three suspicions investigated — two confirmed, one DISPROVED.** **Four harness
|
||||
**Findings: R-214 … R-223 from Phases 1 and 3** (seven since fixed and shipped), **plus R-224 … R-228
|
||||
from Phase 2.** **Three suspicions investigated — two confirmed, one DISPROVED.** **Five harness
|
||||
faults, separated from the product's.**
|
||||
|
||||
Evidence: `../tests/campaign11-evidence-2026-08-05/` — `journal.md` (Phases 0, 1, 3) and
|
||||
@@ -155,13 +155,66 @@ was real; **every control that failed is reported as a failed control, not as a
|
||||
| **F4** | agent stopped | **M2**, the R-216 fix under pressure | **FAIL** — M4. → **R-224** |
|
||||
| **F5** | store unreachable after a successful unlock | unlock counts; „could not be read", not „opened with content" | **PASS** — R-217's fix holds |
|
||||
| **F6** | „Most nem", return later | entry point survives; unlock still works | **PASS** |
|
||||
| **F7** | set aside, then a change of mind | set aside, never deleted; honest afterwards | *(see §4.7)* |
|
||||
| **F7** | set aside, then a change of mind | set aside, never deleted; honest afterwards | **SPLIT** — set-aside **PASS**, verified byte-for-byte; the afterwards **FAIL** → **R-228** |
|
||||
| **F8** | controller restarted mid-unlock | no half-state; the screen says which | **PARTIAL** — no half-state ✅, but a raw English `Bad Gateway` → **R-227** |
|
||||
| **F9** | a box that never had off-site | nothing, incl. a direct `GET /recovery` | *(see §4.9)* |
|
||||
| **F10** | app with a mandatory data path missing | run reports `incomplete`, names the app, digest carries it | *(see §4.10)* |
|
||||
| **F11** | box offline a whole reporting window | hub and box agree once it returns | *(see §4.11)* |
|
||||
| **F9** | a box that never had off-site | nothing, incl. a direct `GET /recovery` | **PARTIAL PASS** — R-215's gate proven live on a narrower shape; the literal precondition was not staged |
|
||||
| **F10** | app with a mandatory data path missing | run reports `incomplete`, names the app, digest carries it | **NOT INJECTED** — harness. Three attempts, each self-healed |
|
||||
| **F11** | box offline a whole reporting window | hub and box agree once it returns | **PASS** — both directions fired, each with an operator mail |
|
||||
|
||||
*(F7, F9, F10 and F11 are written up in the sections below; the table is the index.)*
|
||||
### F7 — the set-aside, and the afterwards
|
||||
|
||||
**The move-aside is exactly what it claims.** Both confirmations state the consequences first
|
||||
(*„félretesszük — nem töröljük"*, *„a gép új, üres mentési tárolót kezd"*, *„ez az oldal többé nem
|
||||
jelenik meg"*), and the result measured against the Storage Box:
|
||||
|
||||
```
|
||||
BEFORE /home/felhom-repo mtime 13:13 snapshot f3d9cd67 du -s 12535
|
||||
AFTER /home/felhom-repo.orphaned-20260805 mtime 13:13 snapshot f3d9cd67 du -s 12535 ← untouched
|
||||
/home/felhom-repo mtime 21:32 (empty) ← fresh
|
||||
```
|
||||
|
||||
**Nothing deleted.** Then the customer changes their mind — and finds nothing: `GET /recovery` 302s,
|
||||
`POST /recovery/unlock` 302s in 0.028 s with no message, and `/backups/remote` never mentions the
|
||||
set-aside history at all, though the box records its exact path. → **R-228**
|
||||
|
||||
### F9 — what was and was not proven
|
||||
|
||||
The literal precondition (a box that never had off-site backups) needs a rebuild, which the brief
|
||||
forbids before Phase 4, so it was **not staged**. But **the assertion that failed in Phase 1 was
|
||||
tested and passes**: Phase 1's defect was that `GET /recovery` never asked the predicate. After F7
|
||||
drives `recoveryOffer()` false, `GET /recovery` → **302 `/backups/remote`**. **R-215's fix is proven
|
||||
live.** The `GetHubEscrowIdentityPresent()==false` arm remains covered by tests only.
|
||||
|
||||
### F10 — not injected, and why that is a harness result
|
||||
|
||||
Three attempts, each with a control confirming the directory was genuinely absent — and each
|
||||
self-healed before capture: (1) the app recreated it; (2) `docker stop` was undone by **the
|
||||
controller's own monitor restarting the stack**; (3) with the stack stopped through the controller
|
||||
API, the directory reappeared at **21:51:38.65**, coincident with the run's own start. All three runs
|
||||
reported `ok` with `1 mandatory path(s)`, and R-203's stat-gap correctly never fired, because by the
|
||||
time `os.Stat` ran the path existed.
|
||||
|
||||
**The state F10 describes is not reachable on a deployed app of this kind.** Recorded as **harness,
|
||||
not product**.
|
||||
|
||||
**One observation kept, with its evidence:** at capture the directory held only a recreated
|
||||
`metadata.db` and **not** the customer's `F10-SENTINEL.txt`, and the run still said `ok`. The verdict
|
||||
is about a path's *presence*, not its *content* — correct as designed, and it means an `ok` off-site
|
||||
run can immediately follow the loss of everything that path contained.
|
||||
|
||||
### F11 — the dead-man's switch, both ways
|
||||
|
||||
```
|
||||
23:28:11 ok → stale (host_stale) + Operator email SENT
|
||||
23:29:59 Received report from c11 ← the box returns unaided
|
||||
23:30:11 stale → ok (host_recovered) + Operator email SENT
|
||||
23:30:11 customer mail skipped — no unanswered customer down mail (pairing miss)
|
||||
```
|
||||
|
||||
The customer mail was correctly **withheld** by the pairing gate under a real outage. **I5 holds** —
|
||||
box and hub agree after the return, judged after a full report cycle rather than from one read.
|
||||
**Not reached:** `STALE → DOWN` (>1 h); the outage was ended once both transitions had fired because
|
||||
Phase 4 needed the venue back.
|
||||
|
||||
### The timing discriminator used throughout
|
||||
|
||||
@@ -297,6 +350,32 @@ nothing about whether the key was installed. **I3** — *"every refusal names a
|
||||
on, in Hungarian, with no raw error."* Low severity (the window is ~1 s wide) and recorded rather than
|
||||
inflated.
|
||||
|
||||
### R-228 — the set-aside history becomes invisible the moment it is set aside
|
||||
|
||||
The move-aside is correct and was verified byte-for-byte (§F7). What follows it is not.
|
||||
|
||||
```json
|
||||
"orphaned_renamed_to": "/home/felhom-repo.orphaned-20260805"
|
||||
```
|
||||
|
||||
The box records the exact path. And:
|
||||
|
||||
```
|
||||
grep -rn "OrphanedRenamedTo" internal/web/templates/ internal/web/*.go → (no hits)
|
||||
```
|
||||
|
||||
The field is **written and read by nobody**. `/backups/remote` after the set-aside contains no
|
||||
occurrence of the path, „félretéve", „régi előzmény" or any equivalent — with instrument controls
|
||||
passing (`felhom-repo` → 2, „letétbe helyezve" → 1), so the page and the matcher both work.
|
||||
|
||||
> **12.5 MB of the customer's deliberately retained data sits at a path the box knows and never
|
||||
> shows.** Its only mention is a flash message on the redirect, gone on the next click.
|
||||
|
||||
**The project's own "seam built but never wired" pattern** — the fifth recorded instance — landing on
|
||||
the one promise the set-aside screen makes. The fix is a plain statement that an earlier history is
|
||||
set aside and not deleted; **it must not promise the history can be reopened**, because R-222 means it
|
||||
cannot be, and that is exactly the conditional promise R-202's gate exists to prevent.
|
||||
|
||||
---
|
||||
|
||||
## 6. What behaved correctly
|
||||
|
||||
Reference in New Issue
Block a user