Files
felhom.eu/documentation/audits/app-guides-2026-10-15/TASK.md
T

21 KiB
Raw Blame History

Night task: app user guides — gate, media pilot, then every other app

Saved verbatim from the operator's message of 2026-10-15 ~21:50 CEST. The spec (the APPENDIX) existed nowhere on disk; this file is the record. The brief above the appendix wins where the two differ.

For the operator (plain language)

Tonight Claude Code writes a user guide and an FAQ for every app in the catalog, in Hungarian and English. It starts with the five media apps, then does the other 60. Each guide is checked against the app's own source code at the exact version we ship. A guide that fails the check stays hidden. It only adds text to the catalog. Old boxes ignore the text, and boxes on 0.315.0 or newer show it on the „Útmutató" tab.

In the morning: read the Plex and the Sonarr guide on demo-hp. If you want the format changed, it is one pass over all files.


What to run

Run the full spec in the APPENDIX at the end of this message (Part 0 → A → C → B → N). It is the spec. It is not on disk anywhere — this message is the only copy. Save it as felhom.eu/documentation/audits/app-guides-2026-10-15/TASK.md in your first docs commit, so the record exists. The part above the appendix states what changed since the spec was written and the night rules. Where they differ, the part above wins.

The pilot has not run yet. At 21:45 CEST the catalog main is still e67aad49: no gate change, no guide.

1. Baselines (re-read at start; do not trust)

Repo main @ Note
app-catalog-felhom.eu e67aad49 the repo this task changes
felhom-controller e7b64af1 (v0.317.0) read only. Guide schema as built: internal/stacks/metadata.go AppGuide (~L171–L200: checked_version, sections[].title/intro/steps, faq[].q/a), overlay in metadata_i18n.go (~L73–L104). It matches the spec's Part 5.
felhom.eu 371b72da docs, register, STATUS only

demo-hp guest 9201 runs controller 0.317.0 — it renders guides.

2. Night rules

  1. Unattended. Ask nothing. Take the most reasonable reading, write it at the top of the report, go on.
  2. demo-hp is shared tonight (other sessions may be building or testing on it). For the pilot's box check (Part A.3): use only media apps already running on 9201, read only — API reads and page fetches, no install, no remove, no restart, no setting change, no Plex claim. An app that is not running there gets the label check only; set checked_version by the spec's §8 label-check row and list it in the report as „box check owed". Tester 1, N100, ep0, DooPlex: not touched (DooPlex runs your git and reads only).
  3. The rendering check goes through the public address: https://felhom.enkisfelhom.hu/apps/sonarr/guide (and plex) after the catalog sync reaches 9201. Log in the way the earlier sessions did (password stored out-of-band, never printed). Assert the data-guide-section count; save a screenshot if a browser is at hand. If the sync has not arrived by the end, say so — do not force it.
  4. Push in batches of about 10 apps, gates green before each push. Before every push in any repo: git pull --rebase; other sessions push tonight. Never force-push. Never --no-verify. No branches.
  5. Time. If the night runs out, stop at a pushed batch boundary. The report lists the apps done, hidden (and why), and not started. Never leave a half-written template on main.
  6. One format. Keep every guide in the same shape (section count range, step style, FAQ length) so a morning format change is mechanical.
  7. Part C (pi_compatible removal): do it only if the hub's controller floor is ≥ 0.315.0. If not, do nothing — R-1067 already holds it; do not open a second row.
  8. Content rules from the spec stand, especially: no indexer, tracker or download-site names; nothing the box already wires (15-media-library.md §6, §11); labels exactly as the app shows them at the pinned tag.

3. One register item from the reviewer (felhom.eu)

The 0.316.3 controller image contains another session's unreleased work (felhom-controller CHANGELOG.md, v0.316.4 entry: „Do not deploy 0.316.3"). That fact lives only in the CHANGELOG; the session said it was filed with R-1081/R-1082, but neither row mentions it (checked 21:45 CEST). Open one row: Category „Process & tooling", P3, owner CC — „Registry tag felhom-controller:0.316.3 holds another session's uncommitted code; it must never be offered to a box. Today the update button offers the highest tag (0.317.0), so nothing reaches it — but any path that picks a lower or specific tag could." Name the paths that choose a version (09-update-architecture.md) and say which, if any, could select 0.316.3. Do not change code tonight.

4. Report (catalog REPORT.md, overwritten; plain words first)

  1. What a household sees now: how many apps have a visible guide, how many hidden, how many not done.
  2. The five pilot apps: label check and box check result each.
  3. Gate change: tests and red-proofs.
  4. Rows opened and closed (with the 0.316.3 row). Register size as four numbers.
  5. Readings taken without asking (rule 1).
  6. Observations: each FILED: R-NNN or NOT-A-FINDING: <reason>.


APPENDIX — the full spec

Spec: App user guides — media pilot (5 apps), then the night batch (60 apps)


For the operator — what this does, in one page (plain language)

What is missing today. A household that does not know an app has nowhere to look on the box. They ask us. Each such question costs your time and does not scale.

What you get. Every app gets a short user guide and an FAQ, in Hungarian and English. It shows on the new "Útmutató" tab of the app page (built by the companion task). The text lives in the app catalog, next to the app's other text, so it reaches every box with the normal catalog sync.

In what order.

  1. Pilot, five apps — the media stack: Plex, Sonarr, Radarr, Prowlarr, qBittorrent. Each guide is checked twice: against the app's own source code at the exact version we ship, and on a real box.
  2. Night batch, the other 60 apps. Same format. Each is checked against the app's source code. A guide that fails the check stays hidden. Hidden means the box does not show it until a later session fixes it.

Two rules you should know.

  • A guide shows on a box only when it records which app version it was checked against. When we update the app later, the catalog warns that the guide may be stale.
  • The media guides never name a download source, a tracker or an indexer site. Choosing one stays the household's own choice (this is already the rule in 15-media-library.md). The examples use free, legal content.

What it costs you. Tomorrow, read the Plex and the Sonarr guide on demo-hp. If the format is wrong, we change it in all 65 files in one pass.

Nothing here touches customer data or a running box's apps, except throwaway installs on demo-hp.


0. Task class & scope

  • Implementation — catalog content + one catalog gate change; checked live on demo-hp.

Repos touched:

  • app-catalog-felhom.eu — templates/<app>/.felhom.yml (guide blocks), scripts/check-copy-i18n.py, one advisory gate, CHANGELOG/REPORT/CONTEXT.
  • felhom.eu — documentation/ (register rows, STATUS line, the onboarding checklist row).
  • felhom-controller — NOT touched. It renders the guide from v0.315.0 (the controller task of 2026-10-15; see §4 item 4). Older controllers ignore the unknown key (10-localisation.md §7: the controller builds no strict YAML decoder), so the content may land before the controller ships.

1. Confirmed baselines (verified against live Gitea, 2026-10-15 ~17:00 CEST)

Repo main @ commit Version
app-catalog-felhom.eu e67aad4 dated CHANGELOG (2026-10-15 evening, R-1058)
felhom-controller 85f65c7 v0.314.0 (read only)
felhom.eu 3263bb2 docs

Pinned images at baseline (re-read before writing — they are what checked_version records): plexinc/pms-docker:1.41.4.9463-630c9f557, lscr.io/linuxserver/sonarr:4.0.20, lscr.io/linuxserver/radarr:6.4.4, lscr.io/linuxserver/prowlarr:version-2.6.5.5623, qbittorrentofficial/qbittorrent-nox:5.2.4-1.

An unpushed change does not exist. Commit directly to main. No branches. No --no-verify.


2. Overview

Add an app_info.guide block (schema below, identical to what the controller parses, §4 item 4) with an i18n.en overlay to each template. Extend the catalog's copy gate so the guide is checked like all other copy. Add one advisory gate that warns when a template's image tag differs from its guide's checked_version. Write and check the five media guides (Part A), then the remaining 60 (Part B). Remove pi_compatible from the catalog only if the floor allows it (Part C).


3. Spike-first gate

No unproven mechanism. The YAML copy model is measured (10 §7). The one open question is how to check a guide without a browser (none on DooPlex) — answered by method in §8, not by a spike.


4. Read these files first

  1. app-catalog-felhom.eu/CLAUDE.md, CONTEXT.md, NEW-APP-CHECKLIST.md — conventions, the pre-push gates (catalog_gates.py --fast), the gate decoys in scripts/test_gate_decoys.py.
  2. felhom.eu/documentation/architecture/10-localisation.md §7 — the copy model and the copy gate (check-copy-i18n.py, the EN_MISSING_CEILING ratchet).
  3. felhom.eu/documentation/architecture/15-media-library.md §6 and §11 — what the box wires by itself (qBittorrent categories, Sonarr/Radarr tag, root folder, download client, minimum free space, Prowlarr → Sonarr/Radarr, Plex folders and scan). A guide never tells the household to do what the box already did; it tells them it is done. Also: „Indexers stay the household's choice."
  4. The schema and render rules AS BUILT in the controller (the earlier task file is not on disk): read felhom-controller internal/stacks/metadata.go (AppGuide, GuideSection, GuideFAQ), metadata_i18n.go (the overlay), appinfo_address.go (DOMAIN filled), and the guide tab template (templates/app_guide.html). Rendered only when checked_version is set; plain text, no markdown, no HTML.
  5. Source: scripts/check-copy-i18n.py (~L153–L160 base fields, ~L213–L230 overlay keys and the "unknown key app_info.%s" refusal), scripts/catalog_gates.py (the gate table), templates/{plex,sonarr,radarr,prowlarr,qbittorrent}/.felhom.yml (their current first_steps, prerequisites, after_start).

5. Existing functions / helpers to reuse

Symbol Where Use Modify?
base-copy collector (add("app_info.…")) scripts/check-copy-i18n.py count guide strings as copy Yes — Part 0
overlay key whitelist (if k not in ("tagline", …)) same accept guide in i18n.en.app_info Yes — Part 0
catalog_gates.py gate table scripts/ register the advisory guide-version gate (WARN only) Yes — Part 0
scripts/test_gate_decoys.py scripts/ a decoy per new gate rule Yes — Part 0

Do not reuse ladder.py / upgrade-test.py style box drivers to install apps on Tester 1 or any customer box — the pilot check runs on demo-hp only.


6. Pattern references

Existing first_steps / i18n.en.app_info.first_steps pairs in templates/prowlarr/.felhom.yml — tone, tegező form („Nyisd meg…"), the DOMAIN placeholder.


7. Integration scenarios (must pass)

Scenario A — the gate accepts a correct guide

Given templates/sonarr/.felhom.yml with a full HU guide and a full EN overlay, When catalog_gates.py --fast runs, Then it passes and the copy count includes every guide string (sections' title/intro/steps, FAQ q/a).

Scenario B — the gate refuses a broken guide (wrong case)

Given an EN overlay with guide.checked_version, or a section with an empty steps, or an FAQ entry with q but no a, or an overlay with more sections than Hungarian, When the gate runs, Then it fails naming the template and the exact key. checked_version is not copy and may not be overlaid.

Scenario C — the version warning

Given Sonarr's guide says checked_version: "4.0.20" and the image moves to 4.0.21, When the gate runs, Then it prints a WARN naming the template and both versions and does not fail.

Scenario D — a media guide does what it says

Given Sonarr installed on demo-hp from the live catalog, with the media links the box makes, When each step of the Sonarr guide is followed through Sonarr's own API / served pages, Then every menu name in the guide exists at the pinned version, every "the box already did this" claim is true on the box, and no step is needed that the guide leaves out.

Scenario E — no source names (wrong case)

Given any of the five media guides, When it is read, Then it names no indexer, tracker or download site, in either language. A test enforces a deny-list of the obvious names; the human rule is wider than the list.


8. Rules for writing and checking a guide

Content.

  • Hungarian base, English overlay complete for every string (no EN_MISSING_CEILING increase).
  • 3–6 sections, each a task the household wants ("Első film hozzáadása", "Telefonos app beállítása", "Családtag hozzáadása"). One action per step. Short words. Adult tone, tegező form, no emoji.
  • 4–8 FAQ entries: the questions a household will really ask (from the upstream FAQ/wiki/issues and common forum questions). Each answer 1–3 sentences.
  • Do not repeat first_steps (the tab shows them first). Do not describe what the box did except to say it is done. Point at Felhom controls by their tab name where they apply (Plex code → „Beállítások fül"). Use DOMAIN for the household's address (<label>.DOMAIN).
  • Menu and button names: write the label exactly as the app shows it on a fresh install with the default UI language, in „…". If the default is English, write the English label and the Hungarian meaning after it once: „Settings" (Beállítások).
  • Never name an indexer, tracker, or download source. Examples use legal content (public-domain films, Linux images, the household's own discs).

Checking (checked_version is set only when ALL hold).

  1. Every quoted label is found in the app's source or translation files at the pinned tag (upstream git at that tag). Record the file and line per label in the evidence file.
  2. Pilot only (Part A): the app is installed on demo-hp from the live catalog and each step is exercised through the app's API or served pages; every "the box did it" claim is read back from the app. No browser exists on DooPlex — say so; the operator's visual read is the last check.
  3. checked_version = the image tag in docker-compose.yml at the commit that adds the guide.
Label check Box check (pilot) Result
all found all pass checked_version set
all found not run (Part B) checked_version set
any missing any checked_version empty (hidden); listed in REPORT
any any fails (pilot) fix the guide; if not fixable now, empty + a row

9. Strict rules

  1. Green gate (catalog): python3 scripts/catalog_gates.py --fast and python3 -m pytest scripts/ green after every commit. No --no-verify.
  2. Minimal changes: only the guide blocks, the gate change, Part C if allowed. The size rule applies.
  3. No silent failures.
  4. Secrets safety: no token, API key or password in any guide or evidence file; keys not values.
  5. Line numbers are landmarks.
  6. Trunk-based. Revert + report if a commit cannot ship.
  7. Version discipline: one dated CHANGELOG entry per push batch, REPORT overwritten.
  8. Coding standards: app-catalog-felhom.eu/CLAUDE.md.
  9. Instruction files are kept true by the session that finds them wrong — facts only.
  10. Delegation (Part B): subagents may DRAFT guides in parallel, each into a scratch file outside the repo. One writer applies them to the templates and runs the gate. No two agents edit the same file.
  11. Document length: as short as the content allows.

10. Non-hollow test discipline

  • Gate tests assert the exact failing key in the message, not just a non-zero exit.
  • Red-proof each new gate rule: remove the rule, see its decoy pass, restore.
  • The deny-list test (Scenario E) red-proof: insert one listed name into a fixture, see it fail.

Part 0: The gate (first commit, before any guide)

0.1 check-copy-i18n.py: count every guide string as copy (base and overlay); accept guide in the overlay's app_info; refuse guide.checked_version in an overlay; refuse empty steps, an FAQ entry missing q or a, and an overlay list longer than the Hungarian one. 0.2 An advisory gate in catalog_gates.py: guide checked_version ≠ image tag → WARN, never fail. 0.3 Decoys in test_gate_decoys.py for each rule; the deny-list test for media guides.

Part A: The pilot — Plex, Sonarr, Radarr, Prowlarr, qBittorrent

A.1 Read each app's upstream docs and source at the pinned tag; write the guide (HU + EN). A.2 Label check (§8 rule 1). Evidence: felhom.eu/documentation/audits/app-guides-2026-10-15/A/<app>-labels.txt. A.3 Box check on demo-hp (ssh hp): install the five from the live catalog as throwaway apps unless they already run there as the standing media test set (then use them read-only), follow each guide through the API, read back the box's wiring. Evidence: …/A/<app>-box.txt. Do NOT claim a real Plex server, and do not touch Tester 1. A.4 Set checked_version, push.

Part B: The night batch — the other 60 apps

B.1 Same rules, label check only. Batches of about 10 apps per commit; the gate green before each push. B.2 Any app whose labels do not all check: guide committed with checked_version: "" and listed. B.3 Evidence: …/B/<app>-labels.txt. B.4 Order: the apps most households install first (Immich, Nextcloud, Vaultwarden, Paperless-ngx, Jellyfin, Home Assistant), then alphabetical.

Part C: Remove pi_compatible from the catalog — ONLY if the floor allows

Old controllers (≤ v0.314.0) show „csak x86" on every app whose template has no pi_compatible: true. So: if the hub's controller floor is ≥ 0.315.0 when this part starts, remove the key from all 65 templates and update scripts/onboarding_gaps.py (L109, L209) and the decoy fixture in scripts/test_gate_decoys.py (~L980). If the floor is lower, do nothing and open a register row "Catalog still carries pi_compatible; remove after floor ≥ 0.315.0" (P4, Apps & catalog, owner CC).

Part N: Documentation

  • Catalog CHANGELOG.md, REPORT.md (overwrite), CONTEXT.md (the guide rules in §8, briefly).
  • NEW-APP-CHECKLIST.md: add one row — a new app ships with a checked guide.
  • felhom.eu/documentation/backlog/OPEN-ITEMS.md: a row per app left hidden (or one row listing them), the Part C row if not done; close nothing that is not done. Register size as four numbers.
  • felhom.eu/STATUS.md, "waiting on the operator": „Olvasd el a Plex és a Sonarr útmutatót a demo-hp-n."

11. Tests

  • A/B gate tests per rule in test_gate_decoys.py (pass case + each refusal, exact key in message).
  • C advisory gate: a version mismatch fixture prints WARN and exits 0.
  • E deny-list test over the five media templates, both languages.

12. What NOT to do

  • Do NOT name an indexer, tracker or download site, or explain how to find one.
  • Do NOT write a step for something the box already wires (§4 item 3).
  • Do NOT set checked_version on a guide whose labels were not all found.
  • Do NOT put markdown, HTML or links other than the upstream docs URL in guide text — the controller renders plain text.
  • Do NOT move any image tag, change any compose file, or touch first_steps beyond fixing a factual error (size rule; list it).
  • Do NOT install anything on Tester 1, ep0 or DooPlex. demo-hp only.
  • Do NOT create a branch. Do NOT add "Co-Authored by..." anywhere.

13. Build / deploy / STOP

Clean-tree gate first. The catalog has no build: a push to main reaches the boxes through the catalog sync. Verify after push: ssh hp → the box's synced template carries the guide (grep -c checked_version on the synced .felhom.yml, ASCII only). If demo-hp runs controller ≥ 0.315.0, curl /apps/sonarr/guide and assert the data-guide-section marker count.

Teardown: every throwaway app installed in Part A removed; docker ps before/after in the evidence. No hub record is created; say so.


14. Implementation order

Phase 1: Part 0 gate + decoys          → catalog_gates --fast + pytest green, push
Phase 2: Part A pilot (5)              → green, demo-hp checks, push
Phase 3: Part C (only if floor ≥ 0.315.0, else the row)
Phase 4: Part B night batch (60)       → green per batch, push per batch
Phase 5: docs, register, STATUS, push

15. Final verification & deliverables

REPORT.md must include: 1. Baselines. 2. Files changed. 3. Commit hashes. 4. Gate test results and each red-proof. 5. Per app: checked_version set or hidden, with the evidence path. 6. demo-hp checks per pilot app (pass / what was fixed). 7. NOT yet validated: the operator's read of the Plex and Sonarr guides; the rendering on a ≥ 0.315.0 box if none ran it. 8. Teardown evidence. 9. Part C done or its row number. 10. Observations: each with FILED: R-NNN or NOT-A-FINDING: <reason>.