The why layer
Entry 07. This one covered a lot of ground — Phase 4 deduplication, WHY enrichment, and retroactively wiring all the work to GitHub issues.
Drift without a counter
Phase 4 started with an embarrassingly simple missing piece. GARDEN.md has had an “Entries merged since last sweep” field since Phase 2. integrate_entry.py runs on every merge. But nothing ever incremented the counter. Every time an entry merged, the count stayed at zero. We’d built the scaffolding for a drift-based DEDUPE trigger and forgotten to install the trigger.
Three commits to fix it: increment_drift_counter() in integrate_entry.py, --dedupe-check in validate_garden.py with a git-log cross-verification fallback — if the counter drifts out of sync, the commit log count wins — and dedupe_scanner.py for Jaccard pre-scoring. The scanner was the interesting part. It applies the same tokenizer as validate_pr.py’s L1 Jaccard but across all unchecked within-domain pairs, sorted highest-score-first. harvest DEDUPE now calls it before presenting pairs for review.
Rules as data
The WHY work started from a comment I’d been sitting with: “red hat bureaucracy with agentic powers.” Entries capture what — symptom, root cause, fix — but not why this fix over the alternatives, what constraints it assumes, what changes would invalidate it. A thousand WHAT entries with no WHY is just a prescription list.
I wanted soft prompts — no enforcement gate, just incentives. The interesting design decision was the bonus scoring implementation. The instinct is to hardcode:
if results.get('constraints'): points += 1
if results.get('alternatives'): points += 1
We used a dict instead:
BONUS_RULES = {
'constraints': 1,
'alternatives_considered': 1,
'invalidation_triggers': 1,
}
The dict is a module-level constant. contributors.py imports it directly from validate_pr.py. If the bonus for constraints changes from 1 to 2, one line changes and both the validator and the scoreboard stay in sync automatically. Rules as data, not code.
The scoreboard came from thinking about incentives. If people can see their average effective score — base plus bonus — and good WHY documentation raises it, documenting context becomes personally rewarding. contributors.py generates CONTRIBUTORS.md ranked by average effective score, with an Avg Bonus column showing who documents constraints and alternatives most consistently.
Everything finally has an issue
The session ended with something I should have done earlier: wiring all the work to GitHub issues. The issue-workflow skill set up labels and Work Tracking in CLAUDE.md across all three repos. Then retro-issues mapped the commit history to a structured set of epics and child issues — four epics in soredium covering GE-ID migration, Phase 3 staleness, Phase 4 dedup, and contextual capture; two epics in spec covering design artifacts; four standalones in the site. Everything closed immediately with a retrospective note.
Going forward, implementation starts with an issue and commits reference it.
What I notice: the garden is becoming self-aware in a useful way. It knows which entries are stale. It knows which pairs might be duplicates. It knows who contributed what and how thoroughly they documented their reasoning. And now it knows what work was done and in what order.