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

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.