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

5.1 KiB

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.0does 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.