Files
app-catalog-felhom.eu/NEW-APP-CHECKLIST.md
T
2026-10-01 14:48:25 +02:00

9.1 KiB
Raw Blame History

NEW-APP CHECKLIST — draft (reviewer, 2026-10-01)

What this is. The list of things every new catalog app must have measured and recorded BEFORE it reaches the live catalog. Each item exists because something went wrong on a real app — the "why" column names it. The filled-in copy per app is the app's onboarding record; a gate refuses a new app without a complete one.

How to read an item. Each answer is done (with an evidence path), n/a (with a one-line reason), or open (blocks publishing). "Measured" means on the bench or on scratch guest 9202 through the product — never read from upstream alone. Upstream reading is allowed to PLAN a test, never to CLOSE an item.

Where it lives (proposed — CC confirms): the checklist in app-catalog-felhom.eu/NEW-APP-CHECKLIST.md; one record per app in app-catalog-felhom.eu/onboarding/<app>.md (outside templates/, so the box never syncs it — the controller copies only docker-compose.yml and .felhom.yml, sync.go:364). The new app is tested from the drill catalog on 9202 and reaches the live catalog only with a complete record.


0. Fit — should we offer it at all?

# Check How Why (what went wrong before)
0.1 Open-source licence; we pull the upstream image, never redistribute read the repo the business sells installation, not software
0.2 Upstream is alive: a release in the last 6 months, issues answered read the repo plant-it went abandoned, its image is gone
0.3 An official image with version tags (not latest-only), amd64 (+arm64 if Pi) registry pins and digests need real tags
0.4 Telemetry / phone-home — on by default? a switch to turn it off? docs + one packet capture or log read on 9202 data sovereignty is the pitch
0.5 Needs the internet at runtime (claim tokens, first-start downloads)? docs + a first start plex (plex.tv claim), adventurelog (world data), immich (geodata)
0.6 Needs ports other than HTTP(S)? The tunnel carries HTTP only compose + docs gitea SSH, media DLNA, game servers — say what the household loses
0.7 Phone / desktop apps: do they work through the tunnel and the setup gate? docs + one real client if one exists immich's phone app vs the gate (decision 46)
0.8 What a household gets from it, in one sentence (Hungarian) — the catalog card and use_cases

1. Images and the database

# Check How Why
1.1 Every image pinned to a concrete tag; resolvable catalog_gates.py <app> (gates 1, 2) :latest breaks restore fidelity
1.2 Database engine and major = what the app's own upstream compose runs upstream compose at the pinned tag decision 42's rule; avoids an early conversion
1.3 MariaDB sidecar: MARIADB_AUTO_UPGRADE=1; PostgreSQL 18: mount at /var/lib/postgresql compose R-459; PG 18 refuses /data
1.4 The app migrates its own database at start, or the switch that makes it do so is set an update on 9202, login read back wger: no migration without DJANGO_* switch, update said "done", login 500 (R-738)
1.5 The app runs its production server, not a dev server process list in the container wger runserver (R-755)
1.6 Every secret the app needs is generated (no image default, no empty key) compose + a login on 9202 wger JWT key missing → login 500 (R-737)

2. Storage and backup

# Check How Why
2.1 Every path the app writes is mounted — measured gate 3, check-volume-persistence.py <app> papra backed up an empty folder (R-156)
2.2 Where each path lives: named volume (NVMe) / ${HDD_PATH}/appdata / ${USERDATA_PATH} compose, REUSE.md skeleton the household can browse userdata, not appdata
2.3 Backup class for every HDD path (mandatory / excluded …) and data_paths labels .felhom.yml backup: DB rows that point at files need those files (07)
2.4 File owner / uid fits the box (PUID/PGID where the image wants them) first start on 9202 linuxserver images chown their tree
2.5 A backup and a restore through the product, data read back 9202: seed → backup → remove → restore → read back the promise is the restore, not the backup
2.6 "Remove with data" and "remove keep data" both work 9202 R-756 (refused with a folder present)
2.7 Off-site size estimate for a typical household measured size after seed + a sentence decision 50's size warning

3. Accounts and strangers

# Check How Why
3.1 First-admin class (FIRST-ADMIN.md 1–6), measured fresh install on 9202 decision 45
3.2 Known default login → after_install with a generated password (and name, if the name is public and lockable) 9202: default fails, generated works, wrong fails bookstack, calibre-web (decisions 45, 61)
3.3 Open first-run screen → setup_gate (+ probe that flips, measured before and after) 9202 as a stranger 32 apps, decision 46
3.4 Open sign-up after the setup → signup_block / after_setup switch; case-insensitive 9202 as a stranger decisions 47–49
3.5 The install window: a stranger reaches nothing before the password is replaced poll once a second during install R-741
3.6 Lock-out: N wrong passwords by a stranger — who is locked (name / address / everyone), for how long 9202 through traefik mealie 24 h, wger everyone (R-747, R-752, R-753)
3.7 The household can change its password and add family members; the page says how 9202 add_people copy
3.8 Secrets pass to commands as arguments, never inside program code review after_install security review 2026-09-29

4. Health

# Check How Why
4.1 Compose healthcheck of the right family, 127.0.0.1 not localhost REUSE.md §2 vaultwarden IPv6 trap
4.2 The controller probe dials what the compose healthcheck dials; a real health path where one exists gate 7 a wrong probe stops a working app after an update (R-618)
4.3 Healthy within start_period on a cold first start (incl. one-time imports) 9202, timed immich geodata import
4.4 Negative control: a broken app reads unhealthy stop the DB, read the status a probe that is always green proves nothing
4.5 The probe-named container is the stack name; sidecars <app>-db … compose findProbeContainer fallback picks the DB

5. Resources

# Check How Why
5.1 First start from birth, swap OFF: peak anon, oom_kill = 0 bench, sampled every 2 s immich DB killed at 512 MiB, hidden by swap on 9202 (R-732, R-733)
5.2 10-minute light-load soak: peak < 80 % of the limit, 0 kills, 0 restarts harness memory watch romm OOM at +76 s (decision 22)
5.3 mem_limit in .felhom.yml = the sum of the compose limits gate / review immich's header was 128 MB off
5.4 Node/Java apps: does the heap size itself from the limit? two watches at two limits R-693 (docmost)
5.5 Pi-compatible (yes/no), disk it pulls (image size) registry old images filled 9202 (R-736)

6. Updates

# Check How Why
6.1 An upgrade fixture: seed + read-back through the app's own front door, negative control upgrade_fixtures*.py without it the app never updates itself
6.2 A first ladder step proven on bench + 9202 (--write-ladder), or "manual only" with the reason harness 35 of 53 update at night; the rest need a person
6.3 The undo works on a real failure (one forced-fail case) 9202 zipline's real failed jump, undone in 20 s
6.4 files_may_change mark understood (which files change at start) bench immich's six marker files (R-734)
6.5 Tag shape is stable upstream (no v dropped, no flavour prefix) tag list gramps-web, jellyfin, kimai (R-731)

7. Mail

# Check How Why
7.1 Sends mail? → smtp_mapping + ${VAR:-} compose lines; a fresh install with mail OFF boots 9202 vaultwarden empty-vars trap

8. Household-facing text and listing

# Check How Why
8.1 Hungarian + English, informal „te", no „kérjük"; parity green; freeze updated check-copy-i18n.py operator rule
8.2 app_info: tagline, use_cases, first_steps, default_creds (if any), add_people read on 9202's page the page is the manual
8.3 Logo + screenshots on felhom.eu by slug the asset URL answers 200 the card is blank otherwise
8.4 README tables, FIRST-ADMIN row, category, catalog_since review REUSE.md §5

9. Sign-off

# Check How
9.1 python3 scripts/catalog_gates.py <app> — all green (exit 0) bench / scratch
9.2 A fresh install on 9202 from the drill catalog, as a household and as a stranger, start to finish 9202
9.3 Every item above done or n/a-with-reason; every finding that is not fixed is a register row the record
9.4 Published to the live catalog in ONE commit with its record the gate checks