Files
app-catalog-felhom.eu/REPORT.md
T
admin b3eabfd611 catalog: re-pin wanderer to the current upstream shape, retire plant-it, add the resolvability gate
wanderer: ghcr.io/flomp/wanderer:0.16.0 is a ghost - upstream split the app
into web+db images, moved registry and renamed the org. Restructured to
upstream's own v0.20.0 compose (3 services, new /data/plugins volume, second
public hostname for PocketBase, meilisearch pinned DOWN to upstream's v1.36.0
per the R-42 ruling).

plant-it: retired. The repo name was wrong (plant-it-server) but upstream has
DELETED self-hosting; last server image is 2024-12-10 and it needs MySQL+Redis
the template never had. Moved to retired/ rather than deleted - reversible.

R-41 slice 1: check-image-resolvable.py. Encodes two traps - manifest inspect
exits 0 while printing toomanyrequests, and the inverse, where the first sweep
called 24 of 65 pins dead because Hub throttled it. Ambiguity is INCONCLUSIVE,
never an accusation.
2026-07-21 15:30:15 +02:00

88 lines
5.1 KiB
Markdown

# REPORT — catalog honesty pass (TASK-E Part 3), 2026-07-21
## What ran
Diagnose-and-re-pin for the two Campaign 7 apps whose images "do not resolve at all", plus R-41
slice 1 (a standing resolvability gate). Baseline `34d50a3`, clean tree.
## wanderer — RE-PINNED (upstream is alive; the template pointed at a ghost)
| | |
|---|---|
| Old pin | `ghcr.io/flomp/wanderer:0.16.0`**does not resolve** (verified `docker manifest inspect`) |
| Failure class | **repo split + registry move + org rename**, all at once |
| New pins | `flomp/wanderer-web:v0.20.0`, `flomp/wanderer-db:v0.20.0`, `getmeili/meilisearch:v1.36.0` |
| 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 |
Compose restructured from 1 service to 3 (web + PocketBase + Meilisearch), per upstream. Notable
consequences, none of them cosmetic:
- **A second public hostname was unavoidable.** `PUBLIC_POCKETBASE_URL` is browser-side, so
PocketBase must be publicly reachable; added `SUBDOMAIN_DB` (default `hike-db`). Upstream's own
proxy example does the same.
- **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
deployed successfully; it wants a real deploy on the demo box before anyone is invited to it.
## plant-it — RETIRED (operator ruling 2026-07-21)
The pin was only slightly wrong — repository is `msdeluise/plant-it-server`, and `0.10.0` was the
right version. Correcting the name would have been the wrong fix:
- Upstream **discontinued self-hosting**: `backend/` and `deployment/` are deleted from `main`; the
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
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`
Complements the syntactic pin gate, which cannot see rot. Resolves each unique pin one image at a
time; exit 0 / 1 (GONE) / 2 (inconclusive). 14 fixture tests, no network.
**Two traps encoded, both hit live during this change:**
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.