diff --git a/documentation/runbooks/workspace-CLAUDE.md b/documentation/runbooks/workspace-CLAUDE.md index d46478c..29a3ddd 100644 --- a/documentation/runbooks/workspace-CLAUDE.md +++ b/documentation/runbooks/workspace-CLAUDE.md @@ -1,7 +1,3 @@ - - # 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