docs(R-120): CLOSED on both halves — golden current, and the class has a gate that refuses
Half 1, the artifact: golden 0.186.0 baked, published, vouched, and proven on a REAL day-0 on demo-hp (not the fixture, per the rule committed in Part 1). With the target detached, the fresh box's endpoint returned the TargetAbsent copy -- "A rendszermentés meghajtója nem érhető el — amíg vissza nem csatlakoztatod..." -- with offer_path absent entirely. The day-old read on the 0.185.1 golden had returned the false system-disk message plus an offer of the other drive. That is the customer-visible defect closed. Half 2, the mechanism: operator ruled REFUSE, shipped as hub v0.82.0 and DEPLOYED. Proven live by re-attempting the original mistake -- vouching the stale 0.185.1 golden now yields HTTP 303 flash=golden_behind_fleet plus [WARN] artifact vouch REFUSED, and the manifest reads back unchanged at 0.186.0. Refused AND unwritten, against the real fleet signal rather than a unit fixture. Recorded on R-29's audit list as the first ENFORCED gate beside its three orphans, so the contrast is kept rather than lost. The orphans are unchanged -- this proves the pattern is available, not that the backlog moved. Teardown all three layers: VM 9402 purged, r120-images removed with the space measured back, hub layer gate-blocked on ONLINE with the command recorded. Last session's sess-e was deleted this run, discharging its recorded layer 3.
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
# R120-golden-rebake-2026-07-30 — the golden is current again; the class still needs a mechanism
|
||||
# R120-golden-rebake-2026-07-30 — the golden is current again, and the class now has a gate that refuses
|
||||
|
||||
**Run:** R-120, CC on DooPlex, 2026-07-30. **Golden 0.186.0 baked, published, vouched, and proven on a
|
||||
fresh box.** The mechanism half (Part 3) awaits an operator ruling — see §6.
|
||||
**Run:** R-120, CC on DooPlex, 2026-07-30. **CLOSED on both halves.** Golden **0.186.0** baked,
|
||||
published, vouched and proven on a real day-0; and the class now has a **mechanism** — hub **v0.82.0**'s
|
||||
vouch-path gate, which **refuses** a golden the fleet has already outrun, deployed and proven live by
|
||||
re-attempting the original mistake.
|
||||
|
||||
## 1. Baselines, established separately
|
||||
|
||||
@@ -125,7 +127,28 @@ R-120's exact state — and agent 0.116.0's R-116 fix is visible on it:
|
||||
pvesm: felhom-backup dir inactive 0 0 0
|
||||
```
|
||||
|
||||
**The endpoint proof is NOT yet captured**, and is not claimed: `GET /api/storage/backup-target` returns
|
||||
### The capture — R-120's symptom, inverted
|
||||
|
||||
Operator-relayed claim code, then `GET /api/storage/backup-target` **with the target still detached**, on
|
||||
controller **0.186.0** from the new golden. Verbatim:
|
||||
|
||||
```json
|
||||
{"data":{"degraded":true,"known":true,"label":"",
|
||||
"message":"A rendszermentés meghajtója nem érhető el — amíg vissza nem csatlakoztatod, a teljes rendszermentés nem készül el.",
|
||||
"target":"felhom-backup"},"ok":true}
|
||||
```
|
||||
|
||||
- ✅ the **`TargetAbsent`** copy — *the backup drive is unreachable; until you reconnect it the full system
|
||||
backup will not be made*. Reconnect **that** drive.
|
||||
- ✅ **`offer_path` is absent from the payload entirely** — no drive is offered as a remedy.
|
||||
- ✅ **not** the generic *"A rendszermentés jelenleg ugyanazon a lemezen van, mint a rendszer"*.
|
||||
|
||||
For contrast, the **same read on the OLD 0.185.1 golden** one day earlier
|
||||
(`audits/R116-v0116-2026-07-30.md` §6a caveat) returned the generic system-disk message **plus**
|
||||
`offer_label: "Adat meghajto"` and `offer_path: "/mnt/felhom-drives/adat"`. The false message and the wrong
|
||||
offer are both gone. **That is R-120 closed at the customer-visible layer.**
|
||||
|
||||
The claim gate had to be cleared by an operator-relayed code — the endpoint first returned
|
||||
`{"ok":false,"error":"dashboard not yet claimed"}`. The claim gate runs **before** auth
|
||||
(`controller/internal/web/auth.go:52-67`) and exempts only `/claim`, `/claim/request-new-code`,
|
||||
`/api/health`, `/static/` (`claim.go:221-228`) — **no Bearer escape**, and `regen-password`
|
||||
@@ -165,22 +188,50 @@ that the response is the refusal **and** that the manifest was not written. Thre
|
||||
this project were fully green with the seam disconnected; a gate that can be inert is the thing this
|
||||
gate exists to prevent.
|
||||
|
||||
**This is the operator's call because a refusing gate can block a release.** Not implemented pending the
|
||||
ruling. If it is declined, the weaker form goes in and the reason is recorded here rather than absorbed
|
||||
silently.
|
||||
### RULING: REFUSE — approved by the operator, 2026-07-30. Built, deployed, proven live.
|
||||
|
||||
**If the gate is deferred, R-120 does not close** — it is re-opened, or a successor is filed naming the
|
||||
class: *"a published artifact and its baked copy drift and nothing checks"*. Three instances closed
|
||||
individually is how a class survives.
|
||||
Shipped as **hub v0.82.0**: the gate in `handleSetArtifacts` immediately before the only write;
|
||||
`store.NewestReportedControllerVersion()` over `reports.controller_version` (the column `SaveReport`
|
||||
denormalises, `store.go:903`), **semver-compared in Go**; an operator-legible refusal flash naming the
|
||||
remedy; **fail-open in exactly two deliberate cases** — an empty golden field, and an unknown fleet version.
|
||||
|
||||
**A near-miss worth keeping.** The first draft read **`guests.controller_version`** — a column that exists
|
||||
in the schema (`store.go:294`) and that **nothing writes**. That gate would always have seen `""` and
|
||||
failed open: **inert, i.e. this gate's own failure shape**, and one `grep` from shipping. Caught by looking
|
||||
for a writer before trusting the column.
|
||||
|
||||
**Tests: 4, through the production handler over `httptest`, never an injected seam.** The refusal asserts
|
||||
**both** the flash **and** that the manifest was not written — a gate that redirects and saves anyway reads
|
||||
as enforcement while providing none. Plus the allow case, both fail-open cases, and the semver-ordering
|
||||
case (0.99.0 vs 0.186.0, a pair this fleet has shipped). **Red-proof:** deleting the block makes the stale
|
||||
golden vouchable and both refusal assertions fail.
|
||||
|
||||
### PROVEN LIVE on the deployed hub — the original mistake, re-attempted and blocked
|
||||
|
||||
Hub 0.82.0 built, pushed, manifest pinned, ArgoCD hard-refreshed + synced → **Synced / Healthy**, pod on
|
||||
`felhom-hub:0.82.0`. Then the exact R-120 mistake was re-attempted — vouch the stale **0.185.1** golden:
|
||||
|
||||
```
|
||||
POST /configuration/artifacts → HTTP 303 …/configuration?flash=golden_behind_fleet
|
||||
hub log: [WARN] artifact vouch REFUSED: golden 0.185.1 is older than the newest controller the fleet
|
||||
reports (0.186.0) — a fresh install would land on stale application code (R-120)
|
||||
manifest read back afterwards: golden still 0.186.0, sha still b760ac6a… — the refused POST did NOT write
|
||||
```
|
||||
|
||||
**Refused *and* unwritten**, on the live hub against the real fleet signal rather than a unit fixture.
|
||||
|
||||
**R-29's audit list now records it** (`ROADMAP.md`) as the **first enforced gate** beside its three
|
||||
orphans, so the contrast is kept rather than lost. The orphans are unchanged — this proves the pattern is
|
||||
available, not that the backlog moved.
|
||||
|
||||
## 7. Teardown
|
||||
|
||||
| layer | item | disposition |
|
||||
|---|---|---|
|
||||
| 1 — machine | DooPlex bake fixture: build guest 9100 purged, `drill.qcow2` reverted to **`virgin`** | **DONE** |
|
||||
| 1 — machine | demo-hp VM **9402** `r120-drill` | **RETAINED pending the claim code** (§5's endpoint read) |
|
||||
| 2 — host | `r120-images` dir storage at `/mnt/nvme-1tb` | **RETAINED** with 9402 |
|
||||
| 3 — hub | customer **`sess-f`**, host **`sess-f-2670b5`**, appliance **14** | **RETAINED** with 9402 |
|
||||
| 1 — machine | demo-hp VM **9402** `r120-drill` + all volumes | **DESTROYED** `qm destroy 9402 --purge`; `qm list` shows only `drill-r50` |
|
||||
| 2 — host | `r120-images` dir storage at `/mnt/nvme-1tb` | **REMOVED**; `felhom-backup` available **928787076 KiB after == before**, `local-lvm` **38.84 %** unchanged — space returned |
|
||||
| 3 — hub | customer **`sess-f`**, host **`sess-f-2670b5`**, appliance **14** | **GATE-BLOCKED — command recorded below.** Cascade attempted, correctly refused **HTTP 409** (host still ONLINE, `customer_delete.go:220-228`). Deletable once it ages ONLINE→DOWN, exactly as `sess-e` was this run |
|
||||
|
||||
`pvesm status` on demo-hp before this run, for the layer-2 comparison at teardown:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user