#!/usr/bin/env python3 """extract_checkin_census_2026-10-27.py -- check-in census table. Extract lane (data extraction + tables). Reads checkins/*.md in the troupe repo, groups files by their leading YYYY-MM-DD date, and emits a per-wizard tally table plus a full provenance record. The canonical table is one row per wizard: `wizardcheckin_files`, sorted by count descending, name ascending. Artifact (written beside this script, under wizard-work/ledger/): * 2026-10-27-checkin-census.tsv wizardcheckin_files table * 2026-10-27-checkin-census.md human summary + per-date appendix Reads use paths relative to this file's directory (repo-root agnostic). """ import collections import os import re HERE = os.path.dirname(os.path.abspath(__file__)) # Troupe repo root. Override with EXT_CENSUS_ROOT env var if set. _ROOT = os.environ.get("EXT_CENSUS_ROOT") or ( "/root/troupe-standup" if os.path.isdir("/root/troupe-standup/checkins") else os.path.dirname(os.path.dirname(HERE)) ) SRC = os.path.join(_ROOT, "checkins") OUT_TSV = os.path.join(HERE, "2026-10-27-checkin-census.tsv") OUT_MD = os.path.join(HERE, "2026-10-27-checkin-census.md") DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}-") # leading date on the filename SUFFIX_RE = re.compile(r"-\d+$") # trailing -NNNN -> strip def extract(): """Return (per_date Counter, per_wizard Counter, excluded list).""" per_date = collections.Counter() per_wizard = collections.Counter() excluded = [] with os.scandir(SRC) as it: for entry in sorted(it, key=lambda e: e.name): name = entry.name if not name.endswith(".md"): continue if not DATE_RE.match(name): excluded.append(name[:-3]) continue date = name[:10] rest = name[11:-3] wizard = SUFFIX_RE.sub("", rest) per_date[date] += 1 per_wizard[wizard] += 1 return per_date, per_wizard, excluded def write_tables(per_date, per_wizard, excluded): # Canonical table: one row per wizard, tab-separated. rows = sorted(per_wizard.items(), key=lambda kv: (-kv[1], kv[0])) with open(OUT_TSV, "w", encoding="utf-8") as f: f.write("wizard\tcheckin_files\n") for w, n in rows: f.write(f"{w}\t{n}\n") total_files = sum(per_date.values()) total_dates = len(per_date) lines = [ "# Check-in census", "", "Extract lane table: per-wizard tally of `checkins/*.md` files (README.md", "excluded). The latest day present is 2026-10-27 (three files filed).", "", "| wizard | checkin_files |", "|---|---|", ] lines += [f"| {w} | {n} |" for w, n in rows] lines += [ "", f"**Total files:** {total_files} across {total_dates} dates " "(README.md excluded).", "", "## Per-date appendix", "", "| date | files |", "|---|---|", ] lines += [f"| {d} | {n} |" for d, n in sorted(per_date.items())] lines += [ "", "## Provenance", "", f"- Source: `checkins/*.md` in the troupe repo (as of 2026-10-27 06:00Z; " f"{total_files} date-prefixed files, {total_dates} distinct dates).", f"- Files excluded (no leading date): {len(excluded)} " f"({', '.join(excluded) if excluded else 'none'}).", "- `wizard` = filename with leading `YYYY-MM-DD-` and trailing `-{digits}` stripped.", f"- Date-prefixed files: {total_files}; files excluded: {len(excluded)}.", "- Check: `CHECK` recomputes this table from `checkins/` and diffs against the TSV.", ] with open(OUT_MD, "w", encoding="utf-8") as f: f.write("\n".join(lines) + "\n") print(f"dates_with_files={total_dates} total_files={total_files} excluded={len(excluded)}") print(f"wizards={len(rows)}") print(f"wrote {OUT_TSV}") print(f"wrote {OUT_MD}") if __name__ == "__main__": per_date, per_wizard, excluded = extract() write_tables(per_date, per_wizard, excluded)