Scans each new git commit against the Socratic reflection questions and goal-state files it touches, and flags when today's code directly contradicts a stated intent from the last 14 days (e.g. 'simplify the deploy path' followed by a commit adding two more Docker layers). Ethan already generates reflections and tracks goals, but nothing ever checks whether the code agrees with them. The flag lands on the tablet as a single card he can answer with the stylus.
Create ~/.local/bin/commit-contradiction-watch (bash+python, ~90 lines). Trigger from the existing commit-whisper-dispatch hook so it runs on each new commit. For each commit: collect diff --stat plus the message, then pull the last 14 days of reflections from the socratic-reflection-harvester output and any goal-state JSON under ~/.claude/state/goal-loop/*.json for the matching project slug. Send both to claude -p with a strict prompt: return {"contradiction": bool, "claim": str, "evidence": str} and nothing else. On true, write a card via socratic-tablet-pipe into ~/Tablet/ so it appears alongside existing Socratic cards, and log to ~/.local/state/contradiction-watch.jsonl for a weekly tally. Skip commits touching only lockfiles or .md to keep noise down.
**Created**
- `~/bin/commit-contradiction-watch` (executable, ~95 lines) — for each project, takes commits since a per-repo watermark, skips ones touching only markdown/lockfiles, gathers the last 14 days of stated intents (repo `.claude/memory/reflections.md`, `~/.claude/state/goal-loop/*.json`, `session-goal-*.md`, Socratic sidecars), and asks Haiku for strict JSON `{contradiction, claim, evidence}`. On a hit it renders a single stylus-answerable PDF card into `~/Tablet/contradictions/` ("You said" / "This commit" / "Which one is true now?") and appends to `~/.local/state/contradiction-watch/contradiction-watch.jsonl` for the weekly tally.
- `~/bin/commit-contradiction-watch.test.bats` — 4 tests, LLM stubbed via `CONTRA_RUNNER`.
- `~/.config/systemd/user/commit-contradiction-watch.{service,timer}` — hourly, persistent across reboots, MemoryMax 2G / CPUQuota 50%. Enabled; next run 07:04.
**Verified**
- `bats` — 4/4 pass (flag, clear, docs/lock skip, watermark no-repeat).
- Live run against a real repo: exit 0, correctly took the docs-only skip path.
- Real end-to-end card render: produced an actual 32KB PDF in `~/Tablet/contradictions/` plus the matching ledger line (demo card removed afterward).
Two notes: I chose a systemd timer over editing `commit-whisper-dispatch` (which is a daily cleanup-queue dispatcher, not a per-commit hook) so no existing file was touched. And per the hook logs, several of my info-gathering commands ran in main rather than th