Files
felhom.eu/REPORT-new-apps-2026-10-10.md
T

176 lines
12 KiB
Markdown

# REPORT — new apps, 2026-10-10: Grocy and LubeLogger published, Monica stopped
Written as a sibling report, not `REPORT.md`, because two sessions in this repo would clobber the
shared one (`CLAUDE.md` § Workflow).
## 1. The table the brief asked for first
| app | result | why |
|---|---|---|
| **Grocy** 4.7.1 | **published** — catalog `b7f0f7c` | MIT, alive, SQLite in one volume, no HDD; Hungarian UI 91.6 % |
| **LubeLogger** v1.7.3 | **published** — same commit | MIT, 17 releases in 2026, LiteDB in one volume, no HDD |
| **Monica** | **stopped at checklist 0.2 — the operator ruled: keep it out (R-927, closed)** | no release of any kind in 17 months, no stable release in 29, the stable branch untouched since 2024-05-04, upstream winding its hosted service down before a rewrite |
Nothing was "not reached": all three were answered.
**Why one commit and not two.** The brief says each app reaches the catalog in one commit with its
record, and both records travel in that commit. Splitting them would have left `REUSE.md`'s new
healthcheck row and `FIRST-ADMIN.md`'s LubeLogger row pointing at a template that did not exist yet —
the `reuse-refs` gate refuses a dangling path, and rightly. Each template still carries its own
complete record, which is what the rule protects.
## 2. The fit table
`documentation/audits/new-apps-2026-10-10/FIT.md` — licence, last release, image and architectures,
phone-home and its switch, internet at runtime, non-HTTP ports, the client login routes, database,
memory, **the Hungarian-UI column**, first-admin class and a one-sentence verdict for each.
## 3. Claims in the brief that turned out wrong
1. **"Grocy starts with the login `admin`/`admin` (as far as we know)"** — right, and now measured
rather than assumed: a fresh install's `users` table holds exactly one row and that login signs in.
2. **"LubeLogger *may* have no login at all until someone turns it on in its settings"** — right about
the default, wrong about "settings": the switch is a configuration key readable from the
**environment**, which is why the fix needs no post-install step and leaves no window. And the
brief understated it: a stranger does not only *see* the family's car data, a stranger **writes**
it as root. Measured.
3. **"Monica releases slowly"** — too kind. Nothing in 17 months; no stable release in 29; the branch
its own README calls the stable one has not moved since 2024-05-04; and the two commits that ended a
13-month silence add a login-page notice saying the hosted instance and all its data will be deleted
at the end of December 2026 "ahead of the new Monica version".
4. **The test machines.** 9202 *and* the bench 9401 are both on **demo-hp**. felhom-pve carries only
guest 9201. Measured with `pct list` on both hosts. 9202 was already in `operations/nodes.md`;
**the bench 9401 was in no document at all**, so a session had to find it by listing guests. It is
written up there now — which host, why its swap is 0, that it is normally stopped, what it keeps in
`/opt/upg` between runs, and that its images are deliberately not pruned.
5. **Grocy's image.** The brief asks which image upstream recommends. Upstream publishes **none**:
`grocy/grocy` on Docker Hub is 404 and grocy's README answers "How to run using Docker" with one
link, to linuxserver.io.
6. **A near miss of my own, recorded because the control is the point.** My first count of grocy's
Hungarian coverage said **0 % translated**. The German control — a language that must be ~100 % —
also read 0 %, which is what exposed the broken `.po` parser. A second, independent method gave
German 0 untranslated, French 12, **Hungarian 62 of 734 → 91.6 %**. Without the control the fit
table would have carried a false "no" in its newest column.
## 4. Per published app
### Grocy — `onboarding/grocy.md`, every id answered
- **Record:** 61 ids, 0 open, 11 `n/a` with reasons.
- **Bench (swap 0):** peak anon **27.2 MiB = 6.7 %** of the 384 M limit, 0 swap, 0 oom_kill, 0
restarts; a 605-second soak of 10 343 requests. **Box:** 45.7 and 86.6 MiB across two installs.
- **Ladder:** 4.6.0 → 4.7.1, `proven` on the bench and `proven` on 9202 through the product's own
guarded Update (done in 41 s).
- **The two faults, found by the walk and fixed before publishing:** an `after_install` command may not
contain `$` (the controller expands every `$name`); and grocy's persisted `config.php` does not follow
the image, so a 4.6 → 4.7 update answered HTTP 500 on every page. Both are in the catalog's REPORT and
CHANGELOG with the measurements.
- **Catalog commit:** `b7f0f7c`.
### LubeLogger — `onboarding/lubelogger.md`, every id answered
- **Record:** 61 ids, 0 open, 11 `n/a` with reasons.
- **Bench (swap 0):** peak anon **66.2 MiB = 12.3 %** of the 512 M limit, 0 swap, 0 kills; 605-second
soak of 11 988 requests. **Box:** 22.1, 35.1 and 46.6 MiB across three installs.
- **Ladder:** v1.7.2 → v1.7.3, `proven` on both venues (box done in 25.6 s).
- **The fault:** the image ships **no login at all** and hands a stranger the root role. Our entrypoint
turns the app's own login on from a generated password before the first byte.
- **Catalog commit:** `b7f0f7c`.
## 5. The website
`documentation/audits/new-apps-2026-10-10/site-count.txt`.
- Two cards in the „Otthon & Életmód" / "Home & Lifestyle" section of **both** apps pages.
- Assets: `grocy-logo.svg` (grocy's own icon, its single fill made white like the other logos),
`lubelogger-logo.png` (the app's own icon, dark background dropped and the mark made white, the rule
SparkyFitness's PNG follows), and six screenshots of each app's own UI with a household's own data.
- **The count moved 56 → 58** in **15 places per language set**, both languages: the apps page title,
meta description, og:title, twitter:title, the JSON-LD `numberOfItems`, the page's own sentence and
its stats tile; the home page's meta description, feature heading and line; two FAQ answers and their
JSON-LD copies; the technology page's bullet. The open-source tile moved **49 → 51**.
- **Not changed, and listed instead, as the brief asked:** `marketing/facebook/COPY.md` §2 says
„56 alkalmazás" in both post drafts, and the post scheduled for 2026-10-12 19:00 carries that number.
It is already written and scheduled; the next post should say 58.
## 6. Register
**Before 137 · after 138 · opened 2 · closed 1.**
- **R-926** (Backup & restore, P3) — after a household removes an `after_install` app keeping its
backups and restores it, nobody has checked what the app page then shows for the generated password.
Measured here: for **LubeLogger** the box mints a new password, that new one signs in and the data is
back — safe, because its login is derived from the environment at every start. For **grocy** the
install's password still signs in (it is in the restored database) but the deployed environment no
longer carries `ADMIN_PASSWORD` at all. Seven apps are in the same class.
- **R-927** (Apps & catalog, P4) — Monica. **Asked and answered in this session: the operator ruled
keep it out**, so the row was opened and closed, and it is in `CLOSED-ITEMS.md` with the
measurements and the sentence worth keeping — an app is not added because a gap exists, it is
added because the app can be kept.
**Fixed without a row** (the size rule): the `after_install` `$` trap and grocy's `config.php`, both in
the templates and in `REUSE.md`; `check-onboarding.py`'s console crash; `upgrade-test.py`'s platform
encoding; and the same console trap in nineteen `felhom.eu` gate scripts plus `repo_gates.py`, where it
aborted the whole runner at the first gate.
## 7. Gates
- **Catalog:** `catalog_gates.py grocy lubelogger` — all twelve green, both runtime gates included, run
on bench 9401. Saved per app as `box/<app>/gates.txt`.
- **felhom.eu:** `repo_gates.py --fast` — after the console fix, 15 of 19 green. Three reds and one
INCONCLUSIVE are **pre-existing on this workstation and not caused by this session**, proven for one
of them by reverting the change and seeing the same failures:
- `instructions` — `E:\git\CLAUDE.md` and the versioned `workspace-CLAUDE.md` differ **by design**:
the workspace file here is the Windows-adapted copy, and its own first paragraph says not to make
them match.
- `script-tests` — 13 of 25 suites need a POSIX environment (`fcntl`, the `sqlite3` CLI, symlink
privilege Windows does not grant).
- `wire-contract` — INCONCLUSIVE on `agent.HostReport`, a felhom-agent question untouched here.
CI runs the same entry point on Linux; its result is quoted below.
## 8. Teardown, three layers
- **Machine (9202):** both apps removed with their data through the product; the two volumes and the
per-app backups gone; what is left under `/opt/docker/stacks/<app>` is the template pair the syncer
keeps for all 65, not deployed state. 9202 put back on the **live** catalog.
- **Machine (bench 9401):** every container and volume this session made removed; the harness's own
evidence copied off first (standing rule 5). The bench LXC is left **running** — it is the standing
harness guest, not something this session created.
- **Host:** nothing created or changed on demo-hp or felhom-pve. The drill catalog repo carries this
session's drill commits, as it is meant to.
- **Hub:** untouched; no record created. DooPlex: a working directory under `git/.work/` and one
credential read into a 0600 scratch file, both named below.
## 9. Two small things seen and not filed
- **`remove` leaves `hold-logs/` in the stack directory.** After removing grocy with its data, the
install hold's `hold-logs/<timestamp>/compose-logs.txt` stayed behind. It holds the container's
startup banner and **no secret** (read before deciding), the next deploy overwrites it, and the
directory belongs to the syncer anyway. Cleaned by hand on 9202; named here rather than filed.
- **The catalog's pre-push hook is not armed in this clone** (`core.hooksPath` unset), so the push
ran no gate by itself. `catalog_gates.py grocy lubelogger --fast` was run by hand immediately
before the commit and was green, and the two runtime gates were run on the bench; CI re-ran the
entry point on the push. No `--no-verify` was used anywhere.
## 10. CI, read by pulling (the standing rule), by job id
| repo | commit | job | conclusion |
|---|---|---|---|
| app-catalog-felhom.eu | `b7f0f7c` (the publish) | 1631 | **failure — R-887's lost job, not the code** |
| app-catalog-felhom.eu | `8ea72aa` (the same tree + one line) | 1633 | **success** |
| felhom.eu | `970616b7` | 1632 | **failure — the same lost job** |
| felhom.eu | `29c9cb1e` | 1634 | **failure — the same lost job, a third time** |
| felhom.eu | `cf1e1371` | 1635 | **success** — so felhom.eu's gates pass in CI too, which is what
settles that the three Windows reds are the workstation and not the repository |
**All THREE lost jobs ended at :45:58 past the hour** (1631 and 1632 at 10:45:58Z, 1634 at 12:45:58Z) — catalog job 1631 after ~14 minutes
in set-up with three steps, felhom.eu job 1632 after ~11.5 minutes with seven, every step `failure`
with 0 s, and both logs answering `file does not exist`. A per-job fault cannot do that; one runner
event took both, and the runner pod had been restarted earlier the same day. That is new information
for **R-887**, whose row and whose 2026-10-12 due-check now say so: the check's premise ("no CI job
lost since 2026-10-05 16:00Z") is false.
**What proves the code rather than the runner:** the same catalogue tree passed as job 1633, and a
shallow clone with no sibling repository — the CI shape — runs all nine applicable gates green by hand
(`/tmp/cisim` on DooPlex, reproduced deliberately rather than assumed).