Files
felhom.eu/REPORT.md
T
admin e994bf35d2 STATUS.md: a plain-language operator page, and today's four decisions recorded
Documentation only — no code, no box, no build.

STATUS.md (repo root, 652 words / 67 lines): what works · what's broken ·
what we're working on · waiting on you · changed since. A VIEW of
OPEN-ITEMS.md, holding nothing of its own; not CONTEXT.md, and both files
now say why they stay separate. No R-n is the subject of a sentence —
identifiers are bracketed pointers only.

CONTEXT.md S-5 records the four operator decisions taken 2026-08-02
(D-a … D-d), none of them implemented:
  D-a merge mp1 into mp0 rather than resize it — before any external
      install, and D-c ships in the same step        → R-165
  D-b desired/observed app state in its own store, with the state-store
      safety rule verbatim                           → R-166 (BLOCKED)
  D-c customer fill warning + operator backup-failure alert → R-167
  D-d only DooPlex and Peti's box are protected      → target-selection.md

R-163 RE-FRAMED, not closed: the sizing question is withdrawn rather than
answered; the row survives as the record of the constraint until R-165
lands. R-156's papra referral RESOLVED — deployed nowhere, so the template
fix strands nothing; the docker ps evidence is recorded with its
provenance and its scope limit.

target-selection.md: two protected machines, everything else disposable.
ep0 is no longer Tier 2 but is not scratch (it holds the only off-premises
copy of real customer data) — flagged for explicit operator confirmation.
The demo-box backup-target fence drops from prohibition to stated cost,
because D-d spends that reference anyway.

CLAUDE.md gains an End-of-session checklist carrying the STATUS.md
maintenance rule and "a finding goes in OPEN-ITEMS.md first".
2026-08-02 14:20:29 +02:00

11 KiB

REPORT — STATUS.md created, and the 2026-08-02 operator decisions recorded (2026-08-02)

Overwritten per the standing rule. The prior contents (hub v0.85.0 Network card + v0.86.0 Copy without reveal, 2026-07-31) have their durable record in hub/CHANGELOG.md and documentation/audits/host-addresses-visible-2026-07-31.md; nothing was lost by this overwrite.

Class: documentation only. No code, no template, no box, no build. Repo felhom.eu only — app-catalog-felhom.eu was read for context and not modified. No CHANGELOG.md entry exists for this change and none is missing: this repo has no root changelog, only per-area hub/, scripts/, website/ (CLAUDE.md), and this session touched none of those areas.

Baselines: felhom.eu @ 260a8f6, app-catalog-felhom.eu @ fd7747d. Part 1 was derived by reading the register's rows and both ranking sections, not from memory.


1. STATUS.md — the file

Root of felhom.eu, so it is the first thing visible. Sections in the specified order: what works · what's broken · what we're working on · waiting on you · changed since last update.

Word count: 652 total, 581 excluding the header block (wc -w; the header carries the view-not-source, not-CONTEXT.md and maintenance rules, which the spec requires). That is over the ~500 target and it is a deliberate miss, stated rather than hidden. Five passes took it from 819 to 652. Getting under 500 needed either dropping a mandated item or dropping the off-site-credential line — the register's top-ranked open item and the largest customer-data exposure on it. Cutting the biggest data risk to save forty words is the wrong trade on a page whose job is to show the operator what is at stake. It is 67 lines and fits a screen. If the operator disagrees, the line to cut is the R-95/R-87 one and the page drops to ~545.

Content, in the operator's ranking: an app can stay off after a power cut, silently (R-157) · the off-site copy can be erased by the box that wrote it, and has never been restored from (R-95, R-87) · three of fifty-three apps saved data where backups never looked (R-156) · 20 GB of backup space against 50 GB of apps (R-163) · when that trips, one page says so and nothing alerts (R-158) · the checker exists but a person has to remember it (R-161).

Constraints honoured: no R-n is the subject of any sentence — every identifier is a bracketed pointer at the end of a line; no file paths, function names or version numbers appear; every broken item is stated as what a customer or the operator would notice. Shipped, watching and blocked-on-a-predicate rows (R-159, R-160, R-162, R-164) are absent by design.

One deviation, flagged per standing rule 4. "Waiting on you" is specified as decisions only, and it carries one non-decision: the hub password needs rotating (R-132, owner Viktor). It is the only thing on the register waiting on the operator with a live credential consequence, and omitting it from the operator's own page to honour a section rule would be the letter over the point. It is labelled "a job, not a decision" so the section's shape is not quietly eroded.

2. The decisions — where each one went

All four are in CONTEXT.md as standing ruling S-5, labelled D-a … D-d as in the discussion and deliberately kept distinct from S-3's D1…D6. Open work is carried as backlog rows, per the existing convention — no new home was created for either.

Decision Recorded Work
D-a — merge the backup partition away (not resize) CONTEXT.md S-5 R-165 (new)
D-b — desired/observed app state, own store CONTEXT.md S-5 R-166 (new, BLOCKED)
D-c — storage monitoring + backup alerts CONTEXT.md S-5 R-167 (new)
D-d — only DooPlex and Peti's box are protected CONTEXT.md S-5 runbooks/target-selection.md, this session — no row; the decision is the change
Maintenance rule (Part 3) STATUS.md header and CLAUDE.md § End-of-session checklist

Recorded verbatim inside D-b, because it is the decision's binding constraint: losing the state store must never cause an app to be deleted, restarted wrongly, or reported healthy when it is not — the worst acceptable outcome is re-running a backup that already ran. Its two "establish before speccing" items are carried on R-166 as the reason that row is BLOCKED rather than READY.

Deliverable 5 asks for "the five decisions". Part 2 defines four (D-a … D-d); the fifth deliverable line is the Part-3 maintenance rule, and it is in the table above. Nothing else in the task reads as a fifth decision — flagged rather than invented.

D-a's two conditions are recorded as conditions, not commentary: it changes the disk layout so it must land before any external install, and it removes a wall that currently fails safely so R-167 ships in the same step, never after. R-165 restates both; R-167 names R-165 as the thing it gates.

None of D-a, D-b or D-c is implemented. No controller, agent, installer or hub file was opened for editing.

3. R-163 re-framed, and R-156's papra referral resolved

R-163 is re-framed, not closed — as instructed. State went WAITING-ON-OPERATOR — the ratio is a tier-sizing rulingRE-FRAMED 2026-08-02 — open, no longer waiting on a ratio; "Blocked on" went from the operator's sizing decision to a pointer at R-165; owner operatorCC. The cell now says the sizing question is withdrawn rather than answered, that the row survives as the record of the constraint until the merge lands, and that the original finding follows unchanged. The intake ranking (item 4) was updated with it, and records that R-165 inherits R-163's rank and is the highest-ranked item that must land before any external install.

R-156's papra referral is resolved. The referral existed because moving a mount relocates live data out from under a running app; with papra deployed nowhere there is nothing to strand, so the cheaper leg — the template mounts /app/app-data — is takeable without waiting on upstream.

The provenance is recorded with the claim, because it decides the row. The evidence is docker ps -a on demo-hp's guest 9201 returning empty, supplied with the task; this session did not re-measure — it is documentation-only and every box was fenced. The recorded scope is honest about its edge: it covers the one guest papra was convicted on in Campaign 10, and no other customer's guest was enumerated, so the row instructs the task that edits the template to re-check first. Next action on the row is the catalog edit plus catalog_gates.py, explicitly not done here.

4. target-selection.md per D-d

The rule at the top is now D-d: two protected machines, everything else disposable, with the correction stated as a correction — the earlier caution was costing sessions and pushing drills onto DooPlex. The tier table's Tier 2 row is DooPlex + Peti's cluster "and, by D-d, nothing else".

Two consequences the decision did not name, both handled visibly rather than silently:

  • ep0 + the Hetzner Storage Boxes. D-d's protected list has two machines and ep0 is not one, so the page no longer calls it Tier 2. It is not thereby scratch: it holds the PBS-DR datastore and the restic copy of a real customer's data — the only off-premises copy that exists. Read the narrow way (not protected, but not wipeable), using the page's own fences-name-acts rule, and flagged in the page for the operator to confirm explicitly.
  • The shared "do not re-point either backup target" fence on the two demo boxes was downgraded from a prohibition to a stated cost, because D-d makes both boxes freely reinstallable, which spends that reference configuration just as thoroughly — keeping the fence would have left the page self-contradicting. The reason survives: know you are spending the regression reference, and put the box back.

Also corrected while in the file: the fences-name-acts example cited the fence this edit removed, and demo-hp's access line asserted "no baked SSH key" — which R-129 records as measured false on 2026-07-31. It now points at R-129 instead of sending the next session to the hub vault for a credential it may not need.

5. The maintenance rule

In two places, as specified: the STATUS.md header block, and a new ## End-of-session checklist in CLAUDE.md — which also gathers the couplings that were previously scattered (CHANGELOG + REPORT, REUSE, the capability map's own end-of-session line, S-1's architecture coupling) and closes with a finding goes in OPEN-ITEMS.md first, never only in a report, an audit or STATUS.md.

CONTEXT.md gained a header block stating why it and STATUS.md are separate — same subjects, different readers, and STATUS.md holds nothing of its own. STATUS.md says the same from its side.

6. What could not be translated into plain language

Asked for explicitly, because an untranslatable row usually means the row itself is unclear.

  • R-29"gates are enforced nowhere". The class is stateable ("we have checks nobody runs"), but its instances are four differently-broken scripts across two repos with no shared consequence, so every plain sentence either says nothing or misstates one instance. R-161 is its readable fragment, which is why R-161 is on the page and R-29 is not.
  • R-123 / R-125 — process findings about how the register and how tests are written. Real, and they belong on the register; there is no customer-visible symptom to lead with, so they have no honest first sentence for this page. They are not "broken" in the operator's sense.
  • R-133 (the plaintext break-glass credential) — translatable, and left off only for space. It is the strongest candidate for the next update if something else closes.
  • R-115 vs R-110 — separate rows, one plain-language paragraph. Merged into a single "Waiting on you" bullet carrying both pointers, because two adjacent bullets about publishing read as one item the operator has already half-decided.

A register defect found while reading, filed here because the fix is not mine to guess: R-133 is used TWICEOPEN-ITEMS.md:80 (duplicate domain values accepted by the hub) and :86 (the plaintext break-glass credential). Two different findings, one ID, both READY. One needs renumbering, and which one is the operator's call since both are cited from elsewhere (CONTEXT.md S-4 cites the credential one).

7. Files changed

File Change
STATUS.md new — the operator page
CONTEXT.md S-5 (D-a … D-d); header note on the STATUS.md separation
documentation/backlog/OPEN-ITEMS.md R-165/166/167 filed; R-163 re-framed (state, blocked-on, owner, ranking); R-156's referral resolved with its provenance
documentation/runbooks/target-selection.md D-d rule; tier table; ep0; the demo-box fence; two stale lines
CLAUDE.md new ## End-of-session checklist, carrying the STATUS.md maintenance rule

Nothing was built, deployed, published or touched on any host. Every claim about the register above is a claim about pushed source in this repo at the commit below.