Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

goaloptionsdecisionactionsoutcomes
  • 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:

Claude Code — working on auth
You
Add JWT authentication with refresh token rotation
Claude
$ deciduous add goal "Add JWT auth with refresh token rotation" -c 90
Created node 42 (type: goal) [confidence: 90%] [branch: feature-auth]
Claude
$ deciduous add option "jsonwebtoken crate + custom refresh logic" -c 80
Created node 43 (type: option) [confidence: 80%] [branch: feature-auth]
$ deciduous add option "axum-jwt-auth with built-in rotation" -c 75
Created node 44 (type: option) [confidence: 75%] [branch: feature-auth]
$ deciduous link 42 43 -r "possible approach"
$ deciduous link 42 44 -r "possible approach"
Claude
I'll go with jsonwebtoken — it's more mature and gives us full control over the rotation logic.
$ deciduous add decision "Use jsonwebtoken crate for full control" -c 85
Created node 45 (type: decision) [confidence: 85%] [branch: feature-auth]
$ deciduous link 43 45 -r "chosen"
$ deciduous link 44 45 -r "rejected — less control over rotation timing"
Claude
$ deciduous add action "Implement JWT middleware + refresh endpoint" -c 85
Created node 46 (type: action) [confidence: 85%] [branch: feature-auth]
$ deciduous link 45 46 -r "implementing chosen approach"
Writing src/auth/jwt.rs and src/auth/refresh.rs...
Claude
$ deciduous add outcome "JWT auth working — 14 tests passing" -c 95
Created node 47 (type: outcome) [confidence: 95%] [branch: feature-auth]
$ deciduous link 46 47 -r "implementation result"

Three days later, a new session starts. Context is gone. You type /recover:

Claude Code — new session, /recover
You
/recover
Claude
$ deciduous nodes
6 nodes: ID TYPE STATUS TITLE 42 goal pending Add JWT auth with refresh token rotation 43 option pending jsonwebtoken crate + custom refresh logic 44 option pending axum-jwt-auth with built-in rotation 45 decision pending Use jsonwebtoken crate for full control 46 action pending Implement JWT middleware + refresh endpoint 47 outcome pending JWT auth working — 14 tests passing
Claude
$ deciduous edges
42 ─[possible approach]→ 43 42 ─[possible approach]→ 44 43 ─[chosen]→ 45 44 ─[rejected]→ 45 45 ─[implementing chosen approach]→ 46 46 ─[implementation result]→ 47
Claude
$ git status
On branch feature-auth nothing to commit, working tree clean
Claude
Recovered context from the decision graph. Here's where we left off:

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

brew tap notactuallytreyanastasio/tap
brew install deciduous

Pre-built Binaries

Download the latest release from GitHub Releases:

PlatformBinary
Linux (x86_64)deciduous-linux-amd64
Linux (ARM64)deciduous-linux-arm64
macOS (Intel)deciduous-darwin-amd64
macOS (Apple Silicon)deciduous-darwin-arm64
Windowsdeciduous-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

Terminal
$ deciduous --version
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.

Terminal
$ cd ~/projects/my-api
$ deciduous init
Initialized deciduous in /Users/dev/projects/my-api/.deciduous/ Created .claude/commands/decision.md Created .claude/commands/recover.md Created .claude/commands/work.md Created CLAUDE.md with decision graph workflow

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:

goaloptionsdecisionactionsoutcomes
  • 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:

Claude Code — adding rate limiting
You
Add API rate limiting. We need per-user limits with a sliding window, and different tiers for free vs paid users.
Claude
I'll track this work in the decision graph. Let me start with the goal and explore our options.
$ deciduous add goal "Add per-user API rate limiting with tiered limits" -c 90
Created node 1 (type: goal, title: Add per-user API rate limiting with tiered limits) [confidence: 90%] [branch: main]
Claude
There are a few approaches we could take for sliding window rate limiting:
$ deciduous add option "Redis-backed sliding window with sorted sets" -c 80
Created node 2 (type: option, title: Redis-backed sliding window with sorted sets) [confidence: 80%] [branch: main]
$ deciduous add option "In-memory token bucket with governor crate" -c 75
Created node 3 (type: option, title: In-memory token bucket with governor crate) [confidence: 75%] [branch: main]
$ deciduous link 1 2 -r "possible approach"
$ deciduous link 1 3 -r "possible approach"
Claude
Redis gives us distributed rate limiting across multiple instances and persistence across restarts. The governor crate is simpler but only works per-process. Since we're deploying to multiple pods, Redis is the better fit.
$ deciduous add decision "Use Redis sliding window — need distributed limiting across pods" -c 85
Created node 4 (type: decision, title: Use Redis sliding window — need distributed limiting across pods) [confidence: 85%] [branch: main]
$ deciduous link 2 4 -r "chosen — distributed across pods"
$ deciduous link 3 4 -r "rejected — single-process only"
Claude
$ deciduous add action "Implement Redis rate limiter middleware with tier config" -c 85
Created node 5 (type: action, title: Implement Redis rate limiter middleware with tier config) [confidence: 85%] [branch: main]
$ deciduous link 4 5 -r "implementing chosen approach"
Writing src/middleware/rate_limit.rs and src/config/tiers.rs...
Claude
$ deciduous add outcome "Rate limiting working — 8 tests passing, free=100/hr paid=1000/hr" -c 95
Created node 6 (type: outcome, title: Rate limiting working — 8 tests passing, free=100/hr paid=1000/hr) [confidence: 95%] [branch: main]
$ deciduous link 5 6 -r "implementation result"

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:

Terminal
$ deciduous serve
Serving decision graph at http://localhost:3000 Auto-refresh every 30s

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:

Terminal — inspecting the graph
$ deciduous nodes
ID Type Status Conf Title ──────────────────────────────────────────────────────────────── 1 goal active 90% Add per-user API rate limiting with tiered limits 2 option active 80% Redis-backed sliding window with sorted sets 3 option active 75% In-memory token bucket with governor crate 4 decision active 85% Use Redis sliding window — need distributed limiting across pods 5 action active 85% Implement Redis rate limiter middleware with tier config 6 outcome active 95% Rate limiting working — 8 tests passing, free=100/hr paid=1000/hr
$ deciduous edges
From To Reason ────────────────────────────────────────────────────── 1 2 possible approach 1 3 possible approach 2 4 chosen — distributed across pods 3 4 rejected — single-process only 4 5 implementing chosen approach 5 6 implementation result

What You’ve Built

In under two minutes, you have:

  1. A searchable record of what was decided and why
  2. Rejected alternatives preserved for future reference (node 3 – governor crate)
  3. Traceable reasoning from goal through to outcome
  4. 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:

  1. BEFORE you do something – log what you’re about to do
  2. AFTER it succeeds or fails – log the outcome
  3. 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:

TriggerNode TypeExample
User asks for a featuregoal“Add dark mode support”
Exploring approachesoption“CSS custom properties for theming”
Choosing an approachdecision“Use CSS custom properties over Tailwind dark:”
Writing or changing codeaction“Implement theme toggle component”
Something worked or failedoutcome“Dark mode working, 6 tests passing”
A technical findingobservation“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.

Claude Code — adding file upload support
You
Add file upload support to the API. Users should be able to upload images up to 10MB, and we need to generate thumbnails.
Claude
$ deciduous add goal "Add file upload with 10MB image limit and thumbnail generation" -c 90
Created node 10 (type: goal, title: Add file upload with 10MB image limit and thumbnail generation) [confidence: 90%] [branch: feature-uploads]
Claude
Let me explore the options for image processing and storage:
$ deciduous add option "ImageMagick via std::process::Command for thumbnails" -c 70
Created node 11 (type: option, title: ImageMagick via std::process::Command for thumbnails) [confidence: 70%] [branch: feature-uploads]
$ deciduous add option "image crate (pure Rust) for thumbnails" -c 80
Created node 12 (type: option, title: image crate (pure Rust) for thumbnails) [confidence: 80%] [branch: feature-uploads]
$ deciduous link 10 11 -r "possible approach"
$ deciduous link 10 12 -r "possible approach"
Claude
The image crate keeps everything in-process with no external dependency. Let's go with that.
$ deciduous add decision "Use image crate — no external dependencies, pure Rust" -c 85
Created node 13 (type: decision, title: Use image crate — no external dependencies, pure Rust) [confidence: 85%] [branch: feature-uploads]
$ deciduous link 12 13 -r "chosen — no external deps"
$ deciduous link 11 13 -r "rejected — requires ImageMagick installed"
Claude
$ deciduous add action "Implement upload endpoint with image crate thumbnails" -c 80
Created node 14 (type: action, title: Implement upload endpoint with image crate thumbnails) [confidence: 80%] [branch: feature-uploads]
$ deciduous link 13 14 -r "implementing chosen approach"
Writing src/handlers/upload.rs and src/services/thumbnail.rs...

So far, a straightforward flow: goal, options, decision, action. But then the first approach hits a wall:

Claude Code — the approach fails
Claude
$ deciduous add outcome "image crate too slow — 4.2s per thumbnail at 10MB, blocks request" -c 40
Created node 15 (type: outcome, title: image crate too slow — 4.2s per thumbnail at 10MB, blocks request) [confidence: 40%] [branch: feature-uploads]
$ deciduous link 14 15 -r "implementation result — failed"
Claude
The image crate is too slow for synchronous thumbnail generation at this file size. We need to reconsider.
$ deciduous add observation "image crate resizing is single-threaded, no SIMD optimization" -c 90
Created node 16 (type: observation, title: image crate resizing is single-threaded, no SIMD optimization) [confidence: 90%] [branch: feature-uploads]
$ deciduous link 15 16 -r "root cause"

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.

Claude Code — pivoting to a new approach
Claude
$ deciduous add revisit "Reconsidering thumbnail strategy — sync processing too slow" -c 85
Created node 17 (type: revisit, title: Reconsidering thumbnail strategy — sync processing too slow) [confidence: 85%] [branch: feature-uploads]
$ deciduous link 16 17 -r "forced rethinking"
$ deciduous status 13 superseded
Updated node 13 status: active → superseded
Claude
New approach: accept the upload immediately, queue thumbnail generation as a background job using libvips which has SIMD support.
$ deciduous add option "Background job with libvips for fast thumbnail generation" -c 85
Created node 18 (type: option, title: Background job with libvips for fast thumbnail generation) [confidence: 85%] [branch: feature-uploads]
$ deciduous link 10 18 -r "new approach after revisit"
Claude
$ deciduous add decision "Use async job queue + libvips for thumbnail generation" -c 90
Created node 19 (type: decision, title: Use async job queue + libvips for thumbnail generation) [confidence: 90%] [branch: feature-uploads]
$ deciduous link 18 19 -r "chosen after performance failure of sync approach"
$ deciduous link 17 19 -r "new direction"
Claude
$ deciduous add action "Implement upload endpoint + background thumbnail worker" -c 85
Created node 20 (type: action, title: Implement upload endpoint + background thumbnail worker) [confidence: 85%] [branch: feature-uploads]
$ deciduous link 19 20 -r "implementing chosen approach"
Writing src/handlers/upload.rs, src/jobs/thumbnail.rs, src/services/vips.rs...
Claude
$ deciduous add outcome "Upload + async thumbnails working — 120ms upload, 380ms thumbnail job, 12 tests passing" -c 95
Created node 21 (type: outcome, title: Upload + async thumbnails working — 120ms upload, 380ms thumbnail job, 12 tests passing) [confidence: 95%] [branch: feature-uploads]
$ deciduous link 20 21 -r "implementation result"

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.

Claude Code — committing and linking
Claude
$ git add src/handlers/upload.rs src/jobs/thumbnail.rs src/services/vips.rs
Claude
$ git commit -m "feat: add file upload with async thumbnail generation"
[feature-uploads a3f9c12] feat: add file upload with async thumbnail generation 3 files changed, 247 insertions(+)
Claude
$ deciduous add action "Committed upload + thumbnail implementation" -c 95 --commit HEAD
Created node 22 (type: action, title: Committed upload + thumbnail implementation) [confidence: 95%] [branch: feature-uploads] [commit: a3f9c12]
$ deciduous link 20 22 -r "committed to git"

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:

Claude Code — new session, next day
Claude
Recovering context from the decision graph...
$ deciduous nodes
ID Type Status Conf Title ────────────────────────────────────────────────────────────────────── 10 goal active 90% Add file upload with 10MB image limit and thumbnail generation 11 option active 70% ImageMagick via std::process::Command for thumbnails 12 option active 80% image crate (pure Rust) for thumbnails 13 decision superseded 85% Use image crate — no external dependencies, pure Rust 14 action active 80% Implement upload endpoint with image crate thumbnails 15 outcome active 40% image crate too slow — 4.2s per thumbnail at 10MB, blocks request 16 observation active 90% image crate resizing is single-threaded, no SIMD optimization 17 revisit active 85% Reconsidering thumbnail strategy — sync processing too slow 18 option active 85% Background job with libvips for fast thumbnail generation 19 decision active 90% Use async job queue + libvips for thumbnail generation 20 action active 85% Implement upload endpoint + background thumbnail worker 21 outcome active 95% Upload + async thumbnails working — 120ms upload, 380ms thumbnail job 22 action active 95% Committed upload + thumbnail implementation
Claude
$ deciduous show 10
Node #10 goal ──────────────────────────────────────── Title: Add file upload with 10MB image limit and thumbnail generation Status: active Confidence: 90% Branch: feature-uploads

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

Claude
I can see the full history: we tried the image crate (node 13, now superseded), it was too slow at 4.2s per thumbnail (node 15), so we pivoted to async libvips (node 17 revisit, node 19 decision). The implementation is complete with 12 tests passing (node 21). Let me check if there's remaining work on this goal.

The deciduous edges command is also valuable for understanding the connections between nodes:

Terminal — checking edges
$ deciduous edges
From To Reason ────────────────────────────────────────────────────────────────── 10 11 possible approach 10 12 possible approach 10 18 new approach after revisit 12 13 chosen — no external deps 11 13 rejected — requires ImageMagick installed 13 14 implementing chosen approach 14 15 implementation result — failed 15 16 root cause 16 17 forced rethinking 18 19 chosen after performance failure of sync approach 17 19 new direction 19 20 implementing chosen approach 20 21 implementation result 20 22 committed to git

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…
optionIts parent goal
decisionThe option(s) it chose between
actionThe decision that spawned it
outcomeThe action that produced it
observationThe related goal, action, or outcome
revisitThe 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.

TypePurpose
goalHigh-level objective — what you are trying to achieve
optionA possible approach to explore for a goal
decisionChoosing which option to pursue
actionImplementation step — work being done
outcomeResult of an action — what happened
observationA discovery or insight — attaches anywhere relevant
revisitPivot 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 -d flag 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:

goaloptionsdecisionactionsoutcomes
  • 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.

TypeMeaningTypical usage
leads_toNatural progressiongoal → option, action → outcome
chosenOption was selectedoption → decision
rejectedOption was not selectedoption → decision (with reason)
requiresDependency relationshipaction → another action
blocksPrevents progressobservation → action
enablesMakes something possibleaction → outcome

Note: A supersedes edge type is auto-created by the revisit/archaeology system (e.g., deciduous archaeology pivot). It is not a valid parameter for deciduous link.

Node Status

Every node has a status that tracks its lifecycle.

StatusMeaning
pendingNot yet started
activeCurrent truth — how things work today
completedFinished successfully
rejectedConsidered and rejected
supersededReplaced by a newer approach
abandonedTried and rejected — dead end
Terminal
$ deciduous nodes --status active
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.

RangeMeaning
90-100High confidence — well-understood, clear requirement
70-89Moderate confidence — reasonable approach, some unknowns
50-69Low confidence — exploratory, uncertain
0-49Very 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:

  1. An observation identifies why the old approach failed
  2. A revisit node links to that observation
  3. The revisit leads to the new decision
  4. The old decision is marked superseded

This captures why you changed direction, not just what changed.

Terminal
$ deciduous add observation "JWT tokens too large for mobile clients" -c 90
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.

Terminal
$ deciduous add goal "Add user authentication" -c 90
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

FlagDescription
-c, --confidence <0-100>Confidence level for this node
-p, --prompt "..."Short user prompt that triggered this work
--prompt-stdinRead 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-branchSkip 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.

Terminal
$ deciduous add goal "Add rate limiting" -c 90 --prompt-stdin << 'EOF'
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:

Terminal
$ deciduous prompt 1 "The full verbatim user request goes here..."
Updated prompt for node 1

Linking Nodes

Create edges between nodes with deciduous link <from> <to>. Always link immediately after creating a node.

Terminal
$ deciduous link 1 2 -r "Possible approach"
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…
optionIts parent goal
decisionThe option(s) it chose between
actionThe decision that spawned it
outcomeThe action that produced it
observationThe related goal or action
revisitThe decision/outcome being reconsidered

Updating Status

Change a node’s status with deciduous status <id> <status>.

Terminal
$ deciduous status 3 completed
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.

Terminal
$ deciduous show 1
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

Terminal
$ deciduous nodes
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.

Terminal
$ deciduous unlink 5 12
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:

Terminal
Claude
$ deciduous add action "Implementing JWT middleware" -c 85
Created node 5 (type: action) [confidence: 85%] [branch: feature-auth]
Claude
Writing src/auth/jwt.rs and src/auth/refresh.rs...
Claude
$ git commit -m "feat: add JWT auth middleware"
Claude
$ deciduous add outcome "JWT auth working — 14 tests passing" -c 95 --commit HEAD
Created node 6 (type: outcome) [confidence: 95%] [commit: a1b2c3d] [branch: feature-auth]
$ deciduous link 5 6 -r "Implementation complete"
Linked 5 → 6 (leads_to) "Implementation complete"

The web viewer displays commit messages, authors, and dates for linked nodes.

The Core Pattern

The golden rule for working with nodes:

  1. Before you write code – log what you are about to do (action)
  2. After it works – log the result (outcome)
  3. 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.

Terminal
$ 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:

ViewPurpose
ChainsDecision chains grouped by session — the story of a feature
TimelineChronological view merged with git commits
GraphForce-directed interactive visualization
DAGHierarchical goal → decision → outcome flow
ArchaeologyNarrative-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).

Terminal
$ deciduous dot
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

FlagDescription
-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)
--pngGenerate PNG file (requires graphviz)
--autoUse 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.

Terminal
$ deciduous writeup -t "Add JWT Authentication" --nodes 1-11
## 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

FlagDescription
-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)
--autoAuto-detect PNG from branch-specific filename
--no-dotSkip DOT graph section
--no-test-planSkip test plan section
Terminal
$ deciduous dot --auto --nodes 1-11 --png
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.

Terminal
$ 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/:

FileContents
docs/graph-data.jsonDecision graph (nodes + edges)
docs/git-history.jsonCommit info for linked nodes

Deploying to GitHub Pages

  1. Run deciduous sync to export
  2. Commit and push the docs/ directory
  3. In GitHub Settings → Pages → Deploy from branch → select /docs folder

Your graph will be live at https://<user>.github.io/<repo>/.

Full JSON Export

For programmatic access, export the entire graph as JSON:

Terminal
$ deciduous graph > graph.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:

  1. Every add, link, and status command emits an event to your personal log
  2. Events are identified by change_id (UUID), not local integer IDs
  3. Rebuilding replays all events from all users, deduplicating by change_id
  4. Checkpoints snapshot the current state so old events can be cleared

Initializing Sync

Set up the sync directory with deciduous events init.

Terminal
$ 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.

Terminal
$ 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.

Terminal
$ git pull origin main
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:

Terminal
$ deciduous events rebuild --dry-run
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.

Terminal
$ deciduous events checkpoint
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:

Terminal
$ deciduous events emit 42
Emitted event for node 42 to alice.jsonl

PR Workflow for Sharing Decisions

The recommended team workflow:

Terminal — Alice's machine
Claude
Working on the auth feature, logging decisions as we go...
$ deciduous add goal "Add JWT auth" -c 90
Created node 1 (type: goal) [confidence: 90%]
$ deciduous add action "Implementing JWT middleware" -c 85
Created node 2 (type: action) [confidence: 85%]
Events auto-emitted to .deciduous/sync/events/alice.jsonl
Claude
$ git add .deciduous/sync/events/alice.jsonl
$ git commit -m "sync: auth feature decisions"
$ git push
Terminal — Bob's machine
$ git pull
.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:

IDScopePurpose
id (integer)Local databasePrimary key, different on each machine
change_id (UUID)GlobalStable 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.

Terminal
$ deciduous themes create auth blue -d "Authentication and authorization decisions"
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.

Terminal
$ 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.

Terminal
$ deciduous themes delete security
Deleted theme 'security'

Tagging Nodes

Apply themes to nodes with deciduous tag add. A node can have multiple themes.

Terminal
$ deciduous tag add 1 auth
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

Terminal
$ deciduous tag remove 5 security
Removed theme 'security' from node 5

Listing Tags on a Node

Terminal
$ deciduous tag list 5
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.

Terminal
$ deciduous tag suggest
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:

Terminal
$ deciduous tag suggest --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.

Terminal
$ deciduous tag confirm 1 auth
Confirmed theme 'auth' on node 1 (suggested → manual)

Filtering by Theme

Use the --theme flag on deciduous nodes to filter nodes by theme.

Terminal
$ deciduous nodes --theme auth
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:

Setting up MCP for Claude Code
You
$ deciduous mcp setup claude-code

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:

Setting up MCP for Claude Desktop
You
$ deciduous mcp setup claude-desktop

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:

PlatformConfig 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:

Printing MCP config JSON
You
$ deciduous mcp setup --print
{ "mcpServers": { "deciduous": { "command": "/Users/you/.cargo/bin/deciduous", "args": ["mcp", "serve"], "env": { "DECIDUOUS_DB_PATH": "/Users/you/project/.deciduous/deciduous.db" } } } }

Copy the relevant parts into your config file manually.

User-Level vs Project-Level Config

Claude CodeClaude Desktop
Config location.claude/settings.local.json (project)Platform config directory (user)
ScopeOne projectAll conversations
DB pathAuto-detected from cwdSet via DECIDUOUS_DB_PATH env var
Binary pathUses PATH lookup (deciduous)Absolute path (e.g., /Users/you/.cargo/bin/deciduous)
Git tracking.claude/settings.local.json is gitignoredN/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

  1. Verify the binary path exists and is executable
  2. Test the server manually: deciduous mcp serve (it reads JSON-RPC from stdin)
  3. Check that deciduous init has been run in the target project
  4. 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:

  1. Startstart_session creates a root goal node and returns a session ID
  2. Work – all add_node calls auto-associate with the active session
  3. Endend_session marks the session complete with an optional summary
Session lifecycle
Claude
start_session({ name: "auth refactor", goal_title: "Refactor authentication to use OAuth2", goal_prompt: "I need to replace our custom JWT auth with OAuth2..." })
{ "session_id": 3, "root_node_id": 42, "name": "auth refactor" }
During conversation
Every add_node call auto-associates with session #3
Claude
add_node({ node_type: "option", title: "Use Auth0 as provider" })
Node #43 created -- automatically part of session #3
Claude
add_node({ node_type: "option", title: "Self-hosted Keycloak" })
Node #44 created -- automatically part of session #3
Claude
link_nodes({ from_id: 42, to_id: 43, rationale: "possible approach" })
Claude
link_nodes({ from_id: 42, to_id: 44, rationale: "possible approach" })
Claude
add_node({ node_type: "decision", title: "Choose Auth0 - managed service, faster to ship" })
Node #45 created
Claude
end_session({ summary: "Chose Auth0, implemented OAuth2 flow, tests passing" })
{ "session_id": 3, "node_count": 11, "message": "Ended session #3 (11 nodes)" }

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.

Resuming a previous conversation
You
What sessions do I have?
Claude
list_sessions({})
{ "count": 3, "sessions": [ { "session_id": 1, "name": "initial setup", "is_active": false, "node_count": 14 }, { "session_id": 2, "name": "add caching", "is_active": false, "node_count": 8 }, { "session_id": 3, "name": "auth refactor", "is_active": false, "node_count": 11 } ]}
You
Resume the auth refactor
Claude
resume_session({ session_id: 3 })
{ "session_id": 3, "name": "auth refactor", "node_count": 11, "message": "Resumed session #3 (11 nodes)" }
Claude
get_session({ session_id: 3 })
Returns all 11 nodes from the previous conversation for full context
Claude
I can see the previous session chose Auth0 and implemented the OAuth2 flow. Let me continue from where we left off.

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:

New conversation querying past decisions
You
Why did we choose Auth0 over Keycloak?
Claude
search_nodes({ query: "Auth0" })
Found 4 nodes matching "Auth0"
Claude
trace_chain({ node_id: 42, direction: "outgoing" })
{ "node_count": 11, "edge_count": 12 }
Claude
The auth refactor (Session #3) considered two options: Auth0 and self-hosted Keycloak. Auth0 was chosen at 85% confidence because it's a managed service and faster to ship. The implementation included OAuth2 flow with PKCE, and all tests are passing.

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:

Session 1 -- Monday: starting the auth work
You
I need to add user authentication to the app. Users should sign up with email/password, and we need OAuth support for Google and GitHub.
Claude
start_session({ name: "auth implementation", goal_title: "Add user authentication with email + OAuth" })
{ "session_id": 1, "root_node_id": 1, "name": "auth implementation" }
Claude
add_node({ node_type: "option", title: "NextAuth.js - handles OAuth providers out of the box" })
Node #2 created
Claude
add_node({ node_type: "option", title: "Custom auth with Passport.js" })
Node #3 created
Claude
add_node({ node_type: "decision", title: "Use NextAuth.js - built-in Google/GitHub, less code" })
Node #4 created
Claude
add_node({ node_type: "action", title: "Implement NextAuth with Google + GitHub providers" })
Node #5 created
Claude
add_node({ node_type: "outcome", title: "OAuth working for Google, GitHub provider hitting rate limits in dev" })
Node #6 created
Claude
add_node({ node_type: "observation", title: "GitHub OAuth rate limits are per-app in dev mode, need to register a proper OAuth app" })
Node #7 created
Claude
end_session({ summary: "NextAuth chosen and implemented. Google OAuth working. GitHub needs a registered OAuth app to avoid dev rate limits." })
{ "session_id": 1, "node_count": 7, "message": "Ended session #1 (7 nodes)" }
Session 2 -- Thursday: picking up where we left off
You
I registered the GitHub OAuth app. Let's fix the auth and add email/password signup.
Claude
list_sessions({})
{ "count": 1, "sessions": [ { "session_id": 1, "name": "auth implementation", "is_active": false, "node_count": 7 } ]}
Claude
resume_session({ session_id: 1 })
{ "session_id": 1, "node_count": 7, "message": "Resumed session #1 (7 nodes)" }
Claude
get_session({})
Returns all 7 nodes -- I can see the GitHub rate limit observation from Monday
Claude
I can see from the previous session that NextAuth is set up with Google working, and there was a GitHub OAuth rate limit issue. Now that you've registered the app, let me update the config and add email/password support.
Claude
add_node({ node_type: "action", title: "Configure registered GitHub OAuth app credentials" })
Node #8 created -- automatically part of session #1
Claude
add_node({ node_type: "action", title: "Add NextAuth CredentialsProvider for email/password" })
Node #9 created
Claude
add_node({ node_type: "outcome", title: "All three auth methods working - Google, GitHub, email/password" })
Node #10 created
Claude
end_session({ summary: "GitHub OAuth fixed with registered app. Email/password added via CredentialsProvider. All three auth methods tested and working." })
{ "session_id": 1, "node_count": 10, "message": "Ended session #1 (10 nodes)" }

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

ParameterTypeRequiredDescription
node_typestringYesgoal, decision, option, action, outcome, observation, revisit
titlestringYesNode title
descriptionstringLonger description with more detail
confidenceintegerConfidence level 0-100
promptstringVerbatim user prompt (for context recovery)
filesstringComma-separated list of associated files
branchstringGit branch (auto-detected if omitted)
commitstringGit commit hash, or "HEAD" to auto-detect
Example
add_node({ node_type: "goal", title: "Add search functionality", confidence: 90 })
{ "id": 42, "node_type": "goal", "title": "Add search functionality" }

Create an edge between two nodes. CLI: deciduous link

ParameterTypeRequiredDescription
from_idintegerYesSource node ID
to_idintegerYesTarget node ID
rationalestringReason for this connection
edge_typestringleads_to (default), requires, chosen, rejected, blocks, enables
Example
link_nodes({ from_id: 1, to_id: 2, rationale: "possible approach", edge_type: "leads_to" })
{ "from_id": 1, "to_id": 2, "edge_type": "leads_to" }

Remove an edge between two nodes. CLI: deciduous unlink

ParameterTypeRequiredDescription
from_idintegerYesSource node ID
to_idintegerYesTarget node ID

delete_node

Delete a node and all its connected edges. CLI: deciduous delete

ParameterTypeRequiredDescription
node_idintegerYesID of the node to delete
dry_runbooleanIf true, preview what would be deleted without deleting (default: false)

update_status

Change the status of a node. CLI: deciduous status

ParameterTypeRequiredDescription
node_idintegerYesNode ID to update
statusstringYespending, active, completed, rejected, superseded, abandoned

update_prompt

Add or update the verbatim user prompt stored on a node. CLI: deciduous prompt

ParameterTypeRequiredDescription
node_idintegerYesNode ID to update
promptstringYesThe verbatim user prompt text

Querying

Tools for listing, searching, and inspecting graph data.

list_nodes

List all nodes with optional filters. CLI: deciduous nodes

ParameterTypeRequiredDescription
branchstringFilter by git branch
node_typestringFilter by type (goal, decision, option, etc.)
statusstringFilter by status (active, pending, completed, etc.)
themestringFilter 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

ParameterTypeRequiredDescription
node_idintegerYesNode 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

ParameterTypeRequiredDescription
querystringYesSearch text (matched against title, description, and prompt)
node_typestringFilter results by node type
branchstringFilter results by branch
Example
search_nodes({ query: "authentication", node_type: "decision" })
{ "count": 3, "nodes": [ { "id": 45, "node_type": "decision", "title": "Choose Auth0 for OAuth" }, ... ]}

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

ParameterTypeRequiredDescription
node_idintegerYesStarting node ID
max_depthintegerMaximum traversal depth (0 = unlimited, default: 0)
directionstringboth (default), outgoing, incoming
Example
trace_chain({ node_id: 1, direction: "outgoing", max_depth: 3 })
{ "start_node_id": 1, "node_count": 8, "edge_count": 9, "nodes": [ { "id": 1, "node_type": "goal", "title": "Add MCP server", "depth": 0 }, { "id": 2, "node_type": "option", "title": "Embedded server", "depth": 1 }, ... ]}

get_node_context

Get a node’s full neighborhood: the node itself, parents, children, siblings, themes, and documents. MCP-only

ParameterTypeRequiredDescription
node_idintegerYesNode ID to get context for
Example
get_node_context({ node_id: 45 })
Node: #45 [decision] "Choose embedded MCP server" (92%) Parents: #42 [option], #43 [option], #44 [option] Children: #46 [action], #47 [action], #48 [action]

get_timeline

Chronological view of nodes, newest first. CLI: deciduous archaeology timeline

ParameterTypeRequiredDescription
limitintegerMax nodes to return (default: 50, 0 = all)
node_typestringFilter by node type
branchstringFilter by git branch
sincestringOnly 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

ParameterTypeRequiredDescription
branchstringFilter by git branch
Example
get_pulse({ branch: "main" })
total_nodes: 142 | total_edges: 198 By type: goal: 12, option: 28, decision: 15, action: 42, outcome: 38, observation: 7 Active goals: #1 "Build MVP", #89 "Add search", #120 "Migrate to Postgres"

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

ParameterTypeRequiredDescription
branchstringYesGit 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.

ParameterTypeRequiredDescription
namestringYesSession name (e.g., "cowork: auth refactor")
goal_titlestringYesTitle for the root goal node
goal_promptstringVerbatim initial user prompt
Example
start_session({ name: "auth refactor", goal_title: "Refactor auth to OAuth2" })
{ "session_id": 3, "root_node_id": 42, "name": "auth refactor" }

end_session

Close the active session with an optional summary.

ParameterTypeRequiredDescription
summarystringBrief summary of what was accomplished

get_session

View a session’s details and all its nodes.

ParameterTypeRequiredDescription
session_idintegerSession ID to query (omit for current session)

resume_session

Reconnect to a previous session by ID. Use after breaks or server restarts.

ParameterTypeRequiredDescription
session_idintegerYesSession ID to resume

list_sessions

List all conversation sessions.

ParameterTypeRequiredDescription
active_onlybooleanIf 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

ParameterTypeRequiredDescription
node_idintegerYesNode ID to attach the file to
file_pathstringYesPath to the file to attach
descriptionstringDescription of the document

list_documents

List documents attached to a node, or all documents. CLI: deciduous doc list

ParameterTypeRequiredDescription
node_idintegerNode ID to list documents for (omit for all)

create_theme

Create a new theme for tagging nodes. CLI: deciduous themes create

ParameterTypeRequiredDescription
namestringYesTheme name (lowercase, dash-separated)
colorstringHex color code (default: #6b7280)
descriptionstringTheme 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

ParameterTypeRequiredDescription
node_idintegerYesNode ID to tag
themestringYesTheme name to apply

untag_node

Remove a theme tag from a node. CLI: deciduous tag remove

ParameterTypeRequiredDescription
node_idintegerYesNode ID to untag
themestringYesTheme 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

ParameterTypeRequiredDescription
rootsstringRoot node IDs (comma-separated) – traverses children
nodesstringSpecific IDs or ranges (e.g., "1-11" or "1,3,5-10")
titlestringGraph title
rankdirstringTB (top-bottom, default) or LR (left-right)

generate_writeup

Generate a PR writeup from the decision graph. Returns markdown. CLI: deciduous writeup

ParameterTypeRequiredDescription
titlestringPR title
rootsstringRoot node IDs (comma-separated)
nodesstringSpecific node IDs or ranges
no_dotbooleanSkip DOT graph section (default: false)
no_test_planbooleanSkip 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

CategoryCountMCP-only
Graph CRUD60
Querying51 (search_nodes)
Analysis64 (trace_chain, get_node_context, find_orphans, get_branch_summary)
Sessions55
Documents & Themes60
Export30
Total3110

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.

FlagDescription
--claudeSet up Claude Code integration (.claude/, CLAUDE.md)
--no-auto-updateDisable automatic version checking

Default (no flags): sets up Claude Code only.

Terminal
$ deciduous init
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/.

Terminal
$ deciduous update
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.

Terminal
$ deciduous check-update
OK: Integration files are up to date (v0.15.0).

When an update is available:

Terminal
$ deciduous check-update
╔════════════════════════════════════════════════════════════════╗
║ 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.

FlagShortDescription
--port <port>-pPort to listen on (default: 3000)
Terminal
$ deciduous serve
Starting deciduous graph viewer...
Listening on http://127.0.0.1:3000
Press Ctrl+C to stop

Use a custom port:

Terminal
$ deciduous serve -p 8080
Listening on http://127.0.0.1:8080

deciduous backup

Create a backup of the SQLite database. Always back up before any destructive operations.

FlagShortDescription
--output <path>-oOutput path (default: deciduous_backup_<timestamp>.db)
Terminal
$ deciduous backup
Backup created: deciduous_backup_20250509_143022.db

Specify a custom path:

Terminal
$ deciduous backup -o /tmp/before-migration.db
Backup created: /tmp/before-migration.db

deciduous commands

Show the recent command log – every deciduous command that modified the graph.

FlagShortDescription
--limit <n>-lNumber of commands to show (default: 20)
Terminal
$ deciduous commands -l 5
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

FlagShortDescription
--description <text>-dOptional description
--confidence <0-100>-cConfidence level
--commit <hash|HEAD>Link to git commit (HEAD auto-resolves)
--prompt <text>-pPrompt that triggered this decision
--prompt-stdinRead prompt from stdin (for multi-line)
--files <paths>-fAssociated files (comma-separated)
--branch <name>-bGit branch (auto-detected if omitted)
--no-branchSkip auto-detection of git branch
--date <date>Created date (RFC3339, YYYY-MM-DD, or YYYY-MM-DD HH:MM:SS)

Basic usage

Terminal
$ deciduous add goal "Add JWT authentication" -c 90
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

Terminal
$ deciduous add action "Implement JWT middleware" -c 85 --commit HEAD -f "src/auth/jwt.rs,src/auth/refresh.rs"
Created node 46 (type: action) [confidence: 85%] [commit: a1b2c3d] [branch: feature-auth]

Multi-line prompts

Capture the full user request with --prompt-stdin:

Terminal
$ deciduous add goal "Add auth" -c 90 --prompt-stdin << 'EOF'
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)

Terminal
$ deciduous add goal "Original API design" --date "2024-01-15" --no-branch
Created node 51 (type: goal) [date: 2024-01-15]

Add an edge between two nodes.

FlagShortDescription
--rationale <text>-rRationale for this connection
--edge-type <type>-tEdge type (default: leads_to)

Edge types: leads_to, requires, chosen, rejected, blocks, enables

Terminal
$ deciduous link 42 43 -r "possible approach"
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)

Remove an edge between two nodes.

Terminal
$ deciduous unlink 44 45
Removed edge 44 -> 45

deciduous delete <id>

Delete a node and all its connected edges.

FlagDescription
--dry-runShow what would be deleted without deleting
Terminal
$ deciduous delete 44 --dry-run
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

Terminal
$ deciduous status 47 completed
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.

Terminal
$ deciduous prompt 42 "Add JWT auth with refresh token rotation for the API"
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.

FlagDescription
--jsonOutput as JSON instead of formatted text
Terminal
$ deciduous show 42
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.

FlagShortDescription
--branch <name>-bFilter by git branch
--node-type <type>-tFilter by node type (goal, decision, action, etc.)
--theme <name>Filter by theme name
Terminal
$ deciduous nodes
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

Terminal
$ deciduous nodes -t goal
42 goal active Add JWT authentication
50 goal active Add rate limiting
58 goal active Database migration tooling

Filtering by branch

Terminal
$ deciduous nodes -b feature-auth
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

Terminal
$ deciduous nodes --theme performance
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.

Terminal
$ deciduous edges
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.

Terminal
$ deciduous graph > graph.json

$ 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:

Terminal -- building a feature end-to-end
# 1. Create the goal
$ 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.

FlagShortDescription
--output <file>-oOutput file (default: stdout)
--roots <ids>-rRoot node IDs (comma-separated, traverses children)
--nodes <spec>-nNode IDs or ranges (e.g., 1-11 or 1,3,5-10)
--pngGenerate PNG using graphviz (requires dot command)
--autoAuto-generate branch-specific filename in docs/
--title <text>-tGraph title
--rankdir <dir>Graph direction: TB (top-bottom) or LR (left-right). Default: TB

Basic DOT export

Terminal
$ deciduous dot > graph.dot

$ deciduous dot -o graph.dot

Generate PNG directly

Requires Graphviz installed (brew install graphviz / apt install graphviz).

Terminal
$ deciduous dot --png -o docs/graph.dot
Wrote DOT to docs/graph.dot
Generated PNG: docs/graph.png

Filter by node range

Terminal
$ deciduous dot --nodes 1-11 --png -o docs/auth-flow.dot
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.

Terminal
$ deciduous dot --auto --nodes 1-15 --png
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.

FlagShortDescription
--title <text>-tPR title
--roots <ids>-rRoot node IDs (comma-separated, traverses children)
--nodes <spec>-nNode IDs or ranges (e.g., 1-11 or 1,3,5-10)
--output <file>-oOutput file (default: stdout)
--png <filename>PNG filename to embed (auto-detects repo/branch for GitHub URL)
--autoAuto-detect PNG from branch name
--no-dotSkip DOT graph section
--no-test-planSkip test plan section

Basic writeup

Terminal
$ deciduous writeup -t "Add JWT Authentication" --nodes 42-47 -o PR.md
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:

Terminal
$ deciduous writeup --auto -t "Add JWT Auth" --nodes 42-47
# Outputs markdown to stdout with embedded graph image

Update a PR body directly

Terminal
$ gh pr edit 42 --body "$(deciduous writeup --auto -t 'Add JWT Auth' --nodes 42-47)"
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.

FlagShortDescription
--output <path>-oOutput path (default: .deciduous/web/graph-data.json)
Terminal
$ deciduous sync
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:

Terminal -- PR workflow
# 1. Generate branch-specific PNG (avoids merge conflicts)
$ 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:

  1. Run deciduous sync to export
  2. Push the docs/ folder to GitHub
  3. Go to Settings > Pages > Deploy from branch > select /docs folder
  4. 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.

  1. Every add, link, or status command emits an event to .deciduous/sync/events/<user>.jsonl
  2. Event files are git-tracked, so git pull brings in teammate events
  3. deciduous events rebuild replays all events to reconstruct the database
  4. Checkpoints capture full state snapshots to avoid replaying the entire history

Each node has two IDs:

  • id (integer) – local database primary key, different per machine
  • change_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.

Terminal
$ deciduous events init
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.

Terminal
$ deciduous events status
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.

FlagDescription
--dry-runShow what would be done without modifying the database
Terminal
$ deciduous events rebuild --dry-run
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.

FlagDescription
--clear-eventsClear event logs after creating the checkpoint
Terminal
$ deciduous events 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.

Terminal
$ deciduous events emit 42
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.

Terminal
$ deciduous migrate
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

Terminal -- team sync workflow
# One-time setup (each team member)
$ 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.

Terminal
$ deciduous mcp serve
# 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)
FlagDescription
--printPrint the config JSON to stdout without writing anything
Terminal
$ deciduous mcp setup claude-code
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.

Terminal
$ deciduous hooks install
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.

Terminal
$ deciduous hooks status
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.

Terminal
$ deciduous hooks uninstall
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.

Terminal
$ deciduous integration
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

Terminal
# Zsh (add to ~/.zshrc)
$ 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.

FlagDescription
--associate-commitsAssociate commits with nodes by matching titles to commit messages
--min-score <0-100>Minimum keyword match score (default: 50)
--dry-runShow what would be done without modifying database
--yesAuto-apply without confirmation
Terminal
$ deciduous audit --associate-commits --dry-run
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.

FlagShortDescription
--branch <name>-bFilter by git branch
--recent <n>-rNumber of recent nodes to show (default: 10)
--jsonOutput as JSON
--summaryShow only the summary section
Terminal
$ deciduous pulse
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:

Terminal
$ deciduous pulse --summary -b feature-auth
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.

FlagShortDescription
--output <path>-oOutput path (default: .deciduous/narratives.md)
--forceOverwrite existing file
Terminal
$ deciduous narratives init
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.

FlagShortDescription
--path <path>-pPath to narratives.md (default: .deciduous/narratives.md)
Terminal
$ deciduous narratives show
# 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.

FlagShortDescription
--branch <name>-bFilter by git branch
--jsonOutput as JSON
Terminal
$ deciduous narratives pivots
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.

FlagShortDescription
--confidence <0-100>-cConfidence for the new decision
--reason <text>-rRationale for why the old approach failed
--dry-runShow what would be created without modifying database
Terminal
$ deciduous archaeology pivot 15 "Mobile clients can't maintain sessions" "Switch to JWT tokens" -c 85 -r "Stateless auth needed for mobile"
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.

FlagShortDescription
--limit <n>-lNumber of most recent nodes (0 = all, default: 0)
--node-type <type>-tFilter by node type
--branch <name>-bFilter by git branch
--jsonOutput as JSON
Terminal
$ deciduous archaeology timeline -l 5
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.

FlagDescription
--cascadeAlso mark all descendant nodes as superseded
--dry-runShow what would be changed without modifying database
Terminal
$ deciduous archaeology supersede 15 --cascade --dry-run
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.

FlagShortDescription
--path <file>-pPath to ROADMAP.md (default: ROADMAP.md)
Terminal
$ deciduous roadmap init
Parsed ROADMAP.md: 3 sections, 12 items
Roadmap initialized

deciduous roadmap refresh

Re-parse ROADMAP.md, preserving existing decision graph links.

FlagShortDescription
--path <file>-pPath to ROADMAP.md (default: ROADMAP.md)

deciduous roadmap sync

Sync ROADMAP.md with GitHub Issues. Dry-run by default – use --execute to apply.

FlagShortDescription
--path <file>-pPath to ROADMAP.md (default: ROADMAP.md)
--repo <owner/repo>-rGitHub repo (auto-detected from git remote)
--executeActually apply changes (default is dry-run)
--create-issuesCreate GitHub issues for new sections (default: true)
Terminal
$ deciduous roadmap sync
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.

FlagShortDescription
--path <file>-pPath to ROADMAP.md (default: ROADMAP.md)
--section <name>-sFilter by section name
--with-issuesShow only items with GitHub issues
--without-issuesShow only items without GitHub issues
Terminal
$ deciduous roadmap list
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

Link a roadmap item to a decision graph outcome node. <item> is a change_id or title (partial match).

Remove outcome link from a roadmap item.

deciduous roadmap conflicts

Show sync conflicts.

FlagDescription
--resolveResolve conflicts interactively

deciduous roadmap status

Show sync status summary.

FlagShortDescription
--path <file>-pPath to ROADMAP.md (default: ROADMAP.md)

deciduous roadmap check

Audit completion status of roadmap items.

FlagShortDescription
--path <file>-pPath to ROADMAP.md (default: ROADMAP.md)
--incompleteShow only incomplete items
--completeShow 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.

FlagShortDescription
--description <text>-dManual description
--ai-describeGenerate AI description using claude CLI
Terminal
$ deciduous doc attach 42 architecture.png -d "Auth system architecture diagram"
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.

FlagDescription
--include-detachedShow soft-deleted documents too
--jsonOutput as JSON
Terminal
$ deciduous doc list 42
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.

FlagDescription
--jsonOutput as JSON
Terminal
$ deciduous doc show 1
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.

FlagDescription
--aiGenerate AI description using claude CLI
Terminal
$ deciduous doc describe 1 "Updated auth architecture with OAuth2 flows"
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.

Terminal
$ deciduous doc open 1
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.

Terminal
$ deciduous doc detach 2
Detached document 2 from node 42

deciduous doc gc

Garbage-collect orphaned files from disk – files that no active document records reference.

FlagDescription
--dry-runShow what would be deleted without deleting
Terminal
$ deciduous doc gc --dry-run
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.

FlagShortDescription
--color <hex>-cHex color code (default: #6b7280)
--description <text>-dTheme description
Terminal
$ deciduous themes create performance -c "#ef4444" -d "Performance-related decisions and observations"
Created theme "performance" (#ef4444)

$ deciduous themes create security -c "#3b82f6" -d "Security considerations"
Created theme "security" (#3b82f6)

deciduous themes list

List all themes.

Terminal
$ deciduous themes list
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.

Terminal
$ deciduous themes delete tech-debt
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.

Terminal
$ deciduous tag add 55 performance
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.

Terminal
$ deciduous tag remove 55 performance
Removed "performance" from node 55

deciduous tag list <node_id>

List themes for a node.

Terminal
$ deciduous tag list 42
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.

FlagDescription
--applyApply suggestions without confirmation
Terminal
$ deciduous tag suggest 55
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.

Terminal
$ deciduous tag confirm 55 performance
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

Terminal
$ deciduous init
Initializing Deciduous for Claude Code... Directory: /Users/you/my-project

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/:

CommandPurpose
/decisionManage decision graph – add nodes, link edges, sync
/recoverRecover context from decision graph on session start
/workStart a work transaction – creates goal node before implementation
/documentGenerate comprehensive documentation for a file or directory
/build-testBuild the project and run the test suite
/serve-uiStart the decision graph web viewer
/sync-graphExport decision graph to GitHub Pages
/decision-graphBuild a decision graph from commit history
/syncMulti-user sync – pull events, rebuild, push

Skills

Skills are higher-level workflows stored in .claude/skills/:

SkillPurpose
/pulseMap current design as decisions (Now mode)
/narrativesUnderstand how the system evolved (History mode)
/archaeologyTransform 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:

GroupToolsPurpose
Graphadd_node, add_edge, update_status, …Core graph operations
Querylist_nodes, list_edges, show_node, search_nodes, …Read and search the graph
Documentsattach_document, list_documents, …File attachments on nodes
Sessionsstart_session, end_session, resume_session, …Per-conversation decision trees
Exportexport_dot, generate_writeupDOT 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.

Terminal
$ deciduous update
Updating Deciduous tooling for Claude Code... Directory: /Users/you/my-project

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:

Claude Code -- using slash commands
You
/recover
Claude
$ deciduous nodes
ID Type Title Status Confidence 1 goal Add JWT auth with refresh tokens active 90% 2 option jsonwebtoken crate + custom logic active 80% 3 option axum-jwt-auth with built-in rotation active 75% 4 decision Use jsonwebtoken for full control active 85% 5 action Implement JWT middleware active 85% 6 outcome JWT auth working -- 14 tests passing active 95%
$ deciduous edges
From To Reason 1 2 possible approach 1 3 possible approach 2 4 chosen 4 5 implementing chosen approach 5 6 implementation result
Context recovered. We have JWT auth implemented with jsonwebtoken. 14 tests passing. Ready to continue.