215 lines -> 110 (92 effective; block-level HTML comments are stripped before injection and never reach the model, verified empirically on Claude Code 2.1.222 with a control and a treatment run). Four new .claude/rules/*.md, each with a paths: glob list so it loads only when a matching file is read: gates, ui-hungarian, backup-paths, agent-coupling. The ## Layout tree was deleted as derivable; REUSE.md already owns the per-package seams its annotations stood in for. The host/access table was deleted in favour of a pointer to documentation/operations/nodes.md -- it carried three defects at once: demo-felhom given as the LAN fallback address as if it were the route, a pinned "agent 0.93.0" against the project's own no-versions-in-docs rule, and the claim that no drill VM was provisioned on demo-hp. Measured live: qm list shows VM 300 drill-r50. felhom-agent/CLAUDE.md was right; this file was wrong. Kept verbatim: the seven session-critical invariants, the F9 live-validation fence, the end-of-session checklist. controller_gates.py registers the shared instructions gate (felhom.eu/scripts/, never copied here; an absent sibling clone FAILS). Docs only -- no Go, no version bump, no image, no deploy. Ledger: felhom.eu/documentation/audits/LEDGER-instruction-trim-2026-08-06.md Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJc8sAGRWmavP3rMtdpkr2
6.2 KiB
CLAUDE.md — felhom-controller
Stable orientation only — current state lives in
CONTEXT.mdand the top ofCHANGELOG.md, never here. Cross-repo conventions (clean-tree gate, secrets, trunk-based, artifact taxonomy): workspace-root/mnt/5_hdd/felhom.eu/git/CLAUDE.md. Path-scoped detail:.claude/rules/.
What this repo is
The in-guest controller — one per customer LXC, Docker-only, holds NO Proxmox credentials. It
owns the app domain: stack/deploy management, the Hungarian web UI, app-data backup, metrics,
integrations, git-sync, notifications. Disk/host/Proxmox concerns are delegated to the host agent via
internal/agentapi. Whole-guest backup (PBS vzdump) is the agent's, not ours.
Don't confuse the two ex-"controllers": felhom-agent (host, operator-tier, was
proxmox-controller) vs this repo (in-guest, was deploy-felhom-compose).
Doing X → read Y
| Doing | Read |
|---|---|
| writing any new code | REUSE.md — canonical helpers, patterns, traps, seams |
| needing current state / roadmap | CONTEXT.md |
| needing a feature or architecture reference | controller/README.md |
| build, deploy, publish, verify a version | the felhom-build-deploy skill |
| writing or reviewing a test, fixing a bug | the felhom-testing skill |
| UI, tokens, badges, Hungarian copy | the felhom-ui-design skill |
| which box may I break | felhom.eu/documentation/runbooks/target-selection.md |
| host addresses, break-glass, node facts | felhom.eu/documentation/operations/nodes.md |
| what version is live anywhere | ask the hub (/hosts, /configs) or the box — never a doc |
| the authoritative design | felhom.eu/documentation/architecture/01/02/03-*.md |
Session-critical invariants
The rest live in REUSE.md. These cost incidents to learn:
docker compose restartdoes NOT pick up new images/env — alwaysup -d(RedeployFromEnv).- Docker's
.Statesays "running" even for unhealthy containers — the.Statusparse is the truth. - In-memory
Deployedis set BEFOREcompose up -d(slow-pull race); reverted on failure. compose up -dexits 0 on crash-loops — the post-start status check is the detection.- Env var KEYS are logged, never values. Protected stacks (traefik, cloudflared, felhom-controller) cannot be stopped from the UI.
- Verify a container image HAS the healthcheck tool before using it (BusyBox wget / python3 / curl —
the catalog
REUSE.mdmaps the families). IsRunning()is CONCURRENCY, false during a verification restore — display MUST useRestoreStatus().
Live validation — the fence
Exercise the SERVER-SIDE PIPELINE a real user triggers, end-to-end (connect → enroll → deploy). The forbidden shortcut is BYPASSING that pipeline — the F9 episode was a raw agent guest-attach with hand-set state, and it proved nothing.
claude-in-chrome is NOT available on DooPlex. The standard method is endpoint-level: invoke the
exact endpoint the UI invokes (no server logic is skipped, only rendering) and say which method was
used. Strict end-to-end UI coverage is a manual click-through by the operator.
Two traps in that method live in .claude/rules/ui-hungarian.md (ASCII-only greps; ! in
credentials) — they load when you touch a template or stylesheet.
Commands — one per surface
| Surface | Command |
|---|---|
| Gates (after ANY change) | python3 controller/scripts/controller_gates.py — from controller/ |
| Green gate | go build ./... && go vet ./... && go test ./... |
| Build + deploy | the felhom-build-deploy skill — do not hand-roll it |
Guest 9201 is bootstrap-managed — there is no compose file;
felhom-controller-bootstrap.service runs the tag written in /etc/felhom-controller-image. Catalog
changes (app-catalog-felhom.eu) are picked up by controller sync ≤15 min, or via the "Sablonok
frissítése" button.
Working with CHANGELOG.md
DO NOT read the full file — it is large and will waste context.
- Session start:
CONTEXT.md+controller/README.mdfor current state. - Adding an entry: Read only the top ~30 lines for format, then Edit-insert after line 1.
- History: Grep for topics instead of reading.
End-of-session checklist
- Commit and push all code changes (explicit paths; no
git add -A). - Build, push, and deploy the new controller image, if controller code changed.
CHANGELOG.md— always, whenever code changed and was pushed.CONTEXT.md— decisions made, state, what is next.controller/README.md— whenever a feature was added, modified or removed.REPORT.md— overwrite with this run's summary only.REUSE.md— if a shared helper or pattern was added/changed/deprecated (same commit).- Verify the deployment (
docker ps+ logs).