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.
This commit is contained in:
@@ -1,5 +1,55 @@
|
||||
# Changelog
|
||||
|
||||
## 2026-07-21 — catalog honesty: wanderer re-pinned, plant-it retired, and a standing rot gate (R-41 slice 1)
|
||||
|
||||
Campaign 7 left two apps sitting behind a working "Telepítés" button with images that did not
|
||||
resolve at all, recorded as findings rather than fixed. Both are now diagnosed rather than hidden,
|
||||
and the class of defect gets a gate so it cannot recur silently.
|
||||
|
||||
**wanderer — RE-PINNED. The project is alive; the template was pointing at a ghost.**
|
||||
`ghcr.io/flomp/wanderer:0.16.0` does not resolve because upstream did three things at once: split
|
||||
the app into two images, moved registry, and renamed the GitHub org (Flomp → open-wanderer). Current
|
||||
shape, taken from upstream's own compose at tag v0.20.0 (2026-07-07):
|
||||
|
||||
- `flomp/wanderer-web:v0.20.0` — the SvelteKit web app, port 3000, `curl` on PATH.
|
||||
- `flomp/wanderer-db:v0.20.0` — PocketBase, port 8090. Built FROM `scratch`: no shell, no package
|
||||
manager, a static curl baked in at `/curl` — hence the absolute-path healthcheck.
|
||||
- `getmeili/meilisearch:v1.36.0` — still a required sidecar; both other services wait on its health.
|
||||
**Pinned DOWN from the v1.49 Campaign 7 had set**, per the R-42 ruling: a sidecar pin follows the
|
||||
app template's own proposed pin, never the newest tag independently.
|
||||
- **New required volume** `/data/plugins` on the db — v0.20.0 moved the Strava/Komoot/Hammerhead
|
||||
integrations into a WASM plugin sandbox that lives there.
|
||||
- **New: a second hostname** (`SUBDOMAIN_DB`, default `hike-db`). `PUBLIC_POCKETBASE_URL` is a
|
||||
browser-side variable — the user's browser talks to PocketBase directly, so it cannot be an
|
||||
internal address. Upstream's own proxy example uses two hostnames for the same reason.
|
||||
- New generated secret `POCKETBASE_ENCRYPTION_KEY` (`hex:16` → exactly the 32 characters upstream
|
||||
requires). `mem_limit` 384M → 1024M, matching the sum of the three services.
|
||||
|
||||
**plant-it — RETIRED to `retired/plant-it/` (operator ruling 2026-07-21).** The pin was only
|
||||
slightly wrong — the repository is `msdeluise/plant-it-server`, and `0.10.0` was the right version —
|
||||
but correcting the name would have been the wrong fix. Upstream has **discontinued self-hosting**:
|
||||
`backend/` and `deployment/` are deleted from `main`, the project is now an Android app on
|
||||
F-Droid/Obtainium, and the last server image was pushed **2024-12-10** (a security-frozen Spring
|
||||
Boot 3.4.0). It also requires **MySQL 8.0 + Redis**, which the template never had — its header
|
||||
claimed "Database: None (file-based)", which was never true. Ruling: do not ship unmaintained
|
||||
software to customers. Retirement is reversible (`git mv retired/plant-it templates/plant-it`);
|
||||
nothing is deleted. Catalog is now **52 apps**.
|
||||
|
||||
**`scripts/check-image-resolvable.py` — R-41 slice 1: the standing rot gate.** `check-image-pins.py`
|
||||
is syntactic and proves only that a template pins *something* concrete; it cannot see that the thing
|
||||
is gone. This resolves every unique pin with `docker manifest inspect`, one image at a time, and
|
||||
exits 0 / 1 (GONE) / 2 (inconclusive). Two traps are encoded in it, both observed live during this
|
||||
change:
|
||||
|
||||
- `docker manifest inspect` prints `toomanyrequests: …` and **still exits 0** — the same
|
||||
exits-0-on-failure shape as the ISO tooling's `validate-answer`, so stderr is checked even on rc=0.
|
||||
- The inverse, which the first full sweep actually did: it 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 — a gate that cries wolf gets
|
||||
ignored, and then it protects nothing.
|
||||
|
||||
14 fixture tests (`scripts/test_check_image_resolvable.py`), no network — the resolver is injected.
|
||||
|
||||
## 2026-07-19 — docs: workspace-root pointer follows the CC move to DooPlex
|
||||
|
||||
**Docs only, no template change.** Claude Code now runs on DooPlex (192.168.0.180, Debian 13)
|
||||
|
||||
Reference in New Issue
Block a user