#!/usr/bin/env python3 """daybook-ensure — the day's work-log note exists before anyone remembers to want it. Two previous attempts at this log died inside four weeks (`daily-log/` 4 entries, `sessions/` 3, both Mar-Apr 2026). Neither had a trigger; both depended on someone remembering. This hook removes the remembering: at every session start the day's note exists, skeleton in place, so writing into it is an append rather than a decision to begin. Deliberately narrow: - CREATES only. An existing note is never opened for writing, never rewritten, never reordered. The prose is the executor's and the hook must not be able to damage it. - Says so when it fails. The job this replaces died silently for five months behind a `> /dev/null 2>&1` (see the 2026-08-23 daily note). A hook that cannot write must announce that, not shrug. Constitutional Constraint #4, at hook scale. - Always exits 0. Honest reporting must never cost the steward a session. """ import datetime, os, sys VAULT = os.path.expanduser( "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/David, root-and-branch") DAILY = os.path.join(VAULT, "01. Daily") SKELETON = """--- title: "{date} — {dayname}" type: daily date: {date} status: active tags: - daily - worklog --- # {date} — {dayname} *A plain-language record of the day's work, so the history is readable without reading `git log`. Project work sits under its own heading; decisions, insights and open threads are collected at the end.* ## The day in short ## Decisions taken ## Insights and exchanges worth keeping ## Open / next """ def note_path(day, daily_dir=DAILY): return os.path.join(daily_dir, f"{day.isoformat()}.md") def ensure(day=None, daily_dir=DAILY): """-> (status, path). status in {'exists','created','no-dir','error:'}. 'exists' is not a failure and 'created' is not a success worth announcing loudly — the caller decides what is worth a line of the steward's attention. """ day = day or datetime.date.today() p = note_path(day, daily_dir) try: if not os.path.isdir(daily_dir): return "no-dir", p if os.path.exists(p): return "exists", p body = SKELETON.format(date=day.isoformat(), dayname=day.strftime("%A")) # x-mode: refuse to clobber if something raced us between the check and the write. with open(p, "x", encoding="utf-8") as fh: fh.write(body) return "created", p except FileExistsError: return "exists", p except OSError as e: return f"error:{e.__class__.__name__}", p def selftest(): import tempfile, shutil ok = fail = 0 def chk(label, cond): nonlocal ok, fail print(f" [{'ok ' if cond else 'FAIL'}] {label}") ok, fail = (ok + (1 if cond else 0), fail + (0 if cond else 1)) d = tempfile.mkdtemp() try: day = datetime.date(2026, 8, 23) st, p = ensure(day, d) chk("creates the note when absent", st == "created" and os.path.exists(p)) txt = open(p, encoding="utf-8").read() chk("skeleton carries the ISO date and weekday", "2026-08-23" in txt and "Sunday" in txt) chk("skeleton is spec-conformant (type/status/tags present)", "type: daily" in txt and "status: active" in txt and "worklog" in txt) # THE control that matters: an existing note must survive untouched. open(p, "w", encoding="utf-8").write("PROSE THE EXECUTOR WROTE\n") st2, _ = ensure(day, d) chk("does NOT overwrite an existing note [the whole point]", st2 == "exists" and open(p, encoding="utf-8").read() == "PROSE THE EXECUTOR WROTE\n") chk("reports 'exists' rather than 'created' on the second run", st2 == "exists") missing = os.path.join(d, "nope") st3, _ = ensure(day, missing) chk("reports a missing directory instead of creating one [no silent mkdir]", st3 == "no-dir" and not os.path.exists(missing)) # positive control: the failure path must be reachable, or 'no-dir' proves nothing. st4, _ = ensure(day, d) chk("the same call succeeds where the directory exists [positive control — proves" " 'no-dir' reports the directory, not a broken function]", st4 == "exists") finally: shutil.rmtree(d, ignore_errors=True) print(f"\n{'SELFTEST PASS' if not fail else 'SELFTEST FAIL'} — {ok} ok, {fail} failed") return 0 if not fail else 1 if __name__ == "__main__": if "--selftest" in sys.argv: sys.exit(selftest()) status, path = ensure() if status == "created": print(f"DAYBOOK — created {os.path.basename(path)}") elif status.startswith("error") or status == "no-dir": # Loud on purpose. The predecessor's silence cost five months. print(f"DAYBOOK — COULD NOT WRITE the day's note ({status}). " f"Expected at: {path}") sys.exit(0)