60 template directories, 58 offered. Records: onboarding/grocy.md and
onboarding/lubelogger.md, all 61 checks answered, none open. Evidence:
felhom.eu/documentation/audits/new-apps-2026-10-10/.
Grocy 4.7.1 from lscr.io/linuxserver/grocy (grocy publishes no image of its
own). SQLite in one volume, no HDD, ~30 MiB idle, amd64 + arm64, Hungarian UI
91.6 %. First admin class 3: it starts with its documented admin/admin and
after_install replaces that password with a generated one.
LubeLogger v1.7.3 from ghcr.io/hargata/lubelogger. LiteDB in one volume, no
HDD, ~60 MiB idle, amd64 + arm64. First admin class 1 — and it has to be: the
image ships EnableAuth=false, and with that the middleware mints a ticket with
the IsRootUser role for every visitor. Measured on a default start: a stranger
got 200 on /, on /api/vehicles and on /Home/Settings and CREATED A VEHICLE.
The compose entrypoint exports EnableAuth=true and the SHA-256 of a generated
name and password, so the app's own login is on before its first byte (at t+1 s
nothing listening, at t+2 s /api/vehicles already 401).
Two defects found by the walk and fixed before publishing:
1. An after_install command may not contain `$`. The controller runs every
element through os.Expand and refuses one naming anything outside env:, so
PHP cannot be inlined. On 9202 the first attempt came back
`[pw argv dsn db i t e s n q h] not declared in env or has no value — not
run` and the app sat behind its install hold with admin/admin in place. The
code now lives in a file the compose entrypoint writes. Written into
REUSE.md's after_install row as a trap.
2. Grocy's persisted config.php does not follow the image. The image copies
config-dist.php only when that file is absent, so a volume written by 4.6.0
and started under 4.7.1 answered HTTP 500 on every page — AUTH_CLASS names a
class 4.7 moved — while its log said migrations done. The entrypoint now
deletes the file at every start. The 4.6.0 -> 4.7.1 edge failed before this
and is proven after it, on both venues.
Ladders, written by upgrade-test.py --write-ladder from both verdicts:
grocy 4.6.0 -> 4.7.1 bench proven, box proven (guarded Update, 41 s)
lubelogger v1.7.2 -> v1.7.3 bench proven, box proven (25.6 s)
Checklist 6.3 came from a real failure, not a forced one: before the config.php
fix the product undid the same step in 346 s with the data intact.
REUSE.md: a fifth healthcheck family (bash /dev/tcp) for an image with no HTTP
client at all, measured in both directions.
Tool fixes made on the way: check-onboarding.py crashed on a Windows console
while printing which ids were open; upgrade-test.py's read_text/write_text used
the platform encoding and wrote a cp1250 em dash into a template full of
Hungarian.
NEW-APP-CHECKLIST.md: the reviewer's draft reviewed - 60 rows in 10 groups, each with how/why and a since date;
7 rows added, 16 sharpened, 9 wrong claims fixed. onboarding/_TEMPLATE.md (one line per id), onboarding/wger.md
(the pilot, exempt app, 11 open rows each a register row), onboarding/EXISTING-APPS-GAPS.md (read only, from
scripts/onboarding_gaps.py). Gate onboarding (scripts/check-onboarding.py) in --fast: a template directory not
among the 53 published before 2026-10-01 needs a complete record; decoys in test_gate_decoys.py (16 cases, 5 gate
mutants seen red). CLAUDE.md, REUSE.md 5, README point to it. No template changed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS