Deciduous
Decision graph tooling for AI-assisted development. Track every goal, decision, and outcome. Survive context loss. Query your reasoning.
You’re building software with AI assistance. The LLM generates complex code fast. But then:
- Sessions end. Context compacts. The LLM loses memory of what was tried.
- Decisions evaporate. Six months later, no one remembers why you chose approach A over B.
- PRs become incomprehensible. A 50-file diff tells you what changed, not why.
- Onboarding is archaeology. New teammates reverse-engineer decisions from code.
The code tells you what. But decisions tell you why.
What Deciduous Does
Deciduous creates a persistent, queryable graph of every decision made during development. Log decisions in real-time — as they happen — and they survive session boundaries, context compaction, and human memory.
Both you and your AI assistant can:
- Query past reasoning before making new decisions
- See what was tried and what was rejected
- Trace any outcome back to the goal that spawned it
- Recover context after sessions end or memory compacts
The Canonical Flow
Every decision follows this path through the graph:
- goal What you’re trying to achieve
- option Possible approaches to explore
- decision Choosing which option to pursue
- action Implementing the chosen approach
- outcome Results of the implementation
- observation Attach anywhere relevant
- revisit Connect old approaches to new ones when you pivot
See It In Action
Here’s what a real session looks like — Claude logging decisions as it works:
Three days later, a new session starts. Context is gone. You type /recover:
You asked for JWT auth with refresh token rotation (goal #42). We evaluated two options — jsonwebtoken crate vs axum-jwt-auth — and chose jsonwebtoken for full control over rotation logic. The middleware and refresh endpoint are implemented (action #46) with 14 tests passing (outcome #47).
The goal is still pending — what’s next?
This isn’t documentation written after the fact. It’s a real-time record of how software gets built.
Installation
Homebrew (Recommended)
brew tap notactuallytreyanastasio/tap
brew install deciduous
Pre-built Binaries
Download the latest release from GitHub Releases:
| Platform | Binary |
|---|---|
| Linux (x86_64) | deciduous-linux-amd64 |
| Linux (ARM64) | deciduous-linux-arm64 |
| macOS (Intel) | deciduous-darwin-amd64 |
| macOS (Apple Silicon) | deciduous-darwin-arm64 |
| Windows | deciduous-windows-amd64.exe |
# Example: macOS Apple Silicon
curl -LO https://github.com/notactuallytreyanastasio/deciduous/releases/latest/download/deciduous-darwin-arm64
chmod +x deciduous-darwin-arm64
sudo mv deciduous-darwin-arm64 /usr/local/bin/deciduous
Via Cargo
cargo install deciduous
From Source
git clone https://github.com/notactuallytreyanastasio/deciduous.git
cd deciduous
cargo build --release
# Binary at target/release/deciduous
Verify Installation
deciduous 0.15.0
Quick Start
Get deciduous running in your project in under two minutes. By the end of this page, you’ll have a live decision graph with your first connected chain of nodes.
Initialize Your Project
Run deciduous init inside any git repository. This creates the .deciduous/ directory with a SQLite database and installs integration files for your AI assistant.
That’s it for setup. The database is ready and your AI assistant now has instructions to log decisions automatically.
The Canonical Flow
Every piece of work follows this path through the graph:
- goal What you’re trying to achieve
- option Possible approaches to consider
- decision Choosing which option to pursue
- action Implementing the chosen approach
- outcome Results of the implementation
This isn’t arbitrary structure. It forces you to record why you chose an approach, not just what you built. Six months later, when someone asks “why didn’t we use WebSockets instead?”, the graph has the answer.
Your First Decision Graph
Here’s a realistic scenario. You ask Claude to add API rate limiting to your project. Claude logs each step as it works:
You now have six connected nodes forming a complete decision chain. Every node is linked to what came before it, creating a traceable path from the original goal to the final outcome.
Viewing Your Graph
Start the web viewer to see your decision graph rendered as an interactive visualization:
Open http://localhost:3000 in your browser. You’ll see your nodes laid out as a directed graph, color-coded by type, with edges showing the reasoning chain.
You can also inspect the graph from the command line:
What You’ve Built
In under two minutes, you have:
- A searchable record of what was decided and why
- Rejected alternatives preserved for future reference (node 3 – governor crate)
- Traceable reasoning from goal through to outcome
- A live visualization in your browser
The next time someone opens this codebase and asks “why Redis instead of an in-memory solution?”, the graph has the answer: node 4, with the rationale right there in the edge labels.
Next, read the Workflow chapter to learn how to use deciduous throughout a full development session – including how to handle pivots when an approach fails.
The Workflow
Deciduous works because it captures decisions as they happen, not after the fact. This chapter covers the core workflow rules, what to log (and what not to), session recovery, the revisit pattern for pivots, and linking commits to the graph.
The Core Rule
Three things, every time:
- BEFORE you do something – log what you’re about to do
- AFTER it succeeds or fails – log the outcome
- CONNECT immediately – link every node to its parent
If you skip the “before” step, you lose the reasoning. If you skip the “after” step, you lose the result. If you skip the connection, the graph is just a pile of disconnected notes.
What to Log
The decision graph records the project’s decisions, not the AI’s internal process. A good rule of thumb: if it would appear on a project timeline or in a PR description, log it.
Do log:
| Trigger | Node Type | Example |
|---|---|---|
| User asks for a feature | goal | “Add dark mode support” |
| Exploring approaches | option | “CSS custom properties for theming” |
| Choosing an approach | decision | “Use CSS custom properties over Tailwind dark:” |
| Writing or changing code | action | “Implement theme toggle component” |
| Something worked or failed | outcome | “Dark mode working, 6 tests passing” |
| A technical finding | observation | “Existing styles use hardcoded hex colors” |
Do not log:
- Reading or exploring the codebase (“Analyzing project structure”)
- Your planning process (“Evaluating options internally”)
- Tool usage (“Running tests to check status”)
- Context gathering (“Reviewing the auth module”)
- Meta-commentary (“Starting work on this task”)
These are the AI’s internal process, not project decisions. They add noise without value.
A Full Development Session
Here’s a complete session showing the workflow in practice – including a pivot when the first approach fails.
So far, a straightforward flow: goal, options, decision, action. But then the first approach hits a wall:
The Revisit Pattern
When an approach fails, you don’t just start over. You create a revisit node that explicitly connects the failed approach to the new one. This preserves the why – future readers will see what was tried and why it was abandoned.
The graph now tells the full story: we tried synchronous image crate processing, it was too slow (4.2s), we discovered the root cause (no SIMD), and pivoted to async libvips (380ms). Anyone reading this later gets the complete reasoning, not just the final code.
Linking Commits
After committing code, link the commit to the decision graph with --commit HEAD. This connects your git history to the reasoning that produced it.
The --commit HEAD flag captures the commit hash and links it to the node. The web viewer will display commit messages, authors, and dates alongside the decision that produced them.
Session Recovery
Sessions end. Context compacts. But the graph survives. At the start of a new session, recover context by inspecting the existing graph:
Connections Outgoing (3): here ─[possible approach]→ #11: ImageMagick via std::process::Command for thumbnails here ─[possible approach]→ #12: image crate (pure Rust) for thumbnails here ─[new approach after revisit]→ #18: Background job with libvips for fast thumbnail generation
The deciduous edges command is also valuable for understanding the connections between nodes:
Every edge tells you why two nodes are connected. The graph is not just a list of things that happened – it’s a map of the reasoning that produced them.
Connection Rules
The graph’s value is in its connections, not just its nodes. Every node type has a clear parent:
| When you create… | Immediately link to… |
|---|---|
| option | Its parent goal |
| decision | The option(s) it chose between |
| action | The decision that spawned it |
| outcome | The action that produced it |
| observation | The related goal, action, or outcome |
| revisit | The decision or outcome being reconsidered |
Root goal nodes are the only valid orphans. Everything else must be connected.
Decision Graph Concepts
A decision graph is a directed acyclic graph (DAG) where nodes represent things that happened and edges represent relationships between them. This chapter covers the building blocks.
Node Types
Every node has a type that describes its role in the decision-making process.
| Type | Purpose |
|---|---|
| goal | High-level objective — what you are trying to achieve |
| option | A possible approach to explore for a goal |
| decision | Choosing which option to pursue |
| action | Implementation step — work being done |
| outcome | Result of an action — what happened |
| observation | A discovery or insight — attaches anywhere relevant |
| revisit | Pivot point — connects an old approach to a new one |
When to use each type
- Goal: When the user asks for something new or a high-level objective is identified.
- Option: When exploring possible approaches before choosing one. Options always come from a goal.
- Decision: When an option is actually chosen. Decisions come after options, not before.
- Action: When you are about to write or change code. Log it before the work.
- Outcome: When work is complete. Link it back to the action that produced it.
- Observation: When you notice something interesting — a constraint, a codebase pattern, a risk. Use the
-dflag for a detailed description. - Revisit: When a previous approach is being abandoned and replaced. Links old decisions to new ones.
The Canonical Flow
Every decision follows this path through the graph:
- goal leads to option nodes (possible approaches)
- option nodes lead to a decision (choosing which to pursue)
- decision leads to action nodes (implementing the choice)
- action nodes lead to outcome nodes (results)
- observation attaches anywhere relevant
- revisit connects old approaches to new ones during pivots
Goals do not lead directly to decisions. There must be options first. Options do not come after decisions. Decision nodes should only be created when an option is actually chosen.
Edge Types
Edges describe the relationship between two nodes.
| Type | Meaning | Typical usage |
|---|---|---|
leads_to | Natural progression | goal → option, action → outcome |
chosen | Option was selected | option → decision |
rejected | Option was not selected | option → decision (with reason) |
requires | Dependency relationship | action → another action |
blocks | Prevents progress | observation → action |
enables | Makes something possible | action → outcome |
Note: A
supersedesedge type is auto-created by the revisit/archaeology system (e.g.,deciduous archaeology pivot). It is not a valid parameter fordeciduous link.
Node Status
Every node has a status that tracks its lifecycle.
| Status | Meaning |
|---|---|
pending | Not yet started |
active | Current truth — how things work today |
completed | Finished successfully |
rejected | Considered and rejected |
superseded | Replaced by a newer approach |
abandoned | Tried and rejected — dead end |
ID Type Title Status Confidence
1 goal Add user authentication active 90%
5 decision Use JWT for API auth active 85%
$ deciduous nodes --status superseded
ID Type Title Status Confidence
3 decision Use session cookies superseded 75%
Confidence Levels
Every node carries a confidence value from 0 to 100, reflecting how certain you are about it.
| Range | Meaning |
|---|---|
| 90-100 | High confidence — well-understood, clear requirement |
| 70-89 | Moderate confidence — reasonable approach, some unknowns |
| 50-69 | Low confidence — exploratory, uncertain |
| 0-49 | Very low — speculative, needs validation |
Confidence helps future sessions prioritize which decisions to revisit. A low-confidence decision is a natural candidate for re-evaluation.
The Revisit Pattern
When a design approach is abandoned and replaced, a revisit node captures the pivot:
- An observation identifies why the old approach failed
- A revisit node links to that observation
- The revisit leads to the new decision
- The old decision is marked
superseded
This captures why you changed direction, not just what changed.
Created node 12 (type: observation) [confidence: 90%] [branch: main]
$ deciduous add revisit "Reconsidering token strategy" -c 85
Created node 13 (type: revisit) [confidence: 85%] [branch: main]
$ deciduous link 12 13 -r "forced rethinking"
Linked 12 → 13 (leads_to) "forced rethinking"
$ deciduous status 5 superseded
Updated node 5 status to superseded
Sessions and Chains
Sessions group nodes by time proximity. Nodes created within 4 hours of each other belong to the same session. A gap longer than 4 hours starts a new session.
Chains are connected components of the graph. Starting from root nodes (goals or nodes with no incoming edges), BFS traverses all connected nodes. Chains group related decisions together — “show me everything related to authentication.”
Both concepts are used by the web viewer to organize and display your decision history.
Working with Nodes
This chapter covers the core workflow: adding nodes, linking them, updating status, and maintaining the graph.
Adding Nodes
Create nodes with deciduous add <type> "title". The type must be one of: goal, option, decision, action, outcome, observation, or revisit.
Created node 1 (type: goal) [confidence: 90%] [branch: main]
$ deciduous add option "Use JWT tokens" -c 80
Created node 2 (type: option) [confidence: 80%] [branch: main]
$ deciduous add action "Implementing JWT middleware" -c 85 -f "src/auth/jwt.rs,src/auth/mod.rs"
Created node 3 (type: action) [confidence: 85%] [branch: feature-auth]
$ deciduous add outcome "JWT auth working — 14 tests passing" -c 95 --commit HEAD
Created node 4 (type: outcome) [confidence: 95%] [branch: feature-auth] [commit: a1b2c3d]
$ deciduous add observation "Existing bcrypt helper in utils/" -c 85 -d "Found password hashing utilities already in the codebase that we can reuse."
Created node 5 (type: observation) [confidence: 85%] [branch: feature-auth]
All Flags
| Flag | Description |
|---|---|
-c, --confidence <0-100> | Confidence level for this node |
-p, --prompt "..." | Short user prompt that triggered this work |
--prompt-stdin | Read the prompt from stdin (for multi-line prompts) |
-f, --files "a.rs,b.rs" | Associate source files with this node |
-b, --branch <name> | Git branch (auto-detected by default) |
--commit <hash|HEAD> | Link to a git commit |
--date "YYYY-MM-DD" | Backdate the node (useful for archaeology) |
--no-branch | Skip auto-detection of git branch |
-d, --description "..." | Detailed description (especially useful for observations) |
Capturing Verbatim Prompts
For goal nodes, capture the user’s exact request — not a summary. This enables full context recovery in future sessions.
I need to add rate limiting to the API. Should be per-user based on
auth token, with a 100 req/min default and configurable per-plan limits.
EOF
Created node 1 (type: goal) [confidence: 90%] [branch: main]
You can also update the prompt on an existing node:
Updated prompt for node 1
Linking Nodes
Create edges between nodes with deciduous link <from> <to>. Always link immediately after creating a node.
Linked 1 → 2 (leads_to) "Possible approach"
$ deciduous link 2 4 -r "Chosen: mature crate, full control" --edge-type chosen
Linked 2 → 4 (chosen) "Chosen: mature crate, full control"
$ deciduous link 3 5 --edge-type rejected -r "Too much complexity for our scale"
Linked 3 → 5 (rejected) "Too much complexity for our scale"
Connection Rules
Root goal nodes are the only valid orphans. Every other node type must be linked immediately:
| When you create… | Link to… |
|---|---|
| option | Its parent goal |
| decision | The option(s) it chose between |
| action | The decision that spawned it |
| outcome | The action that produced it |
| observation | The related goal or action |
| revisit | The decision/outcome being reconsidered |
Updating Status
Change a node’s status with deciduous status <id> <status>.
Updated node 3 status to completed
$ deciduous status 7 superseded
Updated node 7 status to superseded
$ deciduous status 9 abandoned
Updated node 9 status to abandoned
Valid status values: pending, active, completed, rejected, superseded, abandoned.
Showing Node Details
Use deciduous show <id> to view a node’s full details, including connections.
Node #1 goal
────────────────────────────────────────
Title: Add user authentication
Status: active
Confidence: 90%
Branch: main
Connections
Outgoing (2):
here ─[possible approach]→ #2: Use JWT tokens
here ─[possible approach]→ #3: Use session cookies
Querying Nodes and Edges
ID Type Title Status Confidence
1 goal Add user authentication active 90%
2 option Use JWT tokens active 80%
3 option Use session cookies rejected 75%
4 decision Use JWT for API auth active 85%
5 action Implementing JWT middleware completed 85%
$ deciduous nodes --type goal
ID Type Title Status Confidence
1 goal Add user authentication active 90%
$ deciduous nodes -b feature-auth
ID Type Title Status Confidence
5 action Implementing JWT middleware completed 85%
6 outcome JWT auth working — 14 tests completed 95%
$ deciduous edges
1 → 2 (leads_to) "Possible approach"
1 → 3 (leads_to) "Possible approach"
2 → 4 (chosen) "Mature crate, full control"
4 → 5 (leads_to) "Implementation"
5 → 6 (leads_to) "Complete"
$ deciduous edges --to 4
2 → 4 (chosen) "Mature crate, full control"
Deleting and Unlinking
Remove edges with deciduous unlink and nodes with deciduous delete.
Removed edge 5 → 12
$ deciduous delete 12 --dry-run
Would delete node 12 (observation: "Stale finding") and 2 connected edges
$ deciduous delete 12
Deleted node 12 and 2 connected edges
Use --dry-run to preview what would be removed before committing to a deletion.
Linking Commits
After every git commit, link it to the decision graph with --commit HEAD:
The web viewer displays commit messages, authors, and dates for linked nodes.
The Core Pattern
The golden rule for working with nodes:
- Before you write code – log what you are about to do (action)
- After it works – log the result (outcome)
- Always – link every node to its parent immediately
Visualization & Export
Deciduous provides multiple ways to view and share your decision graph: a live web viewer, DOT/PNG export, PR writeups, and GitHub Pages deployment.
Web Viewer
Start the interactive web viewer with deciduous serve.
Serving decision graph at http://localhost:3000
Press Ctrl+C to stop
$ deciduous serve --port 8080
Serving decision graph at http://localhost:8080
The viewer provides five browsing modes:
| View | Purpose |
|---|---|
| Chains | Decision chains grouped by session — the story of a feature |
| Timeline | Chronological view merged with git commits |
| Graph | Force-directed interactive visualization |
| DAG | Hierarchical goal → decision → outcome flow |
| Archaeology | Narrative-driven exploration with Q&A |
Q&A Chat
Every view includes a built-in Q&A chat panel. Ask questions about your decision graph in natural language — the chat searches across all nodes, traces chains, and returns grounded answers with node references. Conversations are stored in the database and persist across sessions. A copy-to-markdown button makes it easy to pull answers into PRs or docs.
Other Features
Branch filtering, full-text search with type filters, resizable panels, deep linking, click-to-expand node details, keyboard navigation (j/k/g/G/Space), and auto-refresh every 30 seconds.
DOT Export
Generate DOT format graphs with deciduous dot. Add --png to render a PNG image (requires graphviz installed).
digraph deciduous {
rankdir=TB;
node [shape=box, style=rounded];
1 [label="Add user auth" fillcolor="#d1f7d6"];
...
}
$ deciduous dot --png -o docs/decision-graph.dot
Written DOT to docs/decision-graph.dot
Generated PNG: docs/decision-graph.png
$ deciduous dot --png --auto --nodes 1-15
Written DOT to docs/decision-graph-feature-auth.dot
Generated PNG: docs/decision-graph-feature-auth.png
DOT Options
| Flag | Description |
|---|---|
-o, --output <FILE> | Output file (default: stdout) |
-r, --roots <IDS> | Root node IDs for BFS traversal (comma-separated) |
-n, --nodes <SPEC> | Specific node IDs or ranges (e.g., 1-11 or 1,3,5-10) |
-t, --title <TITLE> | Graph title |
--rankdir <DIR> | Graph direction: TB (top-bottom) or LR (left-right) |
--png | Generate PNG file (requires graphviz) |
--auto | Use branch-specific filenames to avoid merge conflicts |
The --auto flag generates filenames like docs/decision-graph-feature-auth.png based on the current branch, which prevents merge conflicts when multiple PRs each have their own graph.
PR Writeups
Generate markdown writeups for pull requests with deciduous writeup.
## Add JWT Authentication
### Decision Flow
- Goal: Add user authentication (confidence: 90%)
- Decision: Use JWT for API auth (chosen over session cookies)
- Actions: 3 implementation steps, all completed
...
$ deciduous writeup --auto -t "JWT Auth" --nodes 1-11 -o PR-WRITEUP.md
Written writeup to PR-WRITEUP.md
Writeup Options
| Flag | Description |
|---|---|
-t, --title <TITLE> | PR title |
-r, --roots <IDS> | Root node IDs (traverses children) |
-n, --nodes <SPEC> | Specific node IDs or ranges |
-o, --output <FILE> | Output file (default: stdout) |
--png <FILENAME> | PNG to embed (auto-detects GitHub repo/branch for URL) |
--auto | Auto-detect PNG from branch-specific filename |
--no-dot | Skip DOT graph section |
--no-test-plan | Skip test plan section |
Recommended PR Workflow
Written DOT to docs/decision-graph-feature-auth.dot
Generated PNG: docs/decision-graph-feature-auth.png
$ git add docs/decision-graph-feature-auth.dot docs/decision-graph-feature-auth.png
$ git commit -m "docs: add decision graph for auth PR"
$ git push
$ gh pr edit 42 --body "$(deciduous writeup --auto -t 'Add JWT Auth' --nodes 1-11)"
https://github.com/user/repo/pull/42
Sync for GitHub Pages
Export your graph to static JSON files for GitHub Pages hosting with deciduous sync.
Exported graph to docs/graph-data.json (42 nodes, 38 edges)
Exported git history to docs/git-history.json (12 linked commits)
This creates two files in docs/:
| File | Contents |
|---|---|
docs/graph-data.json | Decision graph (nodes + edges) |
docs/git-history.json | Commit info for linked nodes |
Deploying to GitHub Pages
- Run
deciduous syncto export - Commit and push the
docs/directory - In GitHub Settings → Pages → Deploy from branch → select
/docsfolder
Your graph will be live at https://<user>.github.io/<repo>/.
Full JSON Export
For programmatic access, export the entire graph as JSON:
Multi-User Sync
The deciduous database (.deciduous/deciduous.db) is local and gitignored. When teams need to share decisions, the events system provides append-only sync via git.
How It Works
Each user writes to their own event log file at .deciduous/sync/events/<username>.jsonl. These files are git-tracked and merge cleanly because each user writes to a separate file. When a teammate pulls, they rebuild their local database from all event logs.
The model:
- Every
add,link, andstatuscommand emits an event to your personal log - Events are identified by
change_id(UUID), not local integer IDs - Rebuilding replays all events from all users, deduplicating by
change_id - Checkpoints snapshot the current state so old events can be cleared
Initializing Sync
Set up the sync directory with deciduous events init.
Initialized sync directory at .deciduous/sync/
Created events directory at .deciduous/sync/events/
Author: alice
Next steps:
1. Add .deciduous/sync/ to git tracking
2. Team members pull and run 'deciduous events rebuild'
After initializing, events are automatically emitted whenever you create nodes, link edges, or update status.
Checking Status
View the current state of sync with deciduous events status.
Sync: Event-based sync status
Author: alice
Events directory: .deciduous/sync/events/
Event files:
alice.jsonl — 24 events
bob.jsonl — 18 events
Checkpoint: .deciduous/sync/checkpoint.json (42 nodes)
Local database: 42 nodes, 38 edges
Rebuilding from Events
After pulling changes from teammates, rebuild your local database.
Updating a1b2c3d..f4e5d6c
.deciduous/sync/events/bob.jsonl | 12 +++
$ deciduous events rebuild
Sync: Rebuilding database from events...
Loaded checkpoint: 42 nodes
Replaying events from alice.jsonl (24 events)
Replaying events from bob.jsonl (18 events)
Applied 12 new events (30 already present)
Database now has 54 nodes, 47 edges
You can preview what would change without modifying the database:
Sync: Dry run — no changes will be made
Would apply 12 new events from bob.jsonl
Would create 12 nodes, 9 edges
Checkpointing
As event logs grow, create a checkpoint to snapshot the current state. This speeds up future rebuilds.
Created checkpoint at .deciduous/sync/checkpoint.json (54 nodes, 47 edges)
$ deciduous events checkpoint --clear-events
Created checkpoint at .deciduous/sync/checkpoint.json (54 nodes, 47 edges)
Cleared event logs (events are now in the checkpoint)
Use --clear-events to remove old event log files after checkpointing. The checkpoint contains everything needed for a full rebuild.
Emitting Events Manually
If you created nodes before sync was initialized, emit them manually:
Emitted event for node 42 to alice.jsonl
PR Workflow for Sharing Decisions
The recommended team workflow:
.deciduous/sync/events/alice.jsonl | 8 +++
$ deciduous events rebuild
Replaying events from alice.jsonl (8 events)
Applied 8 new events
Database now has 50 nodes, 44 edges
Since each user writes to their own .jsonl file, git merges happen automatically with no conflicts.
The Dual-ID Model
Every node has two identifiers:
| ID | Scope | Purpose |
|---|---|---|
id (integer) | Local database | Primary key, different on each machine |
change_id (UUID) | Global | Stable across all databases |
Event logs and patches reference nodes by change_id, so they work correctly even when local id values differ between machines.
If your database predates the sync system, run deciduous migrate to add change_id columns.
Themes & Organization
Themes let you organize decision nodes into cross-cutting categories. A node about “JWT middleware” might belong to both an “auth” theme and a “security” theme. Themes work independently of the graph structure — they are tags, not edges.
Creating Themes
Define a theme with deciduous themes create. Each theme has a name, a color, and an optional description.
Created theme 'auth' (color: blue)
$ deciduous themes create performance green -d "Performance optimization work"
Created theme 'performance' (color: green)
$ deciduous themes create security red
Created theme 'security' (color: red)
Theme names are lowercase and dash-separated. Colors help distinguish themes visually in the web viewer.
Listing Themes
View all defined themes with deciduous themes list.
Name Color Description
auth blue Authentication and authorization decisions
performance green Performance optimization work
security red
Deleting Themes
Remove a theme and all its node associations with deciduous themes delete.
Deleted theme 'security'
Tagging Nodes
Apply themes to nodes with deciduous tag add. A node can have multiple themes.
Tagged theme 'auth' to node 1
$ deciduous tag add 5 auth
Tagged theme 'auth' to node 5
$ deciduous tag add 5 security
Tagged theme 'security' to node 5
Removing Tags
Removed theme 'security' from node 5
Listing Tags on a Node
Themes for node 5:
auth (blue)
security (red)
Auto-Suggestions
Deciduous can analyze node titles and suggest theme assignments with deciduous tag suggest. This scans nodes for keyword matches against existing theme names and descriptions.
Suggested tags:
Node 1 "Add user authentication" → auth
Node 5 "Implementing JWT middleware" → auth
Node 8 "Optimize query performance" → performance
Node 12 "Add rate limiting" → security
$ deciduous tag suggest 5
Suggested tags for node 5:
auth
Apply all suggestions at once with --apply:
Suggested tags:
Node 1 "Add user authentication" → auth (applied)
Node 5 "Implementing JWT middleware" → auth (applied)
Node 8 "Optimize query performance" → performance (applied)
Applied 3 suggested tags
Suggestions are tagged with source "suggested" rather than "manual", so you can distinguish them later.
Confirming Suggestions
Review and confirm auto-suggested tags with deciduous tag confirm. This upgrades a suggestion from "suggested" to "manual" status.
Confirmed theme 'auth' on node 1 (suggested → manual)
Filtering by Theme
Use the --theme flag on deciduous nodes to filter nodes by theme.
ID Type Title Status Confidence
1 goal Add user authentication active 90%
2 option Use JWT tokens active 80%
5 action Implementing JWT middleware completed 85%
6 outcome JWT auth working — 14 tests completed 95%
$ deciduous nodes --theme performance --status active
ID Type Title Status Confidence
8 goal Optimize query performance active 85%
Themes combine with other filters like --status, --type, and --branch for precise queries across the graph.
Setup
The Model Context Protocol (MCP) is an open standard that lets AI assistants call tools hosted by external servers. Deciduous ships with a built-in MCP server that exposes 31 tools for reading, writing, and analyzing your decision graph. When connected, Claude can search decisions, trace chains, and log new nodes directly – no copy-pasting CLI output.
Claude Code
One command, project-level config:
MCP configured for Claude Code!
Updated /Users/you/project/.claude/settings.local.json
Added mcpServers.deciduous entry.
Claude Code will automatically discover and use the MCP server.
That’s it. Restart Claude Code and the tools appear as mcp__deciduous__*. The command writes to .claude/settings.local.json in your project directory, which is gitignored by default – each developer gets their own config.
Claude Desktop
Claude Desktop needs absolute paths because it doesn’t inherit your shell PATH:
MCP configured for Claude Desktop!
Config file ~/Library/Application Support/Claude/claude_desktop_config.json
Binary /Users/you/.cargo/bin/deciduous
Database /Users/you/project/.deciduous/deciduous.db
Restart Claude Desktop to pick up the new configuration.
The command auto-detects your binary path and the .deciduous/deciduous.db location in the current directory. It writes to the platform-specific Claude Desktop config file:
| Platform | Config path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
| Windows | %APPDATA%/Claude/claude_desktop_config.json |
If other MCP servers are already configured, deciduous merges its entry without disturbing them. You must restart Claude Desktop after running this command.
Manual Setup
If you prefer to inspect the config before writing it, use --print:
Copy the relevant parts into your config file manually.
User-Level vs Project-Level Config
| Claude Code | Claude Desktop | |
|---|---|---|
| Config location | .claude/settings.local.json (project) | Platform config directory (user) |
| Scope | One project | All conversations |
| DB path | Auto-detected from cwd | Set via DECIDUOUS_DB_PATH env var |
| Binary path | Uses PATH lookup (deciduous) | Absolute path (e.g., /Users/you/.cargo/bin/deciduous) |
| Git tracking | .claude/settings.local.json is gitignored | N/A |
Claude Code uses project-level config. Each project has its own .deciduous/deciduous.db, and the MCP server automatically finds it from the working directory.
Claude Desktop uses user-level config. You point DECIDUOUS_DB_PATH at a specific database file, and every conversation in Claude Desktop reads and writes to that same database. This is the foundation of the Master Memory pattern.
Generated Config
For Claude Code, the generated JSON is minimal – no absolute paths needed:
{
"mcpServers": {
"deciduous": {
"command": "deciduous",
"args": ["mcp", "serve"]
}
}
}
For Claude Desktop, absolute paths and the database env var are included:
{
"mcpServers": {
"deciduous": {
"command": "/Users/you/.cargo/bin/deciduous",
"args": ["mcp", "serve"],
"env": {
"DECIDUOUS_DB_PATH": "/Users/you/project/.deciduous/deciduous.db"
}
}
}
}
Troubleshooting
Binary not found
Claude Desktop does not inherit your shell PATH. If you see errors about the command not being found, verify the absolute path:
which deciduous
# /Users/you/.cargo/bin/deciduous
Use that full path in the config’s command field.
Database not found
If deciduous mcp setup claude-desktop warns that .deciduous/deciduous.db was not found, run deciduous init in your project directory first. The MCP server will create the database on first use if it doesn’t exist, but init also sets up Claude integration files.
DECIDUOUS_DB_PATH
The DECIDUOUS_DB_PATH environment variable tells the MCP server which SQLite database to use. This is only needed for Claude Desktop (where there is no working directory context). Claude Code runs in your project directory and finds the database automatically.
You can override it to point at any database:
"env": {
"DECIDUOUS_DB_PATH": "/Users/you/other-project/.deciduous/deciduous.db"
}
Server not connecting
- Verify the binary path exists and is executable
- Test the server manually:
deciduous mcp serve(it reads JSON-RPC from stdin) - Check that
deciduous inithas been run in the target project - Restart Claude Desktop / Claude Code after config changes
Conversational Memory
Every conversation with Claude gets its own decision tree. When a session starts, a root goal node is created. Every node added during that conversation is automatically associated with the session – no manual bookkeeping. When the conversation ends, an optional summary captures what was accomplished.
The result: each conversation produces a self-contained, queryable record of what was discussed, decided, and built.
Session Lifecycle
A session has three phases:
- Start –
start_sessioncreates a root goal node and returns a session ID - Work – all
add_nodecalls auto-associate with the active session - End –
end_sessionmarks the session complete with an optional summary
Resuming Sessions
Pick up where you left off. Use list_sessions to find previous conversations, then resume_session to reconnect. New nodes continue building on the same decision tree.
Persistence Across Restarts
The active session ID is written to .deciduous/active_session on disk. When the MCP server starts (or restarts – Claude Desktop and Claude Code may kill and re-spawn the server process), it reads this file and automatically resumes the active session. No manual intervention needed.
If the session was already ended, the stale file is cleaned up automatically.
Master Memory
Claude Desktop users get a persistent decision graph across every conversation. The MCP config points DECIDUOUS_DB_PATH at a single .deciduous/deciduous.db file. Every conversation – whether it runs for five minutes or five hours – writes to the same database.
This means you can ask Claude in a new conversation about decisions made in previous ones. The graph is the memory layer that outlasts any single chat.
Conversation 1 (Jan) --> .deciduous/deciduous.db <-- Session #1 (14 nodes)
Conversation 2 (Feb) --> .deciduous/deciduous.db <-- Session #2 (8 nodes)
Conversation 3 (Mar) --> .deciduous/deciduous.db <-- Session #3 (11 nodes)
In a brand new conversation, you can query the entire history:
The database is the single source of truth. Sessions organize it by conversation. Search and trace work across all of them.
Multi-Session Workflow Example
Here is a realistic workflow spanning two sessions days apart, showing how memory persists:
The decision tree now contains the full story: what was tried, what worked, what needed a second pass, and why. Any future session can query this history without having been part of either conversation.
API Reference
All 31 MCP tools exposed by the deciduous server, organized by category. Tools marked CLI have a direct CLI equivalent. Tools marked MCP-only are exclusive to the MCP server.
Graph CRUD
Tools for creating, connecting, and modifying nodes and edges.
add_node
Add a new node to the decision graph. CLI: deciduous add
| Parameter | Type | Required | Description |
|---|---|---|---|
node_type | string | Yes | goal, decision, option, action, outcome, observation, revisit |
title | string | Yes | Node title |
description | string | Longer description with more detail | |
confidence | integer | Confidence level 0-100 | |
prompt | string | Verbatim user prompt (for context recovery) | |
files | string | Comma-separated list of associated files | |
branch | string | Git branch (auto-detected if omitted) | |
commit | string | Git commit hash, or "HEAD" to auto-detect |
link_nodes
Create an edge between two nodes. CLI: deciduous link
| Parameter | Type | Required | Description |
|---|---|---|---|
from_id | integer | Yes | Source node ID |
to_id | integer | Yes | Target node ID |
rationale | string | Reason for this connection | |
edge_type | string | leads_to (default), requires, chosen, rejected, blocks, enables |
unlink_nodes
Remove an edge between two nodes. CLI: deciduous unlink
| Parameter | Type | Required | Description |
|---|---|---|---|
from_id | integer | Yes | Source node ID |
to_id | integer | Yes | Target node ID |
delete_node
Delete a node and all its connected edges. CLI: deciduous delete
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | ID of the node to delete |
dry_run | boolean | If true, preview what would be deleted without deleting (default: false) |
update_status
Change the status of a node. CLI: deciduous status
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | Node ID to update |
status | string | Yes | pending, active, completed, rejected, superseded, abandoned |
update_prompt
Add or update the verbatim user prompt stored on a node. CLI: deciduous prompt
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | Node ID to update |
prompt | string | Yes | The verbatim user prompt text |
Querying
Tools for listing, searching, and inspecting graph data.
list_nodes
List all nodes with optional filters. CLI: deciduous nodes
| Parameter | Type | Required | Description |
|---|---|---|---|
branch | string | Filter by git branch | |
node_type | string | Filter by type (goal, decision, option, etc.) | |
status | string | Filter by status (active, pending, completed, etc.) | |
theme | string | Filter by theme name |
list_edges
List all edges in the decision graph. CLI: deciduous edges
No parameters.
show_node
Show detailed information about a single node including connections, themes, and documents. CLI: deciduous show
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | Node ID to display |
get_graph
Export the full decision graph as JSON (all nodes and edges). CLI: deciduous graph
No parameters.
search_nodes
Full-text search across titles, descriptions, and prompts. MCP-only
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | Search text (matched against title, description, and prompt) |
node_type | string | Filter results by node type | |
branch | string | Filter results by branch |
Analysis
Tools for traversing, tracing, and understanding the graph structure.
trace_chain
BFS traversal from a starting node. Returns the connected subgraph with depth. MCP-only
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | Starting node ID |
max_depth | integer | Maximum traversal depth (0 = unlimited, default: 0) | |
direction | string | both (default), outgoing, incoming |
get_node_context
Get a node’s full neighborhood: the node itself, parents, children, siblings, themes, and documents. MCP-only
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | Node ID to get context for |
get_timeline
Chronological view of nodes, newest first. CLI: deciduous archaeology timeline
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | Max nodes to return (default: 50, 0 = all) | |
node_type | string | Filter by node type | |
branch | string | Filter by git branch | |
since | string | Only show nodes after this date (YYYY-MM-DD) |
get_pulse
Graph health check: summary statistics, active goals, recent activity, orphans, and connection gaps. CLI: deciduous pulse
| Parameter | Type | Required | Description |
|---|---|---|---|
branch | string | Filter by git branch |
find_orphans
Find nodes that violate connection rules (outcomes without parent actions, actions without parent decisions, etc.). Root goals are excluded since they are valid orphans. MCP-only
No parameters.
get_branch_summary
Summary of all decisions and activity on a specific git branch. MCP-only
| Parameter | Type | Required | Description |
|---|---|---|---|
branch | string | Yes | Git branch name to summarize |
Sessions
Tools for managing conversation-scoped decision trees. All session tools are MCP-only.
start_session
Begin a new conversation session. Creates a root goal node; all subsequent add_node calls auto-associate.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Session name (e.g., "cowork: auth refactor") |
goal_title | string | Yes | Title for the root goal node |
goal_prompt | string | Verbatim initial user prompt |
end_session
Close the active session with an optional summary.
| Parameter | Type | Required | Description |
|---|---|---|---|
summary | string | Brief summary of what was accomplished |
get_session
View a session’s details and all its nodes.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | integer | Session ID to query (omit for current session) |
resume_session
Reconnect to a previous session by ID. Use after breaks or server restarts.
| Parameter | Type | Required | Description |
|---|---|---|---|
session_id | integer | Yes | Session ID to resume |
list_sessions
List all conversation sessions.
| Parameter | Type | Required | Description |
|---|---|---|---|
active_only | boolean | If true, only show sessions that haven’t ended (default: false) |
Documents & Themes
Tools for attaching files and organizing nodes with tags.
attach_document
Attach a file to a decision graph node. CLI: deciduous doc attach
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | Node ID to attach the file to |
file_path | string | Yes | Path to the file to attach |
description | string | Description of the document |
list_documents
List documents attached to a node, or all documents. CLI: deciduous doc list
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Node ID to list documents for (omit for all) |
create_theme
Create a new theme for tagging nodes. CLI: deciduous themes create
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Theme name (lowercase, dash-separated) |
color | string | Hex color code (default: #6b7280) | |
description | string | Theme description |
list_themes
List all defined themes. CLI: deciduous themes list
No parameters.
tag_node
Add a theme tag to a node. CLI: deciduous tag add
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | Node ID to tag |
theme | string | Yes | Theme name to apply |
untag_node
Remove a theme tag from a node. CLI: deciduous tag remove
| Parameter | Type | Required | Description |
|---|---|---|---|
node_id | integer | Yes | Node ID to untag |
theme | string | Yes | Theme name to remove |
Export
Tools for generating visualizations, writeups, and sync status.
export_dot
Export the decision graph as DOT format for Graphviz visualization. CLI: deciduous dot
| Parameter | Type | Required | Description |
|---|---|---|---|
roots | string | Root node IDs (comma-separated) – traverses children | |
nodes | string | Specific IDs or ranges (e.g., "1-11" or "1,3,5-10") | |
title | string | Graph title | |
rankdir | string | TB (top-bottom, default) or LR (left-right) |
generate_writeup
Generate a PR writeup from the decision graph. Returns markdown. CLI: deciduous writeup
| Parameter | Type | Required | Description |
|---|---|---|---|
title | string | PR title | |
roots | string | Root node IDs (comma-separated) | |
nodes | string | Specific node IDs or ranges | |
no_dot | boolean | Skip DOT graph section (default: false) | |
no_test_plan | boolean | Skip test plan section (default: false) |
events_status
Show the status of event-based multi-user sync. CLI: deciduous events status
No parameters.
Tool Count by Category
| Category | Count | MCP-only |
|---|---|---|
| Graph CRUD | 6 | 0 |
| Querying | 5 | 1 (search_nodes) |
| Analysis | 6 | 4 (trace_chain, get_node_context, find_orphans, get_branch_summary) |
| Sessions | 5 | 5 |
| Documents & Themes | 6 | 0 |
| Export | 3 | 0 |
| Total | 31 | 10 |
Core Commands
Setup, server, and maintenance commands that manage your deciduous installation.
deciduous init
Initialize deciduous in the current directory. Creates the .deciduous/ database directory and sets up AI assistant integration files.
| Flag | Description |
|---|---|
--claude | Set up Claude Code integration (.claude/, CLAUDE.md) |
--no-auto-update | Disable automatic version checking |
Default (no flags): sets up Claude Code only.
Created .deciduous/deciduous.db
Created .deciduous/config.toml
Created .claude/commands/decision.md
Created .claude/commands/recover.md
Created .claude/commands/work.md
Created .claude/commands/document.md
Created .claude/commands/build-test.md
Created .claude/commands/serve-ui.md
Created .claude/commands/sync-graph.md
Created .claude/commands/decision-graph.md
Created .claude/commands/sync.md
Created .claude/skills/pulse.md
Created .claude/skills/narratives.md
Created .claude/skills/archaeology.md
Updated CLAUDE.md with decision graph workflow
Updated .gitignore
Deciduous initialized successfully!
deciduous update
Update AI assistant integration files to the latest version. Auto-detects installed integration files (.claude/) and updates them.
Does not touch: settings files, .deciduous/config.toml, or docs/.
Detected: Claude Code (.claude/)
Updated .claude/commands/decision.md
Updated .claude/commands/recover.md
Updated .claude/skills/pulse.md
Updated CLAUDE.md
Updated .deciduous/.version to 0.15.0
Integration files updated to v0.15.0
deciduous check-update
Compare .deciduous/.version with the current binary version. Exits with code 0 if up to date, code 1 if an update is needed.
OK: Integration files are up to date (v0.15.0).
When an update is available:
╔════════════════════════════════════════════════════════════════╗
║ DECIDUOUS UPDATE AVAILABLE ║
╚════════════════════════════════════════════════════════════════╝
Integration files: 0.14.0 -> Binary: 0.15.0
What's new:
- MCP server for Claude Code, Desktop, and cowork
Run deciduous update to update integration files.
deciduous serve
Start the web graph viewer. Opens an interactive browser-based visualization of your decision graph.
| Flag | Short | Description |
|---|---|---|
--port <port> | -p | Port to listen on (default: 3000) |
Starting deciduous graph viewer...
Listening on http://127.0.0.1:3000
Press Ctrl+C to stop
Use a custom port:
Listening on http://127.0.0.1:8080
deciduous backup
Create a backup of the SQLite database. Always back up before any destructive operations.
| Flag | Short | Description |
|---|---|---|
--output <path> | -o | Output path (default: deciduous_backup_<timestamp>.db) |
Backup created: deciduous_backup_20250509_143022.db
Specify a custom path:
Backup created: /tmp/before-migration.db
deciduous commands
Show the recent command log – every deciduous command that modified the graph.
| Flag | Short | Description |
|---|---|---|
--limit <n> | -l | Number of commands to show (default: 20) |
2025-05-09 14:20:01 add goal "Add JWT authentication" (node 42)
2025-05-09 14:20:15 add option "jsonwebtoken crate" (node 43)
2025-05-09 14:20:18 link 42 -> 43 (leads_to)
2025-05-09 14:21:02 add decision "Use jsonwebtoken" (node 45)
2025-05-09 14:21:05 link 43 -> 45 (chosen)
deciduous auto-update <on|off>
Deprecated. Version checking is now always-on (checks crates.io once per 24h). This command exists for backward compatibility but has no effect.
Graph Management
The heart of deciduous – commands for building and querying your decision graph. These are the commands you will use most.
deciduous add <type> <title>
Add a new node to the decision graph.
Node types: goal, decision, option, action, outcome, observation, revisit
| Flag | Short | Description |
|---|---|---|
--description <text> | -d | Optional description |
--confidence <0-100> | -c | Confidence level |
--commit <hash|HEAD> | Link to git commit (HEAD auto-resolves) | |
--prompt <text> | -p | Prompt that triggered this decision |
--prompt-stdin | Read prompt from stdin (for multi-line) | |
--files <paths> | -f | Associated files (comma-separated) |
--branch <name> | -b | Git branch (auto-detected if omitted) |
--no-branch | Skip auto-detection of git branch | |
--date <date> | Created date (RFC3339, YYYY-MM-DD, or YYYY-MM-DD HH:MM:SS) |
Basic usage
Created node 42 (type: goal) [confidence: 90%] [branch: feature-auth]
$ deciduous add option "jsonwebtoken crate + custom refresh logic" -c 80
Created node 43 (type: option) [confidence: 80%] [branch: feature-auth]
$ deciduous add observation "Redis adds complexity" -d "Adding Redis for token storage introduces operational complexity -- need to manage another service in production."
Created node 44 (type: observation) [branch: feature-auth]
With metadata flags
Created node 46 (type: action) [confidence: 85%] [commit: a1b2c3d] [branch: feature-auth]
Multi-line prompts
Capture the full user request with --prompt-stdin:
I need to add user authentication to the app. Users should be
able to sign up with email/password, and we need OAuth support
for Google and GitHub. Use JWT tokens with refresh rotation.
EOF
Created node 50 (type: goal) [confidence: 90%] [branch: main]
Backdating nodes (archaeology)
Created node 51 (type: goal) [date: 2024-01-15]
deciduous link <from> <to>
Add an edge between two nodes.
| Flag | Short | Description |
|---|---|---|
--rationale <text> | -r | Rationale for this connection |
--edge-type <type> | -t | Edge type (default: leads_to) |
Edge types: leads_to, requires, chosen, rejected, blocks, enables
Linked 42 -> 43 (leads_to)
$ deciduous link 43 45 -t chosen
Linked 43 -> 45 (chosen)
$ deciduous link 44 45 -t rejected -r "Less control over rotation timing"
Linked 44 -> 45 (rejected)
$ deciduous link 10 11 -t blocks -r "Can't deploy until migration runs"
Linked 10 -> 11 (blocks)
deciduous unlink <from> <to>
Remove an edge between two nodes.
Removed edge 44 -> 45
deciduous delete <id>
Delete a node and all its connected edges.
| Flag | Description |
|---|---|
--dry-run | Show what would be deleted without deleting |
Would delete node 44: "axum-jwt-auth with built-in rotation" (option)
Would delete edge 42 -> 44 (leads_to)
Would delete edge 44 -> 45 (rejected)
$ deciduous delete 44
Deleted node 44 and 2 connected edges
deciduous status <id> <status>
Update a node’s status.
Valid statuses: pending, active, completed, rejected, superseded, abandoned
Updated node 47 status: active -> completed
$ deciduous status 44 superseded
Updated node 44 status: active -> superseded
deciduous prompt <id> [text]
Update or add a prompt to an existing node. Omit text to read from stdin.
Updated prompt for node 42
$ deciduous prompt 50 << 'EOF'
I need authentication with email/password signup,
OAuth for Google and GitHub, and JWT with refresh
token rotation.
EOF
Updated prompt for node 50
deciduous show <id>
Show detailed information about a single node, including its connections, metadata, and prompt.
| Flag | Description |
|---|---|
--json | Output as JSON instead of formatted text |
Node 42: Add JWT authentication
Type: goal
Status: active
Confidence: 90%
Branch: feature-auth
Created: 2025-05-09 14:20:01
Prompt:
Add JWT auth with refresh token rotation for the API
Outgoing edges:
42 -> 43 leads_to "jsonwebtoken crate + custom refresh logic" (option)
42 -> 44 leads_to "axum-jwt-auth with built-in rotation" (option)
Incoming edges:
(none)
deciduous nodes
List all nodes in the graph. Use filters to narrow results.
| Flag | Short | Description |
|---|---|---|
--branch <name> | -b | Filter by git branch |
--node-type <type> | -t | Filter by node type (goal, decision, action, etc.) |
--theme <name> | Filter by theme name |
42 goal active Add JWT authentication
43 option active jsonwebtoken crate + custom refresh logic
44 option active axum-jwt-auth with built-in rotation
45 decision active Use jsonwebtoken crate for full control
46 action active Implement JWT middleware + refresh endpoint
47 outcome completed JWT auth working -- 14 tests passing
Filtering by type
42 goal active Add JWT authentication
50 goal active Add rate limiting
58 goal active Database migration tooling
Filtering by branch
42 goal active Add JWT authentication
43 option active jsonwebtoken crate + custom refresh logic
45 decision active Use jsonwebtoken crate for full control
46 action active Implement JWT middleware + refresh endpoint
47 outcome completed JWT auth working -- 14 tests passing
Filtering by theme
55 observation active Redis adds 2ms latency per request
61 decision active Cache tokens in memory instead
deciduous edges
List all edges in the graph.
42 -> 43 leads_to "possible approach"
42 -> 44 leads_to "possible approach"
43 -> 45 chosen "more mature, full control"
44 -> 45 rejected "less control over rotation timing"
45 -> 46 leads_to "implementing chosen approach"
46 -> 47 leads_to "implementation result"
deciduous graph
Export the full graph as JSON to stdout. Useful for scripting or piping to other tools.
$ deciduous graph | jq '.nodes | length'
47
Realistic Example: Full Decision Flow
Here is a complete example showing the canonical flow – goal, options, decision, action, outcome – with all connections:
$ deciduous add goal "Add rate limiting to API" -c 90 -p "We need rate limiting on all public endpoints"
Created node 1 (type: goal) [confidence: 90%] [branch: feature-ratelimit]
# 2. Explore options
$ deciduous add option "Token bucket in Redis" -c 80
Created node 2 (type: option) [confidence: 80%]
$ deciduous link 1 2 -r "possible approach"
Linked 1 -> 2 (leads_to)
$ deciduous add option "Sliding window in-memory" -c 75
Created node 3 (type: option) [confidence: 75%]
$ deciduous link 1 3 -r "simpler alternative"
Linked 1 -> 3 (leads_to)
# 3. Make a decision
$ deciduous add decision "Use token bucket in Redis for distributed limiting" -c 85
Created node 4 (type: decision) [confidence: 85%]
$ deciduous link 2 4 -t chosen -r "need distributed state across instances"
Linked 2 -> 4 (chosen)
$ deciduous link 3 4 -t rejected -r "won't work with multiple app servers"
Linked 3 -> 4 (rejected)
# 4. Implement
$ deciduous add action "Implement Redis rate limiter middleware" -c 85 --commit HEAD -f "src/middleware/ratelimit.rs"
Created node 5 (type: action) [confidence: 85%] [commit: f4e5d6a]
$ deciduous link 4 5 -r "implementing chosen approach"
Linked 4 -> 5 (leads_to)
# 5. Record outcome
$ deciduous add outcome "Rate limiting deployed -- 8 tests passing" -c 95
Created node 6 (type: outcome) [confidence: 95%]
$ deciduous link 5 6 -r "implementation result"
Linked 5 -> 6 (leads_to)
$ deciduous status 6 completed
Updated node 6 status: active -> completed
Visualization & Export
Commands for generating DOT graphs, PR writeups, and exporting your decision graph for GitHub Pages.
deciduous dot
Export the graph as DOT format for Graphviz visualization.
| Flag | Short | Description |
|---|---|---|
--output <file> | -o | Output file (default: stdout) |
--roots <ids> | -r | Root node IDs (comma-separated, traverses children) |
--nodes <spec> | -n | Node IDs or ranges (e.g., 1-11 or 1,3,5-10) |
--png | Generate PNG using graphviz (requires dot command) | |
--auto | Auto-generate branch-specific filename in docs/ | |
--title <text> | -t | Graph title |
--rankdir <dir> | Graph direction: TB (top-bottom) or LR (left-right). Default: TB |
Basic DOT export
$ deciduous dot -o graph.dot
Generate PNG directly
Requires Graphviz installed (brew install graphviz / apt install graphviz).
Wrote DOT to docs/graph.dot
Generated PNG: docs/graph.png
Filter by node range
Wrote DOT to docs/auth-flow.dot (11 nodes)
Generated PNG: docs/auth-flow.png
$ deciduous dot -r 42 --rankdir LR -t "Auth Decision Tree"
# Outputs DOT to stdout, rooted at node 42, left-to-right layout
Auto-naming for PRs
The --auto flag generates branch-specific filenames (e.g., docs/decision-graph-feature-auth.dot), which prevents merge conflicts when multiple PRs each have their own graph.
Wrote DOT to docs/decision-graph-feature-auth.dot (15 nodes)
Generated PNG: docs/decision-graph-feature-auth.png
deciduous writeup
Generate a PR writeup from the decision graph. Includes a decision summary, the graph in DOT format, and a test plan section.
| Flag | Short | Description |
|---|---|---|
--title <text> | -t | PR title |
--roots <ids> | -r | Root node IDs (comma-separated, traverses children) |
--nodes <spec> | -n | Node IDs or ranges (e.g., 1-11 or 1,3,5-10) |
--output <file> | -o | Output file (default: stdout) |
--png <filename> | PNG filename to embed (auto-detects repo/branch for GitHub URL) | |
--auto | Auto-detect PNG from branch name | |
--no-dot | Skip DOT graph section | |
--no-test-plan | Skip test plan section |
Basic writeup
Wrote PR writeup to PR.md (6 nodes)
Auto-detect PNG for embedding
When you have already generated a PNG with deciduous dot --auto --png, use --auto on writeup to find and embed it:
# Outputs markdown to stdout with embedded graph image
Update a PR body directly
https://github.com/owner/repo/pull/42
deciduous sync
Export graph data to JSON files for GitHub Pages deployment. Creates the files needed for a static version of the web viewer.
| Flag | Short | Description |
|---|---|---|
--output <path> | -o | Output path (default: .deciduous/web/graph-data.json) |
Exported graph to docs/graph-data.json (47 nodes, 52 edges)
Exported git history to docs/git-history.json
Copied viewer to docs/index.html
Ready for GitHub Pages deployment from /docs
The PR Workflow
The recommended workflow for including decision graphs in pull requests:
$ deciduous dot --auto --nodes 1-11 --png
Wrote DOT to docs/decision-graph-feature-auth.dot (11 nodes)
Generated PNG: docs/decision-graph-feature-auth.png
# 2. Commit and push
$ git add docs/decision-graph-feature-auth.dot docs/decision-graph-feature-auth.png
$ git commit -m "docs: add decision graph"
$ git push
# 3. Generate writeup with auto PNG detection
$ deciduous writeup --auto -t "Add Auth" --nodes 1-11
# 4. Update PR body
$ gh pr edit 42 --body "$(deciduous writeup --auto -t 'Add Auth' --nodes 1-11)"
https://github.com/owner/repo/pull/42
GitHub Pages Deployment
To make your decision graph publicly viewable:
- Run
deciduous syncto export - Push the
docs/folder to GitHub - Go to Settings > Pages > Deploy from branch > select
/docsfolder - Your graph will be live at
https://<user>.github.io/<repo>/
Multi-User Sync
Commands for synchronizing decision graphs across multiple users. Uses an append-only event log model – each user emits events to their own JSONL file, and git handles merging.
How Event-Based Sync Works
The problem: each user has a local .deciduous/deciduous.db (gitignored). How do you share decisions?
The solution: an append-only event log.
- Every
add,link, orstatuscommand emits an event to.deciduous/sync/events/<user>.jsonl - Event files are git-tracked, so
git pullbrings in teammate events deciduous events rebuildreplays all events to reconstruct the database- Checkpoints capture full state snapshots to avoid replaying the entire history
Each node has two IDs:
id(integer) – local database primary key, different per machinechange_id(UUID) – globally unique, stable across all databases
deciduous events init
Initialize event-based sync in the repository. Creates the .deciduous/sync/ directory structure and configures gitignore to track sync files while ignoring the local database.
Created .deciduous/sync/events/
Created .deciduous/sync/checkpoints/
Updated .gitignore
Event-based sync initialized
deciduous events status
Show sync status – pending events, last checkpoint, and whether a rebuild is needed.
Sync status:
Event files: 2 (alice.jsonl, bob.jsonl)
Total events: 47
Last checkpoint: 2025-05-08 10:30:00 (24 nodes)
Pending events: 12 (since checkpoint)
Local DB nodes: 36
Status: rebuild recommended (new teammate events found)
deciduous events rebuild
Rebuild the local database from event logs and the latest checkpoint. Loads the checkpoint (if one exists), then replays all events after the checkpoint timestamp.
| Flag | Description |
|---|---|
--dry-run | Show what would be done without modifying the database |
Would load checkpoint: 2025-05-08 10:30:00 (24 nodes, 28 edges)
Would replay 12 events from 2 users:
alice.jsonl: 7 events
bob.jsonl: 5 events
Result: 36 nodes, 41 edges
$ deciduous events rebuild
Loaded checkpoint: 24 nodes, 28 edges
Replayed 12 events
Database rebuilt: 36 nodes, 41 edges
deciduous events checkpoint
Create a checkpoint snapshot of the current graph state. Checkpoints allow future rebuilds to skip replaying old events.
| Flag | Description |
|---|---|
--clear-events | Clear event logs after creating the checkpoint |
Created checkpoint: 36 nodes, 41 edges
Saved to .deciduous/sync/checkpoints/2025-05-09T143022.json
$ deciduous events checkpoint --clear-events
Created checkpoint: 36 nodes, 41 edges
Cleared 47 events from 2 event files
Checkpoint created and events cleared
deciduous events emit <node_id>
Emit an event for a specific node. Primarily for testing or manual sync scenarios.
Emitted event for node 42 to .deciduous/sync/events/alice.jsonl
deciduous migrate
Add change_id columns to the database for multi-user sync support. Run this once on existing databases before using the events system.
Added change_id column to nodes table
Added change_id column to edges table
Generated UUIDs for 36 existing nodes
Generated UUIDs for 41 existing edges
Migration complete
Typical Team Workflow
$ deciduous events init
$ deciduous migrate
# Daily workflow: pull teammate events and rebuild
$ git pull
$ deciduous events rebuild
# Work normally -- events auto-emit on add/link/status
$ deciduous add goal "New feature" -c 90
Created node 37 (type: goal) [confidence: 90%]
# Push your events for teammates
$ git add .deciduous/sync/events/alice.jsonl
$ git commit -m "sync: decision graph events"
$ git push
# Periodically compact old events
$ deciduous events checkpoint --clear-events
AI Integration
Commands for connecting deciduous to AI assistants – MCP server, Claude Code hooks, and shell completions.
deciduous mcp
MCP (Model Context Protocol) server and setup. Running deciduous mcp with no subcommand starts the server (backward-compatible with deciduous mcp serve).
deciduous mcp serve
Start the MCP server on stdin/stdout. Exposes the full deciduous API as MCP tools for AI assistants.
# Server starts on stdin/stdout (no visible output -- communicates via JSON-RPC)
Configure in your MCP client:
{"command": "deciduous", "args": ["mcp", "serve"]}
deciduous mcp setup
Set up MCP configuration for Claude Code or Claude Desktop.
Subcommands:
deciduous mcp setup claude-code– Configure MCP for Claude Code (writes.claude/settings.local.json)deciduous mcp setup claude-desktop– Configure MCP for Claude Desktop (platform-specific config file)
| Flag | Description |
|---|---|
--print | Print the config JSON to stdout without writing anything |
Updated .claude/settings.local.json with MCP server config
MCP configured for Claude Code
$ deciduous mcp setup claude-desktop --print
{
"mcpServers": {
"deciduous": {
"command": "deciduous",
"args": ["mcp", "serve"]
}
}
}
deciduous hooks
Manage Claude Code hooks – pre-edit blocks, post-commit reminders, and other automation configured in .deciduous/config.toml.
deciduous hooks install
Install Claude Code hooks from config. Generates shell scripts in .claude/hooks/ and updates settings.json.
Created .claude/hooks/pre-edit.sh
Created .claude/hooks/post-commit.sh
Updated .claude/settings.json
Hooks installed
deciduous hooks status
Show status of configured and installed hooks.
Hooks:
pre-edit installed .claude/hooks/pre-edit.sh
post-commit installed .claude/hooks/post-commit.sh
deciduous hooks uninstall
Remove hooks and clear hook configuration from settings.
Removed .claude/hooks/
Cleared hooks from .claude/settings.json
Hooks uninstalled
deciduous integration
Show Claude Code integration status – which hooks, commands, and skills are installed and active.
Claude Code Integration Status
==============================
Commands:
/decision .claude/commands/decision.md
/recover .claude/commands/recover.md
/work .claude/commands/work.md
/build-test .claude/commands/build-test.md
/serve-ui .claude/commands/serve-ui.md
/sync-graph .claude/commands/sync-graph.md
/decision-graph .claude/commands/decision-graph.md
/sync .claude/commands/sync.md
/document .claude/commands/document.md
Skills:
/pulse .claude/skills/pulse.md
/narratives .claude/skills/narratives.md
/archaeology .claude/skills/archaeology.md
Hooks:
pre-edit .claude/hooks/pre-edit.sh
post-commit .claude/hooks/post-commit.sh
CLAUDE.md: present
Database: .deciduous/deciduous.db
Version: 0.15.0
deciduous completion <shell>
Generate shell completions for tab completion of commands and flags.
Supported shells: bash, zsh, fish, powershell, elvish
$ deciduous completion zsh > ~/.zfunc/_deciduous
# Bash (add to ~/.bashrc)
$ deciduous completion bash > /etc/bash_completion.d/deciduous
# Fish
$ deciduous completion fish > ~/.config/fish/completions/deciduous.fish
Advanced
Graph health, archaeology, narratives, roadmap management, document attachments, and theming.
deciduous audit
Audit and maintain graph data quality. Can associate git commits with nodes by matching titles to commit messages.
| Flag | Description |
|---|---|
--associate-commits | Associate commits with nodes by matching titles to commit messages |
--min-score <0-100> | Minimum keyword match score (default: 50) |
--dry-run | Show what would be done without modifying database |
--yes | Auto-apply without confirmation |
Scanning git log for commit matches...
Node 5 "Implement JWT middleware" -> commit a1b2c3d "feat: add JWT middleware" (score: 85)
Node 8 "Add rate limiter" -> commit f4e5d6a "feat: add redis rate limiter" (score: 72)
Node 12 "Fix token refresh" -> commit 9c8d7e6 "fix: token refresh race condition" (score: 68)
3 matches found (dry run, no changes made)
$ deciduous audit --associate-commits --min-score 70 --yes
Associated node 5 with commit a1b2c3d (score: 85)
Associated node 8 with commit f4e5d6a (score: 72)
2 commits associated
deciduous pulse
Show the pulse of the decision graph – active state, gaps, and health. A quick overview of where things stand.
| Flag | Short | Description |
|---|---|---|
--branch <name> | -b | Filter by git branch |
--recent <n> | -r | Number of recent nodes to show (default: 10) |
--json | Output as JSON | |
--summary | Show only the summary section |
Decision Graph Pulse
====================
Summary:
Total nodes: 47
Active goals: 3
Open actions: 5
Completed: 12
Superseded: 2
Health:
Orphan nodes: 0
Unlinked actions: 2 (nodes 38, 41)
Dangling outcomes: 0
Recent (last 10):
47 outcome completed JWT auth working -- 14 tests passing
46 action active Implement JWT middleware + refresh endpoint
45 decision active Use jsonwebtoken crate for full control
44 option active axum-jwt-auth with built-in rotation
43 option active jsonwebtoken crate + custom refresh logic
42 goal active Add JWT authentication
...
Summary only:
Summary (branch: feature-auth):
Total nodes: 6 | Active goals: 1 | Completed: 1
deciduous narratives
Manage evolution narratives in .deciduous/narratives.md. Narratives capture how the system evolved over time – the story behind the decisions.
deciduous narratives init
Initialize narratives.md with active goal titles as section headings.
| Flag | Short | Description |
|---|---|---|
--output <path> | -o | Output path (default: .deciduous/narratives.md) |
--force | Overwrite existing file |
Created .deciduous/narratives.md with 3 goal sections:
- Add JWT authentication
- Add rate limiting
- Database migration tooling
deciduous narratives show
Display the contents of narratives.md.
| Flag | Short | Description |
|---|---|---|
--path <path> | -p | Path to narratives.md (default: .deciduous/narratives.md) |
# Evolution Narratives
## Add JWT authentication
Started with session-based auth, pivoted to JWT when mobile
clients needed stateless tokens. Chose jsonwebtoken crate over
axum-jwt-auth for more control over refresh rotation timing.
## Add rate limiting
(narrative pending)
deciduous narratives pivots
List all pivot points (revisit nodes) with their full chains – showing what changed and why.
| Flag | Short | Description |
|---|---|---|
--branch <name> | -b | Filter by git branch |
--json | Output as JSON |
Pivot 1:
Revisit node 30: "Reconsidering session-based auth"
Triggered by: observation 29 "Mobile clients can't maintain sessions"
Old approach: decision 15 "Use server-side sessions" (superseded)
New approach: decision 31 "Switch to JWT tokens"
deciduous archaeology
Retroactive graph building – atomic operations for common archaeology patterns. Useful when reconstructing decision history from an existing codebase.
deciduous archaeology pivot <from_id> <observation> <new_approach>
Create a full pivot chain atomically (replaces 7 manual commands). Creates: observation -> revisit -> new decision, and marks the old node as superseded.
| Flag | Short | Description |
|---|---|---|
--confidence <0-100> | -c | Confidence for the new decision |
--reason <text> | -r | Rationale for why the old approach failed |
--dry-run | Show what would be created without modifying database |
Created observation 29: "Mobile clients can't maintain sessions"
Created revisit 30: "Reconsidering node 15"
Created decision 31: "Switch to JWT tokens" [confidence: 85%]
Linked 15 -> 29 (leads_to)
Linked 29 -> 30 (leads_to)
Linked 30 -> 31 (leads_to)
Marked node 15 as superseded
Pivot chain created (3 nodes, 3 edges)
deciduous archaeology timeline
Show all nodes sorted chronologically.
| Flag | Short | Description |
|---|---|---|
--limit <n> | -l | Number of most recent nodes (0 = all, default: 0) |
--node-type <type> | -t | Filter by node type |
--branch <name> | -b | Filter by git branch |
--json | Output as JSON |
2025-05-09 14:25:01 47 outcome JWT auth working -- 14 tests passing
2025-05-09 14:22:30 46 action Implement JWT middleware + refresh endpoint
2025-05-09 14:21:02 45 decision Use jsonwebtoken crate for full control
2025-05-09 14:20:15 43 option jsonwebtoken crate + custom refresh logic
2025-05-09 14:20:01 42 goal Add JWT authentication
$ deciduous archaeology timeline -t decision -b feature-auth
2025-05-09 14:21:02 45 decision Use jsonwebtoken crate for full control
2025-05-07 09:15:00 31 decision Switch to JWT tokens
deciduous archaeology supersede <id>
Mark a node as superseded, optionally cascading to all descendant nodes.
| Flag | Description |
|---|---|
--cascade | Also mark all descendant nodes as superseded |
--dry-run | Show what would be changed without modifying database |
Would mark as superseded:
15 decision Use server-side sessions
16 action Implement session store
17 outcome Session auth working
3 nodes would be affected
$ deciduous archaeology supersede 15 --cascade
Marked 3 nodes as superseded
deciduous roadmap
Manage ROADMAP.md sync with GitHub Issues. Parse your roadmap file, sync items to GitHub Issues, and track completion.
deciduous roadmap init
Initialize roadmap sync – parses ROADMAP.md and adds metadata.
| Flag | Short | Description |
|---|---|---|
--path <file> | -p | Path to ROADMAP.md (default: ROADMAP.md) |
Parsed ROADMAP.md: 3 sections, 12 items
Roadmap initialized
deciduous roadmap refresh
Re-parse ROADMAP.md, preserving existing decision graph links.
| Flag | Short | Description |
|---|---|---|
--path <file> | -p | Path to ROADMAP.md (default: ROADMAP.md) |
deciduous roadmap sync
Sync ROADMAP.md with GitHub Issues. Dry-run by default – use --execute to apply.
| Flag | Short | Description |
|---|---|---|
--path <file> | -p | Path to ROADMAP.md (default: ROADMAP.md) |
--repo <owner/repo> | -r | GitHub repo (auto-detected from git remote) |
--execute | Actually apply changes (default is dry-run) | |
--create-issues | Create GitHub issues for new sections (default: true) |
Dry-run mode (use --execute to apply)
Would create issue: "Add JWT authentication"
Would create issue: "Add rate limiting"
Would update issue #5: "Database migration tooling"
$ deciduous roadmap sync --execute
Created issue #8: "Add JWT authentication"
Created issue #9: "Add rate limiting"
Updated issue #5: "Database migration tooling"
Synced 3 items
deciduous roadmap list
List roadmap items with status.
| Flag | Short | Description |
|---|---|---|
--path <file> | -p | Path to ROADMAP.md (default: ROADMAP.md) |
--section <name> | -s | Filter by section name |
--with-issues | Show only items with GitHub issues | |
--without-issues | Show only items without GitHub issues |
Core:
[x] Add JWT authentication issue #8 outcome #47
[ ] Add rate limiting issue #9
[ ] Database migration tooling issue #5
Infrastructure:
[x] CI/CD pipeline issue #3 outcome #22
[ ] Monitoring and alerting
deciduous roadmap link <item> <outcome_id>
Link a roadmap item to a decision graph outcome node. <item> is a change_id or title (partial match).
deciduous roadmap unlink <item>
Remove outcome link from a roadmap item.
deciduous roadmap conflicts
Show sync conflicts.
| Flag | Description |
|---|---|
--resolve | Resolve conflicts interactively |
deciduous roadmap status
Show sync status summary.
| Flag | Short | Description |
|---|---|---|
--path <file> | -p | Path to ROADMAP.md (default: ROADMAP.md) |
deciduous roadmap check
Audit completion status of roadmap items.
| Flag | Short | Description |
|---|---|---|
--path <file> | -p | Path to ROADMAP.md (default: ROADMAP.md) |
--incomplete | Show only incomplete items | |
--complete | Show only complete items |
deciduous doc
Manage document attachments on decision nodes. Attach images, PDFs, diagrams, specs, and other files to nodes for rich context.
deciduous doc attach <node_id> <file>
Attach a file to a decision graph node. Files are stored in .deciduous/documents/ with content-hash naming for deduplication.
| Flag | Short | Description |
|---|---|---|
--description <text> | -d | Manual description |
--ai-describe | Generate AI description using claude CLI |
Attached document 1 to node 42
File: architecture.png
Stored: .deciduous/documents/a1b2c3d4e5f6.png
$ deciduous doc attach 42 spec.pdf --ai-describe
Attached document 2 to node 42
File: spec.pdf
Description: API authentication specification covering JWT token format, refresh rotation policy, and OAuth2 flow diagrams
deciduous doc list [node_id]
List documents. Omit node_id to list all documents.
| Flag | Description |
|---|---|
--include-detached | Show soft-deleted documents too |
--json | Output as JSON |
Documents for node 42 "Add JWT authentication":
1 architecture.png "Auth system architecture diagram"
2 spec.pdf "API authentication specification..."
$ deciduous doc list
All documents:
1 node 42 architecture.png "Auth system architecture diagram"
2 node 42 spec.pdf "API authentication specification..."
3 node 50 rate-limit.md "Rate limiting design notes"
deciduous doc show <doc_id>
Show details of a specific document.
| Flag | Description |
|---|---|
--json | Output as JSON |
Document 1:
Node: 42 "Add JWT authentication"
Original: architecture.png
Stored at: .deciduous/documents/a1b2c3d4e5f6.png
Description: Auth system architecture diagram
Attached: 2025-05-09 14:30:00
Status: active
deciduous doc describe <doc_id> [text]
Set or update the description of a document. Omit text to read from stdin.
| Flag | Description |
|---|---|
--ai | Generate AI description using claude CLI |
Updated description for document 1
$ deciduous doc describe 2 --ai
Generated description: "API authentication specification covering JWT token format, refresh rotation policy, and OAuth2 flow diagrams for Google and GitHub providers"
deciduous doc open <doc_id>
Open the attached file in the default application.
Opening .deciduous/documents/a1b2c3d4e5f6.png...
deciduous doc detach <doc_id>
Soft-delete (detach) a document from its node. The file remains on disk until garbage collected.
Detached document 2 from node 42
deciduous doc gc
Garbage-collect orphaned files from disk – files that no active document records reference.
| Flag | Description |
|---|---|
--dry-run | Show what would be deleted without deleting |
Would remove 1 orphaned file (340 KB):
.deciduous/documents/b2c3d4e5f6a7.pdf
$ deciduous doc gc
Removed 1 orphaned file (340 KB)
deciduous themes
Manage theme definitions for organizing nodes by cross-cutting concerns (e.g., “performance”, “security”, “tech-debt”).
deciduous themes create <name>
Create a new theme.
| Flag | Short | Description |
|---|---|---|
--color <hex> | -c | Hex color code (default: #6b7280) |
--description <text> | -d | Theme description |
Created theme "performance" (#ef4444)
$ deciduous themes create security -c "#3b82f6" -d "Security considerations"
Created theme "security" (#3b82f6)
deciduous themes list
List all themes.
performance #ef4444 Performance-related decisions and observations (3 nodes)
security #3b82f6 Security considerations (5 nodes)
tech-debt #6b7280 Technical debt items (2 nodes)
deciduous themes delete <name>
Delete a theme and remove all node associations.
Deleted theme "tech-debt" and removed 2 node associations
deciduous tag
Tag or untag nodes with themes.
deciduous tag add <node_id> <theme>
Add a theme to a node.
Tagged node 55 with "performance"
$ deciduous tag add 42 security
Tagged node 42 with "security"
deciduous tag remove <node_id> <theme>
Remove a theme from a node.
Removed "performance" from node 55
deciduous tag list <node_id>
List themes for a node.
Themes for node 42 "Add JWT authentication":
security #3b82f6 (manual)
performance #ef4444 (suggested)
deciduous tag suggest [node_id]
Auto-suggest themes for a node based on keyword matching. Omit node_id to suggest for all untagged nodes.
| Flag | Description |
|---|---|
--apply | Apply suggestions without confirmation |
Suggested themes for node 55 "Redis adds 2ms latency per request":
performance (keyword match: "latency")
$ deciduous tag suggest --apply
Suggested and applied:
Node 55 -> performance (keyword: "latency")
Node 61 -> performance (keyword: "cache")
Node 42 -> security (keyword: "auth")
3 suggestions applied
deciduous tag confirm <node_id> <theme>
Confirm a suggested theme – changes it from “suggested” to “manual” status.
Confirmed "performance" on node 55 (suggested -> manual)
Claude Code
Claude Code is the default assistant integration. Running deciduous init with no flags sets up everything Claude Code needs to track decisions automatically.
Setup
Creating .deciduous/config.toml Creating .deciduous/.version (0.15.0) Creating .deciduous/deciduous.db Creating .claude/commands/decision.md Creating .claude/commands/recover.md Creating .claude/commands/work.md Creating .claude/commands/document.md Creating .claude/commands/build-test.md Creating .claude/commands/serve-ui.md Creating .claude/commands/sync-graph.md Creating .claude/commands/decision-graph.md Creating .claude/commands/sync.md Creating .claude/agents.toml Creating .claude/hooks/require-action-node.sh (executable) Creating .claude/hooks/post-commit-reminder.sh (executable) Creating .claude/hooks/version-check.sh (executable) Creating .claude/settings.json Creating .claude/skills/pulse.md Creating .claude/skills/narratives.md Creating .claude/skills/archaeology.md Creating CLAUDE.md Creating docs/index.html Creating docs/graph-data.json
Deciduous initialized for Claude Code!
What Gets Created
Slash Commands
These appear in Claude Code as /command-name and are stored in .claude/commands/:
| Command | Purpose |
|---|---|
/decision | Manage decision graph – add nodes, link edges, sync |
/recover | Recover context from decision graph on session start |
/work | Start a work transaction – creates goal node before implementation |
/document | Generate comprehensive documentation for a file or directory |
/build-test | Build the project and run the test suite |
/serve-ui | Start the decision graph web viewer |
/sync-graph | Export decision graph to GitHub Pages |
/decision-graph | Build a decision graph from commit history |
/sync | Multi-user sync – pull events, rebuild, push |
Skills
Skills are higher-level workflows stored in .claude/skills/:
| Skill | Purpose |
|---|---|
/pulse | Map current design as decisions (Now mode) |
/narratives | Understand how the system evolved (History mode) |
/archaeology | Transform narratives into queryable graph |
Hooks
Enforcement hooks in .claude/hooks/ run automatically to keep the decision graph consistent:
- require-action-node.sh – Blocks file edits unless an action node exists in the graph. Prevents coding without logging what you are about to do.
- post-commit-reminder.sh – After every git commit, reminds Claude to link the commit to the decision graph with
--commit HEAD. - version-check.sh – Checks whether integration files are out of date and suggests running
deciduous update.
Hook configuration lives in .claude/settings.json.
Other Files
.claude/agents.toml– Subagent configurations for scoping work to specific parts of the codebase (rust-core, web, tooling, docs, ci).CLAUDE.md– A “Decision Graph Workflow” section is appended to your project’s CLAUDE.md (or created if it does not exist). This section teaches Claude the node flow rule, behavioral triggers, and connection patterns. Your existing CLAUDE.md content is preserved.
MCP Server
The MCP server gives Claude direct tool access to the decision graph instead of shelling out to the CLI. Add the following to .claude/settings.local.json:
{
"mcpServers": {
"deciduous": {
"command": "deciduous",
"args": ["mcp"]
}
}
}
This exposes 31 tools organized into five groups:
| Group | Tools | Purpose |
|---|---|---|
| Graph | add_node, add_edge, update_status, … | Core graph operations |
| Query | list_nodes, list_edges, show_node, search_nodes, … | Read and search the graph |
| Documents | attach_document, list_documents, … | File attachments on nodes |
| Sessions | start_session, end_session, resume_session, … | Per-conversation decision trees |
| Export | export_dot, generate_writeup | DOT visualization and PR writeups |
Keeping Integration Files Current
When you upgrade deciduous, run deciduous update to refresh all integration files to the latest version. It overwrites slash commands, hooks, skills, and the CLAUDE.md section while preserving your custom content.
Updated .claude/commands/decision.md Updated .claude/commands/recover.md Updated .claude/commands/work.md Updated .claude/commands/document.md Updated .claude/commands/build-test.md Updated .claude/commands/serve-ui.md Updated .claude/commands/sync-graph.md Updated .claude/commands/decision-graph.md Updated .claude/commands/sync.md Updated .claude/hooks/require-action-node.sh (executable) Updated .claude/hooks/post-commit-reminder.sh (executable) Updated .claude/hooks/version-check.sh (executable) Updated .claude/agents.toml Updated .claude/skills/pulse.md Updated .claude/skills/narratives.md Updated .claude/skills/archaeology.md Updated CLAUDE.md (section replaced) Updated .deciduous/.version (0.15.0)
Tooling updated for Claude Code!
To check whether an update is needed without applying it:
deciduous check-update
The version-check.sh hook runs this automatically at the start of each Claude Code session (checked every 24 hours). If your integration files are out of date, Claude will suggest running deciduous update.
Using Slash Commands
Once initialized, start a Claude Code session and use slash commands directly: