7db42c5fec
gates / gates (push) Successful in 12s
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
111 lines
6.2 KiB
Markdown
111 lines
6.2 KiB
Markdown
# CLAUDE.md — `felhom-controller`
|
|
|
|
> Stable orientation only — **current state lives in `CONTEXT.md` and the top of `CHANGELOG.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 restart` does NOT pick up new images/env — always `up -d` (`RedeployFromEnv`).
|
|
- Docker's `.State` says "running" even for unhealthy containers — the `.Status` parse is the truth.
|
|
- In-memory `Deployed` is set BEFORE `compose up -d` (slow-pull race); reverted on failure.
|
|
- `compose up -d` exits 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.md` maps the families).
|
|
- `IsRunning()` is CONCURRENCY, false during a verification restore — display MUST use
|
|
`RestoreStatus()`.
|
|
|
|
## 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.md` for 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
|
|
|
|
1. **Commit and push** all code changes (explicit paths; no `git add -A`).
|
|
2. **Build, push, and deploy** the new controller image, if controller code changed.
|
|
3. **`CHANGELOG.md`** — always, whenever code changed and was pushed.
|
|
4. **`CONTEXT.md`** — decisions made, state, what is next.
|
|
5. **`controller/README.md`** — whenever a feature was added, modified or removed.
|
|
6. **`REPORT.md`** — overwrite with this run's summary only.
|
|
7. **`REUSE.md`** — if a shared helper or pattern was added/changed/deprecated (same commit).
|
|
8. **Verify** the deployment (`docker ps` + logs).
|
|
|
|
<!--
|
|
WHY THIS FILE IS SHORT (2026-08-06, instruction-trim task).
|
|
Removed from here and rehomed, not lost:
|
|
- the `## Layout (verified against the tree)` block -> derivable by `ls internal/`; REUSE.md
|
|
carries the per-package seams and traps that the annotations were really for.
|
|
- the `!!! IMPORTANT !!!` header -> its two requirements are checklist items 3 and 5. One voice,
|
|
one place; a rule stated twice in one file is a rule that gets edited in one of them.
|
|
- the host/access table -> documentation/operations/nodes.md is the single home. The copy here
|
|
had drifted: it gave demo-felhom as plain root@192.168.0.162 (the LAN fallback, not the route),
|
|
pinned "agent 0.93.0" against the project's own no-versions-in-docs rule, and claimed no drill
|
|
VM was provisioned on demo-hp. Measured 2026-08-06: `qm list` on demo-hp shows VM 300
|
|
`drill-r50` present. felhom-agent/CLAUDE.md was right; this file was wrong.
|
|
- the "felhom-pve is back on the home LAN" block -> it was bookkeeping about a retired block; the
|
|
record is in documentation/audits/AUDIT-vacation-remote-ops-2026-07-20.md.
|
|
- the "Legacy: Windows workstation" block -> the workspace-root CLAUDE.md carries the full version.
|
|
- the gates/logging/coupling/UI paragraphs -> .claude/rules/*.md, which load when a matching file
|
|
is read instead of in every session.
|
|
Full per-block accounting: felhom.eu/documentation/audits/LEDGER-instruction-trim-2026-08-06.md
|
|
-->
|