Files
troupe-standup/wizard-work/ledger/build_dir_census.py
T

61 lines
2.0 KiB
Python

#!/usr/bin/env python3
# build_dir_census.py -- regenerate the ledger dir census CSV (extract lane).
#
# Schema (must match verify_ledger_dir_census.py):
# rel_path,size_bytes,sha256
# rel_path is relative to the troupe-standup repo root, sorted ascending.
# The artifact itself is excluded from BOTH the re-derivation and the
# committed file, so the check is self-consistent across regeneration.
#
# Consumes (real tool output): the live filesystem of wizard-work/ledger/.
# Produces: the committed artifact at
# wizard-work/ledger/2026-10-31-ledger-dir-census.csv
# and the primary deliverable at
# /root/.hermes/wizard-outputs/ledger/2026-10-31-ledger-dir-census.csv
import os
import csv
import hashlib
HERE = os.path.dirname(os.path.abspath(__file__)) # wizard-work/ledger
REPO_ROOT = os.path.abspath(os.path.join(HERE, "..", "..")) # troupe-standup root
SRC = HERE
OUT = "/root/troupe-standup/wizard-work/ledger/2026-10-31-ledger-dir-census.csv"
def sha256_of(path):
h = hashlib.sha256()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(1024 * 1024), b""):
h.update(chunk)
return h.hexdigest()
def re_derive():
rows = []
for dirpath, dirnames, filenames in os.walk(SRC):
dirnames.sort()
for fn in sorted(filenames):
full = os.path.join(dirpath, fn)
if os.path.abspath(full) == os.path.abspath(OUT):
continue
rel = os.path.relpath(full, REPO_ROOT)
size = os.path.getsize(full)
rows.append((rel, size, sha256_of(full)))
rows.sort(key=lambda r: r[0])
return rows
def main():
rows = re_derive()
os.makedirs(os.path.dirname(OUT), exist_ok=True)
with open(OUT, "w", newline="", encoding="utf-8") as f:
w = csv.writer(f)
w.writerow(["rel_path", "size_bytes", "sha256"])
w.writerows(rows)
print(f"rows: {len(rows)}")
print(f"wrote: {OUT}")
if __name__ == "__main__":
main()