Files
felhom.eu/REPORT.md
T

6.3 KiB
Raw Blame History

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. Detectorinternal/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 carddeliveryViewFor + 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 eventoffsite_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-limitLastEventAt/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:41applied; 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).