docs+skills: felhom-{build-deploy,ui-design,testing} skills + install_skills.py (junction); CLAUDE.md refresh (version-free); consolidated REPORT

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-03 11:27:48 +02:00
parent ad61e96abd
commit 9282d60f96
9 changed files with 502 additions and 137 deletions
+81 -79
View File
@@ -4,104 +4,106 @@
---
# REPORT — docs: REUSE.md introduced across all four felhom repos (consolidated)
# REPORT — hub v0.31.0 critical-severity fix + Felhom skills + CLAUDE.md refresh (consolidated)
**Date:** 2026-07-03 · **Class:** docs-only (no code change, no version bumps, no builds, no deploys)
**Deliverable:** a per-repo `REUSE.md` reuse map (canonical helpers / patterns / traps / seams /
extension points / known duplication), code-verified at file+symbol, plus `scripts/reuse_refs_check.py`
as the staleness gate, plus CLAUDE.md maintenance hooks.
**Date:** 2026-07-03 · **Class:** implementation (hub v0.31.0, deployed) + docs/skills across all repos
## 1. Baselines used (all matched the task's expected hashes; trees clean, pulled fresh)
## 1. Baselines & commits
| Repo | `main` @ baseline | State |
All four repos matched the task's expected baselines (pulled clean).
| Repo | Baseline | Commits pushed to `main` |
|---|---|---|
| felhom-controller | `d0c70a7da6f4060422a545cea2396f9df5f7d61f` | v0.98.3 |
| felhom-agent | `0db09bf34fe2eff4b80ac77ed19afa18aef7675f` | v0.61.0 |
| felhom.eu | `b0de6b34f61fef2e14807fba2c6176b888dc3327` | hub v0.30.1 |
| app-catalog-felhom.eu | `bb81cd414afcb89e28ac60f405133f40195e6c43` | n/a |
| felhom.eu | `d331eb26d1` | `b5f0050` (fix+tests+REUSE), `4a18306` (manifest→0.31.0), `ad61e96` (render test), + the docs/skills commit carrying this REPORT |
| felhom-controller | `eda33400da` | `a518023` (CLAUDE.md refresh) |
| felhom-agent | `2a024b6039` | `3e760a5` (CLAUDE.md refresh) |
| app-catalog-felhom.eu | `c5a3d1b15b` | `15cdf7b` (CLAUDE.md expansion) |
## 2. Files created/modified per repo
## 2. Part 1 — hub v0.31.0 (the critical-severity fix)
- **felhom-controller:** `REUSE.md` (new, 210 lines); `CLAUDE.md` (+2 hook lines); `CHANGELOG.md`
(docs entry); `CONTEXT.md` (note); `REPORT.md` (overwritten).
- **felhom-agent:** `REUSE.md` (new, 160 lines); `CLAUDE.md` (+2 hook lines); `CHANGELOG.md`;
`CONTEXT.md`; `REPORT.md`.
- **felhom.eu:** `REUSE.md` (new, 151 lines — hub + website + scripts + manifests);
`scripts/reuse_refs_check.py` (new gate); `CLAUDE.md` (+2 hook lines); `hub/CHANGELOG.md` +
`scripts/CHANGELOG.md` (docs entries); `CONTEXT.md` (new, minimal — repo had none); `REPORT.md`
(this file).
- **app-catalog-felhom.eu:** `REUSE.md` (new, 58 lines, light §2/§5 variant per spec); `CLAUDE.md`
(new, minimal — repo had none; full CLAUDE.md is a separate task); `CHANGELOG.md`; `CONTEXT.md`
(new, minimal); `REPORT.md`.
**Change:** `handleEvent` severity switch gains `"critical"` (unknown values still coerce to `"info"`,
exact-match lowercase); `severityLabels["critical"] = "Kritikus hiba"` added; dashboard consumer
gains `EventCriticals`; critical badge renders FIRST in dashboard + customer-page count chains;
`style.css` defines the previously-referenced-but-undefined `.severity-critical` (`--crit` tokens)
and `.severity-ok` (neutral). Frozen legacy `/notify` path and `allowedEventTypes` untouched.
## 3. Commits pushed to `main` (one per repo)
**Tests (new `hub/internal/api/event_test.go` — first tests on /event):**
- A: critical preserved to store — **companion red-proof run:** with the one-line fix reverted the
test FAILED with `stored severity = "info", want "critical"`; fix restored → PASS.
- B: severity `"banana"` → stored `"info"`. C: unknown event_type → 400 + store empty. Auth: 401.
- D: `TestTemplates_DashboardCriticalBadge` (render_test.go) asserts the rendered HTML contains the
`severity-critical` count badge ordered before the error badge. **Method note:** UI verification
used the Go render test — Chrome verification stopped at the operator login (password entry is
out of CC's scope).
- Green gate: `go build ./... && go vet ./... && go test ./...` — all green.
| Repo | Commit |
|---|---|
| felhom-controller | `eda33400da0fd6a3b80271c44df24a177f7a444a` |
| felhom-agent | `2a024b603973e79a0c84d6847a7cde0898091c61` |
| app-catalog-felhom.eu | `c5a3d1b15b71103a3d1da217f1ff5a834857375c` |
| felhom.eu | the commit carrying this REPORT (HEAD of `main` after this push) |
**Deploy (GitOps):** image `felhom-hub:0.31.0` built+pushed on 180; `manifests/hub.yaml` bumped;
ArgoCD app `felhom` hard-refresh + sync → `Synced`/`Healthy`, rollout complete, pod image
`...felhom-hub:0.31.0`, clean startup logs.
## 4. Per-repo sweep counts (evidence of depth)
**Live probe (real pipeline):** POSTed one `event_type:"test"`, `severity:"critical"` event from
guest 9201 using its own controller.yaml credentials (key never echoed — length-only). Result:
HTTP 200; hub log `Event from demo-felhom: test (critical)` (stored severity critical, not info);
dispatcher sent the operator email (`Test email sent to nagyfenyvesi.viktor@gmail.com`).
| Repo | funcs scanned (non-test) | §1 rows | §3 traps | §6 duplications |
|---|---|---|---|---|
| felhom-controller | 1174 | 62 | 8 | 12 |
| felhom-agent | 702 | 48 | 10 | 7 |
| felhom.eu (hub Go) | 297 | 34 | 8 | 5 |
| app-catalog | 53 apps scanned | 0 (by design) | 3 | 6 |
**REUSE.md** §1 gotcha + §3 trap row updated in the same commit as the fix;
`reuse_refs_check.py``OK [felhom.eu]: 31 cited paths, all exist`.
Trap sweeps ran mechanically per §Method (`--delete`, `wipefs`, `mkfs`, `os.RemoveAll`, `rm -rf`,
`sfdisk`, `dd `, `Format`, `Wipe`) in every repo; each hit classified as guarded-canonical (§1, guard
named) or §3 trap. Known traps (rsyncMirror `--delete`, gokapi entrypoint, AGENT-001 TOCTOU shape,
allowedEventTypes 400) were independently rediscovered from code.
## 3. Part 2 — skills
## 5. reuse_refs_check.py output (final, all four repos)
Three skills authored in `felhom.eu/skills/` (each SKILL.md ≤160 lines, pushy trigger descriptions):
`felhom-build-deploy`, `felhom-ui-design`, `felhom-testing`. Content verified against live
source/infra before writing (see §5). New `scripts/install_skills.py`: idempotent, junction-first
(`mklink /J`) with copy fallback + re-run reminder.
**Install mode: JUNCTION** — created for all three; second run detected them and no-op'd.
**Discovery (Scenario E):** fresh `claude -p` session listed all three:
```
OK [felhom-controller]: 65 cited paths, all exist
OK [felhom-agent]: 57 cited paths, all exist
OK [felhom.eu]: 30 cited paths, all exist
OK [app-catalog-felhom.eu]: 10 cited paths, all exist
felhom-build-deploy
felhom-testing
felhom-ui-design
```
Bonus trigger probe: "which skill to deploy a new hub version?" → answered `felhom-build-deploy`
with the correct first command (`./build.sh <VER> --push` on 180).
(The gate earned its keep during authoring: it caught the controller map citing
`scripts/{template_id_gate,emoji_gate}.py` — the real location is `controller/scripts/` — fixed
before commit.)
## 4. Part 3 — CLAUDE.md refresh
## 6. Observations — doc↔code drift & findings (recorded, NOT acted on)
Standing rule adopted everywhere: **CLAUDE.md carries no version-pinned current state** (that lives
in CONTEXT/CHANGELOG/REUSE); deep runbooks live in the skills, CLAUDE.md keeps a summary table + pointer.
**Worth operator attention:**
- **hub severity-coercion gotcha (NEW finding):** the remembered "dispatcher drops critical" issue is
FIXED in code (`severityNotifies` routes warning/error/critical since v0.24.0), **but**
`handleEvent` (hub/internal/api/handler.go) coerces any severity outside {info,warning,error} —
including `"critical"` — to `"info"` at ingest, so a controller-POSTed critical event never
notifies. Hub-internal events bypass this. Recorded in felhom.eu REUSE.md §3.
- **Committed secrets:** `manifests/felhom.secret.yaml` still carries inline `stringData`
credentials (healthchecks superuser pw + Django secret — not deployed; umami APP_SECRET +
POSTGRES_PASSWORD — deployed), unlike the de-gitted Resend key. Recorded as a §3 trap; rotation/
de-git is an operator follow-up.
| File | Diffstat | Headlines |
|---|---|---|
| felhom-controller/CLAUDE.md | +119/294 (338→~160 lines) | full 30-package map (was 7); stale `/opt/docker` demo deploy replaced with verified 9201 bootstrap flow; hub build section deleted; patterns pruned to 6 invariants |
| felhom-agent/CLAUDE.md | +86/71 | "Current: v0.31.0" narrative + slice history deleted (30 versions stale); layout completed (+8 packages, opsign); deploy facts re-verified on felhom-pve |
| felhom.eu/CLAUDE.md | +73/58 | "Hub — current state (v0.7.x)" (23 versions stale) → version-free architecture section; GitOps rules kept incl. live-image-lag note; skills section added |
| app-catalog CLAUDE.md | +26/5 | stub → ~30-line proper file (purpose, deploy contract, pointers) |
| E:\git\CLAUDE.md (local) | +8 | Skills section only |
**Stale docs (each a separate refresh task):**
- `felhom-agent/CLAUDE.md` says "Current: v0.31.0" and omits ~8 live packages (localapi, signedjobs,
escrow, capability, guesthook, lanresolver, desired, provision).
- `felhom.eu/CLAUDE.md` "Hub — current state (v0.7.x)" is ~23 minor versions stale (live 0.30.1).
- `felhom-controller/CLAUDE.md` layout lists ~7 of ~30 internal packages; bare-metal deploy steps
superseded (already flagged in-file).
- app-catalog `README.md`: phantom `filebrowser/` template, missing `recipe-importer/`, field-type
table omits `subdomain`/`secret_input`, smtp_mapping list undercounts (2 listed, 6 real).
## 5. Commands/facts re-verified against live infra (stale findings)
**Duplication highlights (full lists in each REUSE.md §6):** controller atomic-write ×4 (+1 inline,
two with deliberate non-atomic bind-mount fallback), dir-size ×6, JSON writers ×5/3 envelopes;
agent lsblk parsers ×2, atomic JSON store ×3, run() helper ×4, plus the acknowledged
antiRetarget↔WipeExecutor mirror; hub Resend sender ×2 + Hungarian formatter ×2 (frozen legacy
path) and semver-compare ×2 with different failure semantics; agent dead config knobs
`Binaries.MkfsExt4/MkfsXfs` (never executed — wrapper paths are hardcoded).
- Guest 9201 deploy mechanism confirmed live (`/etc/felhom-controller-image` = 0.98.3 tag,
`felhom-controller-bootstrap.service` enabled, container healthy) — the OLD controller CLAUDE.md
still documented the pre-re-platform `/opt/docker` compose deploy for node 1: **stale, replaced**.
- Agent service confirmed on felhom-pve: `User=felhom-agent`,
`ExecStart=/usr/local/bin/felhom-agent --config /etc/felhom-agent/agent.json`, live 0.61.0 — the
OLD agent CLAUDE.md claimed v0.31.0 current: **stale, removed**.
- Build dirs on 180 confirmed: `~/build/{felhom-agent,felhom-controller,felhom-hub}` + `~/git`
clones; Go present.
- Design tokens confirmed byte-identical across website site.css / hub style.css / controller
style.css `:root` blocks (values inlined in the ui-design skill).
- Hub GitOps flow re-verified by executing it (this deploy). Red-proof citation
(`dispatcher_test.go` ~L2749) verified in source.
- Website displays no hub version anywhere (checked) — no website change needed.
## 7. Maintenance hooks now active
## 6. Observations (noticed, NOT acted on)
Every repo's CLAUDE.md: "See `REUSE.md` before writing new code" + "update REUSE.md in the SAME
commit that adds/changes/deprecates a shared helper or pattern". Staleness gate:
`python scripts/reuse_refs_check.py <repo-root> [...]` (run from felhom.eu). Reviewer-side: symbols
spot-verified at file:line (line numbers in the maps are landmarks only).
- The hub severity badge classes predating this task (`.severity-error/-warning/-info`) use legacy
raw hexes, not the v2 `--warn/--crit` tokens — left alone per the no-restyle rule; a token
migration is a candidate D-series follow-up.
- The hub login page appears unstyled relative to the v2 design system (default-blue button, white
background) — pre-existing, out of scope.
- `manifests/felhom.secret.yaml` inline credentials (from the REUSE report) remain an open operator
follow-up.
- The controller currently emits no `critical`-severity events; the fix future-proofs the channel
(hub-internal `host_disk_critical`/`storage_fill_critical` already flow at critical severity —
they bypass ingest).