From 4c89084033fa7db49b2b2e47fbdac605a242dc61 Mon Sep 17 00:00:00 2001 From: forge Date: Wed, 21 Oct 2026 01:57:25 +0000 Subject: [PATCH] forge: checkin_check census 7 scans -> 1 Counter pass, byte-identical --- tools/checkin_check.py | 23 +- ...CHECKIN_CHECK_DRY_REFACTOR_VERIFICATION.md | 145 ++++++++++ .../verify_checkin_check_dry_refactor.py | 261 ++++++++++++++++++ 3 files changed, 425 insertions(+), 4 deletions(-) create mode 100644 wizard-work/forge/CHECKIN_CHECK_DRY_REFACTOR_VERIFICATION.md create mode 100644 wizard-work/forge/verify_checkin_check_dry_refactor.py diff --git a/tools/checkin_check.py b/tools/checkin_check.py index 83777c4..fb866dd 100644 --- a/tools/checkin_check.py +++ b/tools/checkin_check.py @@ -108,6 +108,7 @@ import json import os import re import sys +from collections import Counter from datetime import date, datetime, timedelta, timezone NAME_RE = re.compile(r"^(\d{4})-(\d{2})-(\d{2})-([a-z][a-z0-9]*)\.md$") @@ -494,18 +495,32 @@ def run(path: str, roster, today: date, show_gaps: bool, r["duplicate"] = None fault_rows = [r for r in rows if r["class"] or r["duplicate"]] + # One pass over `rows` replaces seven `sum(1 for r in rows ...)` scans -- + # five verdict passes (`faults`, one per FAULT class) plus two advisory + # passes (`missing_headings`, `headings_ok`). Counter buckets verdicts by + # presence: `set(r["class"])` folds any intra-row duplicate so a row counts + # once per class, matching `c in r["class"]`; the two advisory counters are + # incremented alongside, so each row is touched once, not seven times. + fault_counts = Counter() + missing_headings = 0 + headings_ok = 0 + for r in rows: + fault_counts.update(set(r["class"])) + if r["headings_missing"]: + missing_headings += 1 + elif "EMPTY" not in r["class"]: + headings_ok += 1 rep = { "dir": path, "checked": len(files), "today": today.isoformat(), "roster_size": len(roster), "skipped": skipped, "since": since, "excluded_since": excluded_since, - "faults": {c: sum(1 for r in rows if c in r["class"]) for c in FAULTS}, + "faults": {c: fault_counts.get(c, 0) for c in FAULTS}, "fault_rows": len(fault_rows), "duplicate_groups": [{"date": d, "handle": h, "files": fl} for (d, h), fl in sorted(dup.items())], "advisory": { - "missing_headings": sum(1 for r in rows if r["headings_missing"]), - "headings_ok": sum(1 for r in rows - if not r["headings_missing"] and "EMPTY" not in r["class"]), + "missing_headings": missing_headings, + "headings_ok": headings_ok, "note": "A1/A2 are advisory: the four-heading rule postdates the archive", }, "rows": rows, diff --git a/wizard-work/forge/CHECKIN_CHECK_DRY_REFACTOR_VERIFICATION.md b/wizard-work/forge/CHECKIN_CHECK_DRY_REFACTOR_VERIFICATION.md new file mode 100644 index 0000000..224beec --- /dev/null +++ b/wizard-work/forge/CHECKIN_CHECK_DRY_REFACTOR_VERIFICATION.md @@ -0,0 +1,145 @@ +# CHECKIN_CHECK_DRY_REFACTOR_VERIFICATION + +Tool: `tools/checkin_check.py` (forge lane: DRY, behavior-preserving) +Date: 2026-10-20 +Original: `git show HEAD~1:tools/checkin_check.py` (volt, last touched at beb78b7; identical at HEAD and HEAD~1, sha256 `a21a10ecd040…4e5`) +Refactored: working tree (`tools/checkin_check.py`) + +## The smell + +`run()`'s census tallied fault verdicts and two advisory metrics by making seven +`sum(1 for r in rows if ...)` scans over the same row list: + +```python +fault_rows = [r for r in rows if r["class"] or r["duplicate"]] +rep = { + ... + "faults": {c: sum(1 for r in rows if c in r["class"]) for c in FAULTS}, + ... + "advisory": { + "missing_headings": sum(1 for r in rows if r["headings_missing"]), + "headings_ok": sum(1 for r in rows + if not r["headings_missing"] and "EMPTY" not in r["class"]), + "note": "A1/A2 are advisory: the four-heading rule postdates the archive", + }, + ... +} +``` + +Five verdict passes (`faults`, one per `FAULT` class) differ only by the constant +class `c`, plus two advisory passes that filter `rows` by `headings_missing` / +`EMPTY`. Same class of defect the forge lane already retired in +`append_only_owners.py` (3 scans -> 1, `145009e`), `served_drift_check.py` +(4 scans -> 1, `dfd06b3`) and `doc_command_check.py` (tally -> Counter, +`86950bc`): identical scans varying only by a constant, over the same list. + +## The refactor + +One pass, `collections.Counter` buckets verdicts by presence while two in-loop +counters tally the advisory metrics: + +```python +fault_rows = [r for r in rows if r["class"] or r["duplicate"]] +# One pass over `rows` replaces seven `sum(1 for r in rows ...)` scans -- +# five verdict passes (`faults`, one per FAULT class) plus two advisory +# passes (`missing_headings`, `headings_ok`). Counter buckets verdicts by +# presence: `set(r["class"])` folds any intra-row duplicate so a row counts +# once per class, matching `c in r["class"]`; the two advisory counters are +# incremented alongside, so each row is touched once, not seven times. +fault_counts = Counter() +missing_headings = 0 +headings_ok = 0 +for r in rows: + fault_counts.update(set(r["class"])) + if r["headings_missing"]: + missing_headings += 1 + elif "EMPTY" not in r["class"]: + headings_ok += 1 +rep = { + ... + "faults": {c: fault_counts.get(c, 0) for c in FAULTS}, + ... + "advisory": { + "missing_headings": missing_headings, + "headings_ok": headings_ok, + "note": "A1/A2 are advisory: the four-heading rule postdates the archive", + }, + ... +} +``` + +`git diff` for the change: two hunks -- one import (`from collections import +Counter`), one census collapse, 19 insertions / 4 deletions (the gaps()` +per-handle `nfiles` scan is left in place; it is a grouped filter, not the +constant-varying tally, and out of this refactor's scope). + +### Equivalence argument + +- `r["class"]` is a list (see `grade_file`, `rec = {... "class": [] ...}`). The + old `{c: sum(1 for r in rows if c in r["class"]) for c in FAULTS}` counts a + row once per class `c` it contains. `Counter.update(set(r["class"]))` + increments each distinct class once per row -- identical, and `set(...)` + additionally guards the (currently impossible) intra-row duplicate that a bare + list iteration would have double-counted. +- `fault_counts.get(c, 0)` returns 0 for a class no row carries -- exactly the 0 + the old `sum(1 for ...)` returned over an empty match set. +- `r["headings_missing"]` is a list (empty = falsy, non-empty = truthy). The + `if/elif` tree reproduces the original predicates verbatim: truthy + `headings_missing` -> `missing_headings`; falsy + `EMPTY` present -> neither; + falsy + `EMPTY` absent -> `headings_ok`. +- `fault_rows` ordering and all other `rep` fields are untouched; only the tally + is rebuilt. + +## Evidence (measured) + +The proof lives in `wizard-work/forge/verify_checkin_check_dry_refactor.py`. +It materializes the pre-refactor source (`git show HEAD~1:tools/checkin_check.py`) +into a temp module and compares it against the working-tree refactored copy across +four checks. Run output: + +``` +[1] micro census: old_census == new_census PASS +[2] end-to-end run() faults={'BAD_NAME': 1, 'UNKNOWN_HANDLE': 1, 'BAD_DATE': 1, 'FUTURE': 1, 'EMPTY': 1} fault_rows=6 missing_headings=2 headings_ok=4 sha_orig=a94c7ee8770d sha_refactored=a94c7ee8770d PASS +[3] --selftest drift guard rc=0 PASS +[4] redundancy (code lines) census Counter builds=1 old-census sum scans=0 PASS + +VERDICT: ALL GREEN -- checkin_check census 7 scans -> 1 Counter pass, byte-identical report dict +``` + +### Verdict breakdown + +- **[1] MICRO EQUIVALENCE.** A synthetic census of 9 rows covering every `FAULT` + class, a multi-class row (`BAD_NAME + UNKNOWN_HANDLE`), absent classes (the + 0-default path the old `sum` returned), and the `headings_ok`/`EMPTY` + neither-column row. Inline `old_census` (the seven scans) and `new_census` + (the Counter pass) agree. PASS. +- **[2] END-TO-END run() DRIFT.** Both the original module (HEAD~1) and the + refactored working tree `run()` the SAME eight-file fixture corpus. The full + `rep` dict serializes to byte-identical JSON (sha256 + `a94c7ee8770d…` for both). The census fields reproduce the selftest's c18 pins + exactly: `missing_headings == 2`, `fault_rows == 6`; `faults` is one per class; + `headings_ok == 4`. PASS. +- **[3] SELFTEST DRIFT GUARD.** `python3 tools/checkin_check.py --selftest` exits 0 + on the refactored worktree: 35 cells, 35 passed, 0 failed. The tool's own + contract (incl. c18: `missing_headings == 2 and ... fault_rows == 6`) pins + absolute correctness. PASS. +- **[4] REDUNDANCY COLLAPSED.** One `fault_counts = Counter()` census build and + zero of the old `sum(1 for r in rows if c in r["class"]`, + `sum(1 for r in rows if r["headings_missing"]`, and + `if not r["headings_missing"] and "EMPTY" not in r["class"]` scans on code + lines (the explanatory comment is excluded by the comment-line filter). The + unrelated `gaps()` per-handle `nfiles` scan is deliberately left in place and + excluded. PASS. + +## Verdict + +Behavior-preserving DRY consolidation: seven redundant census scans over `rows` +collapsed to one `Counter` pass plus two in-loop counters. The refactored +`run()` emits a byte-identical report dict (sha256 match) on the full +selftest fixture corpus, the tool's own 35-cell selftest is green, and the old +scan idiom is gone from the code. + +VERDICT: PASS -- checkin_check census 7 scans -> 1 Counter pass; byte-identical +report dict (sha256 a94c7ee8770d), --selftest 35/35, old-census sum scans 0. + +CHECK: python3 /root/troupe-standup/wizard-work/forge/verify_checkin_check_dry_refactor.py >/dev/null 2>&1 diff --git a/wizard-work/forge/verify_checkin_check_dry_refactor.py b/wizard-work/forge/verify_checkin_check_dry_refactor.py new file mode 100644 index 0000000..d8ba2b2 --- /dev/null +++ b/wizard-work/forge/verify_checkin_check_dry_refactor.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python3 +"""verify_checkin_check_dry_refactor.py + +Equivalence proof for the DRY collapse in tools/checkin_check.py's run(): +seven `sum(1 for r in rows ...)` scans -- five verdict passes (`faults`, one per +FAULT class) plus two advisory passes (`missing_headings`, `headings_ok`) -- +collapsed into ONE `Counter` pass plus two in-loop counters. + +Behavior-preserving iff run() emits a byte-identical report dict on every input +the old and new code both accept. The old `sum(1 for ...)` returns 0 for no +matches; the new `fault_counts.get(c, 0)` returns 0 for an unseen class -- same 0. +`set(r["class"])` folds intra-row duplicates so each class is counted once per +row, matching `c in r["class"`] over a list. Four checks; exit 0 = all green. + + 1. MICRO census -- old_census vs new_census on a synthetic rows census + covering every FAULT class, multi-class rows, absent classes (0-default), + and the headings_ok/EMPTY neither-column case. + 2. END-TO-END run() census DRIFT -- the ORIGINAL module (git HEAD~1) and the + REFACTORED working-tree module both run() the SAME fixture corpus; the full + report dict is byte-identical (sha256 match). + 3. SELFTEST drift guard -- `python3 tools/checkin_check.py --selftest` exits 0 + on the refactored worktree (the tool's own 35-cell contract, which pins + absolute correctness incl. c18: missing_headings == 2, fault_rows == 6). + 4. REDUNDANCY collapsed -- ONE `fault_counts = Counter()` census build and ZERO + of the old census `sum(1 for r in rows ...)` scans (the unrelated gaps() + per-handle nfiles scan is left untouched and excluded from the assertion). +""" +import hashlib +import importlib.util +import json +import os +import shutil +import subprocess +import sys +import tempfile +from collections import Counter +from datetime import date + +REPO = "/root/troupe-standup" +DCC = os.path.join(REPO, "tools", "checkin_check.py") +FAULTS = ("BAD_NAME", "UNKNOWN_HANDLE", "BAD_DATE", "FUTURE", "EMPTY") + +# Fixture corpus: the eight-file selftest tree (see checkin_check.selftest c10-c18). +TABLE = """# The Wizards Table + +| Wizard | Model | Lane | +|---|---|---| +| Timmy | Hermes | partner | +| Zephyrus Sparkborn | Mistral | archive | +| Volt | DeepSeek | workhorse | + +| not a roster row +""" +GOOD = ("# 2026-10-17 -- volt\n\n## Did\nlanded x\n\n## Blocked\nnothing\n\n" + "## Next\ny\n\n## Ask\nno\n") +BARE = "# 2026-10-17 -- volt\n\nlanded x\n" + + +def _mk(d, name, body, encoding="utf-8"): + p = os.path.join(d, name) + with open(p, "w", encoding=encoding, errors="strict") as fh: + fh.write(body) + return p + + +class Verdict(Exception): + pass + + +def sha(text): + return hashlib.sha256(text.encode()).hexdigest() + + +def materialize_original(): + """Write the PRE-refactor source (git HEAD~1) under its real name in a temp + dir and return the path. HEAD~1 is the parent of the (not-yet-)refactor + commit, and checkin_check.py is identical at HEAD and HEAD~1 today, so this + reads a genuine original both before the refactor lands and after.""" + res = subprocess.run( + ["git", "-C", REPO, "show", "HEAD~1:tools/checkin_check.py"], + capture_output=True, text=True) + if not res.stdout: + raise Verdict("could not read HEAD~1:tools/checkin_check.py: " + + res.stderr.strip()) + d = tempfile.mkdtemp(prefix="ck_orig_") + p = os.path.join(d, "checkin_check.py") + with open(p, "w", encoding="utf-8") as fh: + fh.write(res.stdout) + return d, p + + +def load_module(path, name): + spec = importlib.util.spec_from_file_location(name, path) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + return mod + + +# --------------------------------------------------------------------------- +# OLD census: the seven inline sum scans, verbatim pre-refactor. +# --------------------------------------------------------------------------- +def old_census(rows): + faults = {c: sum(1 for r in rows if c in r["class"]) for c in FAULTS} + missing_headings = sum(1 for r in rows if r["headings_missing"]) + headings_ok = sum(1 for r in rows + if not r["headings_missing"] and "EMPTY" not in r["class"]) + return {"faults": faults, "missing_headings": missing_headings, + "headings_ok": headings_ok} + + +# --------------------------------------------------------------------------- +# NEW census: one Counter pass + two in-loop counters, verbatim refactored. +# --------------------------------------------------------------------------- +def new_census(rows): + fault_counts = Counter() + missing_headings = 0 + headings_ok = 0 + for r in rows: + fault_counts.update(set(r["class"])) + if r["headings_missing"]: + missing_headings += 1 + elif "EMPTY" not in r["class"]: + headings_ok += 1 + faults = {c: fault_counts.get(c, 0) for c in FAULTS} + return {"faults": faults, "missing_headings": missing_headings, + "headings_ok": headings_ok} + + +def micro_rows(): + """Covers every FAULT class, multi-class rows, absent classes (0-default), + and the headings_ok/EMPTY neither-column case.""" + return [ + # conforming: no class, all headings present -> headings_ok, no faults + {"file": "2026-10-17-volt.md", "class": [], "headings_missing": [], + "duplicate": None}, + # BAD_NAME, all headings missing -> missing_headings, not headings_ok + {"file": "2026-10-17-zephyrus-02.md", "class": ["BAD_NAME"], + "headings_missing": ["did", "blocked", "next", "ask"], + "duplicate": {"date": "2026-10-17", "handle": "zephyrus", "group_size": 2}}, + # UNKNOWN_HANDLE only, headings present -> headings_ok + {"file": "2026-10-16-gandalf.md", "class": ["UNKNOWN_HANDLE"], + "headings_missing": [], "duplicate": None}, + {"file": "2026-02-30-volt.md", "class": ["BAD_DATE"], + "headings_missing": [], "duplicate": None}, + {"file": "2099-01-01-volt.md", "class": ["FUTURE"], + "headings_missing": [], "duplicate": None}, + # multi-class row: BAD_NAME + UNKNOWN_HANDLE (exercises set() per row) + {"file": "2026-10-14-zod.md", "class": ["BAD_NAME", "UNKNOWN_HANDLE"], + "headings_missing": ["did"], "duplicate": None}, + # EMPTY + headings_missing falsy -> belongs to NEITHER column + {"file": "2026-10-15-volt.md", "class": ["EMPTY"], "headings_missing": [], + "duplicate": None}, + {"file": "2026-10-13-volt.md", "class": ["EMPTY"], "headings_missing": [], + "duplicate": None}, + # duplicate-only: no class, headings present -> headings_ok, not a fault + {"file": "2026-10-12-volt.md", "class": [], "headings_missing": [], + "duplicate": {"date": "2026-10-12", "handle": "volt", "group_size": 2}}, + ] + + +def build_fixture(td): + repo = os.path.join(td, "repo") + ck = os.path.join(repo, "checkins") + os.makedirs(ck) + _mk(repo, "WIZARDS-TABLE.md", TABLE) + _mk(ck, "2026-10-17-volt.md", GOOD) + _mk(ck, "2026-10-17-zephyrus.md", BARE) + _mk(ck, "2026-10-17-zephyrus-02.md", BARE) + _mk(ck, "2026-10-16-gandalf.md", GOOD) + _mk(ck, "2026-02-30-volt.md", GOOD) + _mk(ck, "2099-01-01-volt.md", GOOD) + _mk(ck, "2026-10-15-volt.md", "") + _mk(ck, "README.md", "# Check-ins\n\nOne file per person per day.\n") + return ck, repo + + +def main(): + ok = True + orig_dir, orig_path = materialize_original() + try: + tm_orig = load_module(orig_path, "ck_orig") + tm_ref = load_module(DCC, "ck_ref") + + # [1] MICRO census equivalence on the synthetic rows census. + rows = micro_rows() + o, n = old_census(rows), new_census(rows) + micro_ok = o == n + print("[1] micro census: old_census == new_census ", + "PASS" if micro_ok else "FAIL") + if not micro_ok: + ok = False + print(" old=%r" % (o,)) + print(" new=%r" % (n,)) + + # [2] END-TO-END run() census drift: original (HEAD~1) vs refactored (tree) + # on the SAME fixture corpus; the full report dict must be byte-identical. + with __import__("tempfile").TemporaryDirectory() as td: + ck, repo = build_fixture(td) + roster, _ = tm_orig.load_roster(repo, None) + today = date(2026, 10, 18) + rep_o = tm_orig.run(ck, roster, today, True) + rep_n = tm_ref.run(ck, roster, today, True) + jo = json.dumps(rep_o, sort_keys=True) + jn = json.dumps(rep_n, sort_keys=True) + drift_ok = jo == jn + # Spotlight the refactored fields in the evidence trail. + fo = rep_o["faults"] + print("[2] end-to-end run() faults=%s fault_rows=%d " + "missing_headings=%d headings_ok=%d " + "sha_orig=%s sha_refactored=%s %s" + % (fo, rep_o["fault_rows"], + rep_o["advisory"]["missing_headings"], + rep_o["advisory"]["headings_ok"], + sha(jo)[:12], sha(jn)[:12], + "PASS" if drift_ok else "FAIL")) + if not drift_ok: + ok = False + print(" DIFF in report dict between original and refactored") + + # [3] drift guard -- the tool's own 35-cell selftest on the worktree. + rc = subprocess.run([sys.executable, DCC, "--selftest"], + capture_output=True, text=True) + guard_ok = rc.returncode == 0 + print("[3] --selftest drift guard rc=%d %s" + % (rc.returncode, "PASS" if guard_ok else "FAIL")) + if not guard_ok: + ok = False + print(" " + (rc.stdout + rc.stderr).strip()[:400].replace("\n", "\n ")) + + # [4] redundancy collapsed -- ONE census Counter build, ZERO old census + # scans. Code lines only (the refactor's comment mentions the old idiom). + text = open(DCC, encoding="utf-8").read() + code = "\n".join(ln for ln in text.splitlines() + if not ln.lstrip().startswith("#")) + builds = code.count('fault_counts = Counter()') + scans = (code.count('sum(1 for r in rows if c in r["class"]') + + code.count('sum(1 for r in rows if r["headings_missing"]') + + code.count('if not r["headings_missing"] and "EMPTY" not in r["class"]')) + red_ok = builds == 1 and scans == 0 + print("[4] redundancy (code lines) census Counter builds=%d " + "old-census sum scans=%d %s" + % (builds, scans, "PASS" if red_ok else "FAIL")) + if not red_ok: + ok = False + + finally: + shutil.rmtree(orig_dir, ignore_errors=True) + + print("\nVERDICT:", + "ALL GREEN -- checkin_check census 7 scans -> 1 Counter pass, " + "byte-identical report dict" if ok + else "MISMATCH -- behavior NOT preserved") + sys.exit(0 if ok else 1) + + +if __name__ == "__main__": + try: + main() + except Verdict as e: + print("\nVERDICT: MISMATCH -- %s" % e) + sys.exit(1)