test record: an image move must carry its proof (09 decision 13, part 4)
gates / gates (push) Successful in 1s

update_ladder: in .felhom.yml, one JSON entry per line (spiked live on
controller v0.266.0 and v0.267.0 first). Two gates: check-test-record.py
(static, CI too) and check-test-record-move.py (history + registry for
moved refs only). 16 decoys, 3 red-proofs. The ONLY writer is
upgrade-test.py --write-ladder (bench AND box proven, digests resolved).
Harness v3: box fixtures on the bench, files_may_change.
Backfill: the 21 moves of 2026-09-22, 21 proven from their records.
No image: line moved.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-23 20:52:32 +02:00
parent cfcfe52784
commit 6db08a5eb3
38 changed files with 2944 additions and 37 deletions
+10 -1
View File
@@ -6,7 +6,13 @@
## 1. Canonical helpers
None — this repo is templates/config, not code. See §2/§5.
Templates are config; the few script helpers other scripts must REUSE, never re-implement:
- `scripts/ladder.py` — the test record (`update_ladder:` in `.felhom.yml`): `parse`, `check_entry`,
`images_in` (the per-service image reading every gate makes), `append_entry`. One JSON entry per line.
- `scripts/image_digest.py` — `resolve(ref)` → the digest the registry serves now (the one Docker
records in `RepoDigests`). stdlib only — the CI runner has no `requests`/PyYAML.
- `scripts/upgrade_boxport.py` — runs the box walk's fixtures (`upgrade_fixtures_box*.py`) on the bench.
## 2. Canonical patterns (copy structure from THE named file)
@@ -55,6 +61,9 @@ None — this repo is templates/config, not code. See §2/§5.
3. Update `README.md` App Catalog + Variable-types tables (convention — every existing app is listed).
4. Skip `templates.json` / `generate-customer.sh` (legacy, §3).
5. Email-capable app: add `smtp_mapping` + matching `${VAR:-}` compose lines (§2 last row).
6. **Moving an existing app's `image:`** is not an edit: run `scripts/upgrade-test.py --move <app> <svc>=<ref>`
on the bench, walk it on a scratch box, then `upgrade-test.py --write-ladder …` writes the compose move,
`catalog_since` and the ladder entry. `check-test-record-move.py` refuses a move without it (`09` decision 13).
## 6. Known inconsistencies (observed — NOT fixed)