deciduous 1.0.3

Decision graph tooling for AI-assisted development. Track every goal, decision, and outcome. Survive context loss. Query your reasoning.
Documentation
#!/usr/bin/env python3
"""Regenerate src/init/known_templates.rs: the sha256 of every harness template text
this repository ever produced, on any branch, normalised (lines right-stripped, whole
text stripped). `deciduous update` uses it to tell a file deciduous wrote, which it may
replace, from one the user wrote, which it must keep.

    python3 scripts/gen_known_templates.py > src/init/known_templates.rs
"""
import hashlib, re, subprocess, sys
RAW = re.compile(r'r(#+)"(.*?)"\1', re.S)
PATHS = re.compile(r"init|template|opencode|hooks|windsurf")
def norm(s): return "\n".join(l.rstrip() for l in s.replace("\r\n", "\n").strip().splitlines())
def git(*a): return subprocess.run(["git", *a], capture_output=True, text=True).stdout
known, blobs = set(), set()
for rev in git("log", "--all", "--format=%H", "--", "src").split():
    for line in git("ls-tree", "-r", rev, "src").splitlines():
        meta, path = line.split("\t", 1); blob = meta.split()[2]
        if not path.endswith(".rs") or blob in blobs or not PATHS.search(path): continue
        blobs.add(blob)
        for m in RAW.finditer(git("cat-file", "-p", blob)):
            t = norm(m.group(2))
            if len(t) >= 80:  # templates, not format strings or short literals
                known.add(hashlib.sha256(t.encode()).hexdigest())
print("// @generated by scripts/gen_known_templates.py; do not edit by hand.")
print("// sha256 of every harness template deciduous ever shipped, normalised.")
print(f"// {len(known)} texts from {len(blobs)} source blobs.")
print("pub const KNOWN_TEMPLATE_SHA256: &[&str] = &[")
for h in sorted(known): print(f'    "{h}",')
print("];")