#!/usr/bin/env python3 """Rewrite the rotation file's line for each of the 28, from its own verdict record. A tick means the app was WALKED FULLY — deployed, backed up, restored, removed clean. An app whose data half is `inconclusive` is still ticked when the rest of the walk completed, and the line SAYS what could not be judged; an app that could not be deployed is not ticked. """ import glob, io, json, os, re HERE = os.path.dirname(os.path.abspath(__file__)) ROT = "/mnt/5_hdd/felhom.eu/git/felhom.eu/documentation/runbooks/nightly-rotation.md" D = "2026-09-22" EV = "`audits/DRILL-the-28-2026-09-22.md`" recs = {} for f in glob.glob(os.path.join(HERE, "apps", "*", "verdict.json")): d = json.load(open(f, encoding="utf-8")) recs[d["app"]] = d def line(a, d): if not d["deployed"]: why = "; ".join(d["notes"]) or "deploy refused" return (f"- [ ] {a} — NOT A FULL WALK; attempted {D} (the 28, scratch guest 9202): " f"**could not be deployed** — {why}. {EV}.") bits = ["install", f"front door {d.get('front_door_after_deploy',{}).get('code','?')}"] if d["seed_read_before"]: bits.append(f"seeded through {d.get('seed_route')} and read back") else: bits.append("NO non-browser data route (" + ( "; ".join(n for n in d["notes"] if "route" in n) or "recorded, not faked") + ")") bits.append("„Mentés most\"") e = d.get("edge") if e: bits.append("real upstream Update %s->%s (%s)" % ( e["from"].rsplit(":", 1)[1], e["to"].rsplit(":", 1)[1], d.get("update_phase_final"))) if d.get("migration_observed"): bits.append("own migration line quoted") if d["seed_read_after_update"]: bits.append("read back after the update") else: bits.append("no upstream edge tonight") bits.append("restore " + str(d.get("restore_verdict"))) if d["seed_read_after_restore"]: bits.append("read back after the restore") bits.append("removed " + ("clean" if d.get("removed_clean") else "**with a leftover container**")) tick = "x" if (d["deployed"] and d.get("removed_clean")) else " " pre = "" if tick == "x" else "NOT A FULL WALK; attempted " return f"- [{tick}] {a} — {pre}{D} (the 28, scratch guest 9202): " + ", ".join(bits) + f". {EV}." t = io.open(ROT, encoding="utf-8").read() n = 0 for a, d in sorted(recs.items()): pat = re.compile(r'^- \[[ x]\] ' + re.escape(a) + r'( .*)?$', re.M) if pat.search(t): t = pat.sub(lambda m: line(a, d).replace("\\", "\\\\"), t, count=1) n += 1 else: print(" NO EXISTING LINE for", a) io.open(ROT, "w", encoding="utf-8").write(t) print(f"rewrote {n} rotation lines")