docs(report): lifecycle replaces retired/, live-proven on 9201

This commit is contained in:
2026-07-21 16:36:41 +02:00
parent a32541684a
commit 3067a94652
+47 -74
View File
@@ -1,87 +1,60 @@
# REPORT — catalog honesty pass (TASK-E Part 3), 2026-07-21 # REPORT — app lifecycle replaces the `retired/` move (TASK-F Part 1, catalog half), 2026-07-21
## What ran Baseline `857ba53`, clean tree.
Diagnose-and-re-pin for the two Campaign 7 apps whose images "do not resolve at all", plus R-41 ## What changed and why
slice 1 (a standing resolvability gate). Baseline `34d50a3`, clean tree.
## wanderer — RE-PINNED (upstream is alive; the template pointed at a ghost) The `retired/` directory mechanism shipped earlier the same day is **withdrawn**. It un-offers an app
correctly, but the controller discovers catalog templates by directory — so removing one makes the
orphan detector see the template as GONE for anyone already running the app, flagging their working
install `Elavult` and offering a Törlés button. Withdrawing an app must never take a working app away
from a customer.
| | | Replaced by an optional top-level `lifecycle:` in `.felhom.yml` (controller v0.158.0/.1):
`available` (default, absent/empty ≡ this) / `hidden` / `abandoned`.
- **`plant-it` returns to `templates/`** with `lifecycle: abandoned` — the first user of the
mechanism and the case that motivated it. `retired/` is removed. Catalog: **53 apps** (52 offered).
- Its compose is deliberately **unchanged**. It pins `msdeluise/plant-it:0.10.0`, a repository that
does not exist (the real one is `-server`), and the app is not installable — rewriting it would
imply it is. The evidence for abandonment is recorded in the template's own header comment.
## Live-proven on 9201
Through the normal git-sync and the real endpoints, not a hand-copy:
| check | result |
|---|---| |---|---|
| Old pin | `ghcr.io/flomp/wanderer:0.16.0`**does not resolve** (verified `docker manifest inspect`) | | `lifecycle: abandoned` present in `/opt/docker/stacks/plant-it/.felhom.yml` | yes |
| Failure class | **repo split + registry move + org rename**, all at once | | plant-it on the Alkalmazások page | **0 occurrences** (control `bookstack`: 10) |
| New pins | `flomp/wanderer-web:v0.20.0`, `flomp/wanderer-db:v0.20.0`, `getmeili/meilisearch:v1.36.0` | | direct `POST /api/stacks/plant-it/deploy` | **HTTP 409** „Ez az alkalmazás jelenleg nem telepíthető." |
| Evidence | upstream `docker-compose.yml` at tag `v0.20.0` (github.com/open-wanderer/wanderer); latest release 2026-07-07; all three tags confirmed present | | `/apps/plant-it` | 200, permanent abandoned notice, no Telepítés button |
Compose restructured from 1 service to 3 (web + PocketBase + Meilisearch), per upstream. Notable ## The resolvability gate is now lifecycle-aware
consequences, none of them cosmetic:
- **A second public hostname was unavoidable.** `PUBLIC_POCKETBASE_URL` is browser-side, so An abandoned app's dead image is the **expected end state**, not a finding. Left unhandled, plant-it
PocketBase must be publicly reachable; added `SUBDOMAIN_DB` (default `hike-db`). Upstream's own would have made the gate permanently exit 1 — and a gate that is always red is a gate nobody reads,
proxy example does the same. which is the same lesson as yesterday's throttle false-alarm.
- **New required volume** `/data/plugins` — v0.20.0 moved the Strava/Komoot/Hammerhead integrations
into a WASM plugin sandbox.
- **New generated secret** `POCKETBASE_ENCRYPTION_KEY` (`hex:16` → exactly 32 chars, as required).
- **Meilisearch pinned DOWN v1.49 → v1.36.0**, applying the R-42 ruling (sidecar follows the app
template's proposed pin). Campaign 7 had bumped it while the app image was dead.
- `mem_limit` 384M → 1024M = the exact sum of the three services (REUSE.md §2 rule).
- Probe container name kept equal to the stack dir (`wanderer`), or the health probe would hit the DB.
**Not deployed live.** This is a from-scratch 3-service restructure of an app that has never once - Non-available apps are **skipped by default and REPORTED**, never silently dropped.
deployed successfully; it wants a real deploy on the demo box before anyone is invited to it. - `--all` includes them again.
- An all-skipped run is a **pass (0)**, not the "no images found" error — that would have been a
false alarm of its own.
## plant-it — RETIRED (operator ruling 2026-07-21) 6 new fixture tests (**19 total**, no network), including the `lifecycle:` line-parse table: absent,
quoted, unknown (→ available), and an indented `lifecycle:` that must NOT match because it is not a
top-level key.
The pin was only slightly wrong — repository is `msdeluise/plant-it-server`, and `0.10.0` was the ## Gates
right version. Correcting the name would have been the wrong fix:
- Upstream **discontinued self-hosting**: `backend/` and `deployment/` are deleted from `main`; the `check-image-pins.py` → OK, 53 templates, 0 unpinned. `test_check_image_resolvable.py` → 19/19.
project is now an Android app on F-Droid/Obtainium, maintainer notes development has slowed.
- Last server image pushed **2024-12-10** — a security-frozen Spring Boot 3.4.0.
- Requires **MySQL 8.0 + Redis**. The template claimed "Database: None (file-based)" — never true.
Moved to `retired/plant-it/` rather than deleted: the controller discovers apps by directory, so this ## Remaining
un-offers it while keeping it revivable with one `git mv`. Catalog is now **52 apps**.
## R-41 slice 1 — `scripts/check-image-resolvable.py` - **The full resolvability table is still owed** — Part 4 was skipped by operator ruling (no Docker
Hub login on DooPlex), so the sweep would still hit the anonymous throttle and exit 2. One
Complements the syntactic pin gate, which cannot see rot. Resolves each unique pin one image at a `docker login` + `python3 scripts/check-image-resolvable.py` closes it.
time; exit 0 / 1 (GONE) / 2 (inconclusive). 14 fixture tests, no network. - **`hidden` has no user yet.** Implemented and tested, but only `abandoned` is exercised end to end.
- **wanderer is still undeployed** (from the previous session): re-pinned to a 3-service upstream
**Two traps encoded, both hit live during this change:** shape with a second public hostname, and never once deployed. It wants a real deploy on the demo
box before anyone is invited to it.
1. `docker manifest inspect` prints `toomanyrequests: …` and **still exits 0** — the same
exits-0-on-failure shape as the ISO tooling's `validate-answer`. stderr is therefore checked
even on rc=0.
2. The inverse, and the more dangerous one: the **first full sweep called 24 of 65 pins dead**,
including `postgres:16-alpine` and `redis:7-alpine`, purely because Docker Hub throttled it
partway through. Ambiguity now resolves to INCONCLUSIVE, never to an accusation.
### Sweep result — INCOMPLETE, and that is the honest answer
The full 65-pin sweep **could not be completed**: DooPlex is not logged in to Docker Hub, and the
anonymous limit was exhausted partway. The pre-throttle probes are trustworthy and are what the
findings above rest on:
| Image | Result | When |
|---|---|---|
| `ghcr.io/flomp/wanderer:0.16.0` | **GONE** | pre-throttle |
| `msdeluise/plant-it:0.10.0` | **GONE** | pre-throttle |
| `getmeili/meilisearch:v1.49` | resolves | pre-throttle |
| `flomp/wanderer-web:latest`, `flomp/wanderer-db:latest` | resolve | pre-throttle |
| `msdeluise/plant-it-backend/-frontend:latest` | resolve | pre-throttle |
| `flomp/wanderer-{web,db}:v0.20.0`, `getmeili/meilisearch:v1.36.0`, `msdeluise/plant-it-server:0.10.0` | exist (Hub tag API, HTTP 200) | post-throttle cross-check |
**Follow-up for the operator:** re-run `python3 scripts/check-image-resolvable.py` after
`docker login` to get the complete 52-app table. The gate now reports the throttle as INCONCLUSIVE
(exit 2) instead of inventing 24 dead images, so a repeat is safe to trust.
## Observations (recorded, not acted on)
- `REUSE.md` cited `felhom-controller/internal/stacks/healthprobe.go`; the real path has an extra
`controller/` segment. Corrected, but `reuse_refs_check.py` still flags it — it resolves citations
against the repo root and cannot follow a cross-repo pointer. Pre-existing checker limitation.
- The `-app`-suffixed wanderer tags (`v0.20.0-app`) are undocumented upstream; deliberately not used.
- 6 apps' `.felhom.yml` still carry `mem_limit` values that do not equal the sum of their services'
limits. wanderer is now correct; the others were out of scope.