Deciduous Guide

Real-world patterns for decision graph tooling in AI-assisted development

Why Decision Graphs?

If you've worked with AI coding assistants, you've experienced this:

"Why did we use Redux instead of Context? I thought we discussed this yesterday..."
"I don't have context from previous sessions. Could you remind me what was decided?"

Every time Claude's context resets, you lose:

  • Why you chose approach A over B
  • What was tried and didn't work
  • The reasoning behind architectural decisions
  • The full scope of what the user originally asked for

Deciduous fixes this. It creates a persistent graph of goals, decisions, actions, and outcomes that survives context loss. When a new session starts, Claude can query the graph to understand what happened and why.

[goal] "Add user authentication" | +---> [decision] "Choose auth method" | | | +---> [option] "JWT tokens" (CHOSEN: stateless, scales well) | +---> [option] "Sessions" (REJECTED: need Redis, more complexity) | +---> [action] "Implement JWT middleware" | | | +---> [outcome] "JWT auth working" (commit: a1b2c3d) | +---> [observation] "Found existing bcrypt in codebase, will reuse"

This graph is queryable. In a new session, Claude can run deciduous nodes and immediately understand the project's decision history.

Quick Start (5 minutes)

1 Install deciduous
cargo install deciduous
2 Initialize in your project
cd your-project
deciduous init

This creates .deciduous/, .claude/ with slash commands, and updates CLAUDE.md.

3 Start working - log as you go
# When starting new work
deciduous add goal "Add dark mode toggle" -c 90

# Before writing code
deciduous add action "Creating ThemeContext provider" -c 85
deciduous link 1 2 -r "Implementation step"

# After committing
git commit -m "feat: add theme context"
deciduous add outcome "Theme context working" -c 95 --commit HEAD
deciduous link 2 3 -r "Complete"
4 View your graph
# Terminal UI
deciduous tui

# Web viewer (opens browser)
deciduous serve

# Export for GitHub Pages
deciduous sync
That's it! You now have a queryable decision history. In future sessions, run deciduous nodes to see what decisions exist.

Real Scenario: Building an E-commerce Cart

Let's walk through a realistic development scenario. Watch how the work evolves, requirements expand, and decisions compound - all captured in the graph.

Phase 1: Initial Request The user asks for a shopping cart
I need to add a shopping cart to our React e-commerce site. Users should be able to add items, change quantities, and see a running total. The cart should persist across page refreshes.
First, I'll create a goal node with the user's exact request:
deciduous add goal "Add shopping cart feature" -c 90 --prompt-stdin << 'EOF'
I need to add a shopping cart to our React e-commerce site. Users should be able
to add items, change quantities, and see a running total. The cart should persist
across page refreshes.
EOF

Output: Created node 1 (type: goal)

Why capture the full prompt? When context resets, Claude can read this verbatim request and understand exactly what was asked for - not a summary, but the actual words.
Current Understanding
  • [ ] Add shopping cart UI
  • [ ] Persist cart across refreshes
Phase 2: Exploration & Decisions Claude investigates the codebase and makes decisions
Before coding, I'll explore the codebase to understand the existing patterns...
# After exploring, log what was found
deciduous add observation "App uses Redux Toolkit, should follow existing pattern" -c 85
deciduous link 1 2 -r "Codebase discovery"

deciduous add observation "Found existing useLocalStorage hook in utils/" -c 90
deciduous link 1 3 -r "Codebase discovery"
Now I need to decide on the cart state management approach:
# Create the decision
deciduous add decision "Choose cart state management approach" -c 75
deciduous link 1 4 -r "Architectural decision needed"

# Add the options we're considering
deciduous add option "Redux slice with localStorage sync" -c 80
deciduous link 4 5 -r "Option: follows existing patterns"

deciduous add option "React Context with useLocalStorage" -c 70
deciduous link 4 6 -r "Option: simpler but inconsistent with app"

deciduous add option "Zustand store" -c 60
deciduous link 4 7 -r "Option: new dependency"
[goal:1] "Add shopping cart feature" | +---> [observation:2] "App uses Redux Toolkit" +---> [observation:3] "Found useLocalStorage hook" +---> [decision:4] "Choose cart state management" | +---> [option:5] "Redux + localStorage" +---> [option:6] "Context + useLocalStorage" +---> [option:7] "Zustand"
I'll recommend Redux since it matches the existing architecture:
# Mark the decision
deciduous link 4 5 -r "CHOSEN: Consistent with existing Redux architecture, team already knows it" -t chosen
deciduous link 4 6 -r "REJECTED: Would create inconsistency in state management" -t rejected
deciduous link 4 7 -r "REJECTED: Adds new dependency when Redux already exists" -t rejected
Expanded Understanding
  • [x] Decide state management (Redux)
  • [ ] Create cart Redux slice
  • [ ] Add localStorage persistence
  • [ ] Build cart UI components
  • [ ] Add "Add to Cart" buttons to product pages
Phase 3: Implementation Writing code with action/outcome logging
Before each piece of implementation, I log what I'm about to do:
# About to create the Redux slice
deciduous add action "Creating cartSlice with add/remove/updateQty reducers" -c 85 \
  -f "src/store/cartSlice.ts"
deciduous link 1 8 -r "Implementation"

...writes the cartSlice.ts code...

# After committing
git add src/store/cartSlice.ts
git commit -m "feat(cart): add cartSlice with core reducers"

deciduous add outcome "Cart slice created with add/remove/updateQty" -c 95 --commit HEAD
deciduous link 8 9 -r "Complete"
Key pattern: Log the action BEFORE writing code, then log the outcome AFTER committing. This creates a clear trail of intent -> result.
# Next piece: localStorage persistence
deciduous add action "Adding localStorage sync middleware" -c 85 \
  -f "src/store/cartSlice.ts,src/store/index.ts"
deciduous link 1 10 -r "Implementation"

# ...writes the middleware...

git commit -m "feat(cart): add localStorage persistence"
deciduous add outcome "Cart persists across page refreshes" -c 95 --commit HEAD
deciduous link 10 11 -r "Complete"
[goal:1] "Add shopping cart feature" | +---> [decision:4] "Choose state management" -> [option:5] Redux (CHOSEN) | +---> [action:8] "Creating cartSlice" | +---> [outcome:9] "Cart slice created" (commit: f3e4d5c) | +---> [action:10] "Adding localStorage sync" +---> [outcome:11] "Persistence working" (commit: a1b2c3d)
Phase 4: Scope Expansion User adds requirements mid-stream
Oh, I forgot to mention - we also need the cart to sync with the backend when users are logged in, so it persists across devices. Can you add that?
This is a significant scope change. I'll create a new goal linked to the original:
deciduous add goal "Add backend cart sync for logged-in users" -c 85 --prompt-stdin << 'EOF'
Oh, I forgot to mention - we also need the cart to sync with the backend when
users are logged in, so it persists across devices. Can you add that?
EOF
deciduous link 1 12 -r "Scope expansion from user"
# This triggers new decisions
deciduous add decision "Cart sync strategy" -c 70
deciduous link 12 13 -r "Need to decide sync approach"

deciduous add option "Sync on every change (real-time)" -c 60
deciduous link 13 14 -r "Option: immediate but chatty"

deciduous add option "Debounced sync (batch changes)" -c 80
deciduous link 13 15 -r "Option: efficient, handles rapid changes"

deciduous add option "Sync only on checkout/logout" -c 50
deciduous link 13 16 -r "Option: minimal but risks data loss"
Why link scope changes? When someone asks "why does cart have backend sync?", the graph shows the exact user request that triggered it, linked to the original goal.
Expanded Scope (discovered during implementation)
  • [x] Decide state management (Redux)
  • [x] Create cart Redux slice
  • [x] Add localStorage persistence
  • [ ] Build cart UI components
  • [ ] Add "Add to Cart" buttons
  • [ ] NEW: Backend cart API endpoints
  • [ ] NEW: Sync middleware for logged-in users
  • [ ] NEW: Merge local cart with server cart on login
  • [ ] NEW: Handle sync conflicts
Phase 5: Bug Discovery Something goes wrong and needs investigation
The cart total is showing wrong values sometimes. Can you investigate?
deciduous add goal "Fix cart total calculation bug" -c 75 --prompt-stdin << 'EOF'
The cart total is showing wrong values sometimes. Can you investigate?
EOF
deciduous link 1 17 -r "Bug in cart feature"
I'll log observations as I investigate...
# While debugging
deciduous add observation "Total uses floating point, seeing precision errors" -c 90
deciduous link 17 18 -r "Investigation finding"

deciduous add observation "Bug only occurs with items priced at $X.99" -c 95
deciduous link 17 19 -r "Investigation finding"
# Decide on fix approach
deciduous add decision "How to fix price precision" -c 80
deciduous link 17 20 -r "Need to decide fix"

deciduous add option "Store prices as cents (integers)" -c 90
deciduous link 20 21 -r "Best practice for money"

deciduous add option "Use decimal.js library" -c 70
deciduous link 20 22 -r "Adds dependency"

# Choose and implement
deciduous link 20 21 -r "CHOSEN: Standard practice, no dependencies" -t chosen
deciduous add action "Converting price storage to cents" -c 85 -f "src/store/cartSlice.ts"
deciduous link 17 23 -r "Bug fix implementation"
Future value: When someone encounters a similar bug, they can search the graph and find this exact debugging journey - the observations, the decision, and the fix.
Phase 6: Context Recovery (New Session) Picking up work after context loss

The next day, in a fresh Claude session...

Let's continue working on the cart. Where were we?
I'll query the decision graph to recover context:
deciduous nodes
ID Type Title Status Confidence 1 goal Add shopping cart feature active 90% 2 observation App uses Redux Toolkit active 85% 4 decision Choose cart state management active 75% 5 option Redux slice with localStorage sync active 80% 8 action Creating cartSlice with reducers completed 85% 9 outcome Cart slice created completed 95% 12 goal Add backend cart sync active 85% 17 goal Fix cart total calculation bug active 75% ...
deciduous edges
1 -> 4 (leads_to) "Architectural decision needed" 4 -> 5 (chosen) "Consistent with existing Redux architecture" 1 -> 8 (leads_to) "Implementation" 8 -> 9 (leads_to) "Complete" 1 -> 12 (leads_to) "Scope expansion from user" ...
Based on the graph, I can see:
  • Main goal: Shopping cart feature (goal 1)
  • Decision made: Using Redux (not Context/Zustand)
  • Completed: Cart slice, localStorage persistence
  • In progress: Backend sync (goal 12), bug fix (goal 17)
  • Bug: Floating point precision, fixing with cents storage
Full context recovered - Claude now knows the decisions, the reasoning, what's done, and what's in progress, all from querying the graph.

Common Patterns

goal Starting New Work
deciduous add goal "Feature name" \
  -c 90 \
  --prompt-stdin << 'EOF'
[User's exact request here]
EOF

Always capture the verbatim user prompt for context recovery.

decision Making Choices
deciduous add decision "What to decide"
deciduous add option "Choice A"
deciduous add option "Choice B"
deciduous link DECISION OPTION_A -t chosen
deciduous link DECISION OPTION_B -t rejected

Document why you chose A over B.

action Before Coding
deciduous add action "What I'm implementing" \
  -c 85 \
  -f "file1.ts,file2.ts"
deciduous link GOAL ACTION -r "Implementation"

Log BEFORE you write code, not after.

outcome After Committing
git commit -m "feat: ..."
deciduous add outcome "What was accomplished" \
  -c 95 \
  --commit HEAD
deciduous link ACTION OUTCOME -r "Complete"

Links the commit hash to the graph.

observation Discoveries
deciduous add observation "What I found" -c 85
deciduous link GOAL OBSERVATION -r "Discovery"

Log interesting findings, constraints, or insights.

Session Recovery
deciduous nodes          # What exists?
deciduous edges          # How connected?
deciduous commands       # Recent activity?
git status               # Current state?

Run these at the start of every session.

The Golden Rule

BEFORE you code  ->  Log what you're ABOUT to do (action)
AFTER it works   ->  Log what happened (outcome)
ALWAYS           ->  Link nodes to their parents immediately

Command Reference

Adding Nodes

Create a goal (high-level objective)
deciduous add goal "Feature title" -c 90 -p "Short prompt"
deciduous add goal "Feature title" -c 90 --prompt-stdin  # Read from stdin
Create a decision (choice point)
deciduous add decision "What needs to be decided" -c 75
Create an option (for a decision)
deciduous add option "Possible approach" -c 70
Create an action (about to implement)
deciduous add action "What I'm implementing" -c 85 -f "file1.ts,file2.ts"
Create an outcome (result of action)
deciduous add outcome "What happened" -c 95 --commit HEAD
Create an observation (finding/insight)
deciduous add observation "What I discovered" -c 80

Linking Nodes

Create a connection between nodes
deciduous link FROM_ID TO_ID -r "Reason for connection"
deciduous link 4 5 -r "Implementation step" -t leads_to  # Explicit type
deciduous link 4 5 -t chosen    # Mark option as chosen
deciduous link 4 6 -t rejected  # Mark option as rejected

Querying

List nodes (with filters)
deciduous nodes                    # All nodes
deciduous nodes --type goal        # Only goals
deciduous nodes --branch main      # Only from main branch
deciduous nodes --type decision    # Only decisions
List edges
deciduous edges                    # All connections
Export full graph
deciduous graph > graph.json       # JSON export

Viewing

Start viewers
deciduous tui                      # Terminal UI
deciduous serve                    # Web viewer (port 3000)
deciduous serve --port 8080        # Custom port

Exporting

Sync for GitHub Pages
deciduous sync                     # Exports to docs/
Generate visualizations
deciduous dot                      # DOT format to stdout
deciduous dot --png -o graph.dot   # Generate PNG (needs graphviz)
deciduous writeup -t "PR Title"    # Generate PR writeup

Team Collaboration

Export/import patches for teammates
deciduous diff export --branch feature-x -o patches/my-work.json
deciduous diff apply patches/teammate.json
deciduous diff apply --dry-run patches/teammate.json  # Preview first

Troubleshooting

Enforcement Hooks

Deciduous includes Claude Code hooks that enforce decision logging. These are installed with deciduous init.

Error: "No recent action/goal node found"

The Edit/Write hook blocked you because no node was logged in the last 15 minutes.

Fix: Log what you're about to do first:

deciduous add action "What I'm about to implement" -c 85
# Now you can edit files
Reminder: "Link this commit to the decision graph!"

After git commits, the hook reminds you to link the commit.

Fix: Create an outcome linked to the commit:

deciduous add outcome "What was accomplished" -c 95 --commit HEAD
deciduous link ACTION_ID OUTCOME_ID -r "Complete"

Common Issues

Orphan nodes (disconnected from graph)

Every node except root goals should be linked to a parent.

Fix: Run deciduous edges to find gaps, then link:

deciduous link PARENT_ID ORPHAN_ID -r "Retroactive connection"
Lost context on what to do next

Use the recovery pattern:

deciduous nodes    # See what goals exist
deciduous edges    # See connections and progress
git status         # See uncommitted work
deciduous commands # See recent deciduous activity
Graph not updating on GitHub Pages

Make sure to sync and push:

deciduous sync     # Export to docs/
git add docs/
git commit -m "docs: update decision graph"
git push