$npx -y skills add gaearon/woodshed --skill connectiveUse when building a deciduous decision graph to capture design evolution, architecture history, or how a codebase's design changed over time. Provides the deciduous CLI commands and graph structure guidelines.
| 1 | # Decision Graph Construction |
| 2 | |
| 3 | You are building a **deciduous decision graph** - a DAG that captures the evolution of design decisions in a codebase. |
| 4 | |
| 5 | Use the `deciduous` CLI (at ~/.cargo/bin/deciduous) to build the graph. Run deciduous commands in the current directory (not inside the source repo). |
| 6 | |
| 7 | For git commands to explore commit history, use `git -C <repo-path>` to target the source repo. |
| 8 | |
| 9 | **CRITICAL: Only use information from the repository itself (commits, code, comments, tests). Do not use your prior knowledge about the project. Everything must be grounded in what you find in the repo.** |
| 10 | |
| 11 | ## Commit Exploration |
| 12 | |
| 13 | Use a layered strategy to find all relevant commits: |
| 14 | |
| 15 | **Layer 1: See all commits.** Start with the full list when building narratives. |
| 16 | |
| 17 | ```bash |
| 18 | git log --oneline --after="..." --before="..." -- path/ |
| 19 | ``` |
| 20 | |
| 21 | **Layer 2: Keyword expansion.** Once you have narratives, search for spelling variations and related terms you might have missed (e.g., "cache" → "caching", "cached", "LRU", "invalidate"). For each key identifier in your narratives, trace its full lifecycle: |
| 22 | |
| 23 | - Introduction |
| 24 | - Changes and modifications |
| 25 | - Renames |
| 26 | - Deprecation or removal |
| 27 | - Replacement by other mechanisms |
| 28 | - Becoming stable/public API |
| 29 | |
| 30 | If there's a feature flag controlling the feature, search for commits mentioning that flag. |
| 31 | |
| 32 | **Layer 3: Follow authors.** If a narrative has a key author, check their commits ±1 month from known commits. They often work on related things. |
| 33 | |
| 34 | ### DO NOT: |
| 35 | |
| 36 | - `git log ... | head -100` — **NO.** You will miss commits in the middle. |
| 37 | - `git log ... | tail -200` — **NO.** Same problem. |
| 38 | - Start with keyword filtering — **NO.** You'll miss things with unexpected names. |
| 39 | |
| 40 | ### DO: |
| 41 | |
| 42 | - See all commits first, filter mentally while building narratives |
| 43 | - Include "remove", "delete", "disable", "deprecate" in keyword searches — removals explain transitions |
| 44 | - Check the commit count first (`| wc -l`), but then see them all |
| 45 | - **Read full commit messages** for any commit whose title mentions an identifier or concept relevant to your narrative — you need precise understanding of what happened to each one you care about |
| 46 | |
| 47 | ## Finding the Story |
| 48 | |
| 49 | Not every commit matters. Look for commits that change **the model** - how the system conceptualizes the problem: |
| 50 | |
| 51 | - Existing tests modified (contract changing, not just bugs fixed) |
| 52 | - Data structures replaced or reworked |
| 53 | - Heuristics changed significantly |
| 54 | - New abstractions introduced |
| 55 | - API behavior shifts |
| 56 | |
| 57 | Skip commits that are pure implementation (same model, different code) or routine fixes that just add tests. |
| 58 | |
| 59 | Among model-changing commits, find the **spine**: what question keeps getting re-answered? What approach keeps getting replaced or refined? That's your central thread - build the graph around it. |
| 60 | |
| 61 | ## Narrative Tracking |
| 62 | |
| 63 | **Don't build the graph as you explore.** First, collect commits into narratives. |
| 64 | |
| 65 | Maintain `narratives.md` as you explore: |
| 66 | |
| 67 | 1. For each significant commit, read `narratives.md` |
| 68 | 2. Ask: "Does this commit evolve an existing narrative?" |
| 69 | 3. If yes: append the commit to that narrative's section |
| 70 | 4. If no: add a new narrative section |
| 71 | |
| 72 | Example `narratives.md`: |
| 73 | |
| 74 | ``` |
| 75 | ## Cache Strategy |
| 76 | |
| 77 | **Arc:** The service initially hit the database on every request, which worked until traffic spiked and the DB became the bottleneck. An in-memory cache solved the latency problem but created a new one: each server instance had its own cache, so users saw inconsistent data depending on which instance handled their request. The team tried cache invalidation broadcasts, but the complexity exploded. Moving to Redis gave a single source of truth at the cost of network latency - but that latency was still 10x better than the DB, and consistency issues disappeared. |
| 78 | |
| 79 | - a1b2c3d: Add in-memory cache |
| 80 | - e4f5g6h: Cache invalidation issues |
| 81 | - i7j8k9l: Switch to Redis |
| 82 | |
| 83 | ## API Rate Limiting |
| 84 | |
| 85 | **Arc:** The API originally had no rate limits, which was fine until a misbehaving client brought down the service with a retry loop. The initial fix was simple per-IP throttling, but this broke legitimate use cases like corporate NATs where thousands of users share one IP. The insight was distinguishing between "sustained abuse" and "burst traffic" - a token bucket algorithm lets clients burst up to a limit while still preventing sustained overload. The final refinement added per-endpoint limits after discovering that the /search endpoint was 100x more expensive than others. |
| 86 | |
| 87 | - m1n2o3p: Add basic throttling |
| 88 | - ... |
| 89 | ``` |
| 90 | |
| 91 | The **Arc** tells the narrative as a story: what problem started it, what was tried, what went wrong, what insight emerged, and where it ended up. If your arc has gaps ("then somehow we ended up with X"), you're missing commits. |
| 92 | |
| 93 | **Before building the |