D39 = B: 09 §3 decision 255 (the security-fix step) + a dated note on decision 13; capability B23; R-1239 closed, R-1240 opened, R-1238 updated (register 186 -> 186); STATUS/CONTEXT; nodes.md (9202 password, Tester 1 DHCP); evidence security-lane-2026-10-23 (controller 0.341.0, global floor 11:24 UTC)
gates / gates (push) Successful in 13m49s
gates / gates (push) Successful in 13m49s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qRErfCoiTkvDK9N5XHbzb
This commit is contained in:
1 parent
4b9b0af3cb
commit
87dc50743c
37 files changed
+1104
-8
No files matched your search
@@ -124,6 +124,7 @@
|
||||
| <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) |
|
||||
| <a id="b23"></a>[B23](capability-map-detail/B.md#b23) | An urgent security fix reaches the boxes at night — a `security_fix` ladder step (box walk required, bench optional, a CVE/GHSA notice), taken by the night update (`09` §3 decision 255, D39 = B) | catalog `3898593`, controller v0.341.0 | **PROVEN-LIVE** | scratch 9202 (drill catalog), Plex 1.43.4 → 1.43.5; an app with no box fixture is checked by health, version and a soak only (`seed: none`) | `audits/security-lane-2026-10-23/` (2026-10-23) |
|
||||
|
||||
## C. Protection & recovery (the product promise)
|
||||
|
||||
|
||||
@@ -286,6 +286,9 @@ builds them (`audits/update-rulings-2026-09-23/`).
|
||||
update night measured the proxy wrong in both directions — minor moves that held
|
||||
(adventurelog, outline) and a tag shape it cannot read at all (§3b Q3). The test record is the
|
||||
thing the proxy was guessing at.
|
||||
**Dated note 2026-10-23 (decision 255, D39 = B):** a second step kind now exists — the `security_fix` step, proven
|
||||
on the box with the bench optional, for an urgent upstream fix with a public notice. Decision 13's rule is
|
||||
unchanged for every other move: a step a box takes was still tested, on at least the box venue.
|
||||
|
||||
14. **The update ladder** (Q3). A box more than one step behind **climbs one tested step at a time, in
|
||||
order, and never jumps**. Each step is the full guarded update of §6.1. **Why:** a step was tested
|
||||
@@ -1031,6 +1034,52 @@ its length, and both fixes cost something the household would notice — operato
|
||||
Built in controller v0.314.0 (`internal/stacks/restore_gate.go`); pinned by `restore_gate_test.go` and
|
||||
`r1057_unit_gate_test.go` (ten mutations each seen failing). Proof: `audits/gate-restore-2026-10-15/9202/`.
|
||||
|
||||
### 2026-10-23 (~12:00) — D39 = B: the security-fix step (operator ruling by starting the run; R-1239)
|
||||
|
||||
255. **An urgent upstream security fix reaches the boxes at night as a `security_fix` ladder step: the box walk is
|
||||
required, the bench is optional, and a public notice is the authority.** *Operator ruling 2026-10-23 ~12:00 (D39 =
|
||||
B, R-1239), taken by starting the D39 brief; its design is Claude.ai's recommendation, taken with it.* Why: on
|
||||
2026-10-23 the only route for the Plex2Shell fix was an operator word, `git push --no-verify` past the move gate,
|
||||
and a hand press on each box — and the night leg never takes a step with no test record (R-1238). That does not
|
||||
scale past the first customers and needs the operator awake.
|
||||
1. **The entry** (`scripts/ladder.py` `check_security`, the one reader): `"verdict": "security_fix"` with `security`
|
||||
`{ids: [CVE-…|GHSA-…], advisory: "https://…", fixed_in}`, `box_evidence` (required), `seed` `read_back`|`none`,
|
||||
`memory_peak_pct` from the BOX soak with `memory_basis: "box_soak"`; `evidence` = the bench record or null — a
|
||||
bench given must be `proven` (`bench_verdict`, `harness_version` ≥ 2 ride with it). Never `backfilled`,
|
||||
`digest_from` (a same-tag fix stays decision 52's lane), `engine_conversion`, nor a database engine MAJOR (any
|
||||
engine — MariaDB included; the judgement is `check-engine-major.py`'s own `engine_of`/`major_of`, imported).
|
||||
2. **No operator word per incident.** The session that writes the step reports it to the operator after the push.
|
||||
3. **The gates:** the move gate accepts a `security_fix` move exactly as a proven one (from/to per service, digests
|
||||
the registry still serves); `check-test-record.py` WARNs on every push while a template's head is a security-fix
|
||||
step with no bench test („<app>: security-fix step <to> has no bench test (since <tested_at>)"). Seven decoys
|
||||
(`test_gate_decoys.py`), each seen failing with the rules switched off.
|
||||
4. **The box venue:** `box_walk.py --security` on 9202 through the product's Update; verdict `proven` only if the
|
||||
update ended `done` with no undo and no hold, the app runs, the four version observables are TO, the seed (if
|
||||
any) reads back, and a soak (default 600 s, cgroup `anon` against the limit, OOM kills and restarts counted)
|
||||
sees no kill and no restart. A negative control (a TO image that exits at once) comes back `failed`.
|
||||
5. **The writer:** `upgrade-test.py --write-ladder --security …`, refusing a box walk not proven, a bench given and
|
||||
not proven, a template not at the walk's FROM, a digest that moved since the walk, an engine major, a missing
|
||||
field. The compose move, `catalog_since` and the superseded step's own files are the shared `apply_entry`.
|
||||
6. **The controller (v0.341.0):** the leg takes `proven` OR `security_fix`; every other guard runs unchanged, in
|
||||
the same order; it logs `[update-leg] <app>: security fix <ids> taken (<from> → <to>)` and the hub report's
|
||||
step carries the ids. A person's press and the badge are unchanged. **A controller ≤ 0.340.0 skips the step at
|
||||
night (`not_proven`) and a hand press takes it** — proven on 9202, below.
|
||||
7. **The trade, stated.** A security-fix step skipped the bench. For an app with a box fixture the data is still
|
||||
read back after the update; for an app without one (Plex today) the step is checked only by „it starts, it is
|
||||
healthy, it runs the new version, and a 10-minute soak sees no kill or restart". `files_may_change` is a bench
|
||||
measurement: with no bench the step carries `false`. That is accepted because the leg's own guard is not the only
|
||||
net — the update takes a per-app backup first, the undo puts the pre-update data back on a failed health check
|
||||
(decision 15), and a security fix that rewrites files without breaking the health check is the case the bench
|
||||
would catch and this lane accepts the risk of. A session that knows a fix migrates files runs the bench.
|
||||
**Proof (9202, drill catalog, 2026-10-23):** `audits/security-lane-2026-10-23/` — the negative control (TO
|
||||
`busybox:1.36.1`) came back `failed` (the box undid it after 335 s) and the writer refused it; Plex 1.43.4.10903 →
|
||||
1.43.5.11029 `proven` (done in 36.9 s, the four observables at TO, digest `sha256:01bdf0ad…5c5f`, soak 600 s: anon
|
||||
peak 10.7 % of 2 GiB, 0 kills, 0 restarts, `seed: none`); the writer wrote the drill step (CVE-2026-96652, -96654,
|
||||
-96655, -96656; Plex's own notice as CISA KEV cites it, added 2026-10-20; fixed in 1.43.3.10861); on 0.340.0 the
|
||||
night leg logged `plex: skipped — not_proven` and a hand press took the step; on 0.341.0-rc.1 the night leg logged
|
||||
`plex: security fix CVE-2026-96652,CVE-2026-96654,CVE-2026-96655,CVE-2026-96656 taken` and ended `done` in 30.1 s
|
||||
after the update's second-drive copy and undo copy. Released as controller 0.341.0, global floor 11:24 UTC.
|
||||
|
||||
### 2026-10-15 (07:48–08:20) — bake first; Plex through its own key; HSTS one day (recorded before the media build)
|
||||
|
||||
247. ~~**Bake first.** A controller version is RELEASED only when its golden is baked.~~ **REVERSED by decision 250,
|
||||
|
||||
@@ -379,3 +379,28 @@
|
||||
**Gap / roadmap (as written):** Remaining ~39 apps are legacy-class by design (unit-only offsite)
|
||||
|
||||
---
|
||||
|
||||
## B23 — An urgent security fix reaches the boxes at night (the security-fix step)
|
||||
|
||||
*Map row: [B23](../00-capability-map.md#b23) · added 2026-10-23.*
|
||||
|
||||
**Scenario:** an app has a published hole (a CVE or GHSA id with its notice) and a fixed upstream version. CC walks the
|
||||
step on scratch 9202 through the product's Update (`box_walk.py --security`: install at FROM, the guarded Update, the
|
||||
four version observables at TO, a 600 s memory soak), and the only writer turns a proven walk into a `security_fix`
|
||||
ladder step. Every box on controller >= 0.341.0 takes it at night with the usual guards (backup first, undo on a
|
||||
failed health check, held / stopped / needs_person / W+5h respected).
|
||||
|
||||
**Components:** catalog `3898593` (`ladder.py check_security`, the two test-record gates, `upgrade-test.py --write-ladder
|
||||
--security`, `box_walk.py --security`); controller v0.341.0 (`legCandidate`).
|
||||
|
||||
**Status:** **PROVEN-LIVE** on 9202 with the drill catalog, 2026-10-23.
|
||||
|
||||
**Evidence:** `audits/security-lane-2026-10-23/` — the negative control (TO `busybox:1.36.1`) `failed` and the writer
|
||||
refused it; Plex 1.43.4.10903 → 1.43.5.11029 `proven`; on 0.340.0 the night leg logged `plex: skipped — not_proven` and
|
||||
a hand press took the step; on 0.341.0-rc.1 the night leg logged `plex: security fix CVE-2026-96652,… taken` and ended
|
||||
`done` after a second-drive copy and an undo copy.
|
||||
|
||||
**Gap:** an app with no box fixture (Plex today, R-1238) is checked only by health, version and the soak — no data is
|
||||
read back. `files_may_change` is a bench measurement and reads `false` when no bench ran (decision 255 item 7).
|
||||
|
||||
---
|
||||
Reference in new issue
Block a user