docs: retract the expired NVMe fence, drop component versions from the inventory, fence acts in the template

Follow-up acting on the observations filed with runbooks/target-selection.md.

operations/nodes.md
- The demo-hp NVMe was documented "PRESENT AND UNENROLLED -- do not touch" and
  listed under "What is NOT enrolled here (deliberately)". Both are FALSE and had
  been for eight days: it was enrolled 2026-07-22 through the normal Tarhely flow
  and is now /mnt/nvme-1tb -- the enrolled user-data drive AND the felhom-backup
  target (verified live 2026-07-30: nvme0n1 -> /mnt/nvme-1tb, and
  dir: felhom-backup / path /mnt/nvme-1tb / is_mountpoint 1). The fence's own
  condition (join via Tarhely, not the installer, not by hand) was SATISFIED, so
  the prohibition expired with it -- while still contradicting the task specs that
  correctly sent drill-VM disks there. Retracted with its reason recorded, and the
  caution that IS still live kept (dir storage at the mountpoint ROOT, else
  exactMount fails and the storage reads disconnected forever).
- Component versions REMOVED and a note explains why: agent/controller/hub versions
  change several times a day, so a number written in an inventory is wrong within
  hours and then read as fact -- and the fleet is not uniform (on 2026-07-30 the two
  boxes ran different agent AND different controller versions). Points at the
  authorities instead: hub /hosts + /configs, felhom-agent --version, docker ps.
- Site addresses now say re-check rather than asserting one (the N100 read .162, not
  the recorded .147); records that LAN literals are unreachable from DooPlex while
  the boxes are away. Adds the target-selection pointer: this page is what the
  hardware IS, that page is what may be done to it.

PROMPT-TEMPLATE.md -- the upstream generator of the defect
- Section 12's "Do NOT touch [the untouchable]" asked the spec author to name a
  THING. Now asks for the forbidden ACT plus its REASON, with the demo-hp case as
  the worked example of how a bare object-fence over-reads.
- Section 13 gains the positive counterpart, which was the actual gap: if a task
  needs a machine to break, NAME IT. Listing only what is off-limits leaves the
  most valuable unfenced machine as the residual choice.

runbooks/workspace-CLAUDE.md (+ the untracked root copy re-synced, verified identical)
- Host table gains a Blast radius column and the missing demo-hp row, notes felhotest
  as Connection refused, and points at target-selection.md. This is the file that
  loads FIRST every session, so leaving it with the old table would have undercut
  the whole fix.

No code, no build, no deploy, no host reconfigured or renamed.
This commit is contained in:
2026-07-30 08:25:14 +02:00
parent 699790b12d
commit e6b5fa1e63
3 changed files with 69 additions and 22 deletions
+12 -1
View File
@@ -377,7 +377,12 @@ an owner — a row nobody owns is how items got lost in the first place.
<!-- Concrete temptations for THIS task, not "don't add features". -->
- Do NOT [specific out-of-scope thing CC might build].
- Do NOT touch [the untouchable: e.g. the operator-signed `DecommissionExecutor` / `classify.go`].
- Do NOT [**the forbidden ACT**, and **its reason**: e.g. "modify the operator-signed
`DecommissionExecutor` — it is the signature boundary"]. **Fence the act, not the object.** A bare
"do not touch X" is read as covering every act on X, including ones nobody meant to restrict — that
is how "do not re-target demo-hp's backup target" became "do not use demo-hp at all", which pushed a
destructive drill onto the one machine holding the recovery chain. State the reason too: a rule whose
reason is recorded can be correctly narrowed later, and one without it becomes permanent by default.
- Do NOT reuse [the dangerous lookalike from §5].
- Do NOT refactor nearby code, change passing tests, or create a branch.
- Do NOT add "Co-Authored by..." anywhere
@@ -391,6 +396,12 @@ an owner — a row nobody owns is how items got lost in the first place.
**Clean-tree gate first:** `git status --porcelain` empty AND `HEAD` == `origin/main` in the repo
being built. An unpushed change does not exist.
**If the task needs a machine to break — NAME IT.** A drill, destructive test or throwaway VM gets an
explicit target: *"run this on demo-hp"*. Do not leave it to be inferred from the prohibition list;
listing only what is off-limits leaves the most valuable unfenced machine as the residual choice, which
is exactly how a drill landed on DooPlex. Tiers and per-machine permitted/care/forbidden:
[`runbooks/target-selection.md`](runbooks/target-selection.md).
**Controller** (local build on DooPlex → guest via golden/bootstrap):
```bash
FELHOM_ROOT=/mnt/5_hdd/felhom.eu