25cb3eb9c1
gates / gates (push) Successful in 29s
- R-463 CLOSED: rallly, outline, sparkyfitness -> PostgreSQL 18 (catalog 25ffd89 / aeb0cd6 / 1666572), each proven on the bench and on 9202 through the guarded Update with one undo case; zipline, adventurelog, immich stay on 16 by 09 decision 42's rule (upstream runs 16 / 16 / 14). - Part F: bookstack, kimai, audiobookshelf, n8n, navidrome, grafana, komga moved on both venues; immich not (R-732: its first start OOM-killed its database on the bench). - R-687 item 4 PROVEN LIVE on demo-hp: two deferrals while the leg stepped two apps, the whole-guest backup on the first poll after, success; config + window put back and read back. - Catalog currency audit (Part D): 25/53 behind inside a major, 19 across; night-updatable 28 -> 31 (+1). - R-446 and R-440 narrowed (measured on demo-hp); R-624 corrected (outline, rallly, zipline have routes); R-548 note (demo-hp's local tier refused for space since 09-27). - New rows: R-730 (the ISO 1.29.0 build commit cannot be proven -> no tag; installer-v* is the script's line), R-731 (tag-shape switches), R-732. Register 361 -> 364. - 09 §3: the 2026-09-30 operator notes (by day; Tester-2 pre-checks done; decision 52 not needed, not recorded); §6.4 dated currency note. STATUS, CONTEXT, REPORT-pg-last-six-2026-09-30.md. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
44 lines
2.6 KiB
Python
44 lines
2.6 KiB
Python
"""drillmove.py <app> <svc> <from-ref> <to-ref> <from-major> <to-major>
|
|
DRILL-ONLY commit: move one PostgreSQL service in the drill catalog and add the ladder entry that carries the
|
|
engine_conversion mark, so the box (9202) can prove the conversion through its own guarded Update. The live
|
|
catalog's entry is written later ONLY by `upgrade-test.py --write-ladder` from both verdicts."""
|
|
import json, re, subprocess, sys
|
|
D = "/mnt/5_hdd/felhom.eu/drill/app-catalog-drill"
|
|
app, svc, frm, to, fmj, tmj = sys.argv[1:7]
|
|
subprocess.run(["git", "-C", D, "pull", "-q", "--rebase", "origin", "main"], check=True)
|
|
comp = f"{D}/templates/{app}/docker-compose.yml"
|
|
fy = f"{D}/templates/{app}/.felhom.yml"
|
|
s = open(comp).read()
|
|
assert f"image: {frm}" in s, "from ref not in compose"
|
|
pins = {}
|
|
cur = None
|
|
for line in s.splitlines():
|
|
m = re.match(r"^ ([a-z0-9-]+):\s*$", line)
|
|
if m: cur = m.group(1)
|
|
m = re.match(r"^\s+image:\s*(\S+)", line)
|
|
if m and cur: pins[cur] = m.group(1)
|
|
s = s.replace(f"image: {frm}", f"image: {to}")
|
|
# the mount follows the major PER SERVICE, exactly as the catalog writer and the bench do (upgrade-test.py
|
|
# pg_mounts_for) — the old regex needed "postgres" in the VOLUME name and missed sparkyfitness_db_data.
|
|
import importlib.util
|
|
_spec = importlib.util.spec_from_file_location("ut", "/mnt/5_hdd/felhom.eu/git/app-catalog-felhom.eu/scripts/upgrade-test.py")
|
|
_ut = importlib.util.module_from_spec(_spec); _spec.loader.exec_module(_ut)
|
|
s = _ut.pg_mounts_for(s)
|
|
open(comp, "w").write(s)
|
|
top = dict(pins); top[svc] = to
|
|
entry = {"from": pins, "to": top, "verdict": "proven", "tested_at": "DRILL", "harness_version": 4,
|
|
"evidence": "DRILL (box proof in progress)", "marks": {"files_may_change": False, "needs_person": None, "memory_tight": False},
|
|
"engine_conversion": {"service": svc, "engine": "postgres", "from": int(fmj), "to": int(tmj)}}
|
|
f = open(fy).read()
|
|
line = " - " + json.dumps(entry) + "\n"
|
|
if "update_ladder:" in f:
|
|
f = f.replace("update_ladder:\n", "update_ladder:\n", 1)
|
|
f = f.rstrip("\n") + "\n" + line if f.rstrip("\n").endswith("}") else f + line
|
|
else:
|
|
f = f.rstrip("\n") + "\nupdate_ladder:\n" + line
|
|
open(fy, "w").write(f)
|
|
subprocess.run(["git", "-C", D, "commit", "-q", "-am", f"DRILL {app}: {svc} {frm} -> {to} with the engine_conversion mark (box proof)"], check=True)
|
|
subprocess.run(["git", "-C", D, "push", "-q", "origin", "main"], check=True, capture_output=True)
|
|
print(subprocess.run(["git", "-C", D, "log", "--oneline", "-1"], capture_output=True, text=True).stdout.strip())
|
|
print(subprocess.run(["git", "-C", D, "show", "--stat", "HEAD"], capture_output=True, text=True).stdout[-300:])
|