docs: sync workspace-CLAUDE.md with the live file, carrying R-96's three rules

The workspace root /mnt/5_hdd/felhom.eu/git/CLAUDE.md is NOT a git repo — this is
its only version-controlled copy, and it had drifted since 2026-07-19. Committing
the three standing rules to the live file alone would have left them exactly as
undurable as the chat log they came from, which is the whole point of R-96.
This commit is contained in:
2026-07-27 17:08:24 +02:00
parent 655b69f37d
commit 9ea5675950
+21 -4
View File
@@ -1,7 +1,3 @@
<!-- VERSIONED COPY. The LIVE file is /mnt/5_hdd/felhom.eu/git/CLAUDE.md on DooPlex (it is not
inside any repo, so it is mirrored here to be versioned and restorable). Keep the two in
sync when either changes. -->
# CLAUDE.md — `/mnt/5_hdd/felhom.eu/git` workspace root (DooPlex)
## What this workspace is
@@ -70,6 +66,27 @@ The planning/architecture assistant (in claude.ai, "project Claude") produces fi
## Shared conventions
### Standing rules — each one earned by a real failure (R-96, committed 2026-07-27)
These were agreed in conversation and lived nowhere, so they bound nobody. They do now.
1. **Never combine a test run and a commit in one command.** A combined command has ONE exit code and
the interesting one gets swallowed. Three recorded occurrences; the worst pushed a red suite
because `packages ok: 28` was read while `rc=1` was not. Run the suite, read `rc`, *then* commit.
2. **A "no access" claim must list what was tried.** "No access" is unfalsifiable unless it names its
attempts. Two wrong verdicts on 2026-07-27 alone: ep0 (declared unreachable after trying exactly
one route — `felhom-pve → 10.77.0.1`; `DooPlex → 167.233.158.164` worked and the project memory
said so), and the storage-box API (`api.hetzner.cloud` 404s for every storage-box endpoint;
`api.hetzner.com/v1` is the real one, and the hub's own `hetznerapi.go:3` records it).
3. **An absent log line is not evidence of correct behaviour.** Verify with a POSITIVE observable —
something that MUST appear when the system is healthy. An empty log is equally consistent with
"working" and "stopped entirely". Earned twice on 2026-07-27: the R-88 watcher (an empty quiesce
log could not distinguish a healthy loop from a dead one — retired in favour of the per-tier
`/backup/due` polls in `pveproxy/access.log`), and a hub DB copy whose write had silently failed,
returning a confident "0 events in window" from a file a day stale until its mtime was checked.
- **Push to `main` directly** — no feature branches.
> **Clean-tree gate before any build:** `git status --porcelain` must be empty and