527d81cf70
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NKSN3gSg4TKVBBqkwW2djR
94 lines
6.3 KiB
Markdown
94 lines
6.3 KiB
Markdown
# REPORT — hub v0.72.0: R-70 + R-71(c) — the offsite last mile becomes visible, burned credentials heal themselves (2026-07-23)
|
||
|
||
**Spec:** R-70 + R-71(c) prompt (project Claude, 2026-07-23). Companion controller leg: v0.161.0
|
||
(see `felhom-controller/REPORT.md`). Origin: `documentation/audits/DIAG-f10-demo-hp-offsite-2026-07-23.md`.
|
||
R-71(a) (day-0 ordering) untouched — separate upcoming spec.
|
||
|
||
## Baselines
|
||
|
||
| Repo | start | shipped |
|
||
|---|---|---|
|
||
| felhom.eu | `c801cee6`, hub 0.71.0 | hub **0.72.0** (code + separate manifest chore commit), ArgoCD Synced/Healthy |
|
||
| felhom-controller | `0eba37d5`, v0.160.0 | **v0.161.0** (`ce85314`), deployed BOTH boxes, healthy |
|
||
|
||
## What shipped (one detector, four consumers)
|
||
|
||
1. **Detector** — `internal/offsite/delivery.go` `DeliveryStateFor`: `applied` /
|
||
`consumed_awaiting_apply` / `staged_awaiting_consume` / `no_secret` from the secret-row
|
||
timestamps × report offsite-presence. Applied wins (the box's own report is the strongest
|
||
evidence); applied+unconsumed-staged (demo-felhom) = `applied` + `StaleStagedSince` flag.
|
||
New store reads (`GetOneTimeSecretInfo` — timestamps only, value never selected;
|
||
`LatestReportOffsitePresence`; `CountReportsOffsiteSince`; `LastEventAt`) + the PBSDR-style
|
||
test back-dater.
|
||
2. **Customer card** — `deliveryViewFor` + `config_form_body.html`: the static "delivered to the
|
||
controller once" claim is deleted; the card renders state + age (badge `n-ok/n-warn/n-neutral`,
|
||
consumed goes amber past 30 min, stale-staged info line). Render test per branch.
|
||
3. **Loud event** — `offsite_delivery_stuck` (WARNING) at ≥ 1 h of consumed_awaiting_apply;
|
||
24 h/customer cooldown, durable via the events table (restart-proof).
|
||
4. **Self-heal (R-71c)** — `monitor.OffsiteDeliveryChecker` on the shared 60 s ticker invokes
|
||
`web.Server.ReissueOffsiteForCustomer` behind the narrow `monitor.OffsiteReissuer` interface
|
||
(pbsdrheal precedent; armed only when the provisioner exists — else a restaged event would
|
||
lie about a silent no-op). Trigger: consumed ≥ 1 h + ≥ 4 consecutive offbox-less reports +
|
||
zero offbox evidence since consume. One restage/customer/24 h (durable); every firing emits
|
||
`offsite_credential_restaged` (WARNING). **R-39(a) guard**: the heal re-reads the secret row
|
||
immediately before acting and refuses over an unconsumed row — the store's
|
||
`SaveOneTimeSecret` clobber semantics are untouched (Re-issue depends on supersede; the guard
|
||
lives in the caller, exactly as specced).
|
||
|
||
## Red-proofs (run, observed, restored — verbatim failures)
|
||
|
||
1. **THE CLOBBER RED-PROOF** — R-39(a) guard block removed from `maybeHeal`; the TOCTOU test
|
||
(operator Re-issue staged mid-tick via the onEvent hook) failed with:
|
||
`reissue calls = 1, want 0 — the R-39(a) guard must refuse over an unconsumed secret`
|
||
— i.e. the operator's fresh unconsumed secret would have been clobbered
|
||
(the fake reissuer mimics the production `SaveOneTimeSecret` side effect, so the clobber is
|
||
observed on the row, not inferred). Guard restored → green.
|
||
2. **Heal rate-limit** — `LastEventAt`/`healCooldown` check removed; failed with:
|
||
`reissue calls after recurrence = 2, want STILL 1 (one restage per customer per 24h)`. Restored.
|
||
3. **Stuck-event cooldown** — cooldown check removed; failed with:
|
||
`stuck events = 2, want exactly 1 (24h per-customer cooldown)`. Restored.
|
||
|
||
Plus: the full-Check demo-felhom-shape test (applied + stale staged → zero events, zero calls,
|
||
row byte-untouched), evidence gates (<4 reports → no heal but stuck event still fires; mixed
|
||
offbox history → no heal), young-consumed silence, disabled/blocked skip, dispatcher severity
|
||
tests (warning routes operator-only; an info variant would be silent — pinned beside the v0.71.0
|
||
guard, `severityNotifies` untouched), 5 card render tests + `deliveryViewFor` amber derivation.
|
||
Green gates: hub 17 packages ok + `hub_confirm_gate.py`; controller 25 packages ok + all template
|
||
gates (the pre-existing R-29 `docker_run_volume_path_gate` red noted, untouched).
|
||
|
||
## Live validation (read-only, both fixtures intact)
|
||
|
||
- **Checker silence:** 10 min of 60 s ticks on the live fleet → **0** `offsite-delivery` log
|
||
lines, **0** detector events in the DB — both fixtures are healthy and the detector agrees.
|
||
- **Fixture states from live data** (fresh DB copy, shredded after):
|
||
demo-hp `latest_report_offsite=True, secret consumed 09:53:41` → **applied**;
|
||
demo-felhom `latest_report_offsite=True, secret_row=(2026-07-21 08:29:29, None)` →
|
||
**applied + stale-staged since 07-21** — the live specimen SURVIVED the train untouched
|
||
(`consumed_at` still NULL, created_at unchanged); peti-felhom → applied.
|
||
- **demo-hp controller page** (authed endpoint fetch inside the guest, ASCII-safe greps):
|
||
banner count 0, `felhom-offsite-card` id count 0 (configured + 1 toggled app → no card at all),
|
||
configured markers present. v0.161.0 healthy on both boxes.
|
||
- **Method:** endpoint-level + DB-input derivation (no browser on DooPlex). The rendered card is
|
||
pinned by render tests; the operator's 10-second residual: demo-hp Edit page shows
|
||
`applied`, demo-felhom shows `applied` + the stale-staged note (since 2026-07-21).
|
||
- **The self-heal is NOT live-fired** — no broken box exists and none was broken for it (F9
|
||
rule). It ships unit-proven + red-proofed, PARTIAL/IMPLEMENTED on the ROADMAP with the
|
||
explicit "fires on next natural occurrence or a staged drill" note — never PROVEN-LIVE.
|
||
The controller banner leg is likewise unit-proven/live-pending (no box occupies the
|
||
enabled+no-offbox window; the next fresh onboarding is its natural live leg).
|
||
|
||
## Rulings recorded (CONTEXT.md)
|
||
|
||
State precedence (applied wins; stale-staged is a flag, never a downgrade); durable cooldowns via
|
||
the events table (restart-proof by design); both detector events operator-only (no
|
||
customerMessages entry, not in allowedEventTypes — the pbsdr_* precedent) until the mechanism has
|
||
history; heal disabled without a provisioner.
|
||
|
||
## Observed, not acted on
|
||
|
||
- R-29: `docker_run_volume_path_gate` red on `appexport/estimate.go:179` (pre-existing, has its
|
||
own row — the 3-line allowlist fix remains undone by design of this train's scope).
|
||
- The `szolg` single-hit on the demo-hp page grep is an accent-truncated unrelated word (the
|
||
ASCII-only-grep trap documented in felhom-controller/CLAUDE.md — verified benign via the
|
||
card-id count of 0).
|