v0.235.0: freeze the version, keep the fixes flowing (operator ruling 2026-09-06)
gates / gates (push) Successful in 12s
gates / gates (push) Successful in 12s
Slice 3. R-447 was BLOCKED because R-438 established that RestartStack's use of up -d to pick up template changes was CHOSEN and written down in its own comment. The operator ruled Option 1, and this implements it. The rule: while the catalog offers the same version you run, its fixes flow to you; the moment it moves to a newer version you are frozen until you update. NOTHING was added to any of the thirteen compose up -d call sites. Most of them are repairs - the boot reconciler, the drive-return gate, the app-stop guard - and a repair path that refuses to repair leaves a customer's app down, which is worse than the problem. They are made safe by removing the reason. app.yaml gains pinned_images: what the app is SUPPOSED to run. It is NOT installed_images, which is an observation; letting a reading become a deployment is the R-166 category error one field over. Four writers, each also storing the exact definition as applied-compose.yml. UpdateStack advances the pin and re-renders BEFORE the pull, because pull and up -d act on the file on disk, and a pin set afterwards would pull the frozen version and report success. The syncer renders instead of copying, through one nil-safe seam. Catalog images equal the pin -> verbatim, so fixes and self-healing both survive; they differ -> the WHOLE stored definition, never a substitution of refs into a newer template (wger 2.6 needs a DB config the older template cannot supply). This is deliberately not 'skip deployed apps', which was option B and was rejected. AdoptPins runs once at boot after the backfill, files only, and skips loudly rather than inventing a pin. syncer.Start() moved to after it: the initial sync would otherwise run while every app was unpinned and overwrite a deployed app's version once per boot. THE BADGE HAD TO CHANGE OR SLICE 2 WOULD HAVE INVERTED SILENTLY. TemplateImages reads the LIVE compose file, which is now the frozen one, so the comparison would have answered Naprakesz on exactly the apps that are behind - with every test green, because the new field has the same type. It now reads CatalogImages. +16 tests (1729 -> 1745), 28 packages green. Three red-proofs run and reverted. A test also caught the syncer writing an empty compose file over a live app.
This commit is contained in:
@@ -532,6 +532,29 @@ the current template pins and returns a `*MetaBadge` rendered by the existing `m
|
||||
|
||||
Reasoning and the seven-slice plan: `felhom.eu/documentation/architecture/09-update-architecture.md`.
|
||||
|
||||
#### Freeze the version, keep the fixes flowing (v0.235.0 — update arc slice 3)
|
||||
|
||||
**Operator ruling, 2026-09-06.** An app's version is frozen to what the customer has; only a
|
||||
deliberate Update moves it. Everything else in a template — health checks, memory limits, new deploy
|
||||
fields — still arrives on the 15-minute cycle, and a broken definition still repairs itself.
|
||||
|
||||
- **`app.yaml` gains `pinned_images`** (service → ref): what the app is SUPPOSED to run. **Not**
|
||||
`installed_images`, which is an observation. Written only by the deploy path, `UpdateStack`, a
|
||||
restore, and the one-time `AdoptPins`. **Absent = unpinned = pre-v0.235.0 behaviour.**
|
||||
- **`applied-compose.yml`** in the stack dir stores the exact definition the pin came from. The
|
||||
syncer copies only `docker-compose.yml` and `.felhom.yml`, so that name is safe.
|
||||
- **`Syncer` renders instead of copying**, via the nil-safe `SetRenderPlanFn` seam. Catalog images
|
||||
equal the pin → copy verbatim (fixes flow, self-healing works). They differ → write the stored
|
||||
definition, **whole** — never a substitution of refs into a newer template (`wger 2.6`).
|
||||
- **`.felhom.yml` always flows**, even to a frozen app: it holds no image and carries `catalog_since`.
|
||||
Known limitation, R-458.
|
||||
- **Nothing was added to the thirteen `compose up -d` call sites.** Most are repairs; a repair that
|
||||
refuses to repair leaves an app down.
|
||||
- **The badge reads `Stack.CatalogImages`, never `TemplateImages`.** After the freeze the live compose
|
||||
file is the frozen one, so comparing against it would answer „Naprakész" on apps that are behind.
|
||||
|
||||
Reasoning: `felhom.eu/documentation/architecture/09-update-architecture.md` §3, §5.
|
||||
|
||||
#### App Info Pages
|
||||
|
||||
Each app can define rich metadata in `.felhom.yml`:
|
||||
|
||||
Reference in New Issue
Block a user