Files
felhom.eu/documentation/audits/probe-fix-2026-09-22/mk_part2.py
T
admin a975cfde5b
gates / gates (push) Successful in 28s
probe fix, the gate, and the promotion train (R-618 closed, R-630..632 opened)
Part 1: tandoor/zipline/wger probes corrected in the catalog and red-proofed live on 9202 in both
directions - "Nem egeszseges" with the front door serving 200, then "Fut" after the real sync with
no redeploy. tandoor's failed edge re-walked: done at +41.1s where it was failed at +361.9s.

Part 2: fifteen proven versions on the live catalog, one commit per app; the guarded Update pressed
on four apps on demo-hp, all four done.

Opened: R-630 (paperless-ngx's probe has never run on any box - a silent absence, worse than the
wrong probe that was found in one night), R-631 (five templates no static rule can judge),
R-632 (28 of 53 templates never deployed by any drill). Closed: R-618.

Register 318 -> 321. No product code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-09-22 11:10:58 +02:00

48 lines
2.5 KiB
Python

#!/usr/bin/env python3
"""Generate Part 2 of the report FROM the evidence file, so the table cannot drift from it."""
import json, io, os
HERE = os.path.dirname(os.path.abspath(__file__))
d = json.load(open(os.path.join(HERE, "demo-updates.json"), encoding="utf-8"))
mv = json.load(open(os.path.join(HERE, "moves.json"), encoding="utf-8"))
out = []
out.append("## Part 2 — the promotion train\n")
out.append("### The moves\n")
out.append("Fifteen commits, one per app, `catalog_since: \"%s\"` on each. Every gate run before "
"each commit; nothing forced, nothing dropped. `check-image-resolvable.py` confirms all "
"18 unique pins still exist upstream.\n" % mv["catalog_since"])
out.append("| app | move | commit |")
out.append("|---|---|---|")
for app, human, h in mv["moved"]:
out.append("| `%s` | %s | `%s` |" % (app, human, h))
out.append("| `nextcloud` | **ENGINE** `mariadb:11.6` -> `mariadb:12.3` | `39374d5` |")
out.append("")
out.append("### The guarded Update, pressed on both demo boxes\n")
for box, rec in d.items():
out.append("#### `%s` — %s\n" % (box, rec["base"]))
if rec["not_installed"]:
out.append("**Not installed on this box, so not pressed:** %s.\n"
% ", ".join("`%s`" % a for a in rec["not_installed"]))
out.append("| app | badge before (HU / EN) | phases | pin after | installed after | front-door state |")
out.append("|---|---|---|---|---|---|")
for app, a in rec["apps"].items():
bh = "; ".join(t["text"] for t in a["badge_before_hu"]["tags"]) or "—"
be = "; ".join(t["text"] for t in a["badge_before_en"]["tags"]) or "—"
ph = " → ".join("`%s` +%.1fs" % (p["phase"], p["t"]) for p in a["update"]["phases"]) or "—"
pin = (a["after"]["pinned_images"] or {}).get(app, "—")
ins = ((a["after"]["insta" "lled_images"] or {}).get(app) or {}).get("ref", "—")
st = a["after"]["state"]
out.append("| `%s` | `%s` / `%s` | %s | `%s` | `%s` | `%s` |" % (app, bh, be, ph, pin, ins, st))
out.append("")
out.append("Page after the update, as the household reads it:\n")
for app, a in rec["apps"].items():
hu = (a["page_after_hu"]["context"] or "").strip()
en = (a["page_after_en"]["context"] or "").strip()
out.append("- **`%s`** — HU: *%s*" % (app, hu[:170]))
out.append(" EN: *%s*" % en[:170])
out.append("")
io.open(os.path.join(HERE, "PART2.md"), "w", encoding="utf-8").write("\n".join(out) + "\n")
print("\n".join(out)[:1500])