diff --git a/REPORT-new-apps-2026-10-10.md b/REPORT-new-apps-2026-10-10.md new file mode 100644 index 00000000..fed6656f --- /dev/null +++ b/REPORT-new-apps-2026-10-10.md @@ -0,0 +1,136 @@ +# 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 decides (R-927)** | 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. +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 139 · opened 2 · closed 0.** + +- **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, with the measurements, waiting on the operator. + +**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//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/` 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. diff --git a/STATUS.md b/STATUS.md index 53722544..6bbaa11e 100644 --- a/STATUS.md +++ b/STATUS.md @@ -3,8 +3,32 @@ **Ready for the first real tester (Tester-2): yes. Tester 2 (a laptop) is off; nothing was sent to it.** **Updated 2026-10-10: hub 0.145.0; demo-hp, demo-felhom and Tester 1 run agent 0.154.0 and controller -0.305.0. The open-items list is at 137. Reports: `REPORT-release-2026-10-10.md`, `REPORT-break-the-circle-2026-10-09.md`, `REPORT-dooplex-survival-2026-10-09.md`, `REPORT-day4-2026-10-09.md`.** +0.305.0. The open-items list is at 139. Reports: `REPORT-new-apps-2026-10-10.md`, `REPORT-release-2026-10-10.md`, `REPORT-break-the-circle-2026-10-09.md`, `REPORT-dooplex-survival-2026-10-09.md`, `REPORT-day4-2026-10-09.md`.** +## Saturday 2026-10-10 (afternoon): two new apps in the catalogue, and one that was stopped + +- **Grocy and LubeLogger are in the catalogue.** Grocy runs the household — what food is in the house, what + runs out, the shopping list, the chores — and LubeLogger keeps the family car's services, repairs, fuel and + costs. Both went through the whole 61-check list on the test machines; nothing was taken on trust. +- **Monica is NOT in, and that is the one thing I need you to decide.** It has had no release of any kind for + seventeen months and no finished release for two and a half years; the branch its own README calls "the + stable version" has not moved since May 2024; and the two commits that ended a 13-month silence add a notice + saying the authors' own hosted service and all its data will be deleted at the end of December 2026, before a + rewrite. Keeping it out costs us nothing we have today — no app covers a family address book either way, and + Radicale already carries contacts to a phone. **If you do nothing, it stays out.** +- **Two real faults were found and fixed before either app was offered to anyone:** + 1. LubeLogger **ships with no login at all**. On a default install a stranger who found the address could read + the family's car records *and add to them*. I measured exactly that, and our install now turns the app's own + login on from a generated password before the app answers its first request. + 2. Grocy **could not be updated**. Moving it from the previous version to the current one left every page + showing an error, because the app keeps a settings file written at the first install and never updates it. + Our install now rewrites that file at every start. The update works on both test machines after the fix, + and the product's own "undo" was watched putting the old version back, with the data intact, before it. +- **The app count on the website moved from 56 to 58**, in both languages, everywhere it is stated. +- **One thing I could not finish and did not pretend to:** after a household removes an app keeping its backups + and restores it, the password the app's page shows is no longer backed by anything the box stored. The data + and the household's own login are fine — I checked both — but nobody has looked at what that page then + displays. It is written down as an open item. ## Saturday 2026-10-10: released — the security hole is closed, and the kernel button shows - **Hub 0.145.0 is live** (you were present). One box's key could change another household's mail settings. Now it diff --git a/documentation/audits/new-apps-2026-10-10/FIT.md b/documentation/audits/new-apps-2026-10-10/FIT.md new file mode 100644 index 00000000..a6ee0d58 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/FIT.md @@ -0,0 +1,193 @@ +# FIT — checklist group 0 for Grocy, LubeLogger and Monica (2026-10-10) + +Read and measured 2026-10-10 09:40–11:10 UTC. Sources: the GitHub API, raw upstream source at the pinned tag, +the Docker Hub / ghcr registry APIs, and **the images themselves started on bench LXC 9401** (demo-hp, Tier 0). +**[U]** upstream code/docs/registry · **[M]** measured on the bench, this session · **[I]** our inference. +Group 0 plans the later tests; it closes only what it measured. + +Raw reads: `A/`. Bench transcripts: `bench/`. + +**Where the test machines actually are** — a correction to the brief's reading: **both** 9202 +(`demo-hp-scratch`) and the bench 9401 (`upgrade-harness`) live on **demo-hp**, not on felhom-pve. +felhom-pve carries only 9201 (`demo-felhom`). Measured with `pct list` on both hosts. + +## The table + +| app (project → image, and why that image) | licence (file read) | last release · 2026 | tags · arch | phone-home (switch) | internet at runtime | non-HTTP ports | clients / login route | DB + services | memory (rough) | **Hungarian UI** | first-admin class | verdict | +|---|---|---|---|---|---|---|---|---|---|---|---|---| +| **Grocy** (grocy/grocy → `lscr.io/linuxserver/grocy`). **There is no image published by grocy itself** — `grocy/grocy` on Docker Hub is 404 [M], and grocy's own README answers "How to run using Docker" with a single link to `hub.docker.com/r/linuxserver/grocy` [U]. So linuxserver **is** the upstream-recommended image, and the catalog already pins four others from the same publisher. | **MIT** — `LICENSE.md`, API `spdx_id: MIT` [U] | **v4.7.1, 2026-09-04** · 3 in 2026 (v4.6.0 03-06, v4.7.0 08-28, v4.7.1 09-04); 83 releases since 2017 | `4.7.1`, `version-v4.7.1`, `v4.7.1-ls343`, `latest` · **amd64 + arm64** [M]. linuxserver rebuilds weekly, so `4.7.1` is **re-pushed** (ls342 2026-09-27 → ls343 2026-10-04) | **none.** The only outbound hosts in the whole codebase are `world.openfoodfacts.org` (the barcode-lookup plugin, on the household's explicit action) and `releases.grocy.info` (demo-data images, only when `MODE` ≠ production) [M, repo-wide grep]. No update check, no analytics. Switch: `GROCY_STOCK_BARCODE_LOOKUP_PLUGIN=""` | **no** | **none** (80 in the image; 443 unused) | PWA only — no native app. Third-party phone apps use the REST API with the header **`GROCY-API-KEY`** (`app.php:102`) [M]; the iCal feed uses `?secret=` | **SQLite**, one container (`/config/data/grocy.db`); nginx + php-fpm 8.5 | **~30 MiB idle** [M] | **yes — ~92 %.** `localization/hu/strings.po` holds 734 strings, 62 untranslated (91.6 %); the login page rendered `Bejelentkezés \| Grocy` with `GROCY_DEFAULT_LOCALE=hu` [M] | **class 3** — `admin`/`admin` exists on a fresh start and signs in [M] | **build** | +| **LubeLogger** (hargata/lubelog → `ghcr.io/hargata/lubelogger`; upstream's own `docker-compose.yml` names exactly this image. `hargata/lubelogger` on Docker Hub carries the same tags — ghcr chosen because it is the one upstream writes down) | **MIT** — `LICENSE`, API `spdx_id: MIT` [U] | **v1.7.3, 2026-09-12** · **17 in 2026** (v1.6.1 02-26 … v1.7.3 09-12) | `v1.7.3`, `v1.7.2` … `latest`, `edge` · **amd64 + arm64** [M] | **none at start.** Three outbound fetches, each on a page the household opens: the sponsors list (`hargata.github.io`), the release check (`api.github.com`, behind a `checkForUpdate` request flag), and the language-pack download (`hargata.github.io`) [M]. Startup makes no request — the first log lines are the banner and `Now listening` [M] | **no** | **none** (8080). A SignalR **websocket** at `/api/ws` — websockets pass the tunnel (MeTube measured 101) | PWA; no official native app. API takes **HTTP Basic** or `x-api-key` / `?apiKey=` on `/api`, `/kiosk`, `/images`, `/documents`, `/temp` (`GetPathAllowAPIKeyAuth`) — Basic measured 200 right / 401 wrong [M] | **LiteDB**, one container (`/App/data/cartracker.db`). PostgreSQL is optional (`POSTGRES_CONNECTION`); **upstream's default compose runs LiteDB**, so per 1.2 that is what we run | **~50–61 MiB idle** [M] | **yes, after one click — ~72 % coverage.** Nothing ships in the image: `/App/data/translations/` is empty on a fresh start [M]. `hu_HU` exists in the project's directory and the household downloads it in Settings; the file holds 403 keys of which 400 are translated (99.3 %), but German's file holds 559 — so hu_HU covers **~72 %** of the largest key set and the rest falls back to English [M] | **class 1 once we set it** — see below | **build** | +| **Monica** (monicahq/monica → `monica`, a Docker Official Image) | **AGPL-3.0** — `LICENSE.md`, API `spdx_id: AGPL-3.0` [U] | **none since 2025-04-21**; the last *stable* release is **v4.1.2, 2024-05-04** — 29 months [U] | `4.1.2`, `5.0.0-beta.5`, each × `-apache`/`-fpm`/`-fpm-alpine` · 7 arches; the image is **re-pushed constantly** (2026-10-08) because Docker Official Images rebuild on base-image changes | not reached | not reached | not reached | not reached | MySQL/MariaDB or PostgreSQL + Redis [U] | not measured | not measured | not measured | **stop — 0.2.** The operator decides. | + +## Monica — the stop, in full, because it is the one decision this run hands back + +Checklist **0.2** asks for *a release in the last 6 months*. Monica has had **none in 17 months**, and no stable +release in **29 months**. Four independent reads, all 2026-10-10: + +1. **Releases.** The newest release of any kind is `v5.0.0-beta.5`, **2025-04-21**, and it is a prerelease. The + newest stable is `v4.1.2`, **2024-05-04**. The tag list agrees: after `v4.1.2` there is nothing but betas. +2. **The stable branch is dead.** `4.x` — the branch the README sends you to for "the stable and current + version" — has its newest commit on **2024-05-04**. +3. **`main` is the beta**, and says so: *"This branch is in development. It's our beta version."* +4. **The commit history has a 13-month hole**: 2025-08-30, then nothing until **2026-09-24**, when two commits + landed. One of them is the telling one — it adds a login-page notice reading *"As we are about to deploy a + brand new version of Monica, this instance and all its data will be deleted at the end of December 2026"* + (PR #7978, merged 2026-09-24). The notice is `APP_SHOW_DELETION_NOTICE`, **off by default**, so it would + never show on a household's box; what it tells us is about the project, not the switch: the author is + preparing a rewrite and is winding the hosted service down. + +So the brief's third anticipated risk is not only real, it is worse than "releases slowly": **nothing has been +released for a year and a half, the stable branch has not moved in two and a half years, and upstream has +announced a replacement with no date.** 790 issues are open. + +**What the operator decides.** Keeping Monica out costs the catalog nothing it has today — no app covers a +family address book, and none did yesterday either. Letting it in means publishing an app whose next version is +a rewrite with no migration story, on a household's box, with our name on the restore promise. The honest +recommendation is **keep it out and look again when the rewrite ships**; `lifecycle:` exists precisely so an app +can be added later without disturbing anything. Radicale already carries contacts over CardDAV for households +that only want the address book itself. + +## The three risks the brief named, measured + +### 1. Grocy starts with `admin` / `admin` — **true**, and the replacement route is proven + +Upstream says it in its own README: *"Default login is user `admin` with password `admin`, please change the +password immediately"*. Measured on the bench, fresh volume: + +- the `users` table holds exactly one row, `id=1 admin`, password hashed `$argon2id$v=19$m=65536,t=4,p=1`; +- `POST /login` with `username=admin&password_base64=YWRtaW4=` → **302 to `/`**, and the cookie returns a 200 + stock overview. So the default really is `admin`/`admin`; +- a stranger with no cookie gets **302 → `/login`** on every page and **401** on `/api/system/info`. There is + **no open first-run screen** — grocy is first-admin **class 3**, the bookstack / mealie / calibre-web shape, + not a `setup_gate` app. + +**How the install replaces it (checklist 3.2).** Grocy ships no CLI, no admin env var and no headless setup. It +does ship the hashing primitive it uses itself: `UsersService` calls `password_hash($password, PASSWORD_ARGON2ID)`, +and the image's PHP 8.5.6 reports `password_algos() = [2y, argon2i, argon2id]` with `pdo_sqlite` present [M]. So +the `after_install` command is a `php -r` that takes **the password as its own argument** (`$argv[1]` — measured: +with `php -r 'code' a b`, `$argv[1]` is `a`), hashes it with grocy's own algorithm, writes it with a prepared +statement, and then **verifies with `password_verify` before printing its success marker**. Proven on the bench: + +| after the command ran | result | +|---|---| +| `admin` / `admin` | **302 → `/login?invalid=true`** (refused) | +| `admin` / *generated* | **302 → `/`** (signed in) | +| `admin` / a wrong password | **302 → `/login?invalid=true`** (refused) | + +**Lock-out (3.6), measured:** 25 wrong passwords in a row for `admin`, then the right one — **in at once**. Grocy +has no lock and no throttle. So the *name* need not be generated (the calibre-web reason, R-752, does not apply +here) and no family member can be locked out by a stranger. + +**Barcode scanning.** Upstream: camera scanning is ZXing, *"totally offline / client-side camera stream +processing"*, and *"due to browser security restrictions, this only works when serving Grocy via a secure +connection (`https://`)"*. Every Felhom app is served `https://` through the tunnel, so it works — and the +scanning itself sends nothing anywhere. The *lookup* of an unknown barcode is the separate, explicit "External +barcode lookup" workflow, and that one does reach `world.openfoodfacts.org` with the barcode number. + +**Overlap with Mealie / Tandoor.** Grocy has recipes and a meal plan too, so the overlap is real but narrow: +Mealie and Tandoor are recipe libraries (import a recipe, scale it, cook from it), grocy is a stock book (what +is in the house, what runs out, what to buy, whose turn the chores are). Grocy's recipes exist to subtract +ingredients from stock. One line goes in `use_cases`. + +### 2. LubeLogger may have no login at all — **true, and worse than "may"** + +`Middleware/Authen.cs` reads `bool.Parse(configuration["EnableAuth"] ?? "false")`, and `appsettings.json` ships +`"EnableAuth": false`. When it is false the middleware **mints a ticket** for every request with +`ClaimTypes.Name = "admin"` and the role `IsRootUser`. Measured on a default start, as an anonymous stranger: + +| request | result | +|---|---| +| `GET /` | **200**, `Garage - LubeLogger` | +| `GET /api/vehicles` | **200** | +| `GET /Home/Settings` | **200** | +| `POST /Vehicle/SaveVehicle` | **200 `{"success":true}`** — and the vehicle came back from `/api/vehicles` | + +So on a default install anyone who finds the subdomain reads and **writes** the family's car records as root. + +**The route that turns it on, and it is better than an `after_install`.** The root login is not a database row: +`AuthenticateRootUser` compares the submitted name and password, each **SHA-256 hex** (`StaticHelper.GetHash`), +against the config keys `UserNameHash` and `UserPasswordHash`. ASP.NET's configuration includes environment +variables, so all three keys can be set at deploy time — which means **auth is on before the app's first byte**, +with no install window to measure. Measured from the container's creation, polled every second: + +``` +t+1s /api/vehicles=000 (not listening yet) /=000 +t+2s /api/vehicles=401 /=302 → /Login/Index +t+3s /api/vehicles=401 /=302 → /Login/Index +``` + +and then, with auth on: + +| request | result | +|---|---| +| stranger `GET /`, `GET /Home/Settings`, `POST /Vehicle/SaveVehicle` | **302 → `/Login/Index`** | +| stranger `GET /api/vehicles` | **401** | +| household's generated login, web form | **`{"success":true}`**, and `/api/vehicles` 200 with the cookie | +| household's login, wrong password | **`{"success":false,"message":"Invalid Login Credentials"}`** | +| API Basic auth, right / wrong | **200 / 401** | + +So the verdict is **build**, and LubeLogger becomes first-admin **class 1** — generated by us at install. + +Two more things that had to be checked before trusting the env route, both measured: + +- **No config file undoes it.** `Program.cs` adds `data/config/userConfig.json` to the configuration *after* + the environment, so a file holding `EnableAuth: false` would win. On a fresh start that file **is not + written** (`/App/data/config/` was empty). And when it is later written, `SaveUserConfig` deliberately + re-reads those three keys from the merged configuration rather than from the posted form — so the household + cannot turn auth off from the UI while the env sets it. +- **Sign-up is closed by the app itself.** `RegisterNewUser` refuses without a token minted by the root user: + `POST /Login/Register` answered **`{"success":false,"message":"Invalid Token"}`**. Nothing for `signup_block` + to do. + +**Lock-out (3.6), measured:** 25 wrong passwords, then the right one — **in at once**. No lock, no throttle. +Same reading as grocy, and the same conclusion: a stranger cannot lock the family out. + +**Database (1.2).** LiteDB, which is upstream's default compose. One container, no engine, so no MariaDB / +PostgreSQL major ever to cross — the whole engine-major rule is `n/a` for this app by construction. + +**File uploads (2.2).** `InitMessage` creates `data/images`, `data/documents`, `data/temp`, `data/themes`, +`data/translations` beside `data/cartracker.db`. Receipts and documents are **household content** → the +`${USERDATA_PATH}` side; the database and the DataProtection keys are appdata. + +**One thing the image lacks, and it changes the healthcheck.** `ghcr.io/hargata/lubelogger:v1.7.3` has **no +curl, no wget, no nc, no python, no node** [M] — none of the four healthcheck families in `REUSE.md` §2 exists +in it. It does have **bash**, and `/dev/tcp` works there (measured: `Connection refused` against a dead port, +which is the mechanism answering). So LubeLogger needs a **fifth family**, a bash `/dev/tcp` probe, and that is +a catalog-wide convention — it goes into `REUSE.md` in the same commit. + +### 3. Monica's release state — see above. The brief said "releases slowly"; the measurement says "stopped". + +## Claims in this brief that turned out wrong, or need sharpening + +1. **"Grocy starts with the login `admin` / `admin` (as far as we know)"** — right, and now measured rather + than assumed, on a fresh volume and through the login route. +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. The brief's worry that "a stranger on the + internet sees the family's car data" understates it: a stranger also **writes** it, as root. +3. **"Monica releases slowly"** — too kind. No release in 17 months, no stable release in 29, the stable branch + untouched since 2024-05-04, and an upstream notice that the hosted instance and its data go away at the end + of December 2026 ahead of a rewrite. +4. **"the test machines"** — 9202 and the bench 9401 are both on **demo-hp**. felhom-pve has only 9201. +5. **Grocy's image.** The brief asks "upstream recommends which?" — the answer is unambiguous and worth writing + down: upstream publishes **no** image of its own and points at linuxserver.io. +6. **A near miss worth recording.** My first pass at grocy's Hungarian coverage reported **0 % translated** — a + broken `.po` parser that mishandled multi-line `msgstr`. The German control (which must be ~100 %) read 0 % + too, which is what caught it; a second, independent counting method gave German 0 untranslated, French 12, + **Hungarian 62 of 734 → 91.6 %**, with real Hungarian strings in the samples. Without the control this table + would have carried a false "no" in its most load-bearing new column. + +## What group 0 did NOT close + +- Memory from birth with swap off (5.1), the 10-minute soak (5.2), backup/restore through the product (2.5), + "remove with data" (2.6), the upload read back through the front door (2.8), the cold-start health timing + (4.3), the negative health control (4.4), the ladder step (6.2) and the forced-fail undo (6.3) are all + Part-B work on the bench and on 9202. Nothing above closes them. +- The forged-`X-Forwarded-For` test (3.10) through the simulated tunnel is Part B. What is **read** so far: + **grocy reads no client address anywhere** (repo-wide grep for `REMOTE_ADDR` / `HTTP_X_FORWARDED_FOR` / + `getClientIp` — nothing), and **LubeLogger reads it in one place only**, `LoginController` ~L521: it takes the + real peer from `Connection.RemoteIpAddress` and then *appends* the whole `X-Forwarded-For` string to a + `LogWarning` for a failed login. Measured with a forged header, the log line read + `Failed Login for … from ::ffff:172.17.0.1, 1.2.3.4, 10.9.9.9` — the real peer first, the forged part visible + and **deciding nothing**. No trusted-proxy list, no `ForwardedHeaders` middleware, no lock and no rights keyed + on the address. So neither app needs the `-xff` reset; both get a line in their record saying why. diff --git a/documentation/audits/new-apps-2026-10-10/README.md b/documentation/audits/new-apps-2026-10-10/README.md new file mode 100644 index 00000000..cdd073b0 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/README.md @@ -0,0 +1,39 @@ +# Three new apps through the checklist (2026-10-10) + +Brief: a fit check (`NEW-APP-CHECKLIST.md` group 0) for **Grocy, LubeLogger and Monica**, chosen from the +2026-10-10 PikaPods scan because no catalog app covers what they do; then build them one at a time, Grocy +first, each with the full 61-check record. + +Architecture read: `09-update-architecture.md` §3 decisions 13, 22, 42, 45–50, 57, 61 and §6.5 (the drill +catalog and the image store); `01-topology-and-trust.md` (the tunnel carries HTTP only; §5 the setup gate); +`07-backup-architecture.md` (the backup classes and what the tier-1 unit holds). Register rows read first: +R-707 (first admin), R-741 (the install window), R-753 (the visitor's address), R-761 (the asset path). + +Baselines: catalog `b38aa923177db40bcb399546c625167fa029f025`, felhom.eu `a406efc7d52807398eacba39a3bb1e94355a9da7`, +register 136 rows / highest R-925; controller on 9202 `0.304.0`. + +## Venues + +- **Bench** — LXC 9401 `upgrade-harness` on **demo-hp**, swap 0, 10 GiB. `upgrade-test.py --move` per app with + a from-birth cgroup sampler beside it (`bench/`). +- **Box** — scratch guest 9202 `demo-hp-scratch`, also on **demo-hp**, on the DRILL catalog only. Per app: + install with a stranger's poll and the sampler, the app's own checks, the guarded Update, remove keeping + backups + restore, remove with data (`box/`). +- **Ladder** — the single writer `upgrade-test.py --write-ladder` from both verdicts. + +**A correction to the brief's reading:** 9202 and the bench 9401 both live on **demo-hp**. felhom-pve +(`demo-felhom`) carries only guest 9201. Measured with `pct list` on both hosts. + +## Per app + +| app | result | catalog commit | memory (peak anon / limit) | ladder step | notes | +|---|---|---|---|---|---| +| **Grocy** | **published** | `b7f0f7c` | bench (swap 0) and box, in `bench/` and `box/grocy/` | 4.6.0 → 4.7.1 | two defects found and fixed before publishing: the controller refuses an `after_install` command containing `$`, and grocy's persisted `config.php` does not follow the image (a 4.6 → 4.7 update answered HTTP 500 on every page) | +| **LubeLogger** | **published** | `b7f0f7c` | `bench/` and `box/lubelogger/` | v1.7.2 → v1.7.3 | the image ships **no login at all** and hands a stranger the root role; the template turns authentication on from a generated password before the app's first byte | +| **Monica** | **stop — checklist 0.2** | not built | — | — | no release of any kind in 17 months, no stable release in 29, the stable branch untouched since 2024-05-04, and upstream has announced that its hosted instance and all its data go away at the end of December 2026 ahead of a rewrite. The operator decides. | + +The fit table, with every group-0 answer and the three measured risks, is `FIT.md`. + +## Teardown + +Stated per layer in `felhom.eu/REPORT-new-apps-2026-10-10.md`. diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/abort-states.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/abort-states.json new file mode 100644 index 00000000..4e7a94b5 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/abort-states.json @@ -0,0 +1,8 @@ +{ + "grocy": { + "status": "running", + "health": "healthy", + "restarts": 0, + "exit": 0 + } +} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/compose-final.log b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/compose-final.log new file mode 100644 index 00000000..90730d69 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/compose-final.log @@ -0,0 +1,33 @@ +grocy | [migrations] started +grocy | [migrations] 01-nginx-site-confs-default: skipped +grocy | [migrations] 02-default-location: skipped +grocy | [migrations] done +grocy | ─────────────────────────────────────── +grocy | +grocy | ██╗ ███████╗██╗ ██████╗ +grocy | ██║ ██╔════╝██║██╔═══██╗ +grocy | ██║ ███████╗██║██║ ██║ +grocy | ██║ ╚════██║██║██║ ██║ +grocy | ███████╗███████║██║╚██████╔╝ +grocy | ╚══════╝╚══════╝╚═╝ ╚═════╝ +grocy | +grocy | Brought to you by linuxserver.io +grocy | ─────────────────────────────────────── +grocy | +grocy | To support LSIO projects visit: +grocy | https://www.linuxserver.io/donate/ +grocy | +grocy | ─────────────────────────────────────── +grocy | GID/UID +grocy | ─────────────────────────────────────── +grocy | +grocy | User UID: 1000 +grocy | User GID: 1000 +grocy | ─────────────────────────────────────── +grocy | Linuxserver.io version: v4.6.0-ls337 +grocy | Build-date: 2026-08-23T08:01:09+00:00 +grocy | ─────────────────────────────────────── +grocy | +grocy | using keys found in /config/keys +grocy | [custom-init] No custom files found, skipping... +grocy | [ls.io-init] done. diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/engine-state.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/engine-state.json new file mode 100644 index 00000000..ec747fa4 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/engine-state.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-after-detail.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-after-detail.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-after-detail.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-after.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-after.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-after.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-before-detail.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-before-detail.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-before-detail.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-before.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-before.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/files-before.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/memory-samples.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/memory-samples.json new file mode 100644 index 00000000..f1d24753 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/memory-samples.json @@ -0,0 +1,762 @@ +[ + { + "t": 15.1, + "containers": { + "grocy": { + "limit": 402653184, + "current": 41213952, + "peak": 102387712, + "anon": 24842240, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 259 + }, + { + "t": 30.2, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39374848, + "peak": 102387712, + "anon": 23896064, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 516 + }, + { + "t": 45.4, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40570880, + "peak": 102387712, + "anon": 24580096, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 774 + }, + { + "t": 60.5, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39919616, + "peak": 102387712, + "anon": 24104960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1034 + }, + { + "t": 75.6, + "containers": { + "grocy": { + "limit": 402653184, + "current": 42422272, + "peak": 102387712, + "anon": 25993216, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1292 + }, + { + "t": 90.8, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40648704, + "peak": 102387712, + "anon": 24645632, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1550 + }, + { + "t": 105.9, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39444480, + "peak": 102387712, + "anon": 23302144, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1807 + }, + { + "t": 121.0, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40873984, + "peak": 102387712, + "anon": 24338432, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2067 + }, + { + "t": 136.2, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40206336, + "peak": 102387712, + "anon": 23613440, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2327 + }, + { + "t": 151.3, + "containers": { + "grocy": { + "limit": 402653184, + "current": 43610112, + "peak": 102387712, + "anon": 27152384, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2586 + }, + { + "t": 166.4, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39763968, + "peak": 102387712, + "anon": 23109632, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2844 + }, + { + "t": 181.6, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39653376, + "peak": 102387712, + "anon": 23236608, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3101 + }, + { + "t": 196.7, + "containers": { + "grocy": { + "limit": 402653184, + "current": 42065920, + "peak": 102387712, + "anon": 25444352, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3359 + }, + { + "t": 211.8, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39346176, + "peak": 102387712, + "anon": 23470080, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3617 + }, + { + "t": 227.0, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40783872, + "peak": 102387712, + "anon": 24256512, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3876 + }, + { + "t": 242.1, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39702528, + "peak": 102387712, + "anon": 23298048, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4134 + }, + { + "t": 257.2, + "containers": { + "grocy": { + "limit": 402653184, + "current": 42172416, + "peak": 102387712, + "anon": 25268224, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4392 + }, + { + "t": 272.4, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39981056, + "peak": 102387712, + "anon": 23298048, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4651 + }, + { + "t": 287.5, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40763392, + "peak": 102387712, + "anon": 23846912, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4911 + }, + { + "t": 302.6, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39370752, + "peak": 102387712, + "anon": 23306240, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5169 + }, + { + "t": 317.8, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40411136, + "peak": 102387712, + "anon": 23339008, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5429 + }, + { + "t": 332.9, + "containers": { + "grocy": { + "limit": 402653184, + "current": 39522304, + "peak": 102387712, + "anon": 23556096, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5685 + }, + { + "t": 348.0, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40988672, + "peak": 102387712, + "anon": 24526848, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5943 + }, + { + "t": 363.2, + "containers": { + "grocy": { + "limit": 402653184, + "current": 41037824, + "peak": 102387712, + "anon": 24551424, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6205 + }, + { + "t": 378.3, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40198144, + "peak": 102387712, + "anon": 23633920, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6464 + }, + { + "t": 393.5, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40230912, + "peak": 102387712, + "anon": 23805952, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6725 + }, + { + "t": 408.6, + "containers": { + "grocy": { + "limit": 402653184, + "current": 41799680, + "peak": 102387712, + "anon": 25055232, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6983 + }, + { + "t": 423.7, + "containers": { + "grocy": { + "limit": 402653184, + "current": 41152512, + "peak": 102387712, + "anon": 24522752, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7242 + }, + { + "t": 438.9, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40235008, + "peak": 102387712, + "anon": 23285760, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7503 + }, + { + "t": 454.0, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40103936, + "peak": 102387712, + "anon": 23285760, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7759 + }, + { + "t": 469.1, + "containers": { + "grocy": { + "limit": 402653184, + "current": 41807872, + "peak": 102387712, + "anon": 24825856, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8016 + }, + { + "t": 484.3, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40210432, + "peak": 102387712, + "anon": 23289856, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8276 + }, + { + "t": 499.4, + "containers": { + "grocy": { + "limit": 402653184, + "current": 41422848, + "peak": 102387712, + "anon": 24178688, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8535 + }, + { + "t": 514.5, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40075264, + "peak": 102387712, + "anon": 23007232, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8793 + }, + { + "t": 529.7, + "containers": { + "grocy": { + "limit": 402653184, + "current": 42205184, + "peak": 102387712, + "anon": 24797184, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9050 + }, + { + "t": 544.8, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40341504, + "peak": 102387712, + "anon": 23285760, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9311 + }, + { + "t": 559.9, + "containers": { + "grocy": { + "limit": 402653184, + "current": 42160128, + "peak": 102387712, + "anon": 24383488, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9570 + }, + { + "t": 575.0, + "containers": { + "grocy": { + "limit": 402653184, + "current": 41033728, + "peak": 102387712, + "anon": 23465984, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9829 + }, + { + "t": 590.2, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40337408, + "peak": 102387712, + "anon": 23289856, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10086 + }, + { + "t": 605.3, + "containers": { + "grocy": { + "limit": 402653184, + "current": 40603648, + "peak": 102387712, + "anon": 23007232, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10343 + } +] \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/migration-lines.txt b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/migration-lines.txt new file mode 100644 index 00000000..15f3c97d --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/migration-lines.txt @@ -0,0 +1,4 @@ +grocy | [migrations] started +grocy | [migrations] 01-nginx-site-confs-default: skipped +grocy | [migrations] 02-default-location: skipped +grocy | [migrations] done \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/run.log b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/run.log new file mode 100644 index 00000000..4c9af4df --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/run.log @@ -0,0 +1,60 @@ +[09:18:26] scratch drive folders cleared before FROM (R-656): none existed +[09:18:26] MV-grocy: deploying grocy at FROM {'grocy': 'lscr.io/linuxserver/grocy:4.6.0'} +[09:19:02] FROM settled=True in 36.1s :: {"grocy": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}} +[09:19:02] fixture: the BOX walk's own (Grocy), through upgrade_boxport +[09:19:03] grocy: signed in with grocy's image default (no after_install on the bench) +[09:19:04] grocy: POST /api/objects/products http=200 :: {"created_object_id":"1"} +[09:19:04] grocy: POST /api/stock/products/1/add http=200 +[09:19:05] grocy: readback http=200 found=True (controls: no cookie 401, wrong 401, absent 404) +[09:19:05] C1 (seed reads back BEFORE): True +[09:19:05] MV-grocy: swapping to TO {'grocy': 'lscr.io/linuxserver/grocy:4.7.1'} +[09:19:09] TO up -d rc=0 +[09:19:40] TO settled=True in 30.9s :: {"grocy": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}} +[09:19:40] migration lines observed: 4 +[09:19:41] grocy: readback http=200 found=True (controls: no cookie 401, wrong 401, absent 404) +[09:19:41] RESULT (seed reads back AFTER): True +[09:19:41] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:80 +[09:19:57] + 15s grocy=39M/384M peak=97M kills=0 rs=0 reqs=259 +[09:20:12] + 30s grocy=37M/384M peak=97M kills=0 rs=0 reqs=516 +[09:20:27] + 45s grocy=38M/384M peak=97M kills=0 rs=0 reqs=774 +[09:20:42] + 60s grocy=38M/384M peak=97M kills=0 rs=0 reqs=1034 +[09:20:57] + 76s grocy=40M/384M peak=97M kills=0 rs=0 reqs=1292 +[09:21:12] + 91s grocy=38M/384M peak=97M kills=0 rs=0 reqs=1550 +[09:21:27] + 106s grocy=37M/384M peak=97M kills=0 rs=0 reqs=1807 +[09:21:42] + 121s grocy=38M/384M peak=97M kills=0 rs=0 reqs=2067 +[09:21:58] + 136s grocy=38M/384M peak=97M kills=0 rs=0 reqs=2327 +[09:22:13] + 151s grocy=41M/384M peak=97M kills=0 rs=0 reqs=2586 +[09:22:28] + 166s grocy=37M/384M peak=97M kills=0 rs=0 reqs=2844 +[09:22:43] + 182s grocy=37M/384M peak=97M kills=0 rs=0 reqs=3101 +[09:22:58] + 197s grocy=40M/384M peak=97M kills=0 rs=0 reqs=3359 +[09:23:13] + 212s grocy=37M/384M peak=97M kills=0 rs=0 reqs=3617 +[09:23:28] + 227s grocy=38M/384M peak=97M kills=0 rs=0 reqs=3876 +[09:23:44] + 242s grocy=37M/384M peak=97M kills=0 rs=0 reqs=4134 +[09:23:59] + 257s grocy=40M/384M peak=97M kills=0 rs=0 reqs=4392 +[09:24:14] + 272s grocy=38M/384M peak=97M kills=0 rs=0 reqs=4651 +[09:24:29] + 288s grocy=38M/384M peak=97M kills=0 rs=0 reqs=4911 +[09:24:44] + 303s grocy=37M/384M peak=97M kills=0 rs=0 reqs=5169 +[09:24:59] + 318s grocy=38M/384M peak=97M kills=0 rs=0 reqs=5429 +[09:25:14] + 333s grocy=37M/384M peak=97M kills=0 rs=0 reqs=5685 +[09:25:29] + 348s grocy=39M/384M peak=97M kills=0 rs=0 reqs=5943 +[09:25:45] + 363s grocy=39M/384M peak=97M kills=0 rs=0 reqs=6205 +[09:26:00] + 378s grocy=38M/384M peak=97M kills=0 rs=0 reqs=6464 +[09:26:15] + 394s grocy=38M/384M peak=97M kills=0 rs=0 reqs=6725 +[09:26:30] + 409s grocy=39M/384M peak=97M kills=0 rs=0 reqs=6983 +[09:26:45] + 424s grocy=39M/384M peak=97M kills=0 rs=0 reqs=7242 +[09:27:00] + 439s grocy=38M/384M peak=97M kills=0 rs=0 reqs=7503 +[09:27:15] + 454s grocy=38M/384M peak=97M kills=0 rs=0 reqs=7759 +[09:27:31] + 469s grocy=39M/384M peak=97M kills=0 rs=0 reqs=8016 +[09:27:46] + 484s grocy=38M/384M peak=97M kills=0 rs=0 reqs=8276 +[09:28:01] + 499s grocy=39M/384M peak=97M kills=0 rs=0 reqs=8535 +[09:28:16] + 514s grocy=38M/384M peak=97M kills=0 rs=0 reqs=8793 +[09:28:31] + 530s grocy=40M/384M peak=97M kills=0 rs=0 reqs=9050 +[09:28:46] + 545s grocy=38M/384M peak=97M kills=0 rs=0 reqs=9311 +[09:29:01] + 560s grocy=40M/384M peak=97M kills=0 rs=0 reqs=9570 +[09:29:16] + 575s grocy=39M/384M peak=97M kills=0 rs=0 reqs=9829 +[09:29:32] + 590s grocy=38M/384M peak=97M kills=0 rs=0 reqs=10086 +[09:29:47] + 605s grocy=38M/384M peak=97M kills=0 rs=0 reqs=10343 +[09:29:47] memory watch: killed=False tight=[] requests=10343 codes={'302': 10343} +[09:29:47] MV-grocy: ABORT — putting the FROM images back +[09:30:23] grocy: the household's own password no longer signs in after the step +[09:30:23] ABORT: app came back in 30.9s; data present=False \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/to-full.log b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/to-full.log new file mode 100644 index 00000000..fda7c0fc --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/to-full.log @@ -0,0 +1,33 @@ +grocy | [migrations] started +grocy | [migrations] 01-nginx-site-confs-default: skipped +grocy | [migrations] 02-default-location: skipped +grocy | [migrations] done +grocy | ─────────────────────────────────────── +grocy | +grocy | ██╗ ███████╗██╗ ██████╗ +grocy | ██║ ██╔════╝██║██╔═══██╗ +grocy | ██║ ███████╗██║██║ ██║ +grocy | ██║ ╚════██║██║██║ ██║ +grocy | ███████╗███████║██║╚██████╔╝ +grocy | ╚══════╝╚══════╝╚═╝ ╚═════╝ +grocy | +grocy | Brought to you by linuxserver.io +grocy | ─────────────────────────────────────── +grocy | +grocy | To support LSIO projects visit: +grocy | https://www.linuxserver.io/donate/ +grocy | +grocy | ─────────────────────────────────────── +grocy | GID/UID +grocy | ─────────────────────────────────────── +grocy | +grocy | User UID: 1000 +grocy | User GID: 1000 +grocy | ─────────────────────────────────────── +grocy | Linuxserver.io version: v4.7.1-ls343 +grocy | Build-date: 2026-10-04T13:27:49+00:00 +grocy | ─────────────────────────────────────── +grocy | +grocy | using keys found in /config/keys +grocy | [custom-init] No custom files found, skipping... +grocy | [ls.io-init] done. diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/to-states.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/to-states.json new file mode 100644 index 00000000..4e7a94b5 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/to-states.json @@ -0,0 +1,8 @@ +{ + "grocy": { + "status": "running", + "health": "healthy", + "restarts": 0, + "exit": 0 + } +} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/verdict.json b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/verdict.json new file mode 100644 index 00000000..6299c757 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/evidence/MV-grocy/verdict.json @@ -0,0 +1,56 @@ +{ + "harness_version": 5, + "edge": "MV-grocy", + "app": "grocy", + "note": "night 2026-09-23 within-a-major move: grocy=lscr.io/linuxserver/grocy:4.7.1", + "from": { + "grocy": "lscr.io/linuxserver/grocy:4.6.0" + }, + "to": { + "grocy": "lscr.io/linuxserver/grocy:4.7.1" + }, + "verdict": "proven", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "migration_observed": "\u001b[2Kgrocy | [migrations] started", + "abort": "starts-data-gone", + "abort_detail": "the app started but the seeded data was gone", + "engine_state_after": null, + "memory": { + "soak_s": 605.5, + "requested_s": 600, + "requests": 10343, + "codes": { + "302": 10343 + }, + "first_kill": null, + "containers": { + "grocy": { + "limit": 402653184, + "peak": 102387712, + "peak_pct": 0.254, + "anon_peak_sampled": 27152384, + "anon_peak_pct": 0.067, + "swap_peak": 0, + "oom_kills": 0, + "restarts": 0, + "oomkilled_flag": false, + "measured": true + } + }, + "unmeasured": [], + "venue_swap_bytes": 0, + "load": "reached" + }, + "marks": [], + "bench_overrides": null, + "duration_s": 30.9, + "measured_at": "2026-10-10T09:30:23Z", + "evidence": "evidence/MV-grocy", + "scratch_cleared": [], + "files_changed": [], + "files_changed_detail": [], + "files_ignored": [], + "total_s": 716.5 +} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/mem-grocy.csv b/documentation/audits/new-apps-2026-10-10/bench/grocy/mem-grocy.csv new file mode 100644 index 00000000..9101baf9 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/mem-grocy.csv @@ -0,0 +1,696 @@ +1791623908,grocy,eb8dbb594830,12898304,21037056,0,0,402653184,0 +1791623908,grocy,eb8dbb594830,12898304,21037056,0,0,402653184,0 +1791623910,grocy,eb8dbb594830,12898304,21028864,0,0,402653184,0 +1791623910,grocy,eb8dbb594830,12898304,21028864,0,0,402653184,0 +1791623912,grocy,eb8dbb594830,12898304,21028864,0,0,402653184,0 +1791623912,grocy,eb8dbb594830,12898304,21028864,0,0,402653184,0 +1791623914,grocy,eb8dbb594830,12898304,21028864,0,0,402653184,0 +1791623914,grocy,eb8dbb594830,12898304,21028864,0,0,402653184,0 +1791623916,grocy,eb8dbb594830,12898304,21028864,0,0,402653184,0 +1791623916,grocy,eb8dbb594830,12898304,21028864,0,0,402653184,0 +1791623918,grocy,eb8dbb594830,12898304,21032960,0,0,402653184,0 +1791623918,grocy,eb8dbb594830,12898304,21032960,0,0,402653184,0 +1791623920,grocy,eb8dbb594830,12902400,21032960,0,0,402653184,0 +1791623920,grocy,eb8dbb594830,12902400,21032960,0,0,402653184,0 +1791623922,grocy,eb8dbb594830,12902400,21032960,0,0,402653184,0 +1791623922,grocy,eb8dbb594830,12902400,21032960,0,0,402653184,0 +1791623924,grocy,eb8dbb594830,12902400,21032960,0,0,402653184,0 +1791623925,grocy,eb8dbb594830,12902400,21032960,0,0,402653184,0 +1791623926,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623927,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623928,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623929,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623931,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623931,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623933,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623933,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623935,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623935,grocy,eb8dbb594830,12902400,21028864,0,0,402653184,0 +1791623937,grocy,eb8dbb594830,19599360,31698944,0,0,402653184,0 +1791623937,grocy,eb8dbb594830,19832832,32251904,0,0,402653184,0 +1791623939,grocy,eb8dbb594830,22847488,37216256,0,0,402653184,0 +1791623939,grocy,eb8dbb594830,22867968,37613568,0,0,402653184,0 +1791623941,grocy,eb8dbb594830,17956864,37306368,0,0,402653184,0 +1791623941,grocy,eb8dbb594830,17956864,37130240,0,0,402653184,0 +1791623943,grocy,eb8dbb594830,18575360,38182912,0,0,402653184,0 +1791623943,grocy,eb8dbb594830,19496960,39362560,0,0,402653184,0 +1791623945,grocy,eb8dbb594830,19357696,40849408,0,0,402653184,0 +1791623945,grocy,eb8dbb594830,19357696,40058880,0,0,402653184,0 +1791623947,grocy,eb8dbb594830,90112,7245824,0,0,402653184,0 +1791623947,grocy,eb8dbb594830,90112,7245824,0,0,402653184,0 +1791623949,grocy,086e0c6cb337,663552,5140480,0,0,402653184,0 +1791623949,grocy,086e0c6cb337,294912,5279744,0,0,402653184,0 +1791623951,grocy,086e0c6cb337,12857344,21225472,0,0,402653184,0 +1791623951,grocy,086e0c6cb337,12857344,21012480,0,0,402653184,0 +1791623953,grocy,086e0c6cb337,12857344,21012480,0,0,402653184,0 +1791623953,grocy,086e0c6cb337,12857344,21012480,0,0,402653184,0 +1791623955,grocy,086e0c6cb337,12857344,21012480,0,0,402653184,0 +1791623955,grocy,086e0c6cb337,12857344,21012480,0,0,402653184,0 +1791623957,grocy,086e0c6cb337,12857344,21012480,0,0,402653184,0 +1791623957,grocy,086e0c6cb337,12857344,21012480,0,0,402653184,0 +1791623959,grocy,086e0c6cb337,12857344,21274624,0,0,402653184,0 +1791623960,grocy,086e0c6cb337,12857344,21016576,0,0,402653184,0 +1791623961,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623962,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623964,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623964,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623966,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623966,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623968,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623968,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623970,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623970,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623972,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623972,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623974,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623974,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623976,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623976,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623978,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623978,grocy,086e0c6cb337,12861440,21012480,0,0,402653184,0 +1791623980,grocy,086e0c6cb337,19927040,34942976,0,0,402653184,0 +1791623980,grocy,086e0c6cb337,19546112,34607104,0,0,402653184,0 +1791623982,grocy,086e0c6cb337,20885504,36425728,0,0,402653184,0 +1791623982,grocy,086e0c6cb337,21594112,37892096,0,0,402653184,0 +1791623984,grocy,086e0c6cb337,24358912,40853504,0,0,402653184,0 +1791623984,grocy,086e0c6cb337,24358912,40779776,0,0,402653184,0 +1791623986,grocy,086e0c6cb337,25337856,41795584,0,0,402653184,0 +1791623986,grocy,086e0c6cb337,24387584,40574976,0,0,402653184,0 +1791623988,grocy,086e0c6cb337,24387584,40693760,0,0,402653184,0 +1791623988,grocy,086e0c6cb337,24387584,40923136,0,0,402653184,0 +1791623990,grocy,086e0c6cb337,24387584,40603648,0,0,402653184,0 +1791623990,grocy,086e0c6cb337,25120768,41299968,0,0,402653184,0 +1791623992,grocy,086e0c6cb337,25354240,41353216,0,0,402653184,0 +1791623992,grocy,086e0c6cb337,24408064,40386560,0,0,402653184,0 +1791623994,grocy,086e0c6cb337,25706496,42795008,0,0,402653184,0 +1791623995,grocy,086e0c6cb337,26902528,43917312,0,0,402653184,0 +1791623997,grocy,086e0c6cb337,24096768,40050688,0,0,402653184,0 +1791623997,grocy,086e0c6cb337,24100864,40357888,0,0,402653184,0 +1791623999,grocy,086e0c6cb337,24100864,40329216,0,0,402653184,0 +1791623999,grocy,086e0c6cb337,24100864,39976960,0,0,402653184,0 +1791624001,grocy,086e0c6cb337,24182784,40517632,0,0,402653184,0 +1791624001,grocy,086e0c6cb337,24182784,41164800,0,0,402653184,0 +1791624003,grocy,086e0c6cb337,24195072,40529920,0,0,402653184,0 +1791624003,grocy,086e0c6cb337,24195072,40476672,0,0,402653184,0 +1791624005,grocy,086e0c6cb337,25292800,41959424,0,0,402653184,0 +1791624005,grocy,086e0c6cb337,24195072,40685568,0,0,402653184,0 +1791624007,grocy,086e0c6cb337,25194496,41492480,0,0,402653184,0 +1791624007,grocy,086e0c6cb337,24195072,40378368,0,0,402653184,0 +1791624009,grocy,086e0c6cb337,24195072,39927808,0,0,402653184,0 +1791624009,grocy,086e0c6cb337,26030080,42176512,0,0,402653184,0 +1791624011,grocy,086e0c6cb337,23896064,40239104,0,0,402653184,0 +1791624011,grocy,086e0c6cb337,23924736,40370176,0,0,402653184,0 +1791624013,grocy,086e0c6cb337,23900160,40001536,0,0,402653184,0 +1791624013,grocy,086e0c6cb337,24612864,40943616,0,0,402653184,0 +1791624015,grocy,086e0c6cb337,23900160,40398848,0,0,402653184,0 +1791624015,grocy,086e0c6cb337,23900160,40394752,0,0,402653184,0 +1791624017,grocy,086e0c6cb337,24641536,40812544,0,0,402653184,0 +1791624017,grocy,086e0c6cb337,23900160,39616512,0,0,402653184,0 +1791624019,grocy,086e0c6cb337,23896064,40210432,0,0,402653184,0 +1791624019,grocy,086e0c6cb337,24899584,40607744,0,0,402653184,0 +1791624021,grocy,086e0c6cb337,23900160,39972864,0,0,402653184,0 +1791624021,grocy,086e0c6cb337,24969216,41299968,0,0,402653184,0 +1791624023,grocy,086e0c6cb337,23900160,40296448,0,0,402653184,0 +1791624023,grocy,086e0c6cb337,23900160,40026112,0,0,402653184,0 +1791624025,grocy,086e0c6cb337,23973888,40833024,0,0,402653184,0 +1791624025,grocy,086e0c6cb337,23904256,40374272,0,0,402653184,0 +1791624027,grocy,086e0c6cb337,23908352,40144896,0,0,402653184,0 +1791624028,grocy,086e0c6cb337,24907776,41058304,0,0,402653184,0 +1791624030,grocy,086e0c6cb337,23969792,40783872,0,0,402653184,0 +1791624030,grocy,086e0c6cb337,23900160,40009728,0,0,402653184,0 +1791624032,grocy,086e0c6cb337,23904256,39989248,0,0,402653184,0 +1791624032,grocy,086e0c6cb337,24403968,40894464,0,0,402653184,0 +1791624034,grocy,086e0c6cb337,23908352,39972864,0,0,402653184,0 +1791624034,grocy,086e0c6cb337,23908352,39727104,0,0,402653184,0 +1791624036,grocy,086e0c6cb337,24952832,41402368,0,0,402653184,0 +1791624036,grocy,086e0c6cb337,23924736,40370176,0,0,402653184,0 +1791624038,grocy,086e0c6cb337,24211456,40173568,0,0,402653184,0 +1791624038,grocy,086e0c6cb337,24948736,41279488,0,0,402653184,0 +1791624040,grocy,086e0c6cb337,24104960,40402944,0,0,402653184,0 +1791624040,grocy,086e0c6cb337,24104960,41115648,0,0,402653184,0 +1791624042,grocy,086e0c6cb337,24104960,39919616,0,0,402653184,0 +1791624042,grocy,086e0c6cb337,24104960,39919616,0,0,402653184,0 +1791624044,grocy,086e0c6cb337,25186304,41394176,0,0,402653184,0 +1791624044,grocy,086e0c6cb337,24096768,40304640,0,0,402653184,0 +1791624046,grocy,086e0c6cb337,25190400,41025536,0,0,402653184,0 +1791624046,grocy,086e0c6cb337,25190400,40960000,0,0,402653184,0 +1791624048,grocy,086e0c6cb337,24104960,40202240,0,0,402653184,0 +1791624048,grocy,086e0c6cb337,24104960,40464384,0,0,402653184,0 +1791624050,grocy,086e0c6cb337,24326144,41078784,0,0,402653184,0 +1791624050,grocy,086e0c6cb337,25513984,42176512,0,0,402653184,0 +1791624052,grocy,086e0c6cb337,24104960,40067072,0,0,402653184,0 +1791624052,grocy,086e0c6cb337,24104960,40067072,0,0,402653184,0 +1791624054,grocy,086e0c6cb337,24104960,40472576,0,0,402653184,0 +1791624054,grocy,086e0c6cb337,24104960,40296448,0,0,402653184,0 +1791624056,grocy,086e0c6cb337,24100864,40435712,0,0,402653184,0 +1791624056,grocy,086e0c6cb337,24100864,40435712,0,0,402653184,0 +1791624058,grocy,086e0c6cb337,24113152,40734720,0,0,402653184,0 +1791624058,grocy,086e0c6cb337,24113152,40669184,0,0,402653184,0 +1791624061,grocy,086e0c6cb337,25907200,42246144,0,0,402653184,0 +1791624061,grocy,086e0c6cb337,25907200,42246144,0,0,402653184,0 +1791624063,grocy,086e0c6cb337,24104960,40620032,0,0,402653184,0 +1791624063,grocy,086e0c6cb337,24104960,40620032,0,0,402653184,0 +1791624065,grocy,086e0c6cb337,24113152,40325120,0,0,402653184,0 +1791624065,grocy,086e0c6cb337,24113152,40325120,0,0,402653184,0 +1791624067,grocy,086e0c6cb337,24113152,40779776,0,0,402653184,0 +1791624067,grocy,086e0c6cb337,24113152,40779776,0,0,402653184,0 +1791624069,grocy,086e0c6cb337,25030656,40218624,0,0,402653184,0 +1791624069,grocy,086e0c6cb337,24109056,40189952,0,0,402653184,0 +1791624071,grocy,086e0c6cb337,24895488,41287680,0,0,402653184,0 +1791624071,grocy,086e0c6cb337,24895488,41299968,0,0,402653184,0 +1791624073,grocy,086e0c6cb337,26607616,42762240,0,0,402653184,0 +1791624073,grocy,086e0c6cb337,26607616,42762240,0,0,402653184,0 +1791624075,grocy,086e0c6cb337,23310336,39546880,0,0,402653184,0 +1791624075,grocy,086e0c6cb337,23310336,39546880,0,0,402653184,0 +1791624077,grocy,086e0c6cb337,23310336,40046592,0,0,402653184,0 +1791624077,grocy,086e0c6cb337,23310336,40046592,0,0,402653184,0 +1791624079,grocy,086e0c6cb337,23298048,39317504,0,0,402653184,0 +1791624079,grocy,086e0c6cb337,23298048,39317504,0,0,402653184,0 +1791624081,grocy,086e0c6cb337,24109056,40628224,0,0,402653184,0 +1791624081,grocy,086e0c6cb337,24109056,40628224,0,0,402653184,0 +1791624083,grocy,086e0c6cb337,23302144,39550976,0,0,402653184,0 +1791624083,grocy,086e0c6cb337,23302144,39550976,0,0,402653184,0 +1791624085,grocy,086e0c6cb337,24125440,40099840,0,0,402653184,0 +1791624085,grocy,086e0c6cb337,23302144,39739392,0,0,402653184,0 +1791624087,grocy,086e0c6cb337,25042944,41521152,0,0,402653184,0 +1791624087,grocy,086e0c6cb337,25042944,41521152,0,0,402653184,0 +1791624089,grocy,086e0c6cb337,23302144,39116800,0,0,402653184,0 +1791624089,grocy,086e0c6cb337,23302144,39116800,0,0,402653184,0 +1791624092,grocy,086e0c6cb337,23355392,39768064,0,0,402653184,0 +1791624092,grocy,086e0c6cb337,23355392,39768064,0,0,402653184,0 +1791624094,grocy,086e0c6cb337,23355392,39424000,0,0,402653184,0 +1791624094,grocy,086e0c6cb337,23355392,39424000,0,0,402653184,0 +1791624096,grocy,086e0c6cb337,23359488,39448576,0,0,402653184,0 +1791624096,grocy,086e0c6cb337,23359488,39448576,0,0,402653184,0 +1791624098,grocy,086e0c6cb337,24432640,40251392,0,0,402653184,0 +1791624098,grocy,086e0c6cb337,24432640,39530496,0,0,402653184,0 +1791624100,grocy,086e0c6cb337,23543808,39714816,0,0,402653184,0 +1791624100,grocy,086e0c6cb337,23543808,39714816,0,0,402653184,0 +1791624102,grocy,086e0c6cb337,24616960,40734720,0,0,402653184,0 +1791624102,grocy,086e0c6cb337,24616960,40734720,0,0,402653184,0 +1791624104,grocy,086e0c6cb337,24416256,41074688,0,0,402653184,0 +1791624104,grocy,086e0c6cb337,24416256,41074688,0,0,402653184,0 +1791624106,grocy,086e0c6cb337,23818240,40669184,0,0,402653184,0 +1791624106,grocy,086e0c6cb337,24412160,41091072,0,0,402653184,0 +1791624108,grocy,086e0c6cb337,23531520,39854080,0,0,402653184,0 +1791624108,grocy,086e0c6cb337,23531520,39854080,0,0,402653184,0 +1791624110,grocy,086e0c6cb337,23531520,39497728,0,0,402653184,0 +1791624110,grocy,086e0c6cb337,23531520,39497728,0,0,402653184,0 +1791624112,grocy,086e0c6cb337,23531520,39714816,0,0,402653184,0 +1791624112,grocy,086e0c6cb337,23531520,39714816,0,0,402653184,0 +1791624114,grocy,086e0c6cb337,25407488,41996288,0,0,402653184,0 +1791624114,grocy,086e0c6cb337,25407488,41996288,0,0,402653184,0 +1791624116,grocy,086e0c6cb337,23613440,39895040,0,0,402653184,0 +1791624116,grocy,086e0c6cb337,23613440,39895040,0,0,402653184,0 +1791624118,grocy,086e0c6cb337,23613440,39804928,0,0,402653184,0 +1791624118,grocy,086e0c6cb337,23613440,39804928,0,0,402653184,0 +1791624120,grocy,086e0c6cb337,23621632,40308736,0,0,402653184,0 +1791624120,grocy,086e0c6cb337,23621632,40308736,0,0,402653184,0 +1791624122,grocy,086e0c6cb337,24346624,40808448,0,0,402653184,0 +1791624122,grocy,086e0c6cb337,24346624,40808448,0,0,402653184,0 +1791624125,grocy,086e0c6cb337,24551424,40787968,0,0,402653184,0 +1791624125,grocy,086e0c6cb337,24551424,40787968,0,0,402653184,0 +1791624127,grocy,086e0c6cb337,23289856,39505920,0,0,402653184,0 +1791624127,grocy,086e0c6cb337,23289856,39448576,0,0,402653184,0 +1791624129,grocy,086e0c6cb337,23289856,39473152,0,0,402653184,0 +1791624129,grocy,086e0c6cb337,23289856,39473152,0,0,402653184,0 +1791624131,grocy,086e0c6cb337,23289856,39620608,0,0,402653184,0 +1791624131,grocy,086e0c6cb337,23289856,39620608,0,0,402653184,0 +1791624133,grocy,086e0c6cb337,26730496,43491328,0,0,402653184,0 +1791624133,grocy,086e0c6cb337,26730496,43491328,0,0,402653184,0 +1791624135,grocy,086e0c6cb337,25276416,41537536,0,0,402653184,0 +1791624135,grocy,086e0c6cb337,25276416,41701376,0,0,402653184,0 +1791624137,grocy,086e0c6cb337,25628672,42029056,0,0,402653184,0 +1791624137,grocy,086e0c6cb337,25628672,42029056,0,0,402653184,0 +1791624139,grocy,086e0c6cb337,23105536,39280640,0,0,402653184,0 +1791624139,grocy,086e0c6cb337,23105536,39280640,0,0,402653184,0 +1791624141,grocy,086e0c6cb337,23105536,39411712,0,0,402653184,0 +1791624141,grocy,086e0c6cb337,23105536,39411712,0,0,402653184,0 +1791624143,grocy,086e0c6cb337,23109632,39755776,0,0,402653184,0 +1791624143,grocy,086e0c6cb337,23109632,39755776,0,0,402653184,0 +1791624145,grocy,086e0c6cb337,25247744,41873408,0,0,402653184,0 +1791624145,grocy,086e0c6cb337,25247744,41852928,0,0,402653184,0 +1791624147,grocy,086e0c6cb337,24178688,40984576,0,0,402653184,0 +1791624147,grocy,086e0c6cb337,25759744,41771008,0,0,402653184,0 +1791624149,grocy,086e0c6cb337,23109632,39600128,0,0,402653184,0 +1791624149,grocy,086e0c6cb337,23109632,40022016,0,0,402653184,0 +1791624151,grocy,086e0c6cb337,23113728,39763968,0,0,402653184,0 +1791624151,grocy,086e0c6cb337,23113728,39763968,0,0,402653184,0 +1791624154,grocy,086e0c6cb337,23113728,39178240,0,0,402653184,0 +1791624154,grocy,086e0c6cb337,24182784,40370176,0,0,402653184,0 +1791624156,grocy,086e0c6cb337,25251840,42184704,0,0,402653184,0 +1791624156,grocy,086e0c6cb337,25235456,42061824,0,0,402653184,0 +1791624158,grocy,086e0c6cb337,23064576,39440384,0,0,402653184,0 +1791624158,grocy,086e0c6cb337,23064576,39440384,0,0,402653184,0 +1791624160,grocy,086e0c6cb337,23232512,39370752,0,0,402653184,0 +1791624160,grocy,086e0c6cb337,23232512,39370752,0,0,402653184,0 +1791624162,grocy,086e0c6cb337,23236608,39235584,0,0,402653184,0 +1791624162,grocy,086e0c6cb337,23236608,39235584,0,0,402653184,0 +1791624164,grocy,086e0c6cb337,23236608,39616512,0,0,402653184,0 +1791624164,grocy,086e0c6cb337,23236608,39616512,0,0,402653184,0 +1791624166,grocy,086e0c6cb337,25407488,42192896,0,0,402653184,0 +1791624166,grocy,086e0c6cb337,25407488,42192896,0,0,402653184,0 +1791624168,grocy,086e0c6cb337,24305664,40460288,0,0,402653184,0 +1791624168,grocy,086e0c6cb337,24305664,40460288,0,0,402653184,0 +1791624170,grocy,086e0c6cb337,23236608,39378944,0,0,402653184,0 +1791624170,grocy,086e0c6cb337,23236608,39378944,0,0,402653184,0 +1791624172,grocy,086e0c6cb337,23281664,39579648,0,0,402653184,0 +1791624172,grocy,086e0c6cb337,23281664,39579648,0,0,402653184,0 +1791624174,grocy,086e0c6cb337,23289856,39473152,0,0,402653184,0 +1791624174,grocy,086e0c6cb337,23289856,39473152,0,0,402653184,0 +1791624176,grocy,086e0c6cb337,24186880,40427520,0,0,402653184,0 +1791624176,grocy,086e0c6cb337,24186880,40460288,0,0,402653184,0 +1791624178,grocy,086e0c6cb337,25227264,41574400,0,0,402653184,0 +1791624178,grocy,086e0c6cb337,25407488,42287104,0,0,402653184,0 +1791624180,grocy,086e0c6cb337,23293952,39780352,0,0,402653184,0 +1791624180,grocy,086e0c6cb337,23293952,39780352,0,0,402653184,0 +1791624182,grocy,086e0c6cb337,23298048,39735296,0,0,402653184,0 +1791624182,grocy,086e0c6cb337,23298048,39735296,0,0,402653184,0 +1791624185,grocy,086e0c6cb337,23298048,39604224,0,0,402653184,0 +1791624185,grocy,086e0c6cb337,23298048,39604224,0,0,402653184,0 +1791624187,grocy,086e0c6cb337,24399872,40763392,0,0,402653184,0 +1791624187,grocy,086e0c6cb337,23298048,39833600,0,0,402653184,0 +1791624189,grocy,086e0c6cb337,24535040,40837120,0,0,402653184,0 +1791624189,grocy,086e0c6cb337,24535040,41795584,0,0,402653184,0 +1791624191,grocy,086e0c6cb337,24350720,41037824,0,0,402653184,0 +1791624191,grocy,086e0c6cb337,24350720,41037824,0,0,402653184,0 +1791624193,grocy,086e0c6cb337,23470080,40325120,0,0,402653184,0 +1791624193,grocy,086e0c6cb337,23470080,40325120,0,0,402653184,0 +1791624195,grocy,086e0c6cb337,26910720,43982848,0,0,402653184,0 +1791624195,grocy,086e0c6cb337,26910720,43900928,0,0,402653184,0 +1791624197,grocy,086e0c6cb337,23412736,40140800,0,0,402653184,0 +1791624197,grocy,086e0c6cb337,23412736,40140800,0,0,402653184,0 +1791624199,grocy,086e0c6cb337,23638016,40484864,0,0,402653184,0 +1791624199,grocy,086e0c6cb337,23638016,41451520,0,0,402653184,0 +1791624201,grocy,086e0c6cb337,23457792,39956480,0,0,402653184,0 +1791624201,grocy,086e0c6cb337,23457792,39956480,0,0,402653184,0 +1791624203,grocy,086e0c6cb337,23232512,39567360,0,0,402653184,0 +1791624203,grocy,086e0c6cb337,23232512,39567360,0,0,402653184,0 +1791624205,grocy,086e0c6cb337,23232512,39346176,0,0,402653184,0 +1791624205,grocy,086e0c6cb337,23232512,39346176,0,0,402653184,0 +1791624207,grocy,086e0c6cb337,23232512,39698432,0,0,402653184,0 +1791624207,grocy,086e0c6cb337,23232512,39698432,0,0,402653184,0 +1791624209,grocy,086e0c6cb337,23240704,39550976,0,0,402653184,0 +1791624209,grocy,086e0c6cb337,23240704,39555072,0,0,402653184,0 +1791624211,grocy,086e0c6cb337,23240704,39649280,0,0,402653184,0 +1791624211,grocy,086e0c6cb337,23240704,39649280,0,0,402653184,0 +1791624213,grocy,086e0c6cb337,23293952,39727104,0,0,402653184,0 +1791624213,grocy,086e0c6cb337,23293952,39727104,0,0,402653184,0 +1791624216,grocy,086e0c6cb337,23306240,39354368,0,0,402653184,0 +1791624216,grocy,086e0c6cb337,23306240,39350272,0,0,402653184,0 +1791624218,grocy,086e0c6cb337,23306240,39944192,0,0,402653184,0 +1791624218,grocy,086e0c6cb337,23306240,40210432,0,0,402653184,0 +1791624220,grocy,086e0c6cb337,23298048,39456768,0,0,402653184,0 +1791624220,grocy,086e0c6cb337,23298048,39456768,0,0,402653184,0 +1791624222,grocy,086e0c6cb337,25415680,42143744,0,0,402653184,0 +1791624222,grocy,086e0c6cb337,25415680,42143744,0,0,402653184,0 +1791624224,grocy,086e0c6cb337,23584768,40402944,0,0,402653184,0 +1791624224,grocy,086e0c6cb337,24301568,40898560,0,0,402653184,0 +1791624226,grocy,086e0c6cb337,23293952,39923712,0,0,402653184,0 +1791624226,grocy,086e0c6cb337,23293952,39923712,0,0,402653184,0 +1791624228,grocy,086e0c6cb337,23298048,39927808,0,0,402653184,0 +1791624228,grocy,086e0c6cb337,23298048,39927808,0,0,402653184,0 +1791624230,grocy,086e0c6cb337,23298048,40013824,0,0,402653184,0 +1791624230,grocy,086e0c6cb337,23298048,39936000,0,0,402653184,0 +1791624232,grocy,086e0c6cb337,26214400,42909696,0,0,402653184,0 +1791624232,grocy,086e0c6cb337,26214400,42045440,0,0,402653184,0 +1791624234,grocy,086e0c6cb337,23298048,40296448,0,0,402653184,0 +1791624234,grocy,086e0c6cb337,23298048,40296448,0,0,402653184,0 +1791624236,grocy,086e0c6cb337,23461888,40628224,0,0,402653184,0 +1791624236,grocy,086e0c6cb337,24358912,41377792,0,0,402653184,0 +1791624238,grocy,086e0c6cb337,23293952,39583744,0,0,402653184,0 +1791624238,grocy,086e0c6cb337,23293952,39583744,0,0,402653184,0 +1791624240,grocy,086e0c6cb337,23298048,39583744,0,0,402653184,0 +1791624240,grocy,086e0c6cb337,23298048,39583744,0,0,402653184,0 +1791624242,grocy,086e0c6cb337,23298048,40210432,0,0,402653184,0 +1791624242,grocy,086e0c6cb337,23298048,40210432,0,0,402653184,0 +1791624244,grocy,086e0c6cb337,23298048,39768064,0,0,402653184,0 +1791624244,grocy,086e0c6cb337,23298048,39768064,0,0,402653184,0 +1791624247,grocy,086e0c6cb337,23298048,40013824,0,0,402653184,0 +1791624247,grocy,086e0c6cb337,23298048,40013824,0,0,402653184,0 +1791624249,grocy,086e0c6cb337,23298048,39661568,0,0,402653184,0 +1791624249,grocy,086e0c6cb337,23298048,39661568,0,0,402653184,0 +1791624251,grocy,086e0c6cb337,24190976,41156608,0,0,402653184,0 +1791624251,grocy,086e0c6cb337,24190976,41156608,0,0,402653184,0 +1791624253,grocy,086e0c6cb337,25243648,41730048,0,0,402653184,0 +1791624253,grocy,086e0c6cb337,25243648,41730048,0,0,402653184,0 +1791624255,grocy,086e0c6cb337,24367104,40853504,0,0,402653184,0 +1791624255,grocy,086e0c6cb337,24367104,40853504,0,0,402653184,0 +1791624257,grocy,086e0c6cb337,23298048,39354368,0,0,402653184,0 +1791624257,grocy,086e0c6cb337,23298048,39354368,0,0,402653184,0 +1791624259,grocy,086e0c6cb337,24166400,40960000,0,0,402653184,0 +1791624259,grocy,086e0c6cb337,24166400,40181760,0,0,402653184,0 +1791624261,grocy,086e0c6cb337,23298048,40341504,0,0,402653184,0 +1791624261,grocy,086e0c6cb337,23912448,41197568,0,0,402653184,0 +1791624263,grocy,086e0c6cb337,24387584,40534016,0,0,402653184,0 +1791624263,grocy,086e0c6cb337,23298048,39780352,0,0,402653184,0 +1791624265,grocy,086e0c6cb337,24383488,41299968,0,0,402653184,0 +1791624265,grocy,086e0c6cb337,25436160,42041344,0,0,402653184,0 +1791624267,grocy,086e0c6cb337,24367104,41070592,0,0,402653184,0 +1791624267,grocy,086e0c6cb337,24367104,41070592,0,0,402653184,0 +1791624269,grocy,086e0c6cb337,23298048,39702528,0,0,402653184,0 +1791624269,grocy,086e0c6cb337,23298048,39702528,0,0,402653184,0 +1791624271,grocy,086e0c6cb337,23298048,40296448,0,0,402653184,0 +1791624271,grocy,086e0c6cb337,23298048,40296448,0,0,402653184,0 +1791624273,grocy,086e0c6cb337,23298048,39714816,0,0,402653184,0 +1791624273,grocy,086e0c6cb337,23298048,39714816,0,0,402653184,0 +1791624276,grocy,086e0c6cb337,23298048,39809024,0,0,402653184,0 +1791624276,grocy,086e0c6cb337,23298048,39809024,0,0,402653184,0 +1791624278,grocy,086e0c6cb337,26312704,43302912,0,0,402653184,0 +1791624278,grocy,086e0c6cb337,26312704,43302912,0,0,402653184,0 +1791624280,grocy,086e0c6cb337,23363584,39624704,0,0,402653184,0 +1791624280,grocy,086e0c6cb337,23363584,39624704,0,0,402653184,0 +1791624282,grocy,086e0c6cb337,23306240,39710720,0,0,402653184,0 +1791624282,grocy,086e0c6cb337,23306240,39710720,0,0,402653184,0 +1791624284,grocy,086e0c6cb337,23306240,39751680,0,0,402653184,0 +1791624284,grocy,086e0c6cb337,23306240,39751680,0,0,402653184,0 +1791624286,grocy,086e0c6cb337,23334912,39649280,0,0,402653184,0 +1791624286,grocy,086e0c6cb337,23334912,39649280,0,0,402653184,0 +1791624288,grocy,086e0c6cb337,25784320,42655744,0,0,402653184,0 +1791624288,grocy,086e0c6cb337,25022464,42151936,0,0,402653184,0 +1791624290,grocy,086e0c6cb337,24117248,39264256,0,0,402653184,0 +1791624290,grocy,086e0c6cb337,23334912,39264256,0,0,402653184,0 +1791624292,grocy,086e0c6cb337,23334912,40259584,0,0,402653184,0 +1791624292,grocy,086e0c6cb337,23334912,40259584,0,0,402653184,0 +1791624294,grocy,086e0c6cb337,23334912,40017920,0,0,402653184,0 +1791624294,grocy,086e0c6cb337,23334912,40017920,0,0,402653184,0 +1791624296,grocy,086e0c6cb337,23334912,40329216,0,0,402653184,0 +1791624296,grocy,086e0c6cb337,23334912,40329216,0,0,402653184,0 +1791624298,grocy,086e0c6cb337,24731648,41684992,0,0,402653184,0 +1791624298,grocy,086e0c6cb337,25268224,40939520,0,0,402653184,0 +1791624300,grocy,086e0c6cb337,23334912,39370752,0,0,402653184,0 +1791624300,grocy,086e0c6cb337,24674304,41750528,0,0,402653184,0 +1791624302,grocy,086e0c6cb337,23339008,40058880,0,0,402653184,0 +1791624302,grocy,086e0c6cb337,23339008,40058880,0,0,402653184,0 +1791624304,grocy,086e0c6cb337,23339008,39919616,0,0,402653184,0 +1791624304,grocy,086e0c6cb337,23339008,39907328,0,0,402653184,0 +1791624307,grocy,086e0c6cb337,25993216,40828928,0,0,402653184,0 +1791624307,grocy,086e0c6cb337,23339008,39833600,0,0,402653184,0 +1791624309,grocy,086e0c6cb337,23285760,40161280,0,0,402653184,0 +1791624309,grocy,086e0c6cb337,24244224,41353216,0,0,402653184,0 +1791624311,grocy,086e0c6cb337,23527424,40255488,0,0,402653184,0 +1791624311,grocy,086e0c6cb337,24412160,40923136,0,0,402653184,0 +1791624313,grocy,086e0c6cb337,23556096,39546880,0,0,402653184,0 +1791624313,grocy,086e0c6cb337,23556096,39546880,0,0,402653184,0 +1791624315,grocy,086e0c6cb337,23556096,39882752,0,0,402653184,0 +1791624315,grocy,086e0c6cb337,23556096,39882752,0,0,402653184,0 +1791624317,grocy,086e0c6cb337,23556096,39927808,0,0,402653184,0 +1791624317,grocy,086e0c6cb337,23556096,39927808,0,0,402653184,0 +1791624319,grocy,086e0c6cb337,24453120,41242624,0,0,402653184,0 +1791624319,grocy,086e0c6cb337,24453120,41439232,0,0,402653184,0 +1791624321,grocy,086e0c6cb337,23552000,40067072,0,0,402653184,0 +1791624321,grocy,086e0c6cb337,23552000,40067072,0,0,402653184,0 +1791624323,grocy,086e0c6cb337,23625728,40247296,0,0,402653184,0 +1791624323,grocy,086e0c6cb337,23625728,40247296,0,0,402653184,0 +1791624325,grocy,086e0c6cb337,23629824,39858176,0,0,402653184,0 +1791624325,grocy,086e0c6cb337,23629824,39858176,0,0,402653184,0 +1791624327,grocy,086e0c6cb337,25432064,42307584,0,0,402653184,0 +1791624327,grocy,086e0c6cb337,25432064,41451520,0,0,402653184,0 +1791624329,grocy,086e0c6cb337,23629824,40316928,0,0,402653184,0 +1791624329,grocy,086e0c6cb337,23629824,40316928,0,0,402653184,0 +1791624331,grocy,086e0c6cb337,23629824,39964672,0,0,402653184,0 +1791624331,grocy,086e0c6cb337,23629824,39964672,0,0,402653184,0 +1791624333,grocy,086e0c6cb337,23629824,40554496,0,0,402653184,0 +1791624333,grocy,086e0c6cb337,23629824,40554496,0,0,402653184,0 +1791624335,grocy,086e0c6cb337,24629248,41414656,0,0,402653184,0 +1791624335,grocy,086e0c6cb337,24629248,40673280,0,0,402653184,0 +1791624337,grocy,086e0c6cb337,24035328,40804352,0,0,402653184,0 +1791624338,grocy,086e0c6cb337,24629248,41304064,0,0,402653184,0 +1791624340,grocy,086e0c6cb337,24530944,41197568,0,0,402653184,0 +1791624340,grocy,086e0c6cb337,23855104,40468480,0,0,402653184,0 +1791624342,grocy,086e0c6cb337,24625152,41172992,0,0,402653184,0 +1791624342,grocy,086e0c6cb337,23633920,40247296,0,0,402653184,0 +1791624344,grocy,086e0c6cb337,23633920,40321024,0,0,402653184,0 +1791624344,grocy,086e0c6cb337,23633920,40321024,0,0,402653184,0 +1791624346,grocy,086e0c6cb337,24625152,41443328,0,0,402653184,0 +1791624346,grocy,086e0c6cb337,24625152,41443328,0,0,402653184,0 +1791624348,grocy,086e0c6cb337,24530944,41308160,0,0,402653184,0 +1791624348,grocy,086e0c6cb337,24530944,41795584,0,0,402653184,0 +1791624350,grocy,086e0c6cb337,24530944,41082880,0,0,402653184,0 +1791624350,grocy,086e0c6cb337,24530944,41082880,0,0,402653184,0 +1791624352,grocy,086e0c6cb337,23629824,40136704,0,0,402653184,0 +1791624352,grocy,086e0c6cb337,23629824,40136704,0,0,402653184,0 +1791624354,grocy,086e0c6cb337,23633920,40333312,0,0,402653184,0 +1791624354,grocy,086e0c6cb337,23633920,40333312,0,0,402653184,0 +1791624356,grocy,086e0c6cb337,24625152,41000960,0,0,402653184,0 +1791624356,grocy,086e0c6cb337,24625152,41000960,0,0,402653184,0 +1791624358,grocy,086e0c6cb337,24530944,41144320,0,0,402653184,0 +1791624358,grocy,086e0c6cb337,24530944,41144320,0,0,402653184,0 +1791624360,grocy,086e0c6cb337,23633920,40022016,0,0,402653184,0 +1791624360,grocy,086e0c6cb337,23633920,40022016,0,0,402653184,0 +1791624362,grocy,086e0c6cb337,23822336,41086976,0,0,402653184,0 +1791624362,grocy,086e0c6cb337,24530944,41566208,0,0,402653184,0 +1791624364,grocy,086e0c6cb337,23633920,40562688,0,0,402653184,0 +1791624364,grocy,086e0c6cb337,23633920,40562688,0,0,402653184,0 +1791624366,grocy,086e0c6cb337,24530944,41455616,0,0,402653184,0 +1791624366,grocy,086e0c6cb337,24530944,41455616,0,0,402653184,0 +1791624369,grocy,086e0c6cb337,23633920,40361984,0,0,402653184,0 +1791624369,grocy,086e0c6cb337,23633920,40361984,0,0,402653184,0 +1791624371,grocy,086e0c6cb337,25395200,41451520,0,0,402653184,0 +1791624371,grocy,086e0c6cb337,25395200,41426944,0,0,402653184,0 +1791624373,grocy,086e0c6cb337,24014848,40804352,0,0,402653184,0 +1791624373,grocy,086e0c6cb337,24014848,41054208,0,0,402653184,0 +1791624375,grocy,086e0c6cb337,23805952,40337408,0,0,402653184,0 +1791624375,grocy,086e0c6cb337,23805952,40337408,0,0,402653184,0 +1791624377,grocy,086e0c6cb337,23805952,40382464,0,0,402653184,0 +1791624377,grocy,086e0c6cb337,23805952,40382464,0,0,402653184,0 +1791624379,grocy,086e0c6cb337,24940544,42057728,0,0,402653184,0 +1791624379,grocy,086e0c6cb337,25251840,41689088,0,0,402653184,0 +1791624381,grocy,086e0c6cb337,23805952,40357888,0,0,402653184,0 +1791624381,grocy,086e0c6cb337,23805952,41017344,0,0,402653184,0 +1791624383,grocy,086e0c6cb337,23805952,40493056,0,0,402653184,0 +1791624383,grocy,086e0c6cb337,23805952,40480768,0,0,402653184,0 +1791624385,grocy,086e0c6cb337,23805952,40427520,0,0,402653184,0 +1791624385,grocy,086e0c6cb337,23805952,40427520,0,0,402653184,0 +1791624387,grocy,086e0c6cb337,24702976,41668608,0,0,402653184,0 +1791624387,grocy,086e0c6cb337,23805952,41021440,0,0,402653184,0 +1791624389,grocy,086e0c6cb337,23805952,40271872,0,0,402653184,0 +1791624389,grocy,086e0c6cb337,24702976,41451520,0,0,402653184,0 +1791624391,grocy,086e0c6cb337,25575424,42606592,0,0,402653184,0 +1791624391,grocy,086e0c6cb337,23805952,41078784,0,0,402653184,0 +1791624393,grocy,086e0c6cb337,24678400,41791488,0,0,402653184,0 +1791624393,grocy,086e0c6cb337,23805952,41177088,0,0,402653184,0 +1791624395,grocy,086e0c6cb337,23666688,41185280,0,0,402653184,0 +1791624395,grocy,086e0c6cb337,24510464,41795584,0,0,402653184,0 +1791624397,grocy,086e0c6cb337,23506944,40017920,0,0,402653184,0 +1791624397,grocy,086e0c6cb337,23506944,39833600,0,0,402653184,0 +1791624399,grocy,086e0c6cb337,23498752,40026112,0,0,402653184,0 +1791624399,grocy,086e0c6cb337,23498752,40026112,0,0,402653184,0 +1791624402,grocy,086e0c6cb337,24694784,41697280,0,0,402653184,0 +1791624402,grocy,086e0c6cb337,23621632,40615936,0,0,402653184,0 +1791624404,grocy,086e0c6cb337,24686592,41701376,0,0,402653184,0 +1791624404,grocy,086e0c6cb337,25260032,41816064,0,0,402653184,0 +1791624406,grocy,086e0c6cb337,23621632,40206336,0,0,402653184,0 +1791624406,grocy,086e0c6cb337,23621632,40206336,0,0,402653184,0 +1791624408,grocy,086e0c6cb337,24129536,40665088,0,0,402653184,0 +1791624408,grocy,086e0c6cb337,24129536,40656896,0,0,402653184,0 +1791624410,grocy,086e0c6cb337,23629824,40255488,0,0,402653184,0 +1791624410,grocy,086e0c6cb337,23629824,40255488,0,0,402653184,0 +1791624412,grocy,086e0c6cb337,23633920,40620032,0,0,402653184,0 +1791624412,grocy,086e0c6cb337,23633920,40620032,0,0,402653184,0 +1791624414,grocy,086e0c6cb337,25165824,42438656,0,0,402653184,0 +1791624414,grocy,086e0c6cb337,24530944,41562112,0,0,402653184,0 +1791624416,grocy,086e0c6cb337,26128384,43220992,0,0,402653184,0 +1791624416,grocy,086e0c6cb337,26128384,43220992,0,0,402653184,0 +1791624418,grocy,086e0c6cb337,23281664,40009728,0,0,402653184,0 +1791624418,grocy,086e0c6cb337,23281664,40009728,0,0,402653184,0 +1791624420,grocy,086e0c6cb337,23285760,40292352,0,0,402653184,0 +1791624420,grocy,086e0c6cb337,23285760,40292352,0,0,402653184,0 +1791624422,grocy,086e0c6cb337,23302144,40361984,0,0,402653184,0 +1791624422,grocy,086e0c6cb337,23302144,40357888,0,0,402653184,0 +1791624424,grocy,086e0c6cb337,25698304,43569152,0,0,402653184,0 +1791624424,grocy,086e0c6cb337,26357760,43560960,0,0,402653184,0 +1791624426,grocy,086e0c6cb337,23334912,40243200,0,0,402653184,0 +1791624426,grocy,086e0c6cb337,23334912,40243200,0,0,402653184,0 +1791624428,grocy,086e0c6cb337,25923584,43065344,0,0,402653184,0 +1791624428,grocy,086e0c6cb337,25923584,43065344,0,0,402653184,0 +1791624430,grocy,086e0c6cb337,23277568,40345600,0,0,402653184,0 +1791624430,grocy,086e0c6cb337,23277568,40345600,0,0,402653184,0 +1791624433,grocy,086e0c6cb337,26329088,43171840,0,0,402653184,0 +1791624433,grocy,086e0c6cb337,26329088,41938944,0,0,402653184,0 +1791624435,grocy,086e0c6cb337,23609344,40734720,0,0,402653184,0 +1791624435,grocy,086e0c6cb337,24227840,41234432,0,0,402653184,0 +1791624437,grocy,086e0c6cb337,23285760,40153088,0,0,402653184,0 +1791624437,grocy,086e0c6cb337,23285760,40153088,0,0,402653184,0 +1791624439,grocy,086e0c6cb337,23285760,40497152,0,0,402653184,0 +1791624439,grocy,086e0c6cb337,23285760,40497152,0,0,402653184,0 +1791624441,grocy,086e0c6cb337,23285760,40423424,0,0,402653184,0 +1791624441,grocy,086e0c6cb337,23285760,40423424,0,0,402653184,0 +1791624443,grocy,086e0c6cb337,25706496,43360256,0,0,402653184,0 +1791624443,grocy,086e0c6cb337,25260032,42717184,0,0,402653184,0 +1791624445,grocy,086e0c6cb337,24166400,41111552,0,0,402653184,0 +1791624445,grocy,086e0c6cb337,24166400,41111552,0,0,402653184,0 +1791624447,grocy,086e0c6cb337,27693056,45121536,0,0,402653184,0 +1791624447,grocy,086e0c6cb337,27693056,45121536,0,0,402653184,0 +1791624449,grocy,086e0c6cb337,23060480,40194048,0,0,402653184,0 +1791624449,grocy,086e0c6cb337,23060480,40194048,0,0,402653184,0 +1791624451,grocy,086e0c6cb337,23064576,40185856,0,0,402653184,0 +1791624451,grocy,086e0c6cb337,23064576,40185856,0,0,402653184,0 +1791624453,grocy,086e0c6cb337,23064576,40038400,0,0,402653184,0 +1791624453,grocy,086e0c6cb337,23064576,40038400,0,0,402653184,0 +1791624455,grocy,086e0c6cb337,23060480,39563264,0,0,402653184,0 +1791624455,grocy,086e0c6cb337,23060480,39563264,0,0,402653184,0 +1791624457,grocy,086e0c6cb337,24199168,41320448,0,0,402653184,0 +1791624457,grocy,086e0c6cb337,24199168,41816064,0,0,402653184,0 +1791624459,grocy,086e0c6cb337,24186880,41664512,0,0,402653184,0 +1791624459,grocy,086e0c6cb337,24186880,41664512,0,0,402653184,0 +1791624462,grocy,086e0c6cb337,23281664,39985152,0,0,402653184,0 +1791624462,grocy,086e0c6cb337,23281664,39772160,0,0,402653184,0 +1791624464,grocy,086e0c6cb337,24354816,41115648,0,0,402653184,0 +1791624464,grocy,086e0c6cb337,24354816,40337408,0,0,402653184,0 +1791624466,grocy,086e0c6cb337,23289856,39833600,0,0,402653184,0 +1791624466,grocy,086e0c6cb337,24313856,41025536,0,0,402653184,0 +1791624468,grocy,086e0c6cb337,23285760,40472576,0,0,402653184,0 +1791624468,grocy,086e0c6cb337,23285760,40656896,0,0,402653184,0 +1791624470,grocy,086e0c6cb337,23236608,40443904,0,0,402653184,0 +1791624470,grocy,086e0c6cb337,23236608,40312832,0,0,402653184,0 +1791624472,grocy,086e0c6cb337,23248896,40550400,0,0,402653184,0 +1791624472,grocy,086e0c6cb337,25362432,42692608,0,0,402653184,0 +1791624474,grocy,086e0c6cb337,23097344,40161280,0,0,402653184,0 +1791624474,grocy,086e0c6cb337,23097344,40161280,0,0,402653184,0 +1791624476,grocy,086e0c6cb337,23097344,40030208,0,0,402653184,0 +1791624476,grocy,086e0c6cb337,23097344,40030208,0,0,402653184,0 +1791624478,grocy,086e0c6cb337,24166400,41627648,0,0,402653184,0 +1791624478,grocy,086e0c6cb337,23097344,40550400,0,0,402653184,0 +1791624480,grocy,086e0c6cb337,25268224,42287104,0,0,402653184,0 +1791624480,grocy,086e0c6cb337,24166400,41349120,0,0,402653184,0 +1791624482,grocy,086e0c6cb337,23097344,39759872,0,0,402653184,0 +1791624482,grocy,086e0c6cb337,24408064,42127360,0,0,402653184,0 +1791624484,grocy,086e0c6cb337,23097344,40583168,0,0,402653184,0 +1791624484,grocy,086e0c6cb337,24166400,41500672,0,0,402653184,0 +1791624486,grocy,086e0c6cb337,23101440,40779776,0,0,402653184,0 +1791624486,grocy,086e0c6cb337,23101440,40685568,0,0,402653184,0 +1791624488,grocy,086e0c6cb337,23048192,40169472,0,0,402653184,0 +1791624488,grocy,086e0c6cb337,23048192,40169472,0,0,402653184,0 +1791624490,grocy,086e0c6cb337,24469504,42151936,0,0,402653184,0 +1791624490,grocy,086e0c6cb337,23101440,40390656,0,0,402653184,0 +1791624492,grocy,086e0c6cb337,23224320,40595456,0,0,402653184,0 +1791624493,grocy,086e0c6cb337,23224320,40337408,0,0,402653184,0 +1791624495,grocy,086e0c6cb337,24297472,41353216,0,0,402653184,0 +1791624495,grocy,086e0c6cb337,23224320,40005632,0,0,402653184,0 +1791624497,grocy,086e0c6cb337,23007232,40058880,0,0,402653184,0 +1791624497,grocy,086e0c6cb337,23007232,40058880,0,0,402653184,0 +1791624499,grocy,086e0c6cb337,24092672,40935424,0,0,402653184,0 +1791624499,grocy,086e0c6cb337,24805376,41885696,0,0,402653184,0 +1791624501,grocy,086e0c6cb337,23113728,39936000,0,0,402653184,0 +1791624501,grocy,086e0c6cb337,24182784,41115648,0,0,402653184,0 +1791624503,grocy,086e0c6cb337,23113728,40468480,0,0,402653184,0 +1791624503,grocy,086e0c6cb337,23113728,40423424,0,0,402653184,0 +1791624505,grocy,086e0c6cb337,23113728,40390656,0,0,402653184,0 +1791624505,grocy,086e0c6cb337,23113728,40382464,0,0,402653184,0 +1791624507,grocy,086e0c6cb337,23113728,40337408,0,0,402653184,0 +1791624507,grocy,086e0c6cb337,23113728,40267776,0,0,402653184,0 +1791624509,grocy,086e0c6cb337,24137728,41738240,0,0,402653184,0 +1791624509,grocy,086e0c6cb337,23117824,40718336,0,0,402653184,0 +1791624511,grocy,086e0c6cb337,24068096,41537536,0,0,402653184,0 +1791624511,grocy,086e0c6cb337,24944640,42098688,0,0,402653184,0 +1791624513,grocy,086e0c6cb337,23060480,40353792,0,0,402653184,0 +1791624513,grocy,086e0c6cb337,23060480,40353792,0,0,402653184,0 +1791624515,grocy,086e0c6cb337,23322624,40943616,0,0,402653184,0 +1791624515,grocy,086e0c6cb337,24133632,41439232,0,0,402653184,0 +1791624517,grocy,086e0c6cb337,23060480,40288256,0,0,402653184,0 +1791624517,grocy,086e0c6cb337,23060480,40288256,0,0,402653184,0 +1791624519,grocy,086e0c6cb337,23060480,40341504,0,0,402653184,0 +1791624519,grocy,086e0c6cb337,23060480,40341504,0,0,402653184,0 +1791624521,grocy,086e0c6cb337,23236608,40525824,0,0,402653184,0 +1791624521,grocy,086e0c6cb337,23236608,40525824,0,0,402653184,0 +1791624523,grocy,086e0c6cb337,24371200,41521152,0,0,402653184,0 +1791624524,grocy,086e0c6cb337,24371200,40636416,0,0,402653184,0 +1791624526,grocy,086e0c6cb337,24236032,41410560,0,0,402653184,0 +1791624526,grocy,086e0c6cb337,25243648,42422272,0,0,402653184,0 +1791624528,grocy,086e0c6cb337,24170496,41377792,0,0,402653184,0 +1791624528,grocy,086e0c6cb337,24170496,41377792,0,0,402653184,0 +1791624530,grocy,086e0c6cb337,23289856,40583168,0,0,402653184,0 +1791624530,grocy,086e0c6cb337,23289856,40583168,0,0,402653184,0 +1791624532,grocy,086e0c6cb337,23302144,40407040,0,0,402653184,0 +1791624532,grocy,086e0c6cb337,23302144,40407040,0,0,402653184,0 +1791624534,grocy,086e0c6cb337,23285760,40808448,0,0,402653184,0 +1791624534,grocy,086e0c6cb337,23285760,40808448,0,0,402653184,0 +1791624536,grocy,086e0c6cb337,23289856,40960000,0,0,402653184,0 +1791624536,grocy,086e0c6cb337,23289856,40960000,0,0,402653184,0 +1791624538,grocy,086e0c6cb337,23289856,40648704,0,0,402653184,0 +1791624538,grocy,086e0c6cb337,23289856,40648704,0,0,402653184,0 +1791624540,grocy,086e0c6cb337,23298048,41111552,0,0,402653184,0 +1791624540,grocy,086e0c6cb337,23298048,41111552,0,0,402653184,0 +1791624542,grocy,086e0c6cb337,24944640,42020864,0,0,402653184,0 +1791624542,grocy,086e0c6cb337,24944640,42020864,0,0,402653184,0 +1791624544,grocy,086e0c6cb337,25788416,42971136,0,0,402653184,0 +1791624544,grocy,086e0c6cb337,25788416,43233280,0,0,402653184,0 +1791624546,grocy,086e0c6cb337,23293952,40804352,0,0,402653184,0 +1791624546,grocy,086e0c6cb337,23293952,40804352,0,0,402653184,0 +1791624548,grocy,086e0c6cb337,23293952,40595456,0,0,402653184,0 +1791624548,grocy,086e0c6cb337,23293952,40787968,0,0,402653184,0 +1791624550,grocy,086e0c6cb337,23293952,40316928,0,0,402653184,0 +1791624550,grocy,086e0c6cb337,23293952,40316928,0,0,402653184,0 +1791624552,grocy,086e0c6cb337,23465984,41291776,0,0,402653184,0 +1791624552,grocy,086e0c6cb337,23465984,41291776,0,0,402653184,0 +1791624555,grocy,086e0c6cb337,26296320,44072960,0,0,402653184,0 +1791624555,grocy,086e0c6cb337,25866240,43892736,0,0,402653184,0 +1791624557,grocy,086e0c6cb337,23465984,41168896,0,0,402653184,0 +1791624557,grocy,086e0c6cb337,23465984,41168896,0,0,402653184,0 +1791624559,grocy,086e0c6cb337,23465984,41000960,0,0,402653184,0 +1791624559,grocy,086e0c6cb337,23465984,40845312,0,0,402653184,0 +1791624561,grocy,086e0c6cb337,26906624,44302336,0,0,402653184,0 +1791624561,grocy,086e0c6cb337,26906624,44302336,0,0,402653184,0 +1791624563,grocy,086e0c6cb337,24309760,41480192,0,0,402653184,0 +1791624563,grocy,086e0c6cb337,24309760,41480192,0,0,402653184,0 +1791624565,grocy,086e0c6cb337,23429120,40685568,0,0,402653184,0 +1791624565,grocy,086e0c6cb337,23429120,41349120,0,0,402653184,0 +1791624567,grocy,086e0c6cb337,23273472,40726528,0,0,402653184,0 +1791624567,grocy,086e0c6cb337,23273472,40726528,0,0,402653184,0 +1791624569,grocy,086e0c6cb337,23273472,40804352,0,0,402653184,0 +1791624569,grocy,086e0c6cb337,23273472,40804352,0,0,402653184,0 +1791624571,grocy,086e0c6cb337,24821760,42475520,0,0,402653184,0 +1791624571,grocy,086e0c6cb337,24821760,42737664,0,0,402653184,0 +1791624573,grocy,086e0c6cb337,23453696,41074688,0,0,402653184,0 +1791624573,grocy,086e0c6cb337,23453696,41074688,0,0,402653184,0 +1791624575,grocy,086e0c6cb337,23289856,40697856,0,0,402653184,0 +1791624575,grocy,086e0c6cb337,23289856,40693760,0,0,402653184,0 +1791624577,grocy,086e0c6cb337,24354816,42119168,0,0,402653184,0 +1791624577,grocy,086e0c6cb337,24354816,42119168,0,0,402653184,0 +1791624579,grocy,086e0c6cb337,25788416,43503616,0,0,402653184,0 +1791624579,grocy,086e0c6cb337,25788416,43503616,0,0,402653184,0 +1791624581,grocy,086e0c6cb337,23232512,41050112,0,0,402653184,0 +1791624581,grocy,086e0c6cb337,23232512,41050112,0,0,402653184,0 +1791624583,grocy,086e0c6cb337,25726976,43040768,0,0,402653184,0 +1791624583,grocy,086e0c6cb337,25726976,43040768,0,0,402653184,0 +1791624586,grocy,086e0c6cb337,23007232,40300544,0,0,402653184,0 +1791624586,grocy,086e0c6cb337,23007232,40300544,0,0,402653184,0 +1791624588,grocy,086e0c6cb337,98304,5189632,0,0,402653184,0 +1791624588,grocy,086e0c6cb337,98304,5189632,0,0,402653184,0 +1791624590,grocy,086e0c6cb337,98304,4550656,0,0,402653184,0 +1791624590,grocy,086e0c6cb337,98304,4550656,0,0,402653184,0 +1791624592,grocy,83ae98528dae,12955648,22126592,0,0,402653184,0 +1791624592,grocy,83ae98528dae,12955648,22126592,0,0,402653184,0 +1791624594,grocy,83ae98528dae,12955648,21098496,0,0,402653184,0 +1791624594,grocy,83ae98528dae,12955648,21098496,0,0,402653184,0 +1791624596,grocy,83ae98528dae,12955648,21098496,0,0,402653184,0 +1791624596,grocy,83ae98528dae,12955648,21098496,0,0,402653184,0 +1791624598,grocy,83ae98528dae,12955648,21098496,0,0,402653184,0 +1791624598,grocy,83ae98528dae,12955648,21098496,0,0,402653184,0 +1791624600,grocy,83ae98528dae,12955648,21098496,0,0,402653184,0 +1791624600,grocy,83ae98528dae,12955648,21098496,0,0,402653184,0 +1791624602,grocy,83ae98528dae,12955648,21127168,0,0,402653184,0 +1791624602,grocy,83ae98528dae,12955648,21127168,0,0,402653184,0 +1791624604,grocy,83ae98528dae,12959744,21127168,0,0,402653184,0 +1791624604,grocy,83ae98528dae,12959744,21127168,0,0,402653184,0 +1791624606,grocy,83ae98528dae,12959744,21127168,0,0,402653184,0 +1791624606,grocy,83ae98528dae,12959744,21127168,0,0,402653184,0 +1791624608,grocy,83ae98528dae,12959744,21127168,0,0,402653184,0 +1791624608,grocy,83ae98528dae,12959744,21127168,0,0,402653184,0 +1791624610,grocy,83ae98528dae,12959744,21385216,0,0,402653184,0 +1791624610,grocy,83ae98528dae,12959744,21385216,0,0,402653184,0 +1791624612,grocy,83ae98528dae,12959744,21110784,0,0,402653184,0 +1791624612,grocy,83ae98528dae,12959744,21110784,0,0,402653184,0 +1791624614,grocy,83ae98528dae,12959744,21110784,0,0,402653184,0 +1791624614,grocy,83ae98528dae,12959744,21110784,0,0,402653184,0 +1791624616,grocy,83ae98528dae,12959744,21110784,0,0,402653184,0 +1791624616,grocy,83ae98528dae,12959744,21110784,0,0,402653184,0 +1791624619,grocy,83ae98528dae,12959744,21110784,0,0,402653184,0 +1791624619,grocy,83ae98528dae,12959744,21110784,0,0,402653184,0 +1791624621,grocy,83ae98528dae,12959744,21106688,0,0,402653184,0 +1791624621,grocy,83ae98528dae,12959744,21106688,0,0,402653184,0 +1791624623,grocy,83ae98528dae,18657280,33853440,0,0,402653184,0 +1791624623,grocy,83ae98528dae,18657280,33853440,0,0,402653184,0 +1791624625,grocy,83ae98528dae,106496,3837952,0,0,402653184,0 +1791624625,grocy,83ae98528dae,106496,3837952,0,0,402653184,0 diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/partA-probes.txt b/documentation/audits/new-apps-2026-10-10/bench/grocy/partA-probes.txt new file mode 100644 index 00000000..8361702e --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/partA-probes.txt @@ -0,0 +1,185 @@ +########## grocy — bench probes, 2026-10-10T09:41:10Z ########## + +=== 0.3 the image, its tags and its architectures === + lscr.io/linuxserver/grocy:4.7.1 -> [('linux', 'amd64'), ('linux', 'arm64')] + image size: 275077460 bytes (11 layers) + +=== 0.6 / 4.5 the image's ports, volumes, entrypoint, user, healthcheck === + ExposedPorts={"443/tcp":{},"80/tcp":{}} Volumes={"/config":{}} Entrypoint=["/init"] Cmd=null User="" Healthcheck=null + +=== 1.7 every start-time switch: the image's s6 oneshots, and the grocy-specific one in full === +ci-service-check init-adduser init-config init-config-end init-crontab-config init-custom-files init-device-perms init-envfile init-folders init-grocy-config init-keygen init-migrations init-mods init-mods-end init-mods-package-install init-nginx init-nginx-end init-os-end init-permissions init-php init-samples init-services init-version-checks svc-cron svc-nginx svc-php-fpm user user2 +--- init-grocy-config/run: +#!/usr/bin/with-contenv bash +# shellcheck shell=bash + +# create missing cache directory +mkdir -p /app/www/data/viewcache || : + +# create symlinks +i=/app/www/data +if [[ -e "$i" && ! -L "$i" && -e /config/"$(basename "$i")" ]]; then + rm -Rf "$i" + ln -s /config/"$(basename "$i")" "$i" +fi +if [[ -e "$i" && ! -L "$i" ]]; then + mv "$i" /config/"$(basename "$i")" + ln -s /config/"$(basename "$i")" "$i" +fi + +# check for config file and copy default if needed +if [[ ! -f "/config/data/config.php" ]]; then + cp /app/www/config-dist.php /config/data/config.php +fi + +if [[ ! -f "/config/data/plugins/DemoBarcodeLookupPlugin.php" ]]; then + cp -R /defaults/plugins /config/data +fi + +# permissions +lsiown -R abc:abc \ + /config + +=== 4.1 which HTTP clients the image actually carries === + curl /usr/bin/curl + wget /usr/bin/wget + nc /usr/bin/nc + python3 MISSING + perl MISSING + ruby MISSING + node MISSING + bash /bin/bash + awk /usr/bin/awk + sed /bin/sed + openssl /usr/bin/openssl + sqlite3 MISSING + php /usr/bin/php + +=== 1.6 / 3.2 the hashing grocy itself uses, as the image reports it === +PHP 8.5.6 (cli) (built: May 7 2026 16:54:58) (NTS) + password_algos: Array +( + [0] => 2y + [1] => argon2i + [2] => argon2id +) + + ext: PDO + ext: pdo_sqlite + +=== a fresh start: what exists, who owns it, which processes serve it === + 4.3 /login answered 200 after 3s + 2.2 what it writes under /config: + /config + /config/.migrations + /config/data + /config/data/.gitignore + /config/data/.htaccess + /config/data/config.php + /config/data/grocy.db + /config/data/plugins + /config/data/viewcache + /config/keys + /config/keys/cert.crt + /config/keys/cert.key + /config/log + /config/log/nginx + /config/log/php + /config/nginx + /config/nginx/nginx.conf + /config/nginx/nginx.conf.sample + /config/nginx/resolver.conf + /config/nginx/site-confs + /config/nginx/ssl.conf + /config/nginx/ssl.conf.sample + /config/nginx/worker_processes.conf + /config/php + /config/php/php-local.ini + /config/php/www2.conf + /config/www + /config/www/index.html + 2.4 ownership: + total 40 + drwxrwxr-x 4 abc users 4096 Oct 10 11:41 . + drwxr-xr-x 8 abc users 4096 Oct 10 11:41 .. + -rw-rw-r-- 1 abc users 34 Sep 4 17:51 .gitignore + -rw-rw-r-- 1 abc users 14 Sep 4 17:51 .htaccess + -rw-r--r-- 1 abc users 15841 Oct 10 11:41 config.php + -rw-r--r-- 1 abc users 0 Oct 10 11:41 grocy.db + drwxrwxr-x 2 abc users 4096 Oct 10 11:41 plugins + drwxr-xr-x 2 abc users 4096 Oct 10 11:41 viewcache + 1.5 the processes that serve it (php-fpm + nginx = a production server; PID 1 is s6, the supervisor): + 1 root /package/admin/s6/command/s6-svscan -d4 -- /run/service + 40 root s6-supervise svc-php-fpm + 41 root s6-supervise svc-nginx + 250 root php-fpm: master process (/etc/php85/php-fpm.conf) + 251 root nginx: master process /usr/sbin/nginx -e stderr + php-fpm worker 28:user = abc + php-fpm worker 29:group = abc + 1.8 MODE and DISABLE_AUTH as the running app reads them, and an unknown page: + 20:Setting('MODE', 'production'); + 74:Setting('STOCK_BARCODE_LOOKUP_PLUGIN', 'OpenFoodFactsBarcodeLookupPlugin'); + 86:Setting('DISABLE_AUTH', false); + unknown page -> 404 + stack-trace markers on that page: 1 + +=== 3.1 a fresh install's users table, before anything replaces the password === + 1|admin|$argon2id$v=19$m=65536,t=4,p=1... + the documented default admin/admin, through the app's own login route: + admin/admin -> 302 http://127.0.0.1:18093/ + +=== 4.1 the compose healthcheck command, both directions === + against the app rc=0 + against a dead port rc=1 + +=== 6.5 the tag shape upstream, and the same-tag re-push === + the catalog pins the plain version tag, as bookstack/code-server/radarr/sonarr do. + digest served now for 4.7.1: + Name: lscr.io/linuxserver/grocy:4.7.1 + MediaType: application/vnd.oci.image.index.v1+json + Digest: sha256:c0d0d9d22d3a54fe3f779a743baa2d7bab96b73fad5597ff1a631e2be4b863c8 + +=== 0.4 / 0.5 every outbound host the source can reach (repo-wide, at the pinned tag) === + 102:https://grocy.info + 105:https://berrnd.de + 113:https://www.sqlite.org/lang + 125:https://github.com/mike42/escpos-php + 12:https://github.com/grocy/grocy/issues + 184:http://htmlpurifier.org/live/configdoc/plain.html + 190:http://htmlpurifier.org/live/configdoc/plain.html + 19:https://grocy.example.com/ + 20:https://github.com/twbs/bootstrap/issues/22753 + 20:https://grocy.info + 20:https://world.openfoodfacts.org/api/v2/product/ + 21:https://bugzilla.mozilla.org/show + 417:https://releases.grocy.info/demoresources/cookies.jpg + 418:https://releases.grocy.info/demoresources/cucumber.jpg + 419:https://releases.grocy.info/demoresources/gummybears.jpg + 420:https://releases.grocy.info/demoresources/paprika.jpg + 421:https://releases.grocy.info/demoresources/tomato.jpg + 422:https://releases.grocy.info/demoresources/loremipsum.pdf + 423:https://releases.grocy.info/demoresources/pizza.jpg + 424:https://releases.grocy.info/demoresources/sandwiches.jpg + 425:https://releases.grocy.info/demoresources/pancakes.jpg + 426:https://releases.grocy.info/demoresources/spaghetti.jpg + 427:https://releases.grocy.info/demoresources/chocolate + 428:https://releases.grocy.info/demoresources/pancakes + 58:https://example.com/grocy + 61:https://example.com/grocy/public/index.php/ + 636:https://grocy.info + 67:https://example.com/grocy + 70:https://grocy.info/ + +=== 3.10 does grocy read the client address anywhere? (repo-wide grep) === + +=== 7.1 does grocy send mail? (its own settings file) === + matches in config-dist.php: 0 + +=== 0.2 Hungarian coverage of the UI, with a control === + de 734 strings, 0 untranslated -> 100.0 % translated + fr 734 strings, 12 untranslated -> 98.4 % translated + hu 734 strings, 62 untranslated -> 91.6 % translated + (de is the control: a language that must be ~100 %. A first attempt at this count read 0 % + for every language — a .po parser that mishandled multi-line msgstr — and the control caught it.) + +########## end ########## diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/1-stock-overview-hu.png b/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/1-stock-overview-hu.png new file mode 100644 index 00000000..a1e2d6cd Binary files /dev/null and b/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/1-stock-overview-hu.png differ diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/2-chores-hu.png b/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/2-chores-hu.png new file mode 100644 index 00000000..76a1b9c8 Binary files /dev/null and b/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/2-chores-hu.png differ diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/3-phone-390px-hu.png b/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/3-phone-390px-hu.png new file mode 100644 index 00000000..fb73c977 Binary files /dev/null and b/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/3-phone-390px-hu.png differ diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/grocy.js b/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/grocy.js new file mode 100644 index 00000000..4bd7c0d8 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/shots/grocy.js @@ -0,0 +1,29 @@ +// Screenshots of Grocy's own web UI for the catalog card (checklist 8.3), taken on bench 9401 with +// headless Chrome (ghcr.io/puppeteer/puppeteer). The app runs from the template with throwaway +// credentials; the browser asks for Hungarian, which is what a Hungarian household's browser sends. +const puppeteer = require('puppeteer'); +const sleep = ms => new Promise(r => setTimeout(r, ms)); +(async () => { + const b = await puppeteer.launch({args: ['--no-sandbox', '--lang=hu-HU', '--accept-lang=hu-HU,hu']}); + const p = await b.newPage(); + await p.setExtraHTTPHeaders({'Accept-Language': 'hu-HU,hu;q=0.9'}); + await p.setViewport({width: 1280, height: 860, deviceScaleFactor: 1}); + // grocy's login form base64-encodes the password in the browser; type it and submit the form. + await p.goto(process.env.URL + '/login', {waitUntil: 'networkidle0'}); + await sleep(500); + await p.type('input[name=username]', 'admin'); + await p.type('input[type=password]', process.env.P); + await p.keyboard.press('Enter'); + await p.waitForNavigation({waitUntil: 'networkidle0', timeout: 30000}); + await sleep(1200); + await p.screenshot({path: '/out/1.png'}); // the stock overview + await p.goto(process.env.URL + '/choresoverview', {waitUntil: 'networkidle0'}); + await sleep(1200); + await p.screenshot({path: '/out/2.png'}); // the chores + await p.goto(process.env.URL + '/stockoverview', {waitUntil: 'networkidle0'}); + await sleep(1200); + await p.setViewport({width: 390, height: 844, deviceScaleFactor: 2}); // the same at phone width + await sleep(1000); + await p.screenshot({path: '/out/3.png'}); + await b.close(); +})().catch(e => { console.error(e); process.exit(1); }); diff --git a/documentation/audits/new-apps-2026-10-10/bench/grocy/volume-persistence.txt b/documentation/audits/new-apps-2026-10-10/bench/grocy/volume-persistence.txt new file mode 100644 index 00000000..507f7a37 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/grocy/volume-persistence.txt @@ -0,0 +1,15 @@ +2.1 — the RUNTIME volume-persistence gate, bench 9401, 2026-10-10 + +`python3 check-volume-persistence.py grocy lubelogger`, run against the catalog's own pins +(grocy 4.7.1, lubelogger v1.7.3). The gate deploys each template, exercises it into writing data and +compares where the data landed with what the compose mounts; it refuses to report at all until it has +re-proven itself in both directions against two canary templates. + +self-testing the prober (both directions)… + prober flags the R-156 signature and clears a correct template — trustworthy +grocy CLEAN +lubelogger CLEAN + +2 clean · 0 broken · 0 undetermined (of 2 in scope) +volume-persistence gate OK +exit 0 diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/abort-states.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/abort-states.json new file mode 100644 index 00000000..c106ce89 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/abort-states.json @@ -0,0 +1,8 @@ +{ + "lubelogger": { + "status": "running", + "health": "healthy", + "restarts": 0, + "exit": 0 + } +} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/compose-final.log b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/compose-final.log new file mode 100644 index 00000000..39db37d3 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/compose-final.log @@ -0,0 +1,36 @@ +lubelogger | LubeLogger 1.7.2 +lubelogger | Website: https://lubelogger.com +lubelogger | Documentation: https://docs.lubelogger.com +lubelogger | GitHub: https://github.com/hargata/lubelog +lubelogger | SMTP Not Configured +lubelogger | Message Of The Day: Not Configured +lubelogger | info: Microsoft.Hosting.Lifetime[14] +lubelogger | Now listening on: http://[::]:8080 +lubelogger | info: Microsoft.Hosting.Lifetime[0] +lubelogger | Application started. Press Ctrl+C to shut down. +lubelogger | info: Microsoft.Hosting.Lifetime[0] +lubelogger | Hosting environment: Production +lubelogger | info: Microsoft.Hosting.Lifetime[0] +lubelogger | Content root path: /App +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. +lubelogger | info: CarCareTracker.Middleware.Authen[12] +lubelogger | AuthenticationScheme: AuthN was challenged. +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. +lubelogger | warn: CarCareTracker.Controllers.LoginController[0] +lubelogger | Failed Login for csalad from ::ffff:172.18.0.1 +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. +lubelogger | info: CarCareTracker.Middleware.Authen[12] +lubelogger | AuthenticationScheme: AuthN was challenged. +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/engine-state.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/engine-state.json new file mode 100644 index 00000000..ec747fa4 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/engine-state.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-after-detail.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-after-detail.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-after-detail.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-after.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-after.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-after.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-before-detail.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-before-detail.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-before-detail.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-before.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-before.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/files-before.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/memory-samples.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/memory-samples.json new file mode 100644 index 00000000..5f6adbce --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/memory-samples.json @@ -0,0 +1,762 @@ +[ + { + "t": 15.1, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 67637248, + "peak": 68583424, + "anon": 40484864, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 300 + }, + { + "t": 30.3, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 72974336, + "peak": 74190848, + "anon": 45150208, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 600 + }, + { + "t": 45.4, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 81289216, + "peak": 82313216, + "anon": 53686272, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 900 + }, + { + "t": 60.5, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 83992576, + "peak": 84324352, + "anon": 55738368, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1200 + }, + { + "t": 75.7, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 82210816, + "peak": 84774912, + "anon": 53747712, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1500 + }, + { + "t": 90.8, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 84226048, + "peak": 85487616, + "anon": 56676352, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 1800 + }, + { + "t": 105.9, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 83095552, + "peak": 85696512, + "anon": 55300096, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2100 + }, + { + "t": 121.1, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 83890176, + "peak": 85696512, + "anon": 55357440, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2400 + }, + { + "t": 136.2, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 84246528, + "peak": 85696512, + "anon": 55967744, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2699 + }, + { + "t": 151.3, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 84516864, + "peak": 86069248, + "anon": 56184832, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 2997 + }, + { + "t": 166.5, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 84475904, + "peak": 86069248, + "anon": 56188928, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3297 + }, + { + "t": 181.6, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 85913600, + "peak": 86769664, + "anon": 57790464, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3597 + }, + { + "t": 196.7, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 86278144, + "peak": 87085056, + "anon": 57880576, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 3897 + }, + { + "t": 211.8, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89677824, + "peak": 90152960, + "anon": 60833792, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4197 + }, + { + "t": 227.0, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 86675456, + "peak": 90152960, + "anon": 58462208, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4497 + }, + { + "t": 242.1, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89526272, + "peak": 90288128, + "anon": 60989440, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 4797 + }, + { + "t": 257.2, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 86986752, + "peak": 90288128, + "anon": 58748928, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5097 + }, + { + "t": 272.3, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 87326720, + "peak": 90288128, + "anon": 58781696, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5397 + }, + { + "t": 287.5, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 86769664, + "peak": 90288128, + "anon": 58777600, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5694 + }, + { + "t": 302.6, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 87412736, + "peak": 90288128, + "anon": 58822656, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 5994 + }, + { + "t": 317.7, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 87220224, + "peak": 90288128, + "anon": 58871808, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6294 + }, + { + "t": 332.8, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89047040, + "peak": 90288128, + "anon": 60395520, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6594 + }, + { + "t": 348.0, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 88993792, + "peak": 90288128, + "anon": 60395520, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 6894 + }, + { + "t": 363.1, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89145344, + "peak": 91078656, + "anon": 60456960, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7194 + }, + { + "t": 378.2, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 88838144, + "peak": 91078656, + "anon": 60436480, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7494 + }, + { + "t": 393.3, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89395200, + "peak": 91873280, + "anon": 60665856, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 7794 + }, + { + "t": 408.5, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89890816, + "peak": 91873280, + "anon": 60674048, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8094 + }, + { + "t": 423.6, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 88932352, + "peak": 91873280, + "anon": 60710912, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8391 + }, + { + "t": 438.7, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89747456, + "peak": 91873280, + "anon": 60829696, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8691 + }, + { + "t": 453.8, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89546752, + "peak": 91873280, + "anon": 60854272, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 8991 + }, + { + "t": 469.0, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89161728, + "peak": 91873280, + "anon": 60899328, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9291 + }, + { + "t": 484.1, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89419776, + "peak": 91873280, + "anon": 60932096, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9591 + }, + { + "t": 499.2, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89919488, + "peak": 91873280, + "anon": 60948480, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 9891 + }, + { + "t": 514.3, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 95514624, + "peak": 95838208, + "anon": 66215936, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10191 + }, + { + "t": 529.4, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 90042368, + "peak": 95838208, + "anon": 61247488, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10488 + }, + { + "t": 544.6, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 90353664, + "peak": 95838208, + "anon": 61272064, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 10788 + }, + { + "t": 559.7, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 90361856, + "peak": 95838208, + "anon": 61308928, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11088 + }, + { + "t": 574.8, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89878528, + "peak": 95838208, + "anon": 61333504, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11388 + }, + { + "t": 589.9, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 89903104, + "peak": 95838208, + "anon": 61353984, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11688 + }, + { + "t": 605.1, + "containers": { + "lubelogger": { + "limit": 536870912, + "current": 90718208, + "peak": 95838208, + "anon": 61636608, + "swap": 0, + "swap_peak": 0, + "oom_kill": 0, + "restarts": 0, + "oomkilled_flag": false, + "status": "running", + "cgroup": true + } + }, + "requests": 11988 + } +] \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/migration-lines.txt b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/migration-lines.txt new file mode 100644 index 00000000..e69de29b diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/run.log b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/run.log new file mode 100644 index 00000000..37411ac1 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/run.log @@ -0,0 +1,59 @@ +[09:41:34] scratch drive folders cleared before FROM (R-656): none existed +[09:41:34] MV-lubelogger: deploying lubelogger at FROM {'lubelogger': 'ghcr.io/hargata/lubelogger:v1.7.2'} +[09:42:15] FROM settled=True in 30.9s :: {"lubelogger": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}} +[09:42:15] fixture: the BOX walk's own (LubeLogger), through upgrade_boxport +[09:42:16] lubelogger: POST /Vehicle/SaveVehicle http=200 :: {"success":true,"message":""} +[09:42:16] lubelogger: POST servicerecords/add http=200 :: {"success":true,"message":"Service Record Added","additionalData":{"recordId":1}} +[09:42:16] lubelogger: readback vehicle=True (http=200) service record=True (http=200) (controls: no cookie 401, wrong 401, absent list empty) +[09:42:16] C1 (seed reads back BEFORE): True +[09:42:16] MV-lubelogger: swapping to TO {'lubelogger': 'ghcr.io/hargata/lubelogger:v1.7.3'} +[09:42:17] TO up -d rc=0 +[09:42:48] TO settled=True in 30.9s :: {"lubelogger": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}} +[09:42:48] migration lines observed: 0 +[09:42:49] lubelogger: readback vehicle=True (http=200) service record=True (http=200) (controls: no cookie 401, wrong 401, absent list empty) +[09:42:49] RESULT (seed reads back AFTER): True +[09:42:49] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:8080 +[09:43:04] + 15s lubelogger=64M/512M peak=65M kills=0 rs=0 reqs=300 +[09:43:20] + 30s lubelogger=69M/512M peak=70M kills=0 rs=0 reqs=600 +[09:43:35] + 45s lubelogger=77M/512M peak=78M kills=0 rs=0 reqs=900 +[09:43:50] + 60s lubelogger=80M/512M peak=80M kills=0 rs=0 reqs=1200 +[09:44:05] + 76s lubelogger=78M/512M peak=80M kills=0 rs=0 reqs=1500 +[09:44:20] + 91s lubelogger=80M/512M peak=81M kills=0 rs=0 reqs=1800 +[09:44:35] + 106s lubelogger=79M/512M peak=81M kills=0 rs=0 reqs=2100 +[09:44:50] + 121s lubelogger=80M/512M peak=81M kills=0 rs=0 reqs=2400 +[09:45:05] + 136s lubelogger=80M/512M peak=81M kills=0 rs=0 reqs=2699 +[09:45:21] + 151s lubelogger=80M/512M peak=82M kills=0 rs=0 reqs=2997 +[09:45:36] + 166s lubelogger=80M/512M peak=82M kills=0 rs=0 reqs=3297 +[09:45:51] + 182s lubelogger=81M/512M peak=82M kills=0 rs=0 reqs=3597 +[09:46:06] + 197s lubelogger=82M/512M peak=83M kills=0 rs=0 reqs=3897 +[09:46:21] + 212s lubelogger=85M/512M peak=85M kills=0 rs=0 reqs=4197 +[09:46:36] + 227s lubelogger=82M/512M peak=85M kills=0 rs=0 reqs=4497 +[09:46:51] + 242s lubelogger=85M/512M peak=86M kills=0 rs=0 reqs=4797 +[09:47:06] + 257s lubelogger=82M/512M peak=86M kills=0 rs=0 reqs=5097 +[09:47:22] + 272s lubelogger=83M/512M peak=86M kills=0 rs=0 reqs=5397 +[09:47:37] + 288s lubelogger=82M/512M peak=86M kills=0 rs=0 reqs=5694 +[09:47:52] + 303s lubelogger=83M/512M peak=86M kills=0 rs=0 reqs=5994 +[09:48:07] + 318s lubelogger=83M/512M peak=86M kills=0 rs=0 reqs=6294 +[09:48:22] + 333s lubelogger=84M/512M peak=86M kills=0 rs=0 reqs=6594 +[09:48:37] + 348s lubelogger=84M/512M peak=86M kills=0 rs=0 reqs=6894 +[09:48:52] + 363s lubelogger=85M/512M peak=86M kills=0 rs=0 reqs=7194 +[09:49:07] + 378s lubelogger=84M/512M peak=86M kills=0 rs=0 reqs=7494 +[09:49:23] + 393s lubelogger=85M/512M peak=87M kills=0 rs=0 reqs=7794 +[09:49:38] + 408s lubelogger=85M/512M peak=87M kills=0 rs=0 reqs=8094 +[09:49:53] + 424s lubelogger=84M/512M peak=87M kills=0 rs=0 reqs=8391 +[09:50:08] + 439s lubelogger=85M/512M peak=87M kills=0 rs=0 reqs=8691 +[09:50:23] + 454s lubelogger=85M/512M peak=87M kills=0 rs=0 reqs=8991 +[09:50:38] + 469s lubelogger=85M/512M peak=87M kills=0 rs=0 reqs=9291 +[09:50:53] + 484s lubelogger=85M/512M peak=87M kills=0 rs=0 reqs=9591 +[09:51:08] + 499s lubelogger=85M/512M peak=87M kills=0 rs=0 reqs=9891 +[09:51:24] + 514s lubelogger=91M/512M peak=91M kills=0 rs=0 reqs=10191 +[09:51:39] + 529s lubelogger=85M/512M peak=91M kills=0 rs=0 reqs=10488 +[09:51:54] + 545s lubelogger=86M/512M peak=91M kills=0 rs=0 reqs=10788 +[09:52:09] + 560s lubelogger=86M/512M peak=91M kills=0 rs=0 reqs=11088 +[09:52:24] + 575s lubelogger=85M/512M peak=91M kills=0 rs=0 reqs=11388 +[09:52:39] + 590s lubelogger=85M/512M peak=91M kills=0 rs=0 reqs=11688 +[09:52:54] + 605s lubelogger=86M/512M peak=91M kills=0 rs=0 reqs=11988 +[09:52:55] memory watch: killed=False tight=[] requests=11988 codes={'302': 11988} +[09:52:55] MV-lubelogger: ABORT — putting the FROM images back +[09:53:27] lubelogger: readback vehicle=True (http=200) service record=True (http=200) (controls: no cookie 401, wrong 401, absent list empty) +[09:53:27] ABORT: app came back in 30.9s; data present=True \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/to-full.log b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/to-full.log new file mode 100644 index 00000000..840cb34c --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/to-full.log @@ -0,0 +1,16 @@ +lubelogger | LubeLogger 1.7.3 +lubelogger | Website: https://lubelogger.com +lubelogger | Documentation: https://docs.lubelogger.com +lubelogger | GitHub: https://github.com/hargata/lubelog +lubelogger | SMTP Not Configured +lubelogger | Message Of The Day: Not Configured +lubelogger | info: Microsoft.Hosting.Lifetime[14] +lubelogger | Now listening on: http://[::]:8080 +lubelogger | info: Microsoft.Hosting.Lifetime[0] +lubelogger | Application started. Press Ctrl+C to shut down. +lubelogger | info: Microsoft.Hosting.Lifetime[0] +lubelogger | Hosting environment: Production +lubelogger | info: Microsoft.Hosting.Lifetime[0] +lubelogger | Content root path: /App +lubelogger | info: CarCareTracker.Middleware.Authen[7] +lubelogger | AuthN was not authenticated. Failure message: Cookie is invalid or does not exist. diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/to-states.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/to-states.json new file mode 100644 index 00000000..c106ce89 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/to-states.json @@ -0,0 +1,8 @@ +{ + "lubelogger": { + "status": "running", + "health": "healthy", + "restarts": 0, + "exit": 0 + } +} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/verdict.json b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/verdict.json new file mode 100644 index 00000000..d39afa94 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/evidence/MV-lubelogger/verdict.json @@ -0,0 +1,56 @@ +{ + "harness_version": 5, + "edge": "MV-lubelogger", + "app": "lubelogger", + "note": "night 2026-09-23 within-a-major move: lubelogger=ghcr.io/hargata/lubelogger:v1.7.3", + "from": { + "lubelogger": "ghcr.io/hargata/lubelogger:v1.7.2" + }, + "to": { + "lubelogger": "ghcr.io/hargata/lubelogger:v1.7.3" + }, + "verdict": "proven", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "migration_observed": null, + "abort": "starts-and-serves", + "abort_detail": null, + "engine_state_after": null, + "memory": { + "soak_s": 605.4, + "requested_s": 600, + "requests": 11988, + "codes": { + "302": 11988 + }, + "first_kill": null, + "containers": { + "lubelogger": { + "limit": 536870912, + "peak": 95838208, + "peak_pct": 0.179, + "anon_peak_sampled": 66215936, + "anon_peak_pct": 0.123, + "swap_peak": 0, + "oom_kills": 0, + "restarts": 0, + "oomkilled_flag": false, + "measured": true + } + }, + "unmeasured": [], + "venue_swap_bytes": 0, + "load": "reached" + }, + "marks": [], + "bench_overrides": null, + "duration_s": 30.9, + "measured_at": "2026-10-10T09:53:27Z", + "evidence": "evidence/MV-lubelogger", + "scratch_cleared": [], + "files_changed": [], + "files_changed_detail": [], + "files_ignored": [], + "total_s": 712.9 +} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/mem-lubelogger.csv b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/mem-lubelogger.csv new file mode 100644 index 00000000..3e584e63 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/mem-lubelogger.csv @@ -0,0 +1,340 @@ +1791625306,lubelogger,e1fb6718a6fc,15933440,52531200,0,0,536870912,0 +1791625308,lubelogger,e1fb6718a6fc,15933440,52047872,0,0,536870912,0 +1791625310,lubelogger,e1fb6718a6fc,15941632,51810304,0,0,536870912,0 +1791625312,lubelogger,e1fb6718a6fc,15945728,51814400,0,0,536870912,0 +1791625314,lubelogger,e1fb6718a6fc,16023552,51892224,0,0,536870912,0 +1791625316,lubelogger,e1fb6718a6fc,16097280,52289536,0,0,536870912,0 +1791625319,lubelogger,e1fb6718a6fc,16117760,52543488,0,0,536870912,0 +1791625321,lubelogger,e1fb6718a6fc,16584704,53039104,0,0,536870912,0 +1791625323,lubelogger,e1fb6718a6fc,16584704,52523008,0,0,536870912,0 +1791625325,lubelogger,e1fb6718a6fc,16584704,52523008,0,0,536870912,0 +1791625327,lubelogger,e1fb6718a6fc,16584704,52523008,0,0,536870912,0 +1791625329,lubelogger,e1fb6718a6fc,16584704,52523008,0,0,536870912,0 +1791625331,lubelogger,e1fb6718a6fc,16584704,52523008,0,0,536870912,0 +1791625333,lubelogger,e1fb6718a6fc,17174528,53248000,0,0,536870912,0 +1791625335,lubelogger,e1fb6718a6fc,23707648,66228224,0,0,536870912,0 +1791625339,lubelogger,21af9d7e6e6d,15880192,30674944,0,0,536870912,0 +1791625341,lubelogger,21af9d7e6e6d,15880192,30060544,0,0,536870912,0 +1791625343,lubelogger,21af9d7e6e6d,15892480,29814784,0,0,536870912,0 +1791625345,lubelogger,21af9d7e6e6d,15896576,29827072,0,0,536870912,0 +1791625347,lubelogger,21af9d7e6e6d,15970304,29900800,0,0,536870912,0 +1791625349,lubelogger,21af9d7e6e6d,16044032,30515200,0,0,536870912,0 +1791625351,lubelogger,21af9d7e6e6d,16064512,30515200,0,0,536870912,0 +1791625354,lubelogger,21af9d7e6e6d,16416768,30408704,0,0,536870912,0 +1791625356,lubelogger,21af9d7e6e6d,16416768,30412800,0,0,536870912,0 +1791625358,lubelogger,21af9d7e6e6d,16416768,30412800,0,0,536870912,0 +1791625360,lubelogger,21af9d7e6e6d,16416768,30412800,0,0,536870912,0 +1791625362,lubelogger,21af9d7e6e6d,16416768,30412800,0,0,536870912,0 +1791625364,lubelogger,21af9d7e6e6d,16416768,30412800,0,0,536870912,0 +1791625366,lubelogger,21af9d7e6e6d,17072128,31203328,0,0,536870912,0 +1791625368,lubelogger,21af9d7e6e6d,23670784,43167744,0,0,536870912,0 +1791625370,lubelogger,21af9d7e6e6d,32116736,56401920,0,0,536870912,0 +1791625372,lubelogger,21af9d7e6e6d,34865152,61362176,0,0,536870912,0 +1791625374,lubelogger,21af9d7e6e6d,37793792,65495040,0,0,536870912,0 +1791625376,lubelogger,21af9d7e6e6d,38170624,65929216,0,0,536870912,0 +1791625378,lubelogger,21af9d7e6e6d,38666240,66555904,0,0,536870912,0 +1791625380,lubelogger,21af9d7e6e6d,39002112,67035136,0,0,536870912,0 +1791625382,lubelogger,21af9d7e6e6d,39870464,67940352,0,0,536870912,0 +1791625384,lubelogger,21af9d7e6e6d,40484864,67375104,0,0,536870912,0 +1791625387,lubelogger,21af9d7e6e6d,40992768,69115904,0,0,536870912,0 +1791625389,lubelogger,21af9d7e6e6d,41488384,69058560,0,0,536870912,0 +1791625391,lubelogger,21af9d7e6e6d,41877504,69763072,0,0,536870912,0 +1791625393,lubelogger,21af9d7e6e6d,42631168,70164480,0,0,536870912,0 +1791625395,lubelogger,21af9d7e6e6d,43360256,71270400,0,0,536870912,0 +1791625397,lubelogger,21af9d7e6e6d,44015616,71847936,0,0,536870912,0 +1791625399,lubelogger,21af9d7e6e6d,44933120,72855552,0,0,536870912,0 +1791625401,lubelogger,21af9d7e6e6d,45211648,73584640,0,0,536870912,0 +1791625403,lubelogger,21af9d7e6e6d,46145536,74113024,0,0,536870912,0 +1791625405,lubelogger,21af9d7e6e6d,46743552,75255808,0,0,536870912,0 +1791625407,lubelogger,21af9d7e6e6d,47345664,75403264,0,0,536870912,0 +1791625409,lubelogger,21af9d7e6e6d,47788032,76271616,0,0,536870912,0 +1791625411,lubelogger,21af9d7e6e6d,48562176,76632064,0,0,536870912,0 +1791625413,lubelogger,21af9d7e6e6d,53686272,81801216,0,0,536870912,0 +1791625415,lubelogger,21af9d7e6e6d,53686272,81534976,0,0,536870912,0 +1791625417,lubelogger,21af9d7e6e6d,53686272,81719296,0,0,536870912,0 +1791625419,lubelogger,21af9d7e6e6d,53628928,81698816,0,0,536870912,0 +1791625422,lubelogger,21af9d7e6e6d,53641216,81965056,0,0,536870912,0 +1791625424,lubelogger,21af9d7e6e6d,53641216,81170432,0,0,536870912,0 +1791625426,lubelogger,21af9d7e6e6d,53628928,81530880,0,0,536870912,0 +1791625428,lubelogger,21af9d7e6e6d,54894592,83316736,0,0,536870912,0 +1791625430,lubelogger,21af9d7e6e6d,55738368,84242432,0,0,536870912,0 +1791625432,lubelogger,21af9d7e6e6d,55738368,84463616,0,0,536870912,0 +1791625434,lubelogger,21af9d7e6e6d,55742464,84492288,0,0,536870912,0 +1791625436,lubelogger,21af9d7e6e6d,55742464,84226048,0,0,536870912,0 +1791625438,lubelogger,21af9d7e6e6d,55746560,83976192,0,0,536870912,0 +1791625440,lubelogger,21af9d7e6e6d,55767040,84013056,0,0,536870912,0 +1791625442,lubelogger,21af9d7e6e6d,55808000,84275200,0,0,536870912,0 +1791625444,lubelogger,21af9d7e6e6d,53747712,82206720,0,0,536870912,0 +1791625446,lubelogger,21af9d7e6e6d,53747712,81944576,0,0,536870912,0 +1791625448,lubelogger,21af9d7e6e6d,53747712,82010112,0,0,536870912,0 +1791625450,lubelogger,21af9d7e6e6d,54104064,82386944,0,0,536870912,0 +1791625452,lubelogger,21af9d7e6e6d,54181888,82685952,0,0,536870912,0 +1791625455,lubelogger,21af9d7e6e6d,54292480,83034112,0,0,536870912,0 +1791625457,lubelogger,21af9d7e6e6d,54448128,82432000,0,0,536870912,0 +1791625459,lubelogger,21af9d7e6e6d,56676352,85184512,0,0,536870912,0 +1791625461,lubelogger,21af9d7e6e6d,56676352,84709376,0,0,536870912,0 +1791625463,lubelogger,21af9d7e6e6d,56676352,84676608,0,0,536870912,0 +1791625465,lubelogger,21af9d7e6e6d,56655872,84910080,0,0,536870912,0 +1791625467,lubelogger,21af9d7e6e6d,56655872,85155840,0,0,536870912,0 +1791625469,lubelogger,21af9d7e6e6d,55308288,83832832,0,0,536870912,0 +1791625471,lubelogger,21af9d7e6e6d,55308288,84119552,0,0,536870912,0 +1791625473,lubelogger,21af9d7e6e6d,55300096,83890176,0,0,536870912,0 +1791625475,lubelogger,21af9d7e6e6d,55300096,83353600,0,0,536870912,0 +1791625477,lubelogger,21af9d7e6e6d,55300096,83845120,0,0,536870912,0 +1791625479,lubelogger,21af9d7e6e6d,55304192,83836928,0,0,536870912,0 +1791625481,lubelogger,21af9d7e6e6d,55308288,84119552,0,0,536870912,0 +1791625483,lubelogger,21af9d7e6e6d,55308288,83611648,0,0,536870912,0 +1791625485,lubelogger,21af9d7e6e6d,55308288,83378176,0,0,536870912,0 +1791625488,lubelogger,21af9d7e6e6d,55308288,83587072,0,0,536870912,0 +1791625490,lubelogger,21af9d7e6e6d,55357440,83697664,0,0,536870912,0 +1791625492,lubelogger,21af9d7e6e6d,55357440,83922944,0,0,536870912,0 +1791625494,lubelogger,21af9d7e6e6d,55357440,84209664,0,0,536870912,0 +1791625496,lubelogger,21af9d7e6e6d,55345152,83382272,0,0,536870912,0 +1791625498,lubelogger,21af9d7e6e6d,55345152,83603456,0,0,536870912,0 +1791625500,lubelogger,21af9d7e6e6d,55353344,83652608,0,0,536870912,0 +1791625502,lubelogger,21af9d7e6e6d,55406592,84406272,0,0,536870912,0 +1791625504,lubelogger,21af9d7e6e6d,55681024,84414464,0,0,536870912,0 +1791625506,lubelogger,21af9d7e6e6d,56152064,84803584,0,0,536870912,0 +1791625508,lubelogger,21af9d7e6e6d,56152064,84705280,0,0,536870912,0 +1791625510,lubelogger,21af9d7e6e6d,56168448,84664320,0,0,536870912,0 +1791625512,lubelogger,21af9d7e6e6d,56172544,83988480,0,0,536870912,0 +1791625514,lubelogger,21af9d7e6e6d,56160256,84176896,0,0,536870912,0 +1791625516,lubelogger,21af9d7e6e6d,56160256,83935232,0,0,536870912,0 +1791625518,lubelogger,21af9d7e6e6d,56180736,84365312,0,0,536870912,0 +1791625520,lubelogger,21af9d7e6e6d,56184832,84516864,0,0,536870912,0 +1791625523,lubelogger,21af9d7e6e6d,56172544,84471808,0,0,536870912,0 +1791625525,lubelogger,21af9d7e6e6d,56172544,84520960,0,0,536870912,0 +1791625527,lubelogger,21af9d7e6e6d,56184832,84570112,0,0,536870912,0 +1791625529,lubelogger,21af9d7e6e6d,56184832,84246528,0,0,536870912,0 +1791625531,lubelogger,21af9d7e6e6d,56180736,84291584,0,0,536870912,0 +1791625533,lubelogger,21af9d7e6e6d,56180736,84471808,0,0,536870912,0 +1791625535,lubelogger,21af9d7e6e6d,56188928,84746240,0,0,536870912,0 +1791625537,lubelogger,21af9d7e6e6d,56188928,84492288,0,0,536870912,0 +1791625539,lubelogger,21af9d7e6e6d,56262656,84746240,0,0,536870912,0 +1791625541,lubelogger,21af9d7e6e6d,56373248,84217856,0,0,536870912,0 +1791625543,lubelogger,21af9d7e6e6d,56360960,84766720,0,0,536870912,0 +1791625545,lubelogger,21af9d7e6e6d,56377344,84934656,0,0,536870912,0 +1791625547,lubelogger,21af9d7e6e6d,56377344,84717568,0,0,536870912,0 +1791625549,lubelogger,21af9d7e6e6d,57790464,85741568,0,0,536870912,0 +1791625551,lubelogger,21af9d7e6e6d,57790464,86425600,0,0,536870912,0 +1791625553,lubelogger,21af9d7e6e6d,57872384,85975040,0,0,536870912,0 +1791625556,lubelogger,21af9d7e6e6d,57872384,86241280,0,0,536870912,0 +1791625558,lubelogger,21af9d7e6e6d,57888768,86315008,0,0,536870912,0 +1791625560,lubelogger,21af9d7e6e6d,57888768,86282240,0,0,536870912,0 +1791625562,lubelogger,21af9d7e6e6d,57888768,86519808,0,0,536870912,0 +1791625564,lubelogger,21af9d7e6e6d,57876480,86011904,0,0,536870912,0 +1791625566,lubelogger,21af9d7e6e6d,57880576,85766144,0,0,536870912,0 +1791625568,lubelogger,21af9d7e6e6d,58114048,86863872,0,0,536870912,0 +1791625570,lubelogger,21af9d7e6e6d,58118144,86315008,0,0,536870912,0 +1791625572,lubelogger,21af9d7e6e6d,58114048,86482944,0,0,536870912,0 +1791625574,lubelogger,21af9d7e6e6d,58114048,86020096,0,0,536870912,0 +1791625576,lubelogger,21af9d7e6e6d,58114048,86261760,0,0,536870912,0 +1791625578,lubelogger,21af9d7e6e6d,60821504,89063424,0,0,536870912,0 +1791625580,lubelogger,21af9d7e6e6d,60829696,89387008,0,0,536870912,0 +1791625582,lubelogger,21af9d7e6e6d,60833792,89849856,0,0,536870912,0 +1791625584,lubelogger,21af9d7e6e6d,58470400,87277568,0,0,536870912,0 +1791625586,lubelogger,21af9d7e6e6d,58474496,86757376,0,0,536870912,0 +1791625589,lubelogger,21af9d7e6e6d,58474496,87191552,0,0,536870912,0 +1791625591,lubelogger,21af9d7e6e6d,58474496,86945792,0,0,536870912,0 +1791625593,lubelogger,21af9d7e6e6d,58486784,86745088,0,0,536870912,0 +1791625595,lubelogger,21af9d7e6e6d,58486784,87764992,0,0,536870912,0 +1791625597,lubelogger,21af9d7e6e6d,58462208,86933504,0,0,536870912,0 +1791625599,lubelogger,21af9d7e6e6d,58466304,87195648,0,0,536870912,0 +1791625601,lubelogger,21af9d7e6e6d,58470400,86921216,0,0,536870912,0 +1791625603,lubelogger,21af9d7e6e6d,58470400,87244800,0,0,536870912,0 +1791625605,lubelogger,21af9d7e6e6d,58474496,86429696,0,0,536870912,0 +1791625607,lubelogger,21af9d7e6e6d,58478592,87232512,0,0,536870912,0 +1791625609,lubelogger,21af9d7e6e6d,60985344,90034176,0,0,536870912,0 +1791625611,lubelogger,21af9d7e6e6d,60989440,89526272,0,0,536870912,0 +1791625613,lubelogger,21af9d7e6e6d,58744832,87248896,0,0,536870912,0 +1791625615,lubelogger,21af9d7e6e6d,58744832,86990848,0,0,536870912,0 +1791625617,lubelogger,21af9d7e6e6d,58748928,87781376,0,0,536870912,0 +1791625619,lubelogger,21af9d7e6e6d,58748928,87519232,0,0,536870912,0 +1791625621,lubelogger,21af9d7e6e6d,58748928,87498752,0,0,536870912,0 +1791625624,lubelogger,21af9d7e6e6d,58748928,87224320,0,0,536870912,0 +1791625626,lubelogger,21af9d7e6e6d,58748928,86990848,0,0,536870912,0 +1791625628,lubelogger,21af9d7e6e6d,58748928,87506944,0,0,536870912,0 +1791625630,lubelogger,21af9d7e6e6d,58769408,87810048,0,0,536870912,0 +1791625632,lubelogger,21af9d7e6e6d,58773504,87306240,0,0,536870912,0 +1791625634,lubelogger,21af9d7e6e6d,58761216,86994944,0,0,536870912,0 +1791625636,lubelogger,21af9d7e6e6d,58761216,86749184,0,0,536870912,0 +1791625638,lubelogger,21af9d7e6e6d,58753024,87797760,0,0,536870912,0 +1791625640,lubelogger,21af9d7e6e6d,58781696,87793664,0,0,536870912,0 +1791625642,lubelogger,21af9d7e6e6d,58781696,87339008,0,0,536870912,0 +1791625644,lubelogger,21af9d7e6e6d,58769408,87281664,0,0,536870912,0 +1791625646,lubelogger,21af9d7e6e6d,58769408,87265280,0,0,536870912,0 +1791625648,lubelogger,21af9d7e6e6d,58769408,87031808,0,0,536870912,0 +1791625650,lubelogger,21af9d7e6e6d,58773504,87523328,0,0,536870912,0 +1791625652,lubelogger,21af9d7e6e6d,58773504,87236608,0,0,536870912,0 +1791625654,lubelogger,21af9d7e6e6d,58773504,87552000,0,0,536870912,0 +1791625656,lubelogger,21af9d7e6e6d,58777600,86773760,0,0,536870912,0 +1791625659,lubelogger,21af9d7e6e6d,58777600,86765568,0,0,536870912,0 +1791625661,lubelogger,21af9d7e6e6d,58777600,87789568,0,0,536870912,0 +1791625663,lubelogger,21af9d7e6e6d,58781696,87523328,0,0,536870912,0 +1791625665,lubelogger,21af9d7e6e6d,58793984,87560192,0,0,536870912,0 +1791625667,lubelogger,21af9d7e6e6d,58793984,87089152,0,0,536870912,0 +1791625669,lubelogger,21af9d7e6e6d,58818560,88084480,0,0,536870912,0 +1791625671,lubelogger,21af9d7e6e6d,58822656,87691264,0,0,536870912,0 +1791625673,lubelogger,21af9d7e6e6d,58822656,86847488,0,0,536870912,0 +1791625675,lubelogger,21af9d7e6e6d,58798080,87392256,0,0,536870912,0 +1791625677,lubelogger,21af9d7e6e6d,58798080,87314432,0,0,536870912,0 +1791625679,lubelogger,21af9d7e6e6d,58793984,87117824,0,0,536870912,0 +1791625681,lubelogger,21af9d7e6e6d,58802176,87658496,0,0,536870912,0 +1791625683,lubelogger,21af9d7e6e6d,58802176,87969792,0,0,536870912,0 +1791625685,lubelogger,21af9d7e6e6d,58884096,87519232,0,0,536870912,0 +1791625687,lubelogger,21af9d7e6e6d,58871808,86949888,0,0,536870912,0 +1791625689,lubelogger,21af9d7e6e6d,58884096,87482368,0,0,536870912,0 +1791625692,lubelogger,21af9d7e6e6d,58884096,87011328,0,0,536870912,0 +1791625694,lubelogger,21af9d7e6e6d,58884096,86978560,0,0,536870912,0 +1791625696,lubelogger,21af9d7e6e6d,58888192,86994944,0,0,536870912,0 +1791625698,lubelogger,21af9d7e6e6d,58888192,88264704,0,0,536870912,0 +1791625700,lubelogger,21af9d7e6e6d,60395520,89034752,0,0,536870912,0 +1791625702,lubelogger,21af9d7e6e6d,60395520,89300992,0,0,536870912,0 +1791625704,lubelogger,21af9d7e6e6d,60375040,88965120,0,0,536870912,0 +1791625706,lubelogger,21af9d7e6e6d,60375040,88727552,0,0,536870912,0 +1791625708,lubelogger,21af9d7e6e6d,60375040,88952832,0,0,536870912,0 +1791625710,lubelogger,21af9d7e6e6d,60383232,88969216,0,0,536870912,0 +1791625712,lubelogger,21af9d7e6e6d,60383232,89243648,0,0,536870912,0 +1791625714,lubelogger,21af9d7e6e6d,60387328,89505792,0,0,536870912,0 +1791625716,lubelogger,21af9d7e6e6d,60387328,89018368,0,0,536870912,0 +1791625718,lubelogger,21af9d7e6e6d,60395520,88715264,0,0,536870912,0 +1791625720,lubelogger,21af9d7e6e6d,60399616,89243648,0,0,536870912,0 +1791625722,lubelogger,21af9d7e6e6d,60403712,89268224,0,0,536870912,0 +1791625725,lubelogger,21af9d7e6e6d,60407808,88961024,0,0,536870912,0 +1791625727,lubelogger,21af9d7e6e6d,60407808,89284608,0,0,536870912,0 +1791625729,lubelogger,21af9d7e6e6d,60456960,89358336,0,0,536870912,0 +1791625731,lubelogger,21af9d7e6e6d,60456960,89665536,0,0,536870912,0 +1791625733,lubelogger,21af9d7e6e6d,60456960,89387008,0,0,536870912,0 +1791625735,lubelogger,21af9d7e6e6d,60436480,89112576,0,0,536870912,0 +1791625737,lubelogger,21af9d7e6e6d,60436480,89133056,0,0,536870912,0 +1791625739,lubelogger,21af9d7e6e6d,60436480,88592384,0,0,536870912,0 +1791625741,lubelogger,21af9d7e6e6d,60436480,89313280,0,0,536870912,0 +1791625743,lubelogger,21af9d7e6e6d,60448768,89866240,0,0,536870912,0 +1791625745,lubelogger,21af9d7e6e6d,60448768,89399296,0,0,536870912,0 +1791625747,lubelogger,21af9d7e6e6d,60448768,89116672,0,0,536870912,0 +1791625749,lubelogger,21af9d7e6e6d,60436480,88825856,0,0,536870912,0 +1791625751,lubelogger,21af9d7e6e6d,60448768,89362432,0,0,536870912,0 +1791625753,lubelogger,21af9d7e6e6d,60448768,89354240,0,0,536870912,0 +1791625755,lubelogger,21af9d7e6e6d,60583936,89120768,0,0,536870912,0 +1791625758,lubelogger,21af9d7e6e6d,60583936,88895488,0,0,536870912,0 +1791625760,lubelogger,21af9d7e6e6d,60690432,89026560,0,0,536870912,0 +1791625762,lubelogger,21af9d7e6e6d,60690432,89649152,0,0,536870912,0 +1791625764,lubelogger,21af9d7e6e6d,60665856,89350144,0,0,536870912,0 +1791625766,lubelogger,21af9d7e6e6d,60665856,89366528,0,0,536870912,0 +1791625768,lubelogger,21af9d7e6e6d,60665856,88870912,0,0,536870912,0 +1791625770,lubelogger,21af9d7e6e6d,60669952,89391104,0,0,536870912,0 +1791625772,lubelogger,21af9d7e6e6d,60674048,89395200,0,0,536870912,0 +1791625774,lubelogger,21af9d7e6e6d,60674048,89362432,0,0,536870912,0 +1791625776,lubelogger,21af9d7e6e6d,60674048,89116672,0,0,536870912,0 +1791625778,lubelogger,21af9d7e6e6d,60674048,89624576,0,0,536870912,0 +1791625780,lubelogger,21af9d7e6e6d,60686336,89124864,0,0,536870912,0 +1791625782,lubelogger,21af9d7e6e6d,60686336,89096192,0,0,536870912,0 +1791625784,lubelogger,21af9d7e6e6d,60686336,89616384,0,0,536870912,0 +1791625786,lubelogger,21af9d7e6e6d,60690432,89145344,0,0,536870912,0 +1791625788,lubelogger,21af9d7e6e6d,60702720,88678400,0,0,536870912,0 +1791625791,lubelogger,21af9d7e6e6d,60715008,89456640,0,0,536870912,0 +1791625793,lubelogger,21af9d7e6e6d,60719104,89468928,0,0,536870912,0 +1791625795,lubelogger,21af9d7e6e6d,60710912,88870912,0,0,536870912,0 +1791625797,lubelogger,21af9d7e6e6d,60710912,89513984,0,0,536870912,0 +1791625799,lubelogger,21af9d7e6e6d,60821504,89776128,0,0,536870912,0 +1791625801,lubelogger,21af9d7e6e6d,60825600,89772032,0,0,536870912,0 +1791625803,lubelogger,21af9d7e6e6d,60825600,90279936,0,0,536870912,0 +1791625805,lubelogger,21af9d7e6e6d,60829696,89759744,0,0,536870912,0 +1791625807,lubelogger,21af9d7e6e6d,60829696,89792512,0,0,536870912,0 +1791625809,lubelogger,21af9d7e6e6d,60829696,89001984,0,0,536870912,0 +1791625811,lubelogger,21af9d7e6e6d,60837888,89780224,0,0,536870912,0 +1791625813,lubelogger,21af9d7e6e6d,60850176,89309184,0,0,536870912,0 +1791625815,lubelogger,21af9d7e6e6d,60850176,89325568,0,0,536870912,0 +1791625817,lubelogger,21af9d7e6e6d,60850176,89534464,0,0,536870912,0 +1791625819,lubelogger,21af9d7e6e6d,60866560,89628672,0,0,536870912,0 +1791625821,lubelogger,21af9d7e6e6d,60866560,89628672,0,0,536870912,0 +1791625823,lubelogger,21af9d7e6e6d,60854272,90333184,0,0,536870912,0 +1791625826,lubelogger,21af9d7e6e6d,60854272,89288704,0,0,536870912,0 +1791625828,lubelogger,21af9d7e6e6d,60854272,89550848,0,0,536870912,0 +1791625830,lubelogger,21af9d7e6e6d,60866560,89853952,0,0,536870912,0 +1791625832,lubelogger,21af9d7e6e6d,60866560,89800704,0,0,536870912,0 +1791625834,lubelogger,21af9d7e6e6d,60866560,89821184,0,0,536870912,0 +1791625836,lubelogger,21af9d7e6e6d,60870656,89096192,0,0,536870912,0 +1791625838,lubelogger,21af9d7e6e6d,60874752,89133056,0,0,536870912,0 +1791625840,lubelogger,21af9d7e6e6d,60899328,90161152,0,0,536870912,0 +1791625842,lubelogger,21af9d7e6e6d,60903424,89878528,0,0,536870912,0 +1791625844,lubelogger,21af9d7e6e6d,60903424,89366528,0,0,536870912,0 +1791625846,lubelogger,21af9d7e6e6d,60903424,89350144,0,0,536870912,0 +1791625848,lubelogger,21af9d7e6e6d,60903424,89128960,0,0,536870912,0 +1791625850,lubelogger,21af9d7e6e6d,60944384,89210880,0,0,536870912,0 +1791625852,lubelogger,21af9d7e6e6d,60944384,89440256,0,0,536870912,0 +1791625854,lubelogger,21af9d7e6e6d,60932096,89890816,0,0,536870912,0 +1791625856,lubelogger,21af9d7e6e6d,60932096,89899008,0,0,536870912,0 +1791625859,lubelogger,21af9d7e6e6d,60932096,89415680,0,0,536870912,0 +1791625861,lubelogger,21af9d7e6e6d,60944384,89698304,0,0,536870912,0 +1791625863,lubelogger,21af9d7e6e6d,60948480,89686016,0,0,536870912,0 +1791625865,lubelogger,21af9d7e6e6d,60948480,89923584,0,0,536870912,0 +1791625867,lubelogger,21af9d7e6e6d,60948480,89411584,0,0,536870912,0 +1791625869,lubelogger,21af9d7e6e6d,60948480,88895488,0,0,536870912,0 +1791625871,lubelogger,21af9d7e6e6d,60948480,89649152,0,0,536870912,0 +1791625873,lubelogger,21af9d7e6e6d,60948480,89399296,0,0,536870912,0 +1791625875,lubelogger,21af9d7e6e6d,60948480,89894912,0,0,536870912,0 +1791625877,lubelogger,21af9d7e6e6d,61075456,90062848,0,0,536870912,0 +1791625879,lubelogger,21af9d7e6e6d,66228224,95039488,0,0,536870912,0 +1791625881,lubelogger,21af9d7e6e6d,66228224,95309824,0,0,536870912,0 +1791625883,lubelogger,21af9d7e6e6d,66215936,94781440,0,0,536870912,0 +1791625885,lubelogger,21af9d7e6e6d,66215936,95498240,0,0,536870912,0 +1791625887,lubelogger,21af9d7e6e6d,61231104,89501696,0,0,536870912,0 +1791625889,lubelogger,21af9d7e6e6d,61243392,89800704,0,0,536870912,0 +1791625892,lubelogger,21af9d7e6e6d,61243392,90062848,0,0,536870912,0 +1791625894,lubelogger,21af9d7e6e6d,61243392,89726976,0,0,536870912,0 +1791625896,lubelogger,21af9d7e6e6d,61243392,89985024,0,0,536870912,0 +1791625898,lubelogger,21af9d7e6e6d,61243392,89739264,0,0,536870912,0 +1791625900,lubelogger,21af9d7e6e6d,61255680,90263552,0,0,536870912,0 +1791625902,lubelogger,21af9d7e6e6d,61255680,90267648,0,0,536870912,0 +1791625904,lubelogger,21af9d7e6e6d,61255680,90517504,0,0,536870912,0 +1791625906,lubelogger,21af9d7e6e6d,61255680,90247168,0,0,536870912,0 +1791625908,lubelogger,21af9d7e6e6d,61255680,90288128,0,0,536870912,0 +1791625910,lubelogger,21af9d7e6e6d,61276160,89571328,0,0,536870912,0 +1791625912,lubelogger,21af9d7e6e6d,61280256,89841664,0,0,536870912,0 +1791625914,lubelogger,21af9d7e6e6d,61272064,90578944,0,0,536870912,0 +1791625916,lubelogger,21af9d7e6e6d,61292544,90554368,0,0,536870912,0 +1791625918,lubelogger,21af9d7e6e6d,61292544,90607616,0,0,536870912,0 +1791625920,lubelogger,21af9d7e6e6d,61300736,89559040,0,0,536870912,0 +1791625922,lubelogger,21af9d7e6e6d,61300736,90066944,0,0,536870912,0 +1791625925,lubelogger,21af9d7e6e6d,61304832,89575424,0,0,536870912,0 +1791625927,lubelogger,21af9d7e6e6d,61308928,90370048,0,0,536870912,0 +1791625929,lubelogger,21af9d7e6e6d,61308928,90107904,0,0,536870912,0 +1791625931,lubelogger,21af9d7e6e6d,61313024,90374144,0,0,536870912,0 +1791625933,lubelogger,21af9d7e6e6d,61313024,89579520,0,0,536870912,0 +1791625935,lubelogger,21af9d7e6e6d,61313024,89837568,0,0,536870912,0 +1791625937,lubelogger,21af9d7e6e6d,61321216,89886720,0,0,536870912,0 +1791625939,lubelogger,21af9d7e6e6d,61345792,90243072,0,0,536870912,0 +1791625941,lubelogger,21af9d7e6e6d,61345792,90173440,0,0,536870912,0 +1791625943,lubelogger,21af9d7e6e6d,61345792,89894912,0,0,536870912,0 +1791625945,lubelogger,21af9d7e6e6d,61333504,90386432,0,0,536870912,0 +1791625947,lubelogger,21af9d7e6e6d,61337600,89878528,0,0,536870912,0 +1791625949,lubelogger,21af9d7e6e6d,61321216,90370048,0,0,536870912,0 +1791625951,lubelogger,21af9d7e6e6d,61329408,90132480,0,0,536870912,0 +1791625953,lubelogger,21af9d7e6e6d,61333504,90394624,0,0,536870912,0 +1791625955,lubelogger,21af9d7e6e6d,61341696,89886720,0,0,536870912,0 +1791625958,lubelogger,21af9d7e6e6d,61341696,89632768,0,0,536870912,0 +1791625960,lubelogger,21af9d7e6e6d,61353984,90152960,0,0,536870912,0 +1791625962,lubelogger,21af9d7e6e6d,61353984,89948160,0,0,536870912,0 +1791625964,lubelogger,21af9d7e6e6d,61353984,90124288,0,0,536870912,0 +1791625966,lubelogger,21af9d7e6e6d,61353984,89923584,0,0,536870912,0 +1791625968,lubelogger,21af9d7e6e6d,61353984,90419200,0,0,536870912,0 +1791625970,lubelogger,21af9d7e6e6d,61640704,90497024,0,0,536870912,0 +1791625972,lubelogger,21af9d7e6e6d,61640704,90742784,0,0,536870912,0 +1791625974,lubelogger,21af9d7e6e6d,61636608,90468352,0,0,536870912,0 +1791625976,lubelogger,a73e4c77bf04,15376384,28901376,0,0,536870912,0 +1791625978,lubelogger,a73e4c77bf04,15794176,29704192,0,0,536870912,0 +1791625980,lubelogger,a73e4c77bf04,15802368,29978624,0,0,536870912,0 +1791625982,lubelogger,a73e4c77bf04,15810560,29982720,0,0,536870912,0 +1791625984,lubelogger,a73e4c77bf04,15884288,29999104,0,0,536870912,0 +1791625986,lubelogger,a73e4c77bf04,15958016,30142464,0,0,536870912,0 +1791625988,lubelogger,a73e4c77bf04,15974400,29937664,0,0,536870912,0 +1791625991,lubelogger,a73e4c77bf04,16322560,30302208,0,0,536870912,0 +1791625993,lubelogger,a73e4c77bf04,16330752,30314496,0,0,536870912,0 +1791625995,lubelogger,a73e4c77bf04,16330752,30318592,0,0,536870912,0 +1791625997,lubelogger,a73e4c77bf04,16330752,30318592,0,0,536870912,0 +1791625999,lubelogger,a73e4c77bf04,16330752,30318592,0,0,536870912,0 +1791626001,lubelogger,a73e4c77bf04,16330752,30318592,0,0,536870912,0 +1791626003,lubelogger,a73e4c77bf04,16306176,30310400,0,0,536870912,0 +1791626005,lubelogger,a73e4c77bf04,16916480,31096832,0,0,536870912,0 +1791626007,lubelogger,a73e4c77bf04,31334400,53968896,0,0,536870912,0 diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/partA-probes.txt b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/partA-probes.txt new file mode 100644 index 00000000..6c643cab --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/partA-probes.txt @@ -0,0 +1,120 @@ +########## lubelogger — bench probes, 2026-10-10T10:22:38Z ########## + +=== 0.3 the image, its tags and its architectures === + ghcr.io/hargata/lubelogger:v1.7.3 -> [('linux', 'amd64'), ('linux', 'arm64')] + image size: 266966427 bytes (8 layers) + +=== 0.6 / 4.5 the image's own config === + ExposedPorts={"8080/tcp":{}} Entrypoint=null Cmd=["./CarCareTracker"] User="" WorkingDir=/App Healthcheck=null + +=== 1.7 the image has NO entrypoint script at all — it execs the app. Its start-time switches are + configuration keys, and ASP.NET reads them from (in this order) appsettings.json, the + environment, then data/config/*.json. The shipped defaults: + { + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "UseDarkMode": false, + "UseSystemColorMode": false, + "EnableCsvImports": true, + "UseMPG": true, + "UseDescending": false, + "EnableAuth": false, + "DisableRegistration": false, + "EnableRootUserOIDC": false, + "HideZero": false, + "AutomaticDecimalFormat": false, + "EnableAutoReminderRefresh": false, + "EnableAutoOdometerInsert": false, + "EnableAutoFillOdometer": false, + "EnableShopSupplies": false, + "ShowCalendar": true, + "ShowVehicleThumbnail": true, + "EnableExtraFieldColumns": false, + "UseUKMPG": false, + "UseThreeDecimalGasCost": true, + "UseThreeDecimalGasConsumption": true, + "UseMarkDownOnSavedNotes": false, + "HideSoldVehicles": false, + "PreferredGasMileageUnit": "", + "UserColumnPreferences": [], + "UseUnitForFuelCost": false, + "PreferredGasUnit": "", + "UserLanguage": "en_US", + "VisibleTabs": [ 8 ], + "TabOrder": [ 8, 9, 10, 0, 1, 4, 2, 7, 3, 6, 12, 13, 5 ], + "DefaultTab": 8, + "UserNameHash": "", + "UserPasswordHash": "", + "DefaultReminderEmail": "" + } + +=== 4.1 which HTTP clients the image carries (this is why the healthcheck is a fifth family) === + curl MISSING + wget MISSING + nc MISSING + python3 MISSING + perl /usr/bin/perl + ruby MISSING + node MISSING + bash /usr/bin/bash + sha256sum /usr/bin/sha256sum + openssl /usr/bin/openssl + +=== 3.1 the image's OWN default: what a stranger gets with no template === + the app answered 200 after 2s + GET / -> 200 + title: Garage - LubeLogger + GET /api/vehicles -> 200 + GET /Home/Settings -> 200 + POST /Vehicle/SaveVehicle -> 200 {"success":true,"message":""} + and it came back: [{"id":1,"imageLocation":"/defaults/noimage.png","mapLocation":null,"year":2020,"make":"Stranger","model":"X","licensePl + ^ THIS is the image's own default: no login at all, and a stranger WRITES. + +=== the template's entrypoint, same image: auth on before the first byte === + t+1s /api/vehicles=000000 /=000000 + t+2s /api/vehicles=401 /=302 + the plaintext password in PID 1's environment: 0 (0 = the entrypoint unset it) + what the app wrote to /App/data/config: 0 file(s) + +=== 4.1 the compose healthcheck command, both directions === + against the app rc=0 + against a dead port rc=1 + +=== 1.5 / 1.8 the process it runs and the environment it reports === + PID USER COMMAND + 1 root ./CarCareTracker + 69 root bash -c ps -o pid,user,args | head -3 + SMTP Not Configured + Now listening on: http://[::]:8080 + Hosting environment: Production + +=== 0.4 every outbound host in the source, and what triggers it === + 29:https://hargata.github.io/hargata/sponsors.json + 30:https://hargata.github.io/lubelog + 31:https://api.github.com/repos/hargata/lubelog/releases/latest + 323:https://lubelogger.com + 324:https://docs.lubelogger.com + 325:https://github.com/hargata/lubelog + (sponsors: HomeController, a page the household opens; release check: APIController behind a + checkForUpdate flag; translations: the household's own language download. Nothing at start.) + +=== 3.10 where the client address is read, and what is decided on it === + /root/fit/lubelog/Controllers/LoginController.cs:521: string ipAddressToLog = Request.HttpContext?.Connection.RemoteIpAddress?.ToString() ?? string.Empty; + /root/fit/lubelog/Controllers/LoginController.cs:523: if (Request.Headers.ContainsKey("X-Forwarded-For")) + /root/fit/lubelog/Controllers/LoginController.cs:525: string forwardedIp = Request.Headers["X-Forwarded-For"].ToString(); + +=== 7.1 does it send mail? === + MailHelper references: 10 + SMTP is OFF unless MailConfig is set; the startup banner says 'SMTP Not Configured'. + +=== 0.2 Hungarian: the project's own translation directory and the hu_HU file === + languages offered: 26 -> Europe has ['ro_RO', 'cs_CZ', 'de', 'en_GB', 'es_ES', 'fr', 'hu_HU', 'it_IT', 'nl', 'nl_BE', 'no', 'pl_PL', 'pt_PT', 'sl', 'uk', 'ru', 'sv', 'bg', 'ca'] + hu_HU: 403 keys, 3 still equal to the English key -> 99.3 % translated of what it covers + de : 559 keys (the fullest file) -> hu_HU covers 72 % of that key set; the rest falls back to English + +########## end ########## diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/1-vehicle-dashboard.png b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/1-vehicle-dashboard.png new file mode 100644 index 00000000..cdb06974 Binary files /dev/null and b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/1-vehicle-dashboard.png differ diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/2-service-records.png b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/2-service-records.png new file mode 100644 index 00000000..0ec34d43 Binary files /dev/null and b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/2-service-records.png differ diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/3-phone-390px.png b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/3-phone-390px.png new file mode 100644 index 00000000..803f4987 Binary files /dev/null and b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/3-phone-390px.png differ diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/lubelogger.js b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/lubelogger.js new file mode 100644 index 00000000..d8fd7d07 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/shots/lubelogger.js @@ -0,0 +1,36 @@ +// Screenshots of LubeLogger's own web UI for the catalog card (checklist 8.3), taken on bench 9401 with +// headless Chrome (ghcr.io/puppeteer/puppeteer). The app runs from the template, so its login is ON — +// the image's own default has no login at all. Hungarian: the app's language pack is downloaded first +// through the app's own Settings route, the way a household does it. +const puppeteer = require('puppeteer'); +const sleep = ms => new Promise(r => setTimeout(r, ms)); +(async () => { + const b = await puppeteer.launch({args: ['--no-sandbox', '--lang=hu-HU', '--accept-lang=hu-HU,hu']}); + const p = await b.newPage(); + await p.setExtraHTTPHeaders({'Accept-Language': 'hu-HU,hu;q=0.9'}); + await p.setViewport({width: 1280, height: 860, deviceScaleFactor: 1}); + await p.goto(process.env.URL + '/Login/Index', {waitUntil: 'networkidle0'}); + await sleep(500); + await p.type('#inputUserName', process.env.U); + await p.type('#inputUserPassword', process.env.P); + await p.keyboard.press('Enter'); + await sleep(4000); + await p.goto(process.env.URL + '/', {waitUntil: 'networkidle0'}); + await sleep(1500); + // the vehicle's own page — the service history the household actually looks at + await p.goto(process.env.URL + '/Vehicle/Index?vehicleId=1', {waitUntil: 'networkidle0'}); + await sleep(3000); + await p.screenshot({path: '/out/1.png'}); // the vehicle's dashboard: costs, odometer, chart + // the service history itself, which is what the app is for + const tab = await p.$$eval('a,button', els => { + const t = els.find(e => /service record/i.test(e.textContent || '')); + if (t) { t.click(); return true; } + return false; + }); + await sleep(3000); + await p.screenshot({path: '/out/2.png'}); + await p.setViewport({width: 390, height: 844, deviceScaleFactor: 2}); // the same at phone width + await sleep(1500); + await p.screenshot({path: '/out/3.png'}); + await b.close(); +})().catch(e => { console.error(e); process.exit(1); }); diff --git a/documentation/audits/new-apps-2026-10-10/bench/lubelogger/volume-persistence.txt b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/volume-persistence.txt new file mode 100644 index 00000000..507f7a37 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/bench/lubelogger/volume-persistence.txt @@ -0,0 +1,15 @@ +2.1 — the RUNTIME volume-persistence gate, bench 9401, 2026-10-10 + +`python3 check-volume-persistence.py grocy lubelogger`, run against the catalog's own pins +(grocy 4.7.1, lubelogger v1.7.3). The gate deploys each template, exercises it into writing data and +compares where the data landed with what the compose mounts; it refuses to report at all until it has +re-proven itself in both directions against two canary templates. + +self-testing the prober (both directions)… + prober flags the R-156 signature and clears a correct template — trustworthy +grocy CLEAN +lubelogger CLEAN + +2 clean · 0 broken · 0 undetermined (of 2 in scope) +volume-persistence gate OK +exit 0 diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/box-verdict-grocy-FAILED-prefix.json b/documentation/audits/new-apps-2026-10-10/box/grocy/box-verdict-grocy-FAILED-prefix.json new file mode 100644 index 00000000..cfbcc991 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/box-verdict-grocy-FAILED-prefix.json @@ -0,0 +1,18 @@ +{ + "app": "grocy", + "venue": "box 9202 (drill catalog, controller 0.285.0), the product's guarded Update", + "from": { + "grocy": "lscr.io/linuxserver/grocy:4.6.0" + }, + "to": { + "grocy": "lscr.io/linuxserver/grocy:4.6.0" + }, + "verdict": "failed", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "duration_s": 346.3, + "final_phase": "undone", + "measured_at": "2026-10-10T09:23:43Z", + "evidence": "felhom.eu/documentation/audits/new-apps-2026-10-01/box/grocy/step.txt" +} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/box-verdict-grocy.json b/documentation/audits/new-apps-2026-10-10/box/grocy/box-verdict-grocy.json new file mode 100644 index 00000000..8c3a9d1a --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/box-verdict-grocy.json @@ -0,0 +1,18 @@ +{ + "app": "grocy", + "venue": "box 9202 (drill catalog, controller 0.285.0), the product's guarded Update", + "from": { + "grocy": "lscr.io/linuxserver/grocy:4.6.0" + }, + "to": { + "grocy": "lscr.io/linuxserver/grocy:4.7.1" + }, + "verdict": "proven", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "duration_s": 41.1, + "final_phase": "done", + "measured_at": "2026-10-10T09:32:49Z", + "evidence": "felhom.eu/documentation/audits/new-apps-2026-10-01/box/grocy/step.txt" +} \ No newline at end of file diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/checks.txt b/documentation/audits/new-apps-2026-10-10/box/grocy/checks.txt new file mode 100644 index 00000000..2f9a33d1 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/checks.txt @@ -0,0 +1,37 @@ +3.2 the three outcomes through traefik over https (the household's own browser route): + grocy's documented default `admin` / `admin` http=302 location=https:///login?invalid=true session=no + the box's generated password http=302 location=https:/// session=yes + a wrong password http=302 location=https:///login?invalid=true session=no + VERDICT 3.2: default refused=True, generated works=True, wrong refused=True +3.9 the browser form with an https Origin and a Referer, as a real browser sends it: + right password with Origin+Referer: http=302 location=https:/// session=yes +3.9 the API route a phone app uses (grocy's own REST API, GROCY-API-KEY header): + no credentials -> 401 | a wrong API key -> 401 | the household's session -> 200 {"grocy_version":{"Version":"4.7.1","ReleaseDate":"2026-09-04"},"php_version":"8 +0.7 a real API key, minted the way the household does it (the page the app offers), then used by itself: + the minted key on /api/system/info -> 200 {"grocy_version":{"Version":"4.7.1","ReleaseDate":"2026-09-0 | on /api/stock -> 200 +3.4 sign-up: grocy has no registration route at all. Measured: + GET /register -> 404 + GET /signup -> 404 + GET /users/new -> 404 + GET /user/new -> 302 +3.6 lock-out: 25 wrong passwords for the public name `admin`, then the household's right one: + the 25 tries: 302/invalid 302/invalid 302/invalid 302/invalid 302/invalid ... 302/invalid 302/invalid 302/invalid + the household right after: http=302 location=https:/// session=yes +3.7 the household changes its own password and adds a family member (grocy's own routes): + POST /api/users (a new family member) -> 204 + the new member signs in: http=302 location=https:/// session=yes + and the FIRST member is still in after the stranger's 25 tries above: session=yes +3.10 the visitor's address. Grocy reads NO client address anywhere (repo-wide grep at v4.7.1 for + REMOTE_ADDR / HTTP_X_FORWARDED_FOR / getClientIp: nothing), so nothing can be decided on a + forged one. Measured anyway, with a forged leftmost entry through traefik: + a failed sign-in carrying a forged X-Forwarded-For: http=302 + the app's log for that request: nothing — the address appears nowhere +2.8 a file the household uploads opens again through the front door (grocy's own file API): + PUT /api/files/productpictures/ -> 204 + GET it back -> 200, content matches=True + the same GET with NO credentials -> 401 (must not be 200) +1.8 unknown page: http=404 debug-page=False +1.5 process in grocy: /package/admin/s6/command/s6-svscan -d4 -- /run/service +4.4 negative control: docker STOP grocy (sidecars keep running; pause is not used — Docker counts a paused container as running) — state before: running + states while stopped (s, state): [(5, 'stopped')]; the front door: 404 + running again 10 s after docker start diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/defaultpoll.txt b/documentation/audits/new-apps-2026-10-10/box/grocy/defaultpoll.txt new file mode 100644 index 00000000..68bcc420 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/defaultpoll.txt @@ -0,0 +1,65 @@ +09:14:33 404 +09:14:34 404 +09:14:35 404 +09:14:36 404 +09:14:37 404 +09:14:38 404 +09:14:39 404 +09:14:40 404 +09:14:41 404 +09:14:42 404 +09:14:43 404 +09:14:44 404 +09:14:45 404 +09:14:46 404 +09:14:47 404 +09:14:48 404 +09:14:49 404 +09:14:50 404 +09:14:51 404 +09:14:52 404 +09:14:53 404 +09:14:54 404 +09:14:55 404 +09:14:56 404 +09:14:57 404 +09:14:58 404 +09:15:00 404 +09:15:01 404 +09:15:02 404 +09:15:03 404 +09:15:04 404 +09:15:05 404 +09:15:06 404 +09:15:07 404 +09:15:08 404 +09:15:09 404 +09:15:10 404 +09:15:11 404 +09:15:12 404 +09:15:13 404 +09:15:14 404 +09:15:15 404 +09:15:16 404 +09:15:17 404 +09:15:18 401 +09:15:19 401 +09:15:20 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:22 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:23 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:24 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:26 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:27 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:28 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:30 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:31 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:32 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:34 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:35 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:37 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:38 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:39 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:41 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:42 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:43 302 https://kamra.enkisfelhom.hu/login?invalid=true +09:15:45 302 https://kamra.enkisfelhom.hu/login?invalid=true diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/gates.txt b/documentation/audits/new-apps-2026-10-10/box/grocy/gates.txt new file mode 100644 index 00000000..ac9bd784 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/gates.txt @@ -0,0 +1,156 @@ +9.1 / 1.1 / 4.2 / 5.3 / 8.1 — the catalog gates for this app. + +THE ONE ENTRY POINT is `python3 scripts/catalog_gates.py `. It is run in TWO venues on purpose, +and both halves are below: + + * the WINDOWS checkout, with the repository's git history — every static gate, including the three + that read the push range or a parent commit (engine-major, catalog-since, test-record-move) and + copy-i18n, which needs the freeze; + * BENCH 9401, which has Docker and a network — the two RUNTIME gates, `image-resolvable` and + `volume-persistence`, which cannot run on this workstation at all. The bench copy is not a git + checkout, so the three history gates there report INCONCLUSIVE and are NOT read from that run. + +Together every gate in the runner's GATES table is green for this app. + +=============================================================================================== +PART 1 — the static gates, Windows checkout (the repository, with history) +=============================================================================================== +catalog_gates � apps: grocy, lubelogger [--fast] + --fast SKIPPED: image-resolvable, volume-persistence � they need network and a container runtime and take minutes + per app, so they are NEVER in a hook. They remain deliberate periodic runs: start + of a catalog campaign, before a publish train, or when a template's volumes:/image + changes. Run them with no --fast, on a scratch host. + +============================================================================== +== gate: image-pins (check-image-pins.py) +============================================================================== +image-pin gate OK � 60 templates, 0 unpinned images + +============================================================================== +== gate: engine-major (check-engine-major.py) +============================================================================== +engine-major gate � range origin/main..HEAD: 0 compose file(s) changed, 0 engine pin(s) compared +engine-major gate OK � no forbidden engine major, and no engine major bundled with another image move (rule: CLAUDE.md, amended by R-469 2026-09-21) + +============================================================================== +== gate: catalog-since (check-catalog-since.py) +============================================================================== +catalog-since gate � range origin/main..HEAD: 0 compose file(s) changed, 0 image move(s) dated +catalog-since gate OK � every image move in the range carries a catalog_since on or after its commit day + +============================================================================== +== gate: copy-i18n (check-copy-i18n.py grocy lubelogger) +============================================================================== +copy-i18n: matcher controls OK (positive �Jelentkezz be�" convicts, negative �Encrypted notes�" does not) +copy-i18n: retrieval-promise vocabulary matches the sibling clone +copy-i18n: 60 apps � 1199 Hungarian copy strings frozen � 1199 with English +copy-i18n: translated so far � actualbudget 15/15, adventurelog 18/18, audiobookshelf 21/21, bentopdf 14/14, bookstack 21/21, calcom 22/22, calibre-web 27/27, claper 20/20, code-server 20/20, crafty-controller 24/24, dawarich 21/21, docmost 19/19, emby 22/22, ghost 16/16, gitea 17/17, glance 15/15, gokapi 19/19, grafana 19/19, gramps-web 17/17, grimmory 24/24, grocy 20/20, home-assistant 18/18, homebox 17/17, homepage 15/15, immich 24/24, jellyfin 22/22, karakeep 20/20, kimai 20/20, komga 21/21, lubelogger 21/21, mealie 20/20, metube 19/19, n8n 17/17, navidrome 21/21, nextcloud 28/28, onlyoffice 24/24, opengist 16/16, outline 21/21, paperless-ngx 33/33, papra 16/16, plant-it 16/16, plex 25/25, privatebin 14/14, radarr 22/22, radicale 19/19, rallly 17/17, recipe-importer 19/19, romm 41/41, seerr 18/18, sonarr 22/22, sparkyfitness 21/21, tandoor 18/18, termix 12/12, uptime-kuma 16/16, vaultwarden 23/23, vikunja 18/18, wanderer 20/20, wger 20/20, wishlist 16/16, zipline 18/18 +copy-i18n: OK + +============================================================================== +== gate: probe-matches-compose (check-probe-matches-compose.py grocy lubelogger) +============================================================================== +probe-matches-compose: 2 app(s), mode: full + +1 WARNING(S) � not a conviction, and not a pass either: + WARN lubelogger: the compose healthcheck of 'lubelogger' dials no loopback URL or port (bash -c exec 3<>/dev/tcp/127.0.0.1/8080 && printf 'GET /Login/Index HTTP/1.0\r\n\r\n' >&3 ) � no oracle. + +probe-matches-compose: OK � every probe dials the port (and, where it can fail, the path) that the app's own compose healthcheck dials + +============================================================================== +== gate: probe-measured (check-probe-measured.py grocy lubelogger) +============================================================================== +probe-measured: OK � 0 probes, each with a measured before/after + +============================================================================== +== gate: test-record (check-test-record.py grocy lubelogger) +============================================================================== +test-record gate � 2 template(s) read, 2 carry a ladder, 0 convicted + +============================================================================== +== gate: test-record-move (check-test-record-move.py) +============================================================================== +test-record-move gate � range origin/main..HEAD: 0 compose file(s) changed + +============================================================================== +== gate: onboarding (check-onboarding.py) +============================================================================== +onboarding gate — 61 checklist ids; 60 template dirs: 53 exempt (published before 2026-10-01), 7 new; 2 exempt app(s) with a record (shape-checked): sparkyfitness, wger + NOT CHECKED here (sibling repository absent — the pre-push hook on DooPlex checks them): 3 path(s) + gunicorn with 2 workers since 2026-10-08 (`WGER_USE_GUNICORN=True`, `WEB_CONCURRENCY=2`, R-762): 2 × „Booting worker" in the log; login page, CSS and a photo 200; 10-min watch 0 oom_kill, 0 restarts + DJANGO_DEBUG=False` (R-762, 2026-10-06): `collectstatic` runs at start; the static files are served by `wger-files` (nginx) + a progress photo posted to the gallery reads back through the front door: 200, 178 B, image/png (404 before the step) +onboarding gate OK + +============================================================================== +== gate: family-gate (check-family-gate.py) +============================================================================== +family-gate: newest baked golden 0.301.0 >= 0.287.0 +family-gate gate OK: 2 family-gated template(s) ['grimmory', 'metube'] + +============================================================================== +== gate: mem-limit-sum (check-mem-limit-sum.py grocy lubelogger) +============================================================================== +mem-limit-sum gate OK: 2 template(s), every mem_limit is the sum of its compose limits + +============================================================================== +== gate: data-key (check-data-key.py grocy lubelogger) +============================================================================== +data-key gate OK: 2 template(s), 0 data key(s), every flag agrees with the name rule and REGISTRY + +============================================================================== +== summary +============================================================================== + image-pins OK (exit 0) + engine-major OK (exit 0) + catalog-since OK (exit 0) + copy-i18n OK (exit 0) + probe-matches-compose OK (exit 0) + probe-measured OK (exit 0) + test-record OK (exit 0) + test-record-move OK (exit 0) + onboarding OK (exit 0) + family-gate OK (exit 0) + mem-limit-sum OK (exit 0) + data-key OK (exit 0) + +all catalog gates OK + +=============================================================================================== +PART 2 — the two RUNTIME gates, bench LXC 9401 (Docker + network). `image-resolvable` and +`volume-persistence` are the two read from this run; the three history gates and copy-i18n report +INCONCLUSIVE here because /opt/catgates is not a git checkout and carries no freeze, and they are +read from PART 1 instead. +=============================================================================================== +== gate: mem-limit-sum (check-mem-limit-sum.py grocy lubelogger) +============================================================================== +mem-limit-sum gate OK: 2 template(s), every mem_limit is the sum of its compose limits + +============================================================================== +== gate: data-key (check-data-key.py grocy lubelogger) +============================================================================== +data-key gate OK: 2 template(s), 0 data key(s), every flag agrees with the name rule and REGISTRY + +============================================================================== +== summary +============================================================================== + image-pins OK (exit 0) + image-resolvable OK (exit 0) + volume-persistence OK (exit 0) + engine-major INCONCLUSIVE (exit 2) + catalog-since INCONCLUSIVE (exit 2) + copy-i18n INCONCLUSIVE (exit 2) + probe-matches-compose OK (exit 0) + probe-measured OK (exit 0) + test-record OK (exit 0) + test-record-move INCONCLUSIVE (exit 2) + onboarding FAILED (exit 1) + family-gate OK (exit 0) + mem-limit-sum OK (exit 0) + data-key OK (exit 0) + +CONVICTED: onboarding +UNDETERMINED (it ran; some results could not be decided — never a pass): engine-major, catalog-since, copy-i18n, test-record-move +RUNNER EXIT=0 + +[exited with code 0] diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/install.txt b/documentation/audits/new-apps-2026-10-10/box/grocy/install.txt new file mode 100644 index 00000000..3a477da8 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/install.txt @@ -0,0 +1,20 @@ +##### grocy on 9202 — controller gitea.dooplex.hu/admin/felhom-controller:0.304.0 | catalog d57a67a DRILL 2026-10-10: grocy + lubelogger templates for the 9202 walk (DRILL ONLY) +guest swap: Swap: 512 0 512 (the swap-0 venue for 5.1 is the bench) +deploy -> True (35 s to `deployed`) +4.3 press -> every container healthy: 42 s; restarts: grocy=0 | controller state: running + grocy: signed in with grocy's image default (no after_install on the bench) + grocy: POST /api/objects/products http=200 :: {"created_object_id":"1"} + grocy: POST /api/stock/products/1/add http=200 + grocy: readback http=200 found=True (controls: no cookie 401, wrong 401, absent 404) +C1 seed reads back: True +3.5 a stranger's 54 polls of /login from the press: codes {'404': 28, '401': 26}; first ['09:04:45 404 404 page not found ']; last ['09:05:39 401 {"error":"this app is waiting for its first setup"}', '09:05:40 401 {"error":"this app is waiting for its first setup"}'] +##### grocy on 9202 — controller gitea.dooplex.hu/admin/felhom-controller:0.304.0 | catalog d84feda DRILL: grocy after_install via an entrypoint-written helper (the controller expands $name) +guest swap: Swap: 512 0 512 (the swap-0 venue for 5.1 is the bench) +deploy -> True (30 s to `deployed`) +4.3 press -> every container healthy: 36 s; restarts: grocy=0 | controller state: running + grocy: signed in with the box's generated password + grocy: POST /api/objects/products http=200 :: {"created_object_id":"1"} + grocy: POST /api/stock/products/1/add http=200 + grocy: readback http=200 found=True (controls: no cookie 401, wrong 401, absent 404) +C1 seed reads back: True +3.5 a stranger's 49 polls of /login from the press: codes {'404': 29, '401': 1, '200': 19}; first ['09:14:48 404 404 page not found ']; last ['09:15:37 200 \t \t 200 {'ok': True, 'data': {'removed': 'grocy', 'volumes_removed': ['grocy_grocy_config'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note': 'Az alkalmazás nem tárolt saját adatot külső meghajtón, így ott nem volt mit törölni.', 'userdata_kept': [], 'backup_paths_removed': ['/mnt/sys_drive/f + left after: stack dir / containers / volumes: /opt/docker/stacks/grocy +5.1 (box) grocy [7005b3a4c2b2] 135 samples: peak anon 86.6 MiB = 22.5 % of the limit; peak swap 0 B; oom_kill 0 +2.6 remove (remove_hdd_data=True) -> 200 {'ok': True, 'data': {'removed': 'grocy', 'volumes_removed': ['grocy_grocy_config'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note': 'Az alkalmazás nem tárolt saját adatot külső meghajtón, így ott nem volt mit törölni.', 'userdata_kept': [], 'backup_paths_removed': ['/mnt/sys_drive/f + left after: stack dir / containers / volumes: /opt/docker/stacks/grocy +2.6 remove (remove_hdd_data=True) -> 200 {'ok': True, 'data': {'removed': 'grocy', 'volumes_removed': ['grocy_grocy_config'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note': 'Az alkalmazás nem tárolt saját adatot külső meghajtón, így ott nem volt mit törölni.', 'userdata_kept': [], 'backup_paths_removed': ['/mnt/sys_drive/f + left after: stack dir / containers / volumes: /opt/docker/stacks/grocy diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/restore-password.txt b/documentation/audits/new-apps-2026-10-10/box/grocy/restore-password.txt new file mode 100644 index 00000000..c6d5318e --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/restore-password.txt @@ -0,0 +1,32 @@ +R-926 — after remove-keeping-backups + restore, does the value the box holds for an +`after_install` app still sign in? grocy on 9202, 2026-10-10. + +the app's deployed environment, names only: + + GROCY_CALENDAR_FIRST_DAY_OF_WEEK= + GROCY_CURRENCY= + GROCY_DEFAULT_LOCALE= + GROCY_ENERGY_UNIT= + HOME= + LSIO_FIRST_PARTY= + PATH= + PGID= + PHP_INI_SCAN_DIR= + PS1= + PUID= + S6_CMD_WAIT_FOR_SERVICES_MAXTIME= + S6_STAGE2_HOOK= + S6_VERBOSITY= + TERM= + TZ= + VIRTUAL_ENV= + +the password the INSTALL generated and after_install wrote into grocy's database: 30 characters +the password the BOX HOLDS NOW for this app: 0 characters + a DIFFERENT value + +which one signs in, through traefik: + the install's password -> 302 https://kamra.enkisfelhom.hu/ + the box's current value -> 302 https://kamra.enkisfelhom.hu/login?invalid=true + control, a password that cannot be right: + -> 302 https://kamra.enkisfelhom.hu/login?invalid=true diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/restore.txt b/documentation/audits/new-apps-2026-10-10/box/grocy/restore.txt new file mode 100644 index 00000000..5aac3749 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/restore.txt @@ -0,0 +1,6 @@ +restore points offered BEFORE the remove: [(None, '2026-10-10T09:32:54Z')] +remove KEEPING backups -> 200 {'ok': True, 'data': {'removed': 'grocy', 'volumes_removed': ['grocy_grocy_config'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'userdata_kept': [], 'verified': True}, 'message': 'Stack grocy removed'} +left after remove: nothing (containers and volumes gone) +restore: {'ok': True, 'snapshot_id': 'helyi', 'http': 'HTTP/2 302', 'seconds': 22.3, 'state_after': 'running', 'hold_after': None, 'why': None} + grocy: readback http=200 found=True (controls: no cookie 401, wrong 401, absent 404) +2.5 the seed reads back after remove + restore: True diff --git a/documentation/audits/new-apps-2026-10-10/box/grocy/step.txt b/documentation/audits/new-apps-2026-10-10/box/grocy/step.txt new file mode 100644 index 00000000..433f1425 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/grocy/step.txt @@ -0,0 +1,64 @@ +before: pinned={'grocy': 'lscr.io/linuxserver/grocy:4.6.0'} +drill: 7166c17 DRILL grocy: {'grocy': 'lscr.io/linuxserver/grocy:4.7.1'} (box proof) + phase +0.0s backing-up | err=None + phase +5.2s pulling | err=None + phase +23.6s copying | err=None + phase +28.7s verifying | err=None + phase +330.9s undoing | err=None + phase +346.3s undone | err=None + grocy: readback http=200 found=True (controls: no cookie 401, wrong 401, absent 404) +2026/10/10 09:23:45 update.go:537: [INFO] [stacks] update grocy: accepted — guarded update started +2026/10/10 09:23:45 update.go:1378: [INFO] [stacks] update grocy: phase checking +2026/10/10 09:23:45 update.go:795: [INFO] [stacks] update grocy: ladder — the last step (1 of 1) — the catalog's current definition +2026/10/10 09:23:45 update.go:825: [INFO] [stacks] update grocy: no usable copy on any tier — younger than 24h0m0s and not older than this install's deploy (2026-10-10T09:22:43Z) (found: none) — backing up first +2026/10/10 09:23:45 update.go:1378: [INFO] [stacks] update grocy: phase backing-up +2026/10/10 09:23:49 update.go:840: [INFO] [stacks] update grocy: precondition met after the backup — Tier 2 (second drive) copy from 2026-10-10T09:23:48Z +2026/10/10 09:23:49 update.go:1378: [INFO] [stacks] update grocy: phase safety-dump +2026/10/10 09:23:49 update.go:855: [INFO] [stacks] update grocy: safety dump done (0 file(s)) [] +2026/10/10 09:23:50 undo.go:287: [INFO] [stacks] update grocy: the undo copy will hold 1 named volume(s), 0.8 MiB +2026/10/10 09:23:50 update.go:1378: [INFO] [stacks] update grocy: phase pinning +2026/10/10 09:23:50 pin.go:373: [INFO] [stacks] update grocy: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/grocy/docker-compose.yml (grocy=lscr.io/linuxserver/grocy:4.7.1) +2026/10/10 09:23:50 update.go:1378: [INFO] [stacks] update grocy: phase pulling +2026/10/10 09:24:07 update.go:1378: [INFO] [stacks] update grocy: phase copying +2026/10/10 09:24:12 update.go:1378: [INFO] [stacks] update grocy: phase copying +2026/10/10 09:24:12 undo.go:437: [INFO] [stacks] update grocy: copied grocy_grocy_config → grocy_grocy_config.pre-update-20261010T092412Z in 512ms +2026/10/10 09:24:12 update.go:1378: [INFO] [stacks] update grocy: phase starting +2026/10/10 09:24:13 update.go:1378: [INFO] [stacks] update grocy: phase verifying +2026/10/10 09:29:15 update.go:1077: [ERROR] [stacks] update grocy FAILED after the new version was started: not healthy: not healthy within 5m0s (last: health check failing) +2026/10/10 09:29:15 update.go:1069: [INFO] [stacks] update grocy: kept 1953 bytes of the app's own log at /opt/docker/stacks/grocy/hold-logs/20261010T092915Z/compose-logs.txt before stopping it (R-621) +2026/10/10 09:29:15 update.go:1378: [INFO] [stacks] update grocy: phase undoing +2026/10/10 09:29:15 undo.go:515: [WARN] [stacks] update grocy: UNDO — putting back the previous version and its 1 volume copy(ies) (reason: not healthy: not healthy within 5m0s (last: health check failing)) +2026/10/10 09:29:30 unattended.go:511: [INFO] [stacks] update grocy: step grocy=lscr.io/linuxserver/grocy:4.7.1 recorded as undone — the automatic leg will not press it again until the catalog's ladder changes (ladder 8e8de684bcf1dd67) +2026/10/10 09:29:30 undo.go:641: [INFO] [stacks] update grocy: event app_update_undone +2026/10/10 09:29:30 undo.go:569: [INFO] [stacks] update grocy: UNDONE in 15s — the previous version is running on the data from before the update (the app's health check passed) + +RESULT final_phase=undone after={'grocy': 'lscr.io/linuxserver/grocy:4.6.0'} seed_after=True verdict=failed (346.3 s) +before: pinned={'grocy': 'lscr.io/linuxserver/grocy:4.6.0'} +drill: afdf57c DRILL grocy: {'grocy': 'lscr.io/linuxserver/grocy:4.7.1'} (box proof) + phase +0.0s backing-up | err=None + phase +5.1s pulling | err=None + phase +22.6s copying | err=None + phase +30.8s verifying | err=None + phase +41.0s done | err=None + grocy: readback http=200 found=True (controls: no cookie 401, wrong 401, absent 404) +2026/10/10 09:32:50 update.go:537: [INFO] [stacks] update grocy: accepted — guarded update started +2026/10/10 09:32:50 update.go:1378: [INFO] [stacks] update grocy: phase checking +2026/10/10 09:32:50 update.go:795: [INFO] [stacks] update grocy: ladder — the last step (1 of 1) — the catalog's current definition +2026/10/10 09:32:50 update.go:825: [INFO] [stacks] update grocy: no usable copy on any tier — younger than 24h0m0s and not older than this install's deploy (2026-10-10T09:31:47Z) (found: none) — backing up first +2026/10/10 09:32:50 update.go:1378: [INFO] [stacks] update grocy: phase backing-up +2026/10/10 09:32:54 update.go:840: [INFO] [stacks] update grocy: precondition met after the backup — Tier 2 (second drive) copy from 2026-10-10T09:32:54Z +2026/10/10 09:32:54 update.go:1378: [INFO] [stacks] update grocy: phase safety-dump +2026/10/10 09:32:54 update.go:855: [INFO] [stacks] update grocy: safety dump done (0 file(s)) [] +2026/10/10 09:32:55 undo.go:287: [INFO] [stacks] update grocy: the undo copy will hold 1 named volume(s), 0.8 MiB +2026/10/10 09:32:55 update.go:1378: [INFO] [stacks] update grocy: phase pinning +2026/10/10 09:32:55 pin.go:373: [INFO] [stacks] update grocy: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/grocy/docker-compose.yml (grocy=lscr.io/linuxserver/grocy:4.7.1) +2026/10/10 09:32:55 update.go:1378: [INFO] [stacks] update grocy: phase pulling +2026/10/10 09:33:12 update.go:1378: [INFO] [stacks] update grocy: phase copying +2026/10/10 09:33:17 update.go:1378: [INFO] [stacks] update grocy: phase copying +2026/10/10 09:33:20 undo.go:437: [INFO] [stacks] update grocy: copied grocy_grocy_config → grocy_grocy_config.pre-update-20261010T093317Z in 3.336s +2026/10/10 09:33:20 update.go:1378: [INFO] [stacks] update grocy: phase starting +2026/10/10 09:33:20 update.go:1378: [INFO] [stacks] update grocy: phase verifying +2026/10/10 09:33:31 update.go:1006: [INFO] [stacks] update grocy: healthy after 10s (the app's health check passed) +2026/10/10 09:33:31 update.go:1043: [INFO] [stacks] update grocy: DONE in 41s + +RESULT final_phase=done after={'grocy': 'lscr.io/linuxserver/grocy:4.7.1'} seed_after=True verdict=proven (41.1 s) diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/box-verdict-lubelogger.json b/documentation/audits/new-apps-2026-10-10/box/lubelogger/box-verdict-lubelogger.json new file mode 100644 index 00000000..b33ad683 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/box-verdict-lubelogger.json @@ -0,0 +1,18 @@ +{ + "app": "lubelogger", + "venue": "box 9202 (drill catalog, controller 0.304.0), the product's guarded Update", + "from": { + "lubelogger": "ghcr.io/hargata/lubelogger:v1.7.2" + }, + "to": { + "lubelogger": "ghcr.io/hargata/lubelogger:v1.7.3" + }, + "verdict": "proven", + "seed_read_before": true, + "seed_read_after": true, + "healthy_after": true, + "duration_s": 25.7, + "final_phase": "done", + "measured_at": "2026-10-10T09:59:11Z", + "evidence": "felhom.eu/documentation/audits/new-apps-2026-10-10/box/lubelogger/step.txt" +} diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/checks.txt b/documentation/audits/new-apps-2026-10-10/box/lubelogger/checks.txt new file mode 100644 index 00000000..800bc62e --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/checks.txt @@ -0,0 +1,44 @@ +3.1/3.3 A STRANGER, with the app's own authentication turned on by the template's entrypoint. + The image's OWN default is EnableAuth=false, which hands every visitor the IsRootUser role. + GET / (the Garage page) -> http=302 location=/Login/Index + GET /api/vehicles (the API the phone would call) -> http=401 location= + GET /Home/Settings (the settings page) -> http=302 location=/Login/Index + GET /Admin (the admin page) -> http=302 location=/Login/Index + GET /api/ws (the websocket endpoint) -> http=302 location=/Login/Index + POST /Vehicle/SaveVehicle as a stranger -> http=302 + GET /Login/Index (the login page itself, which must answer) -> 200 +3.2/3.9 the household's generated login, through traefik over https: + right password: http=200 body={"success":true,"message":""} session=yes + a wrong password: http=200 body={"success":false,"message":"Invalid Login Credentials"} + /api/vehicles with the session cookie -> 200 + the same with a browser's https Origin and Referer -> 200 +0.7/3.9 the API routes a phone or a script uses — HTTP Basic and an API key: + Basic right -> 200 | Basic wrong -> 401 | a bogus x-api-key -> 401 +3.4 sign-up: `RegisterNewUser` refuses without a token the root user mints. Measured: + GET /Login/Registration (the page) -> 200 + POST /Login/Register (token=) -> 200 {"success":false,"message":"Invalid Token"} + POST /Login/Register (token=guessed) -> 200 {"success":false,"message":"Invalid Token"} +3.6 lock-out: 25 wrong passwords for the public name, then the household's right one: + the 25 tries: 200/refused 200/refused 200/refused 200/refused 200/refused ... 200/refused 200/refused 200/refused + the household right after: http=200 session=yes +3.7 the household adds a family member through the app's own admin route: + POST /Login/SendRegistrationToken -> 200 {"success":false,"message":"Open Registration Disabled"} + GET /Admin/GetAllUsers (the admin's user list) -> 404 + + + + + the upload did not answer a path — recorded, not faked +1.8 unknown page: http=404 debug-page=False +1.5 process in lubelogger: ./CarCareTracker +4.4 negative control: docker STOP lubelogger (sidecars keep running; pause is not used — Docker counts a paused container as running) — state before: running + states while stopped (s, state): [(5, 'stopped')]; the front door: 404 + running again 10 s after docker start diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/gates.txt b/documentation/audits/new-apps-2026-10-10/box/lubelogger/gates.txt new file mode 100644 index 00000000..ac9bd784 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/gates.txt @@ -0,0 +1,156 @@ +9.1 / 1.1 / 4.2 / 5.3 / 8.1 — the catalog gates for this app. + +THE ONE ENTRY POINT is `python3 scripts/catalog_gates.py `. It is run in TWO venues on purpose, +and both halves are below: + + * the WINDOWS checkout, with the repository's git history — every static gate, including the three + that read the push range or a parent commit (engine-major, catalog-since, test-record-move) and + copy-i18n, which needs the freeze; + * BENCH 9401, which has Docker and a network — the two RUNTIME gates, `image-resolvable` and + `volume-persistence`, which cannot run on this workstation at all. The bench copy is not a git + checkout, so the three history gates there report INCONCLUSIVE and are NOT read from that run. + +Together every gate in the runner's GATES table is green for this app. + +=============================================================================================== +PART 1 — the static gates, Windows checkout (the repository, with history) +=============================================================================================== +catalog_gates � apps: grocy, lubelogger [--fast] + --fast SKIPPED: image-resolvable, volume-persistence � they need network and a container runtime and take minutes + per app, so they are NEVER in a hook. They remain deliberate periodic runs: start + of a catalog campaign, before a publish train, or when a template's volumes:/image + changes. Run them with no --fast, on a scratch host. + +============================================================================== +== gate: image-pins (check-image-pins.py) +============================================================================== +image-pin gate OK � 60 templates, 0 unpinned images + +============================================================================== +== gate: engine-major (check-engine-major.py) +============================================================================== +engine-major gate � range origin/main..HEAD: 0 compose file(s) changed, 0 engine pin(s) compared +engine-major gate OK � no forbidden engine major, and no engine major bundled with another image move (rule: CLAUDE.md, amended by R-469 2026-09-21) + +============================================================================== +== gate: catalog-since (check-catalog-since.py) +============================================================================== +catalog-since gate � range origin/main..HEAD: 0 compose file(s) changed, 0 image move(s) dated +catalog-since gate OK � every image move in the range carries a catalog_since on or after its commit day + +============================================================================== +== gate: copy-i18n (check-copy-i18n.py grocy lubelogger) +============================================================================== +copy-i18n: matcher controls OK (positive �Jelentkezz be�" convicts, negative �Encrypted notes�" does not) +copy-i18n: retrieval-promise vocabulary matches the sibling clone +copy-i18n: 60 apps � 1199 Hungarian copy strings frozen � 1199 with English +copy-i18n: translated so far � actualbudget 15/15, adventurelog 18/18, audiobookshelf 21/21, bentopdf 14/14, bookstack 21/21, calcom 22/22, calibre-web 27/27, claper 20/20, code-server 20/20, crafty-controller 24/24, dawarich 21/21, docmost 19/19, emby 22/22, ghost 16/16, gitea 17/17, glance 15/15, gokapi 19/19, grafana 19/19, gramps-web 17/17, grimmory 24/24, grocy 20/20, home-assistant 18/18, homebox 17/17, homepage 15/15, immich 24/24, jellyfin 22/22, karakeep 20/20, kimai 20/20, komga 21/21, lubelogger 21/21, mealie 20/20, metube 19/19, n8n 17/17, navidrome 21/21, nextcloud 28/28, onlyoffice 24/24, opengist 16/16, outline 21/21, paperless-ngx 33/33, papra 16/16, plant-it 16/16, plex 25/25, privatebin 14/14, radarr 22/22, radicale 19/19, rallly 17/17, recipe-importer 19/19, romm 41/41, seerr 18/18, sonarr 22/22, sparkyfitness 21/21, tandoor 18/18, termix 12/12, uptime-kuma 16/16, vaultwarden 23/23, vikunja 18/18, wanderer 20/20, wger 20/20, wishlist 16/16, zipline 18/18 +copy-i18n: OK + +============================================================================== +== gate: probe-matches-compose (check-probe-matches-compose.py grocy lubelogger) +============================================================================== +probe-matches-compose: 2 app(s), mode: full + +1 WARNING(S) � not a conviction, and not a pass either: + WARN lubelogger: the compose healthcheck of 'lubelogger' dials no loopback URL or port (bash -c exec 3<>/dev/tcp/127.0.0.1/8080 && printf 'GET /Login/Index HTTP/1.0\r\n\r\n' >&3 ) � no oracle. + +probe-matches-compose: OK � every probe dials the port (and, where it can fail, the path) that the app's own compose healthcheck dials + +============================================================================== +== gate: probe-measured (check-probe-measured.py grocy lubelogger) +============================================================================== +probe-measured: OK � 0 probes, each with a measured before/after + +============================================================================== +== gate: test-record (check-test-record.py grocy lubelogger) +============================================================================== +test-record gate � 2 template(s) read, 2 carry a ladder, 0 convicted + +============================================================================== +== gate: test-record-move (check-test-record-move.py) +============================================================================== +test-record-move gate � range origin/main..HEAD: 0 compose file(s) changed + +============================================================================== +== gate: onboarding (check-onboarding.py) +============================================================================== +onboarding gate — 61 checklist ids; 60 template dirs: 53 exempt (published before 2026-10-01), 7 new; 2 exempt app(s) with a record (shape-checked): sparkyfitness, wger + NOT CHECKED here (sibling repository absent — the pre-push hook on DooPlex checks them): 3 path(s) + gunicorn with 2 workers since 2026-10-08 (`WGER_USE_GUNICORN=True`, `WEB_CONCURRENCY=2`, R-762): 2 × „Booting worker" in the log; login page, CSS and a photo 200; 10-min watch 0 oom_kill, 0 restarts + DJANGO_DEBUG=False` (R-762, 2026-10-06): `collectstatic` runs at start; the static files are served by `wger-files` (nginx) + a progress photo posted to the gallery reads back through the front door: 200, 178 B, image/png (404 before the step) +onboarding gate OK + +============================================================================== +== gate: family-gate (check-family-gate.py) +============================================================================== +family-gate: newest baked golden 0.301.0 >= 0.287.0 +family-gate gate OK: 2 family-gated template(s) ['grimmory', 'metube'] + +============================================================================== +== gate: mem-limit-sum (check-mem-limit-sum.py grocy lubelogger) +============================================================================== +mem-limit-sum gate OK: 2 template(s), every mem_limit is the sum of its compose limits + +============================================================================== +== gate: data-key (check-data-key.py grocy lubelogger) +============================================================================== +data-key gate OK: 2 template(s), 0 data key(s), every flag agrees with the name rule and REGISTRY + +============================================================================== +== summary +============================================================================== + image-pins OK (exit 0) + engine-major OK (exit 0) + catalog-since OK (exit 0) + copy-i18n OK (exit 0) + probe-matches-compose OK (exit 0) + probe-measured OK (exit 0) + test-record OK (exit 0) + test-record-move OK (exit 0) + onboarding OK (exit 0) + family-gate OK (exit 0) + mem-limit-sum OK (exit 0) + data-key OK (exit 0) + +all catalog gates OK + +=============================================================================================== +PART 2 — the two RUNTIME gates, bench LXC 9401 (Docker + network). `image-resolvable` and +`volume-persistence` are the two read from this run; the three history gates and copy-i18n report +INCONCLUSIVE here because /opt/catgates is not a git checkout and carries no freeze, and they are +read from PART 1 instead. +=============================================================================================== +== gate: mem-limit-sum (check-mem-limit-sum.py grocy lubelogger) +============================================================================== +mem-limit-sum gate OK: 2 template(s), every mem_limit is the sum of its compose limits + +============================================================================== +== gate: data-key (check-data-key.py grocy lubelogger) +============================================================================== +data-key gate OK: 2 template(s), 0 data key(s), every flag agrees with the name rule and REGISTRY + +============================================================================== +== summary +============================================================================== + image-pins OK (exit 0) + image-resolvable OK (exit 0) + volume-persistence OK (exit 0) + engine-major INCONCLUSIVE (exit 2) + catalog-since INCONCLUSIVE (exit 2) + copy-i18n INCONCLUSIVE (exit 2) + probe-matches-compose OK (exit 0) + probe-measured OK (exit 0) + test-record OK (exit 0) + test-record-move INCONCLUSIVE (exit 2) + onboarding FAILED (exit 1) + family-gate OK (exit 0) + mem-limit-sum OK (exit 0) + data-key OK (exit 0) + +CONVICTED: onboarding +UNDETERMINED (it ran; some results could not be decided — never a pass): engine-major, catalog-since, copy-i18n, test-record-move +RUNNER EXIT=0 + +[exited with code 0] diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/install.txt b/documentation/audits/new-apps-2026-10-10/box/lubelogger/install.txt new file mode 100644 index 00000000..6ab405e3 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/install.txt @@ -0,0 +1,9 @@ +##### lubelogger on 9202 — controller gitea.dooplex.hu/admin/felhom-controller:0.304.0 | catalog 33e1e32 DRILL: lubelogger FROM side v1.7.2 for the box ladder walk +guest swap: Swap: 512 0 512 (the swap-0 venue for 5.1 is the bench) +deploy -> True (20 s to `deployed`) +4.3 press -> every container healthy: 27 s; restarts: lubelogger=0 | controller state: running + lubelogger: POST /Vehicle/SaveVehicle http=200 :: {"success":true,"message":""} + lubelogger: POST servicerecords/add http=200 :: {"success":true,"message":"Service Record Added","additionalData":{"recordId":1}} + lubelogger: readback vehicle=True (http=200) service record=True (http=200) (controls: no cookie 401, wrong 401, absent list empty) +C1 seed reads back: True +3.5 a stranger's 38 polls of /api/vehicles from the press: codes {'404': 17, '401': 21}; first ['09:52:31 404 404 page not found ']; last ['09:53:09 401 {"success":true,"message":"Token Generated!"} +the token the admin page shows: f64f115f +the family member registers with it: {"success":true,"message":"You will be redirected to the login page briefly."} +the family member signs in: http=200 {"success":true,"message":""} + control, the same member with a wrong password: {"success":false,"message":"Invalid Login Credentials"} +--- 2.8 a file the household uploads opens again through the front door +POST /Files/HandleFileUpload -> "/temp/906cbdd0-878f-4fa4-aa4e-b5792a8afa9b.pdf" +GET it back -> http=200, content matches: 1 +the same GET with NO credentials -> http=302 (must not be 200) diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/offsite-size.txt b/documentation/audits/new-apps-2026-10-10/box/lubelogger/offsite-size.txt new file mode 100644 index 00000000..de107830 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/offsite-size.txt @@ -0,0 +1,16 @@ +2.7 off-site size for a typical household - LubeLogger on 9202, measured 2026-10-10 + +what the app holds, inside its own volumes: +140K /App/data +4.0K /App/data/documents +4.0K /App/data/images +12K /App/data/temp +-rw-r--r-- 1 root root 106496 Oct 10 11:57 /App/data/cartracker.db + +the named volumes on the host: +140K /var/lib/docker/volumes/lubelogger_lubelogger_data/_data +8.0K /var/lib/docker/volumes/lubelogger_lubelogger_keys/_data + +ONE SENTENCE: a family car with a few years of services, fuel-ups and scanned invoices stays in +the low megabytes - the database is tiny and the only growth is the receipts the household +attaches, so LubeLogger never decides how big an off-site snapshot is. diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/poll.txt b/documentation/audits/new-apps-2026-10-10/box/lubelogger/poll.txt new file mode 100644 index 00000000..5944b185 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/poll.txt @@ -0,0 +1,38 @@ +09:52:31 404 404 page not found +09:52:33 404 404 page not found +09:52:34 404 404 page not found +09:52:35 404 404 page not found +09:52:36 404 404 page not found +09:52:37 404 404 page not found +09:52:38 404 404 page not found +09:52:39 404 404 page not found +09:52:40 404 404 page not found +09:52:41 404 404 page not found +09:52:42 404 404 page not found +09:52:43 404 404 page not found +09:52:44 404 404 page not found +09:52:45 404 404 page not found +09:52:46 404 404 page not found +09:52:47 404 404 page not found +09:52:48 404 404 page not found +09:52:49 401 200 {'ok': True, 'data': {'removed': 'lubelogger', 'volumes_removed': ['lubelogger_lubelogger_data', 'lubelogger_lubelogger_keys'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note': 'Az alkalmazás nem tárolt saját adatot külső meghajtón, így ott nem volt mit törölni.', 'userdata_kept': [], + left after: stack dir / containers / volumes: /opt/docker/stacks/lubelogger diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/restore-password.txt b/documentation/audits/new-apps-2026-10-10/box/lubelogger/restore-password.txt new file mode 100644 index 00000000..b5ba6025 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/restore-password.txt @@ -0,0 +1,30 @@ +2.5 follow-up — which password signs in after remove-keeping-backups + restore (9202, 2026-10-10) +The fixture reported that the install's password stopped working. That is true and expected: +a `type: password` field is not in PortableSecretEnvVars, so it does not travel in the backup +unit and the box mints a new one. The question is whether the value the box now holds — the +value its page shows the household — signs in, and whether the DATA came back. + +the container's own environment, names only: + + APP_UID= + ASPNETCORE_HTTP_PORTS= + ASPNET_VERSION= + DOTNET_RUNNING_IN_CONTAINER= + DOTNET_VERSION= + LUBELOGGER_LOCALE_OVERRIDE= + PATH= + ROOT_PASSWORD= + ROOT_USER= + TZ= + +what the app answers a stranger right now: + GET /api/vehicles with no credentials -> 401 + +the password the INSTALL generated (the one the fixture holds), 30 characters: + {"success":false,"message":"Invalid Login Credentials"} +the password the BOX HOLDS NOW, read from the app's own deployed environment: + it is 24 characters, and the name is 'csalad' + a DIFFERENT value from the one the install generated + {"success":true,"message":""} +and the data the household had before the remove: + [{"id":1,"imageLocation":"/defaults/noimage.png","mapLocation":null,"year":2019,"make":"Skoda","model":"Octavia","licensePlate":"FEL-EBA5E5","purchaseDate":null,"soldDate":null,"purchasePrice":0,"soldPrice":0,"isElectric":false,"isDiesel":true,"useHours":false,"odometerOptional":false,"extraFields": diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/restore.txt b/documentation/audits/new-apps-2026-10-10/box/lubelogger/restore.txt new file mode 100644 index 00000000..79d49c73 --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/restore.txt @@ -0,0 +1,6 @@ +restore points offered BEFORE the remove: [(None, '2026-10-10T09:59:13Z')] +remove KEEPING backups -> 200 {'ok': True, 'data': {'removed': 'lubelogger', 'volumes_removed': ['lubelogger_lubelogger_data', 'lubelogger_lubelogger_keys'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'userdata_kept': [], 'verified': True}, 'message': 'Stack lu +left after remove: nothing (containers and volumes gone) +restore: {'ok': True, 'snapshot_id': 'helyi', 'http': 'HTTP/2 302', 'seconds': 22.3, 'state_after': 'running', 'hold_after': None, 'why': None} + lubelogger: the household's own password no longer signs in after the step +2.5 the seed reads back after remove + restore: False diff --git a/documentation/audits/new-apps-2026-10-10/box/lubelogger/step.txt b/documentation/audits/new-apps-2026-10-10/box/lubelogger/step.txt new file mode 100644 index 00000000..a696a88e --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/box/lubelogger/step.txt @@ -0,0 +1,32 @@ +before: pinned={'lubelogger': 'ghcr.io/hargata/lubelogger:v1.7.2'} +drill: 27b019c DRILL lubelogger: {'lubelogger': 'ghcr.io/hargata/lubelogger:v1.7.3'} (box proof) + phase +0.0s backing-up | err=None + phase +2.1s safety-dump | err=None + phase +3.1s pulling | err=None + phase +13.3s copying | err=None + phase +15.4s verifying | err=None + phase +25.6s done | err=None + lubelogger: readback vehicle=True (http=200) service record=True (http=200) (controls: no cookie 401, wrong 401, absent list empty) +2026/10/10 09:59:12 update.go:537: [INFO] [stacks] update lubelogger: accepted — guarded update started +2026/10/10 09:59:12 update.go:1378: [INFO] [stacks] update lubelogger: phase checking +2026/10/10 09:59:12 update.go:795: [INFO] [stacks] update lubelogger: ladder — the last step (1 of 1) — the catalog's current definition +2026/10/10 09:59:12 update.go:825: [INFO] [stacks] update lubelogger: no usable copy on any tier — younger than 24h0m0s and not older than this install's deploy (2026-10-10T09:52:33Z) (found: none) — backing up first +2026/10/10 09:59:12 update.go:1378: [INFO] [stacks] update lubelogger: phase backing-up +2026/10/10 09:59:14 update.go:840: [INFO] [stacks] update lubelogger: precondition met after the backup — Tier 2 (second drive) copy from 2026-10-10T09:59:13Z +2026/10/10 09:59:14 update.go:1378: [INFO] [stacks] update lubelogger: phase safety-dump +2026/10/10 09:59:14 update.go:855: [INFO] [stacks] update lubelogger: safety dump done (0 file(s)) [] +2026/10/10 09:59:15 undo.go:287: [INFO] [stacks] update lubelogger: the undo copy will hold 2 named volume(s), 0.1 MiB +2026/10/10 09:59:15 update.go:1378: [INFO] [stacks] update lubelogger: phase pinning +2026/10/10 09:59:15 pin.go:373: [INFO] [stacks] update lubelogger: pin advanced to /opt/docker/felhom-controller/data/catalog-cache/templates/lubelogger/docker-compose.yml (lubelogger=ghcr.io/hargata/lubelogger:v1.7.3) +2026/10/10 09:59:15 update.go:1378: [INFO] [stacks] update lubelogger: phase pulling +2026/10/10 09:59:25 update.go:1378: [INFO] [stacks] update lubelogger: phase copying +2026/10/10 09:59:26 update.go:1378: [INFO] [stacks] update lubelogger: phase copying +2026/10/10 09:59:26 undo.go:437: [INFO] [stacks] update lubelogger: copied lubelogger_lubelogger_data → lubelogger_lubelogger_data.pre-update-20261010T095926Z in 498ms +2026/10/10 09:59:26 update.go:1378: [INFO] [stacks] update lubelogger: phase copying +2026/10/10 09:59:27 undo.go:437: [INFO] [stacks] update lubelogger: copied lubelogger_lubelogger_keys → lubelogger_lubelogger_keys.pre-update-20261010T095926Z in 425ms +2026/10/10 09:59:27 update.go:1378: [INFO] [stacks] update lubelogger: phase starting +2026/10/10 09:59:27 update.go:1378: [INFO] [stacks] update lubelogger: phase verifying +2026/10/10 09:59:37 update.go:1006: [INFO] [stacks] update lubelogger: healthy after 10s (the app's health check passed) +2026/10/10 09:59:38 update.go:1043: [INFO] [stacks] update lubelogger: DONE in 25s + +RESULT final_phase=done after={'lubelogger': 'ghcr.io/hargata/lubelogger:v1.7.3'} seed_after=True verdict=proven (25.7 s) diff --git a/documentation/audits/new-apps-2026-10-10/site-count.txt b/documentation/audits/new-apps-2026-10-10/site-count.txt new file mode 100644 index 00000000..94a83a0b --- /dev/null +++ b/documentation/audits/new-apps-2026-10-10/site-count.txt @@ -0,0 +1,67 @@ +8.5 - the website's app count moved 56 -> 57 when Grocy was published (2026-10-10). +Every place the count is stated, in both language sets; the move's own run reported +'replaced: hu=15 en=15' and 'control: no pattern still matches the old count in any of the 8 files'. +Below is a READ-BACK: the same patterns asked for 57, which is what they must now hold. + + alkalmazasok.html title 1 place(s) + alkalmazasok.html meta description 1 place(s) + alkalmazasok.html og:title 1 place(s) + alkalmazasok.html twitter:title 1 place(s) + alkalmazasok.html JSON-LD numberOfItems 1 place(s) + alkalmazasok.html the page's own sentence 1 place(s) + alkalmazasok.html the stats tile 1 place(s) + index.html meta description 1 place(s) + index.html the feature heading 1 place(s) + index.html the home-page line 1 place(s) + gyik.html the NAS answer (twice: JSON-LD + visible) 2 place(s) + gyik.html the app-list answer (JSON-LD) 1 place(s) + gyik.html the app-list answer (visible) 1 place(s) + technologiak.html the technology bullet 1 place(s) + en/apps.html title 1 place(s) + en/apps.html meta description 1 place(s) + en/apps.html og:title 1 place(s) + en/apps.html twitter:title 1 place(s) + en/apps.html JSON-LD numberOfItems 1 place(s) + en/apps.html the page's own sentence 1 place(s) + en/apps.html the stats tile 1 place(s) + en/index.html meta description 1 place(s) + en/index.html the feature heading 1 place(s) + en/index.html the home-page line 1 place(s) + en/faq.html the NAS answer (twice: JSON-LD + visible) 2 place(s) + en/faq.html the app-list answer (JSON-LD) 1 place(s) + en/faq.html the app-list answer (visible) 1 place(s) + en/technology.html the technology bullet 1 place(s) +replaced: hu=15 en=15 + + +--- and again when LubeLogger was published, 57 -> 58 (both apps are in the same catalog commit) --- + alkalmazasok.html title 1 place(s) + alkalmazasok.html meta description 1 place(s) + alkalmazasok.html og:title 1 place(s) + alkalmazasok.html twitter:title 1 place(s) + alkalmazasok.html JSON-LD numberOfItems 1 place(s) + alkalmazasok.html the page's own sentence 1 place(s) + alkalmazasok.html the stats tile 1 place(s) + index.html meta description 1 place(s) + index.html the feature heading 1 place(s) + index.html the home-page line 1 place(s) + gyik.html the NAS answer (twice: JSON-LD + visible) 2 place(s) + gyik.html the app-list answer (JSON-LD) 1 place(s) + gyik.html the app-list answer (visible) 1 place(s) + technologiak.html the technology bullet 1 place(s) + en/apps.html title 1 place(s) + en/apps.html meta description 1 place(s) + en/apps.html og:title 1 place(s) + en/apps.html twitter:title 1 place(s) + en/apps.html JSON-LD numberOfItems 1 place(s) + en/apps.html the page's own sentence 1 place(s) + en/apps.html the stats tile 1 place(s) + en/index.html meta description 1 place(s) + en/index.html the feature heading 1 place(s) + en/index.html the home-page line 1 place(s) + en/faq.html the NAS answer (twice: JSON-LD + visible) 2 place(s) + en/faq.html the app-list answer (JSON-LD) 1 place(s) + en/faq.html the app-list answer (visible) 1 place(s) + en/technology.html the technology bullet 1 place(s) +replaced: hu=15 en=15 +control: no pattern still matches the old count in any of the 8 files diff --git a/documentation/backlog/OPEN-ITEMS.md b/documentation/backlog/OPEN-ITEMS.md index 74d64f0f..54085b86 100644 --- a/documentation/backlog/OPEN-ITEMS.md +++ b/documentation/backlog/OPEN-ITEMS.md @@ -122,10 +122,11 @@ stopping line that lies. | **R-494** | Install & onboarding | P4 | **NARROWED 2026-09-14 by operator ruling → [P3-LOW] the hub COULD create the tunnel at customer creation, for a domain already on Cloudflare. Not blocking: every customer has their own domain and the operator creates the tunnel per day-0 A.1 (`architecture/01-topology-and-trust.md`).** *Original finding, kept:* **[P1-HIGH] A new customer's dashboard has NO reachable address unless the operator hand-makes a Cloudflare tunnel — the link in the setup-code mail is dead.** MEASURED 2026-09-14 on a fresh install from the public ISO (drill intervention **I1**): the claim mail points at `https://felhom.drill0242.felhom.eu`; that name has **no A and no AAAA** record (`dig @1.1.1.1`, control `felhom.enkisfelhom.hu` resolves); the hub has **no tunnel- or DNS-creation code** (`hub/internal/cloudflare/` holds only geo-rule removal; `cf_tunnel_token` is a pasted, optional form field, `configs.go:1478`) — day-0 runbook A.1 makes it a manual Cloudflare-dashboard step that nothing on the customer-create page asks for; the box's own split-horizon resolver on the appliance LAN IP answered `google.com` but not the dashboard name at 13:27:39Z; the agent applied the record at **13:27:44Z** (`lanresolver: applied split-horizon record … ip=192.168.0.158`, 3 m 46 s after the controller started), so the box CAN answer the name — **but only to a device that uses the box as its DNS server, and no document, screen or mail tells a household to do that**; the router and the installer-offered DNS answer nothing. The page was reachable only at the guest's LAN address with the name forced (`curl --resolve …:443:192.168.0.158`). **A volunteer could not have done that.** **What it needs:** an operator ruling — the hub creates the tunnel and DNS at customer creation, or the product gives a household a LAN address that works with no DNS change. | **READY — rank P3-LOW; owner: CC** **Re-ranked 2026-10-03: P3→P4: operator-side automation; the operator creates the tunnel by hand per the day-0 runbook.** | — | — | CC | | **R-504** | Install & onboarding | P4 | **[P3-LOW] `iso.felhom.eu` cannot show an index page on its own — its root returns 404, and the download page lives on the website instead.** MEASURED 2026-09-14: `https://iso.felhom.eu/` and `/index.html` → 404; only named objects answer. The host is an R2 bucket behind a custom domain; whether R2 would serve an uploaded `index.html` at `/` was **not measured** (uploading anything to the public bucket is a publication). The ISO v1.27.0 task puts the Hungarian download page at `felhom.eu/letoltes` (published with the ISO, after the operator's yes). **Remaining:** a redirect from `iso.felhom.eu/` to that page needs a Cloudflare rule the session has no credential for. | **WAITING-ON-OPERATOR — rank P3-LOW; owner: operator (Cloudflare rule)** **Re-ranked 2026-10-03: P3→P4: households are sent to the website's download page; the bare address is cosmetic.** | — | — | operator | -## Apps & catalog — 11 rows (P3 3, P4 8) +## Apps & catalog — 12 rows (P3 3, P4 9) | ID | Category | Sev | What | State | Blocked on | Next action | Owner | |---|---|---|---|---|---|---|---| +| **R-927** | Apps & catalog | P4 | **Monica was checked against the new-app checklist and STOPPED at 0.2 — the operator decides whether to keep it out.** Measured 2026-10-10 (`audits/new-apps-2026-10-10/FIT.md`): no release of any kind since 2025-04-21 and that one a prerelease; no STABLE release since v4.1.2 on 2024-05-04, 29 months; the `4.x` branch the README calls "the stable and current version" has not moved since 2024-05-04; `main` says it is the beta; the commit history has a 13-month hole, and the two commits that end it add a login-page notice reading that the hosted instance and all its data will be deleted at the end of December 2026 "ahead of the new Monica version". 790 issues open. Nothing in the catalog covers a family address book, so keeping it out costs nothing we have; letting it in means publishing an app whose next version is a rewrite with no migration story. Radicale already carries contacts over CardDAV. | **OPEN — needs the operator's word** | the operator | Keep it out and look again when the rewrite ships, or say to build it anyway | operator | | **R-562** | Apps & catalog | P3 | **[P3-LOW] Dates and sizes are not formatted for any locale — and the Hungarian pages disagree with themselves.** FOUND 2026-09-17 by the i18n inventory §2.8: the two template date layouts differ (`2006. 01. 02. 15:04` Hungarian vs `2006-01-02 15:04` ISO); 10 layout literals in `internal/web` Go and 25 elsewhere pick formats ad hoc; sizes print a decimal POINT (`%.1f GB`, 4 helpers) where Hungarian uses a comma; `timeAgo`/`nextRunLabel`/`pruneLabel` produce Hungarian words outside the three converted pages. Not changed by v0.247.0 (Hungarian bytes are frozen by the parity rule). **Fix shape:** one date and one size formatter per language in `internal/i18n`, the Hungarian output deliberately changed in ONE reviewed release with the parity fixtures re-captured for that release only and the change named in its CHANGELOG. Needs an operator word on the Hungarian format (comma, date style). | **READY - rank P3-LOW; owner: CC** **2026-10-06 night: not started — the row needs the operator's word on the Hungarian format (decimal comma, date style) before any code.** | — | — | CC | | **R-676** | Apps & catalog | P3 | **[P3-LOW] Watch: immich's first start restarted 12 times — decision 28's crash-loop stop (6 in 10 min) would stop it.** From the 2026-09-17 chaos night (DB connection dropped during the first-start geocoding import on a 6 GB guest; it did not recover that night). No healthy app in any drill evidence restarts on a first start (1831 samples, 40 live containers), so the threshold stands; this row exists so the first immich install under v0.269.x is watched. `audits/night-2026-09-24/A3/40-first-start-restarts.txt` **2026-09-25 night (read from source, v0.271.0): a DEPLOY's first start is NOT covered by decision 28's suppression** — `Deploying` clears when `compose up -d` returns (`deploy.go` "Clear deploying flag"), and `ObserveUnhealthy` then samples the app; an automatic update's step, verify and undo ARE covered (`Updating`, pinned by `TestD28_NoCrashLoopStopDuringAnAutomaticStep`). So a first start that restarts ≥ 6 times in 10 min is stopped — which R-676 already accepts for a broken first start; a healthy slow first start would be stopped too. **-- 2026-09-30: the first-start restarts are explained.** immich's first-start geodata import OOM-kills its database at 512M on a guest with no swap (R-732, measured: 61–104 kills); the 2026-09-17 chaos-night case (DB connection dropped during the import on a 6 GB guest) fits it. Fixed in the catalog (`56c4888`, 768M). The watch itself (decision 28 on a DEPLOY's first start) is unchanged. | **OPEN — P3; owner: CC (watch)** | — | — | CC | | **R-76** | Apps & catalog | P4 | **FileBrowser-created folders break the setgid chain, and a drop-zone's mode is not stable** **MIGRATED FROM `ROADMAP.md` 2026-08-22 (R-369) — originally filed 2026-07-26, size S, roadmap state `idea (surfaced by the R-75 spike, 2026-07-26)`.** Moved verbatim; nothing added or reinterpreted. The roadmap keeps its copy as history, marked moved. | **OPEN — migrated from ROADMAP 2026-08-22, rank unchanged** **2026-10-06 night: not a catalog fix** — the setgid chain is set by the controller's FileBrowser setup; a controller row. | — | Two related findings from `audits/SPIKE-catalog-data-paths-2026-07-26.md` P3/P5, both **pre-existing** and deliberately left alone by that spike. **(a)** FileBrowser Quantum 1.3.3 creates files `0644` and folders `0755` and does **not** propagate the setgid bit — even though the entrypoint wrapper's `umask 002` really is in effect (`/proc/1/status` `Umask: 0002`). Group inheritance itself works (a file uploaded into a 2775 group-100 dir landed group 100, not the process gid 1000), so the convention's *group* half holds and only its *mode* half is lost. The consequence is proven with a control: inside a UI-created `0755` folder a gid-1000 process's file landed group **1000**, while the identical write into the 2775 parent landed group **100**. So **any folder a customer creates through FileBrowser breaks the shared-group chain one level down.** Latent today — every userdata-touching catalog app that declares an identity declares uid/gid **1000**, the same uid FileBrowser runs as, so owner permissions mask it; it bites the day a content app runs as a different non-root uid with gid 1000. The comment at `infra/infra.go:156` is right that the image ignores `-e UMASK` but does not say t | CC | @@ -147,10 +148,11 @@ stopping line that lies. | **R-683** | App updates | P3 | **[P3-LOW] Watch: after a power cut during an update's health check, the hold named an HOUR-OLD second-drive copy, not the one the update's own backup should have just made.** 2026-09-24 chaos round 3 (nextcloud, `backup_max_age: 1m`): no `backing-up` phase was seen and the hold named Tier 2 at 13:04 for an update pressed at 14:04; the pre-cut controller log was lost with the container (the runner now saves it at arm time — R-320). Round 11, the same action without a power cut, named a fresh 14:34 copy and logged the Tier-2 copy. The sentence was TRUE (it named the copy it offered); the question is why the update did not back up first. Not reproduced; watch the next power-cut drill. `audits/night-2026-09-24/E/round-03*.json`, `E/round-11-controller-pre.log` | **OPEN — P3; owner: CC (watch)** | — | — | CC | | **R-785** | App updates | P3 | **[P3-LOW] SparkyFitness is pinned 11 releases and a major behind upstream (v0.17.3; upstream v1.7.3, v1.6.0 dated 2026-07-24).** READ 2026-10-01 (`audits/visitors-2026-10-01/C/bench/C1-previous-tag.txt`). **Needs:** an update walk 0.17 → 1.x through the ladder (bench + box), after R-784 is decided. | **OPEN — rank P3-LOW; owner: CC (after R-784)** | — | — | CC | -## Backup & restore — 30 rows (P2 4, P3 12, P4 14) +## Backup & restore — 31 rows (P2 4, P3 13, P4 14) | ID | Category | Sev | What | State | Blocked on | Next action | Owner | |---|---|---|---|---|---|---|---| +| **R-926** | Backup & restore | P3 | **After a household removes an `after_install` app keeping its backups and then restores it, nobody has checked whether the app page still shows a password that works.** A `type: password` deploy field is NOT in `stacks.PortableSecretEnvVars` (that list is `type: secret` only, `deploy.go:1199`), so it does not travel in the backup unit — the same shape as R-765, where Radicale's restored login was replaced by a value no page showed and every phone lost its calendar. MEASURED on 9202 2026-10-10 for grocy: remove keeping the backups, restore, and **the household's own password still signs in and the seeded data reads back** — so the DATABASE half is right. What was NOT settled is the PAGE half: `app.yaml` holds the value encrypted at rest, so reading it proves nothing (a 76-character string that of course did not sign in), and `POST /apps/grocy/initial-credentials/reveal` answered 404 for this app. Seven apps are in the same class: bookstack, calibre-web, claper, dawarich, grocy, mealie, wger. | **OPEN — the question is unanswered, not the answer bad** | — | Ask the controller what the app page renders for a generated `type: password` after a restore (one endpoint read, one app), and if it differs from the one that works, decide: carry the value in the unit, or re-run `after_install` after a restore | CC | | **R-232** | Backup & restore | P2 | **DooPlex's backup makes every copy inside the same box — and nothing tells anyone when it fails.** Surveyed read-only 2026-08-06 (`audits/RECON-dooplex-backup-2026-08-06.md`). **What works:** five sets, 14/14 successful runs in 14 days; a file was restored from the `data` repo and matched the live original **byte for byte**; every set except two is cross-disk; k3s is integrity-checked on every run. **What the matrix exposes, ranked:** (a) **`notify_failure` is a no-op** — `NOTIFY_ON_FAILURE=true` but `NOTIFY_WEBHOOK_URL` is commented out, so a failed backup notifies **nobody**; the project already has a working Resend path that CI uses. Cheapest item, and it makes every other failure visible. (b) **Nothing leaves the box** — no rclone, no remote repo, no off-site target anywhere; Longhorn's target is `nfs://192.168.0.180:` pointing at DooPlex itself, and the only outbound-looking cron pulls *inbound* from Hetzner for a different project. The machine that runs the hub managing the customers' off-site chain has no off-site copy of its own. (c) **The backup tree is a single writable path** and the restic repos are not append-only — one bad script or ransomware destroys every copy at once. (d) **Two same-disk sets**: `.claude-memory` and the PostgreSQL dumps, whose source directory sits *inside* the backup tree. (e) **Longhorn `retain=1`** — one generation per volume, so a corruption noticed a day late has no earlier copy. (f) **`/opt/backup/docs/BACKUP-RESTORE.md` does not exist** though the systemd unit advertises it. (g) **`secrets/restic-repo` has never held a snapshot** — `backup-secrets.sh` contains no `restic` call; the secrets are GPG files on `sda1` only. (h) **No restore has ever been run** beyond today's single-file probe — the matrix's "ever demonstrated?" column is otherwise entirely empty. **Not a finding:** the restic passphrase. The on-box copy is on `sdb1`, a different disk from the backups, and the **operator holds an offline copy out of band** — so a disk loss is recoverable. The narrow residual is that it is operator-held rather than system-held, unlike the customer case's hub-vaulted escrow, so it should be confirmed current and findable by someone else. **Nothing was changed by the recon.** | **NARROWED 2026-10-08 — owner Viktor.** (a) DONE with the operator's yes in chat: `notify_failure` now mails admin@felhom.eu through Resend; proven by one test mail that reached the inbox (`audits/day-2026-10-08/r232/`; no backup was started). (b) partly: the hub database leaves DooPlex nightly to ep0 (R-173); everything else stays on the box. (c)–(h) unchanged. **2026-10-09 (operator yes in chat): (b) and (h) DONE for Gitea and the secrets.** Nightly 00:20 `felhom-dooplex-offsite` pushes Gitea (614 MB of repositories, the `gitea` database dump taken first, `app.ini`) and the nightly GPG secrets export, encrypted with a NEW key, to ep0 `operator` (`host/dooplex-gitea`) on the hub-DB write-only token — no change on ep0; first push 57 s; restore test weekly (manifest, `git fsck` every repo, `pg_restore --list`), run once: 27 805 files, 10 repos OK; `DooplexGiteaOffsiteStale`/`DooplexGiteaRestoreTestStale` in force (`absent()` included, promtool + 2 red-proofs); every backup unit now mails on failure (`OnFailure=`, dry run reached the inbox). **First real Gitea restore:** into a throwaway on the bench, 10/10 repos, product `main` = live, a file byte for byte, a login (`runbooks/gitea-restore.md`). The hub came back too (R-173, closed). **The registry is left out on purpose:** its images rebuild from the code. **Correction to the recon §7:** the API mirror holds ONE repo (`homelab-manifests`), not all — Gitea had a single copy, on DooPlex. `audits/dooplex-survival-2026-10-09/` **LEFT:** (c) append-only for the on-box tree, (d)–(g) as written; the paper copy of the new key (operator). **READY** for the rest | — | — | operator | | **R-304** | Backup & restore | P2 | **The retained escrow key works, and the customer is told their correct code is wrong.** DRILL 2026-08-12 answered the three questions separately, on `demo-felhom`, with planted data. **(a) retention: WORKS** — the first retained row in fleet history to carry material (`host_escrow_superseded` id 11, `identity_blob` 572 B), byte-identical (`sha256 a10032341c8584ed…`) to the pre-supersession `host_escrow` row. **(b) the material opens the old store: YES** — unsealed with the OLD recovery code it yielded a password byte-identical to the pre-change one (`sha c60c8bc737a6b7c6…`), and restored three planted files **byte-identical** from a store the box itself could no longer open (negative control first: `Fatal: wrong password or no key found`), **including a Hungarian accented filename verified as raw bytes**. **(c) the customer's route: DOES NOT EXIST, and misinforms.** `ListSupersededEscrow` (`store.go:2841`) is the only reader of a retained `identity_blob` and has **zero production callers** — five call sites, all `_test.go`; the product path (`POST /escrow/recover-offsite-password` → `FetchIdentityEscrow` → `GetHostDRBundle`, `store.go:3152`) selects `FROM host_escrow` — the CURRENT row only. Asked for the old password with the code that demonstrably opens the retained row, the product answered **"the recovery code did not open the sealed bundle — nothing was written"**. **This is the R-224 class again**: there an unreachable hub was reported as a bad code; here a VALID code for retained history is reported as a bad code, and the customer's attempt ends there. **Consequence:** the census answer stands (it was about retention); the countdown banner's promise is true in substance and false in practice; **any capability-map claim that the customer can recover the old history with their recovery code is false today and must move** | **READY — the operator mail is BUILT on main 2026-10-08 (decision 183; controller `a40729a` + hub, ships with the next releases).** The honesty fix is on main too (agent `91b9405`, controller `75b3b39`). Left: the runbook „open a retained package for a household" (design option C, second slice). Design `audits/day-2026-10-08/design-R-304.md`. | R-198, R-199, R-224, R-241 | Release controller + hub; write the retained-package runbook from the 2026-08-12 drill §4; then close | CC | | **R-893** | Backup & restore | P3 | **After a failed OFF-SITE replay, the rollback pours the NEWER pre-restore copy over the OLDER volume just put back.** Read in source 2026-10-06 (R-638 option A, not measured): `internal/backup/offbox_reconstitute.go` writes the undo copy from the live (newer) database, replaces the volumes with the snapshot's older tars, then — when the replay fails — `rollbackSafetyDump` loads that newer dump over the older database volume. The loader only drops what the dump knows, so tables the newer migration removed stay; and when the snapshot's older definition was written, the rollback branch does not put the newer definition back, so the older app starts on rolled-back data; non-database volumes stay at the snapshot's state. An order change cannot fix it (the only undo is a logical dump, and its volume was replaced). Known limit in `07` §6.3. **-- 2026-10-08 design:** `audits/day-2026-10-08/design-R-893.md` — re-verified; and the screen's „your data is back as it was" (`err.backup.db_restore_failed_rolled_back`) is false for files, other volumes and the app version. Question D8 on STATUS's decision sheet. **-- 2026-10-08 14:16 operator ruling D8 (`09` §3 decision 192):** yes, both, in that order — first the app stays stopped for support (option C), next „put back exactly as it was" (option A). | **NARROWED — 2026-10-09: the first half DELIVERED in controller 0.304.0. Slice 0 (the live measurement) NOT run: 9202 has no off-site, and a dump cannot be cut by hand inside an encrypted off-site copy on Tester 1; it needs a scratch off-site repo — a plan, not a finding.** **NARROWED 2026-10-08 — the first half (D8 option C, the app held stopped) is built on controller main and ships tomorrow; what stays open is the second half, „put back exactly as it was” (option A: a pre-restore copy of the app's volumes and placed files, a fit check, disk for one copy; the slice-0 measurement on 9202 first).** **OPEN — filed 2026-10-06** **2026-10-06 night: verified in source, no code** — `offbox_reconstitute.go:758` (undo dump from the live DB), `:778-860` (files and volumes from the snapshot), `:804` (the snapshot's definition is written when its version differs), `:898` (the rollback loads the newer dump over the older volume; nothing writes the live definition back). Not a reorder fix: it needs R-638 option B (a rebuilding loader) or a pre-restore volume copy (disk cost; R-685's class). Which state a household gets after a failed off-site replay is the operator's call. Next: the 9202 measurement, then the design. | a design: R-638 option B (a loader that rebuilds instead of overlays) or a pre-restore volume copy | Measure it once on 9202 (a forced replay failure after an off-site restore over a migrated app); then a design for the operator | CC | diff --git a/scripts/check_stands.py b/scripts/check_stands.py index 872b38c2..36eab411 100644 --- a/scripts/check_stands.py +++ b/scripts/check_stands.py @@ -30,6 +30,18 @@ import os import re import sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DEFAULT = os.path.join(ROOT, "documentation", "architecture", "where-felhom-stands.yaml") REGISTER = os.path.join(ROOT, "documentation", "backlog", "OPEN-ITEMS.md") diff --git a/scripts/closed_register_gate.py b/scripts/closed_register_gate.py index bba07bd6..1e681af3 100644 --- a/scripts/closed_register_gate.py +++ b/scripts/closed_register_gate.py @@ -66,6 +66,18 @@ import sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import register_table # noqa: E402 — the shared row reader (2026-10-03) +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) CLOSED = os.path.join(ROOT, "documentation", "backlog", "CLOSED-ITEMS.md") OPEN = os.path.join(ROOT, "documentation", "backlog", "OPEN-ITEMS.md") diff --git a/scripts/decoy_coverage_gate.py b/scripts/decoy_coverage_gate.py index ae087abc..5d6c28bc 100644 --- a/scripts/decoy_coverage_gate.py +++ b/scripts/decoy_coverage_gate.py @@ -29,6 +29,18 @@ import io import os import sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + # ── EXEMPTIONS — each carries its row and one line saying why it is not covered YET ───────────── # Dated 2026-09-01. This list is DEBT, not a settled state: R-426 owns it and names every entry. EXEMPT = { diff --git a/scripts/due_checks_gate.py b/scripts/due_checks_gate.py index e34c2520..b19e619d 100644 --- a/scripts/due_checks_gate.py +++ b/scripts/due_checks_gate.py @@ -60,6 +60,18 @@ import re import sys from datetime import date, datetime, timezone +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DEFAULT_REGISTER = os.path.join(ROOT, "documentation", "backlog", "OPEN-ITEMS.md") diff --git a/scripts/golden_currency_gate.py b/scripts/golden_currency_gate.py index 4b6002ac..a6d60158 100644 --- a/scripts/golden_currency_gate.py +++ b/scripts/golden_currency_gate.py @@ -121,6 +121,18 @@ import os import re import sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # The controller clone sits beside this one. The same sibling assumption reuse_refs_check.py and # instructions_gate.py already make — an absent sibling is INCONCLUSIVE, never a silent pass. diff --git a/scripts/hostinstall_gates.py b/scripts/hostinstall_gates.py index 9d09f9fd..25f2f836 100644 --- a/scripts/hostinstall_gates.py +++ b/scripts/hostinstall_gates.py @@ -26,6 +26,18 @@ Gates (all must pass; non-zero exit on any failure): """ import io, os, re, sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SCRIPT = os.path.join(ROOT, "scripts", "felhom-host-install.sh") HUB_CONFIGS = os.path.join(ROOT, "hub", "internal", "web", "configs.go") diff --git a/scripts/hub_confirm_gate.py b/scripts/hub_confirm_gate.py index f2958283..e54aa2b4 100644 --- a/scripts/hub_confirm_gate.py +++ b/scripts/hub_confirm_gate.py @@ -9,6 +9,18 @@ Exit 1 if any native confirm(/prompt( call remains in hub templates. """ import io, os, re, sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.join("hub", "internal", "web", "templates") # A bare confirm(/prompt( CALL with an argument: not preceded by an identifier character, so felhomConfirm( diff --git a/scripts/hub_copy_gate.py b/scripts/hub_copy_gate.py index 79e4a69d..36668d6e 100644 --- a/scripts/hub_copy_gate.py +++ b/scripts/hub_copy_gate.py @@ -46,6 +46,17 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from customer_copy_vocab import ( # noqa: E402 RETIRED_NAMES, RETRIEVAL_STEMS, RETRIEVAL_STEMS_EN) +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + _HERE = os.path.dirname(os.path.abspath(__file__)) _REPO = os.path.dirname(_HERE) _HUB = os.path.join(_REPO, "hub") diff --git a/scripts/instructions_gate.py b/scripts/instructions_gate.py index e576a802..6fdcb69f 100644 --- a/scripts/instructions_gate.py +++ b/scripts/instructions_gate.py @@ -90,6 +90,18 @@ import os import re import sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + MAX_LINES = 200 # The auto-memory index. Limits are the store's own, not this project's taste: content past them is diff --git a/scripts/iso_bootstrap_gate.py b/scripts/iso_bootstrap_gate.py index ce177977..7756c378 100644 --- a/scripts/iso_bootstrap_gate.py +++ b/scripts/iso_bootstrap_gate.py @@ -37,6 +37,18 @@ import sys import tempfile import uuid +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ISO = os.path.join(ROOT, "scripts", "iso") IMAGE = "felhom-iso-assistant:trixie" diff --git a/scripts/manifest_bearer_gate.py b/scripts/manifest_bearer_gate.py index a29ccca6..c9ef99d8 100644 --- a/scripts/manifest_bearer_gate.py +++ b/scripts/manifest_bearer_gate.py @@ -15,6 +15,18 @@ secret files — would silently un-track a gate with "secret" in its filename.) """ import io, os, re, sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = "manifests" # 64 hex chars with no hex/word neighbors (so longer blobs and sha256-of-file hexes embedded in diff --git a/scripts/observations_gate.py b/scripts/observations_gate.py index 2e2bb846..d9810744 100644 --- a/scripts/observations_gate.py +++ b/scripts/observations_gate.py @@ -71,6 +71,18 @@ import os import re import sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # `## 10. Observations — recorded, not acted on`, `### Observations`, `## Observations:` … diff --git a/scripts/one_register_gate.py b/scripts/one_register_gate.py index e8e6b515..bcd61a7c 100644 --- a/scripts/one_register_gate.py +++ b/scripts/one_register_gate.py @@ -41,6 +41,18 @@ import sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import register_table # noqa: E402 +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ROADMAP = os.path.join(ROOT, "documentation", "backlog", "ROADMAP.md") REGISTER = os.path.join(ROOT, "documentation", "backlog", "OPEN-ITEMS.md") diff --git a/scripts/poster_facts_gate.py b/scripts/poster_facts_gate.py index b026b45b..fa307595 100644 --- a/scripts/poster_facts_gate.py +++ b/scripts/poster_facts_gate.py @@ -32,6 +32,18 @@ import os import subprocess import sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + HERE = os.path.dirname(os.path.abspath(__file__)) DEFAULT_ROOT = os.path.dirname(HERE) ARCH = os.path.join("documentation", "architecture") diff --git a/scripts/register_shape_gate.py b/scripts/register_shape_gate.py index 740b147f..759ed82e 100644 --- a/scripts/register_shape_gate.py +++ b/scripts/register_shape_gate.py @@ -70,6 +70,18 @@ from pathlib import Path sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import register_table # noqa: E402 — the shared row reader (2026-10-03) +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + # The eleven categories (operator request 2026-10-03; the reviewer's default, operator may reverse). # The same list, in the same order, heads OPEN-ITEMS.md's "How a row is filed" section. CATEGORIES = ( diff --git a/scripts/repo_gates.py b/scripts/repo_gates.py index 69c7d3e1..7aeb65de 100644 --- a/scripts/repo_gates.py +++ b/scripts/repo_gates.py @@ -107,6 +107,17 @@ import os import subprocess import sys +# The runner's own console must not decide whether the gates run. It streams each gate's bytes back +# out, decoded with errors="replace"; on a Windows console (cp1250 here) printing the replacement +# character raised UnicodeEncodeError and **aborted the whole runner at the first gate**, so no gate +# after it ran at all. Found 2026-10-10; same trap class as check-onboarding.py's and +# poster_facts_gate.py's. A gate that cannot print is still a gate that must report. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SCRIPTS = os.path.join(ROOT, "scripts") diff --git a/scripts/reuse_refs_check.py b/scripts/reuse_refs_check.py index 9c2a9ab2..67e0f6a3 100644 --- a/scripts/reuse_refs_check.py +++ b/scripts/reuse_refs_check.py @@ -37,6 +37,18 @@ scripts/test_reuse_refs_check.py: a citation that exists nowhere still FAILS. """ import io, os, re, sys +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + # path-looking tokens ending in a checked extension; globs (*) are conventions, not refs. # R-422: `.md` joined the list — a rotted document citation was invisible (measured 2026-09-01: # `documentation/architecture/99-does-not-exist.md` passed). The false-positive walk across all four diff --git a/scripts/script_tests_gate.py b/scripts/script_tests_gate.py index 0daa54fa..b43043b6 100644 --- a/scripts/script_tests_gate.py +++ b/scripts/script_tests_gate.py @@ -21,6 +21,18 @@ import subprocess import sys import time +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + MARK = "FELHOM_SCRIPT_TESTS_GATE" TIMEOUT_S = 300 SKIP_DIRS = {"__pycache__", ".git", "node_modules"} diff --git a/scripts/site_gates.py b/scripts/site_gates.py index f4e38d00..0b6875ce 100644 --- a/scripts/site_gates.py +++ b/scripts/site_gates.py @@ -34,6 +34,18 @@ Gates (all must pass; non-zero exit on any failure): """ import html as _html, io, json, os, re, sys, unicodedata +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) W = os.path.join(ROOT, "website") sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) diff --git a/scripts/wire_contract_gate.py b/scripts/wire_contract_gate.py index 3bac628b..744009e5 100644 --- a/scripts/wire_contract_gate.py +++ b/scripts/wire_contract_gate.py @@ -65,6 +65,18 @@ import shutil import sys import tempfile +# A gate's own console must not decide its verdict. These scripts quote back Hungarian copy, file +# paths and arrow characters; a Windows console here is cp1250, and printing one of them raised +# UnicodeEncodeError *before the gate had decided anything* — reuse_refs_check.py died while printing +# a NOTE, which the runner then reported as a failure (2026-10-10). Same trap class as +# poster_facts_gate.py's, which was found by its own red-proof. +for _stream in (sys.stdout, sys.stderr): + try: + _stream.reconfigure(encoding="utf-8", errors="replace") + except (AttributeError, ValueError, OSError): # pragma: no cover - old Python, or a pipe + pass + + ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) WORKSPACE = os.path.dirname(ROOT) diff --git a/website/CHANGELOG.md b/website/CHANGELOG.md index d8affb3b..ba44528b 100644 --- a/website/CHANGELOG.md +++ b/website/CHANGELOG.md @@ -1,3 +1,21 @@ +## 2026-10-10 — two new apps on the apps page: Grocy and LubeLogger + +- **Two cards added** to the „Otthon & Életmód" / "Home & Lifestyle" section of both apps pages, in the + same commit: **Grocy** (household stock, shopping list, barcodes, chores) and **LubeLogger** (the family + car's services, fuel, reminders and costs). Both went through `NEW-APP-CHECKLIST.md` end to end; + the records are in the catalog and the evidence in `documentation/audits/new-apps-2026-10-10/`. +- **Assets**: `grocy-logo.svg` is grocy's own `public/img/icon.svg` with its single fill made white, like + the other logos; `lubelogger-logo.png` is the app's own icon with its dark background dropped and the + mark made white, the same rule SparkyFitness's PNG follows. The six screenshots are each app's own + **Hungarian** UI with a household's own data, taken headless on the bench from the published template. +- **The app count moved 56 → 58** in every place the website states it, in both language sets (15 places + each): 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; and the technology page's bullet. The open-source tile moved + **49 → 51** (both apps are MIT). Checked by re-running the same patterns against the new number. +- **Not changed, and said here instead:** `marketing/facebook/COPY.md` §2 still says „56 alkalmazás" in + the post drafts, and the post scheduled for 2026-10-12 carries that number. It is already written and + the brief forbids editing posted text, so it stays — the next post should say 58. ## 2026-10-08 (evening) — every app logo white; five logo sets renamed to the catalog's names - **Seven coloured logos made white like the other 49** (operator request): Mealie (one fill → white), Homebox (white diff --git a/website/alkalmazasok.html b/website/alkalmazasok.html index ac4473e0..85c21823 100644 --- a/website/alkalmazasok.html +++ b/website/alkalmazasok.html @@ -3,8 +3,8 @@ - Telepíthető alkalmazások — 56 app otthoni szerverre | Felhom.eu - + Telepíthető alkalmazások — 58 app otthoni szerverre | Felhom.eu + @@ -15,14 +15,14 @@ - + - + @@ -32,7 +32,7 @@ "@type": "ItemList", "name": "Felhom.eu — Telepíthető alkalmazások", "description": "Önhostolt alkalmazások otthoni szerverre, szinte mind nyílt forráskódú", - "numberOfItems": 56, + "numberOfItems": 58, "itemListElement": [ {"@type": "ListItem", "position": 1, "name": "Nextcloud", "description": "Fájlkezelés és irodai csomag"}, {"@type": "ListItem", "position": 2, "name": "Immich", "description": "Fotó és videó kezelés (Google Photos alternatíva)"}, @@ -78,7 +78,7 @@