ledger: 2026-10-30 git-tree manifest table

This commit is contained in:
ledger committed 2026-10-30 05:37:09 +00:00
1 parent 891b044d7a
commit b3bd3c9bdf
5 files changed
+34346

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,111 @@
#!/usr/bin/env python3
"""Extract the troupe repo's tracked file tree into a verified table.
Source of truth: `git ls-files` (tracked files) at the repo root.
Outputs (in this directory, wizard-work/ledger/):
- 2026-10-30-git-tree-manifest.csv : relpath, ext, size_bytes, sha256
- 2026-10-30-git-tree-manifest.json: structured manifest
- 2026-10-30-git-tree-manifest.md : human-readable table
Independent re-derivation:
verify_git_tree_manifest_2026_10_30.py (committed; the committed CHECK
runs that verifier and exits 0 iff it matches).
"""
import datetime
import hashlib
import json
import os
import pathlib
import subprocess
HERE = pathlib.Path(__file__).resolve().parent
def find_repo_root(start: pathlib.Path) -> pathlib.Path:
"""Walk up from `start` until a directory containing `.git` is found."""
current = start.resolve()
for _ in range(12):
if (current / ".git").exists():
return current
if current.parent == current:
break
current = current.parent
raise SystemExit(f"no .git found above {start}")
def sha256_of(path: pathlib.Path) -> str:
h = hashlib.sha256()
with path.open("rb") as fh:
for chunk in iter(lambda: fh.read(1024 * 1024), b""):
h.update(chunk)
return h.hexdigest()
def main() -> None:
REPO_ROOT = find_repo_root(HERE)
out = subprocess.run(
["git", "ls-files"], cwd=REPO_ROOT, check=True,
capture_output=True, text=True, env=os.environ,
).stdout.splitlines()
rows = []
for rel in sorted(out):
p = REPO_ROOT / rel
ext = p.suffix.lower() if p.suffix else "-"
rows.append({
"relpath": rel,
"ext": ext,
"size_bytes": p.stat().st_size,
"sha256": sha256_of(p),
})
ext_counts = {}
total_bytes = 0
for r in rows:
ext_counts[r["ext"]] = ext_counts.get(r["ext"], 0) + 1
total_bytes += r["size_bytes"]
manifest = {
"repo": str(REPO_ROOT),
"generated_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
"tracked_file_count": len(rows),
"total_bytes": total_bytes,
"extension_counts": ext_counts,
"top_extensions": sorted(ext_counts.items(), key=lambda kv: (-kv[1], kv[0]))[:15],
"files": rows,
}
(HERE / "2026-10-30-git-tree-manifest.json").write_text(
json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
with (HERE / "2026-10-30-git-tree-manifest.csv").open("w", encoding="utf-8",
newline="") as fh:
fh.write("relpath\text\tsize_bytes\tsha256\n")
for r in rows:
fh.write(f'{r["relpath"]}\t{r["ext"]}\t{r["size_bytes"]}\t{r["sha256"]}\n')
lines = [
"# Git tree manifest — 2026-10-30",
"",
f"- repo: `{REPO_ROOT}`",
f"- tracked files: {manifest['tracked_file_count']}",
f"- total bytes: {manifest['total_bytes']:,}",
"",
"## Top extensions",
"",
"| extension | files |",
"|---|---|",
]
for ext, cnt in manifest["top_extensions"]:
lines.append(f"| {ext or '(no extension)'} | {cnt} |")
lines += ["", "## Full file list", "", "| # | relpath | ext | bytes |", "|---|---|---|---|"]
for i, r in enumerate(manifest["files"], 1):
lines.append(f"| {i} | {r['relpath']} | {r['ext']} | {r['size_bytes']} |")
(HERE / "2026-10-30-git-tree-manifest.md").write_text("\n".join(lines) + "\n", encoding="utf-8")
print(f"wrote {len(rows)} tracked files -> {HERE}")
if __name__ == "__main__":
main()
@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""Independent verification of 2026-10-30-git-tree-manifest.csv.
Recomputes the tracked-file table from `git ls-files` at the repo root and
compares it against the committed CSV (relpath, ext, size_bytes, sha256).
Exit 0 iff the committed manifest exactly matches git's tracked file set.
"""
import hashlib
import pathlib
import subprocess
import sys
REPO = pathlib.Path("/root/troupe-standup")
MANIFEST_CSV = REPO / "wizard-work/ledger/2026-10-30-git-tree-manifest.csv"
def git_ls_files():
return subprocess.run(
["git", "-C", str(REPO), "ls-files"],
check=True, capture_output=True, text=True,
).stdout.splitlines()
def sha256_of(p: pathlib.Path) -> str:
h = hashlib.sha256()
with p.open("rb") as fh:
for chunk in iter(lambda: fh.read(1024 * 1024), b""):
h.update(chunk)
return h.hexdigest()
def main() -> None:
live = git_ls_files()
live_set = set(live)
print(f"live tracked-file count: {len(live)}", file=sys.stderr)
manifest_rows = MANIFEST_CSV.read_text(encoding="utf-8").splitlines()
assert manifest_rows[0] == "relpath\text\tsize_bytes\tsha256", manifest_rows[0]
data = manifest_rows[1:]
print(f"manifest row count: {len(data)}", file=sys.stderr)
assert len(data) == len(live), (
f"row count mismatch: manifest {len(data)} vs git {len(live)}")
data_paths = {line.split("\t", 1)[0] for line in data}
if data_paths != live_set:
print(f"path-set mismatch: manifest {len(data_paths)} vs live {len(live_set)}",
file=sys.stderr)
bad = sorted(data_paths ^ live_set)
print(f"FAILURES: {len(bad)}", file=sys.stderr)
for b in bad[:10]:
print(" ", b, file=sys.stderr)
sys.exit(1)
live_by_path = {}
for rel in live:
p = REPO / rel
live_by_path[rel] = (
p.suffix.lower() if p.suffix else "-",
p.stat().st_size,
sha256_of(p),
)
bad = []
for line in data:
rel, ext, size_s, sha = line.split("\t")
if rel not in live_by_path:
bad.append(("orphan", rel))
continue
lext, lsize, lsha = live_by_path[rel]
if ext != lext or int(size_s) != lsize or sha != lsha:
bad.append(("cell-mismatch", rel, ext, lext, size_s, lsize, sha, lsha))
print(f"checked rows: {len(data)}", file=sys.stderr)
if bad:
print(f"FAILURES: {len(bad)}", file=sys.stderr)
for b in bad[:10]:
print(" ", b, file=sys.stderr)
sys.exit(1)
print("VERIFY_PASS: manifest matches git ls-files (relpath, ext, size, sha256)",
file=sys.stderr)
if __name__ == "__main__":
main()