Records and process only. No machine contacted.
ONE REGISTER (operator ruling). 17 roadmap rows moved into OPEN-ITEMS.md keeping their
identifiers, evidence and original filing dates - the oldest R-10, filed 2026-07-15, 38 days.
15 ideas stay in ROADMAP.md, which is their home; the gate exempts them by their own state
word. 59 already-closed rows stay as history. Sorting rule recorded in the roadmap header:
does the item assert something about the shipped product a reader could check and find false?
scripts/one_register_gate.py, wired as the 11th gate. Control run: baseline passes, a planted
open roadmap-only row is convicted by name, removing it passes with the file byte-identical,
and a planted `idea` row is correctly exempt. Its four residual holes are in its docstring.
The gate earned its keep immediately: it caught R-103, a READY finding my hand-sort mis-read as
done because my regex matched the whole row where the body contains "shipped" - the gate matches
the state cell. It also caught R-203 and R-163, recorded closed in the register and still open in
the roadmap; the roadmap copies are marked SUPERSEDED with the register's verdict.
HOUSEKEEPING. OPEN-ITEMS 672,376 -> 327,109 bytes (-51%); ROADMAP 239,306 -> 78,110 (-67%).
Closed work compressed to 17% into CLOSED-ITEMS.md and ROADMAP-HISTORY.md; every entry names the
commit whose git show returns the full original text. Rule-sentences are kept verbatim under
"Reasoning kept" rather than judged entry by entry - 25 carry one.
CONTEXT.md deliberately NOT compressed and the disagreement is argued in the report: 86% of it is
standing rulings still in force, this prompt's own 3.4 says the log is never edited, and it has no
per-ruling delimiter. Filed as R-377 - the problem is navigational, not volumetric.
The hot/bulk placement decision was NEVER recorded as a decision anywhere - established, not
assumed. Now marked [DESIGN] with a pointer honest about having no original date, given a
decision-log entry that records what was rejected, and the [DESIGN]/[FACT] legend carried from 1
of 8 architecture documents to 8 of 8. Existing statements deliberately left unmarked (R-376).
PROMPT-TEMPLATE gains N.7: compress what you closed, rehome live reasoning before it goes, state
the register's size before and after.
Ceiling R-375 -> R-378.
Controller v0.190.0. Docs only here; no hub change, no hub version bump.
- audits/DIAG-bootrecon-drive-absent-2026-08-02.md — NEW. The Part 0 diagnosis,
including the run that produced a FALSE NEGATIVE and the mechanism behind it
(the agent re-binds an unmounted drive within ~60s, so the drive gate's startup
reconcile restarted the apps one second before the sweep looked). Records that
the write hazard was blocked only by an ACCIDENTAL filesystem permission that no
code owns and no test pins.
- architecture/02 §0a — the boot-recovery contract (S-1): both gates read desired
state; the sweep observes a SETTLED fleet and each sample must refresh first;
nothing is started without asking, fail-safe. Plus the durable warning:
Manager.StartStack has no gate of its own.
- 00-capability-map — the boot-recovery row, with the repeat count cited per N.5
(6 of 6 hard resets) rather than a bare PROVEN-LIVE.
- OPEN-ITEMS / ROADMAP — R-157 CLOSED (both mechanisms), R-170 CLOSED, R-171 NEW
and closed the same session, marked a regression from v0.189.0.
- STATUS.md — the power-cut line moved from "What's broken" to "What works right
now" with its repeat count; one dated bullet in the change log.
- CONTEXT.md S-13 — the lessons worth carrying: "it didn't happen this time" is
not a disproof; widening a window makes previously-unreachable overlaps
reachable; and a settle detector is only as good as the freshness of what it
samples — the fix's own defect, found live rather than by review.
Controller v0.189.0 implements operator decision D-b. Docs only here; no hub
change and no hub version bump.
- architecture/02-controller-module-map.md §0a — NEW, and it is the S-1 contract:
desired (app.yaml) / in-flight (own marker file) / observed (not persisted),
with the rule that ties them — never derive one from another. Absent desired
state means UNKNOWN, never "running". One file, one writer. D-b's binding
safety rule quoted verbatim.
- 00-capability-map.md — the boot-recovery row now rests on a recorded signal,
with the three live flows from 9201. The interrupted-operation half is marked
IMPLEMENTED, not PROVEN-LIVE: nobody killed the controller mid-backup on metal.
- OPEN-ITEMS/ROADMAP — R-166 SHIPPED with both blocking facts and their answers;
R-157 mechanism B CLOSED and A restated as the whole item; R-170 NEW (the
drive-backed boot gate still infers a Stop from a container count).
- STATUS.md — the "an app can stay switched off and nothing says so" line
rewritten to what is actually left: timing.
- CLAUDE.md — end-of-session checklist gains: confirm your own last push's CI run
went green, BY RUN ID. The failure email is a push signal; this is the pull check.
- CONTEXT.md S-12 — the rulings, and the two lessons worth carrying: a test that
constructs the thing it should prove the caller constructs is hollow (its
red-proof will say so), and a field-by-field struct rebuild in a save path is a
defect on sight.
- hub/internal/web/templatefetcher.go: raw-template URL now points at the renamed
repo (was relying on Gitea's post-rename redirect)
- documentation/ (moved here from the felhom-agent repo): fix controller-source path
refs (deploy-felhom-compose -> felhom-controller) and the platform repo name
(proxmox-controller -> felhom-agent)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>