|
| 1 | +--- |
| 2 | +description: Manage decision graph - track algorithm choices and reasoning |
| 3 | +allowed-tools: Bash(deciduous:*) |
| 4 | +argument-hint: <action> [args...] |
| 5 | +--- |
| 6 | + |
| 7 | +# Decision Graph Management |
| 8 | + |
| 9 | +**Log decisions IN REAL-TIME as you work, not retroactively.** |
| 10 | + |
| 11 | +## When to Use This |
| 12 | + |
| 13 | +| You're doing this... | Log this type | Command | |
| 14 | +|---------------------|---------------|---------| |
| 15 | +| Starting a new feature | `goal` **with -p** | `/decision add goal "Add user auth" -p "user request"` | |
| 16 | +| Choosing between approaches | `decision` | `/decision add decision "Choose auth method"` | |
| 17 | +| Considering an option | `option` | `/decision add option "JWT tokens"` | |
| 18 | +| About to write code | `action` | `/decision add action "Implementing JWT"` | |
| 19 | +| Noticing something | `observation` | `/decision add obs "Found existing auth code"` | |
| 20 | +| Finished something | `outcome` | `/decision add outcome "JWT working"` | |
| 21 | +| Reconsidering a past decision | `revisit` | `/decision add revisit "Reconsidering auth"` | |
| 22 | + |
| 23 | +## Quick Commands |
| 24 | + |
| 25 | +Based on $ARGUMENTS: |
| 26 | + |
| 27 | +### View Commands |
| 28 | +- `nodes` or `list` -> `deciduous nodes` |
| 29 | +- `edges` -> `deciduous edges` |
| 30 | +- `graph` -> `deciduous graph` |
| 31 | +- `commands` -> `deciduous commands` |
| 32 | + |
| 33 | +### Create Nodes (with optional metadata) |
| 34 | +- `add goal <title>` -> `deciduous add goal "<title>" -c 90` |
| 35 | +- `add decision <title>` -> `deciduous add decision "<title>" -c 75` |
| 36 | +- `add option <title>` -> `deciduous add option "<title>" -c 70` |
| 37 | +- `add action <title>` -> `deciduous add action "<title>" -c 85` |
| 38 | +- `add obs <title>` -> `deciduous add observation "<title>" -c 80` |
| 39 | +- `add outcome <title>` -> `deciduous add outcome "<title>" -c 90` |
| 40 | +- `add revisit <title>` -> `deciduous add revisit "<title>" -c 75` |
| 41 | + |
| 42 | +### Optional Flags for Nodes |
| 43 | +- `-c, --confidence <0-100>` - Confidence level |
| 44 | +- `-p, --prompt "..."` - Store the user prompt that triggered this node |
| 45 | +- `-f, --files "file1.rs,file2.rs"` - Associate files with this node |
| 46 | +- `-b, --branch <name>` - Git branch (auto-detected by default) |
| 47 | +- `--no-branch` - Skip branch auto-detection |
| 48 | +- `--commit <hash|HEAD>` - Link to a git commit (use HEAD for current commit) |
| 49 | +- `--date "YYYY-MM-DD"` - Backdate node (for archaeology/retroactive logging) |
| 50 | + |
| 51 | +### CRITICAL: Link Commits to Actions/Outcomes |
| 52 | + |
| 53 | +**After every git commit, link it to the decision graph!** |
| 54 | + |
| 55 | +```bash |
| 56 | +git commit -m "feat: add auth" |
| 57 | +deciduous add action "Implemented auth" -c 90 --commit HEAD |
| 58 | +deciduous link <goal_id> <action_id> -r "Implementation" |
| 59 | +``` |
| 60 | + |
| 61 | +## CRITICAL: Capture VERBATIM User Prompts |
| 62 | + |
| 63 | +**Prompts must be the EXACT user message, not a summary.** When a user request triggers new work, capture their full message word-for-word. |
| 64 | + |
| 65 | +**BAD - summaries are useless for context recovery:** |
| 66 | +```bash |
| 67 | +# DON'T DO THIS - this is a summary, not a prompt |
| 68 | +deciduous add goal "Add auth" -p "User asked: add login to the app" |
| 69 | +``` |
| 70 | + |
| 71 | +**GOOD - verbatim prompts enable full context recovery:** |
| 72 | +```bash |
| 73 | +# Use --prompt-stdin for multi-line prompts |
| 74 | +deciduous add goal "Add auth" -c 90 --prompt-stdin << 'EOF' |
| 75 | +I need to add user authentication to the app. Users should be able to sign up |
| 76 | +with email/password, and we need OAuth support for Google and GitHub. The auth |
| 77 | +should use JWT tokens with refresh token rotation. |
| 78 | +EOF |
| 79 | + |
| 80 | +# Or use the prompt command to update existing nodes |
| 81 | +deciduous prompt 42 << 'EOF' |
| 82 | +The full verbatim user message goes here... |
| 83 | +EOF |
| 84 | +``` |
| 85 | + |
| 86 | +**When to capture prompts:** |
| 87 | +- Root `goal` nodes: YES - the FULL original request |
| 88 | +- Major direction changes: YES - when user redirects the work |
| 89 | +- Routine downstream nodes: NO - they inherit context via edges |
| 90 | + |
| 91 | +**Updating prompts on existing nodes:** |
| 92 | +```bash |
| 93 | +deciduous prompt <node_id> "full verbatim prompt here" |
| 94 | +cat prompt.txt | deciduous prompt <node_id> # Multi-line from stdin |
| 95 | +``` |
| 96 | + |
| 97 | +Prompts are viewable in the TUI detail panel (`deciduous tui`) and web viewer. |
| 98 | + |
| 99 | +## Branch-Based Grouping |
| 100 | + |
| 101 | +**Nodes are automatically tagged with the current git branch.** This enables filtering by feature/PR. |
| 102 | + |
| 103 | +### How It Works |
| 104 | +- When you create a node, the current git branch is stored in `metadata_json` |
| 105 | +- Configure which branches are "main" in `.deciduous/config.toml`: |
| 106 | + ```toml |
| 107 | + [branch] |
| 108 | + main_branches = ["main", "master"] # Branches not treated as "feature branches" |
| 109 | + auto_detect = true # Auto-detect branch on node creation |
| 110 | + ``` |
| 111 | +- Nodes on feature branches (anything not in `main_branches`) can be grouped/filtered |
| 112 | + |
| 113 | +### CLI Filtering |
| 114 | +```bash |
| 115 | +# Show only nodes from specific branch |
| 116 | +deciduous nodes --branch main |
| 117 | +deciduous nodes --branch feature-auth |
| 118 | +deciduous nodes -b my-feature |
| 119 | + |
| 120 | +# Override auto-detection when creating nodes |
| 121 | +deciduous add goal "Feature work" -b feature-x # Force specific branch |
| 122 | +deciduous add goal "Universal note" --no-branch # No branch tag |
| 123 | +``` |
| 124 | + |
| 125 | +### Web UI Branch Filter |
| 126 | +The graph viewer shows a branch dropdown in the stats bar: |
| 127 | +- "All branches" shows everything |
| 128 | +- Select a specific branch to filter all views (Chains, Timeline, Graph, DAG) |
| 129 | + |
| 130 | +### When to Use Branch Grouping |
| 131 | +- **Feature work**: Nodes created on `feature-auth` branch auto-grouped |
| 132 | +- **PR context**: Filter to see only decisions for a specific PR |
| 133 | +- **Cross-cutting concerns**: Use `--no-branch` for universal notes |
| 134 | +- **Retrospectives**: Filter by branch to see decision history per feature |
| 135 | + |
| 136 | +### Create Edges |
| 137 | +- `link <from> <to> [reason]` -> `deciduous link <from> <to> -r "<reason>"` |
| 138 | + |
| 139 | +### Sync Graph |
| 140 | +- `sync` -> `deciduous sync` |
| 141 | + |
| 142 | +### Multi-User Sync (Diff/Patch) |
| 143 | +- `diff export -o <file>` -> `deciduous diff export -o <file>` (export nodes as patch) |
| 144 | +- `diff export --nodes 1-10 -o <file>` -> export specific nodes |
| 145 | +- `diff export --branch feature-x -o <file>` -> export nodes from branch |
| 146 | +- `diff apply <file>` -> `deciduous diff apply <file>` (apply patch, idempotent) |
| 147 | +- `diff apply --dry-run <file>` -> preview without applying |
| 148 | +- `diff status` -> `deciduous diff status` (list patches in .deciduous/patches/) |
| 149 | +- `migrate` -> `deciduous migrate` (add change_id columns for sync) |
| 150 | + |
| 151 | +### Export & Visualization |
| 152 | +- `dot` -> `deciduous dot` (output DOT to stdout) |
| 153 | +- `dot --png` -> `deciduous dot --png -o graph.dot` (generate PNG) |
| 154 | +- `dot --nodes 1-11` -> `deciduous dot --nodes 1-11` (filter nodes) |
| 155 | +- `writeup` -> `deciduous writeup` (generate PR writeup) |
| 156 | +- `writeup -t "Title" --nodes 1-11` -> filtered writeup |
| 157 | + |
| 158 | +## Node Types |
| 159 | + |
| 160 | +| Type | Purpose | Example | |
| 161 | +|------|---------|---------| |
| 162 | +| `goal` | High-level objective | "Add user authentication" | |
| 163 | +| `decision` | Choice point with options | "Choose auth method" | |
| 164 | +| `option` | Possible approach | "Use JWT tokens" | |
| 165 | +| `action` | Something implemented | "Added JWT middleware" | |
| 166 | +| `outcome` | Result of action | "JWT auth working" | |
| 167 | +| `observation` | Finding or data point | "Existing code uses sessions" | |
| 168 | +| `revisit` | Pivot point / reconsideration | "Reconsidering auth approach" | |
| 169 | + |
| 170 | +## Edge Types |
| 171 | + |
| 172 | +| Type | Meaning | |
| 173 | +|------|---------| |
| 174 | +| `leads_to` | Natural progression | |
| 175 | +| `chosen` | Selected option | |
| 176 | +| `rejected` | Not selected (include reason!) | |
| 177 | +| `requires` | Dependency | |
| 178 | +| `blocks` | Preventing progress | |
| 179 | +| `enables` | Makes something possible | |
| 180 | + |
| 181 | +## Graph Integrity - CRITICAL |
| 182 | + |
| 183 | +**Every node MUST be logically connected.** Floating nodes break the graph's value. |
| 184 | + |
| 185 | +### Connection Rules |
| 186 | +| Node Type | MUST connect to | Example | |
| 187 | +|-----------|----------------|---------| |
| 188 | +| `outcome` | The action/goal it resolves | "JWT working" -> links FROM "Implementing JWT" | |
| 189 | +| `action` | The decision/goal that spawned it | "Implementing JWT" -> links FROM "Add auth" | |
| 190 | +| `option` | Its parent decision | "Use JWT" -> links FROM "Choose auth method" | |
| 191 | +| `observation` | Related goal/action/decision | "Found existing code" -> links TO relevant node | |
| 192 | +| `decision` | Parent goal (if any) | "Choose auth" -> links FROM "Add auth feature" | |
| 193 | +| `revisit` | The decision/outcome being reconsidered | "Reconsidering auth" -> links FROM original decision | |
| 194 | +| `goal` | Can be a root (no parent needed) | Root goals are valid orphans | |
| 195 | + |
| 196 | +### Audit Checklist |
| 197 | +Ask yourself after creating nodes: |
| 198 | +1. Does every **outcome** link back to what caused it? |
| 199 | +2. Does every **action** link to why you did it? |
| 200 | +3. Does every **option** link to its decision? |
| 201 | +4. Are there **dangling outcomes** with no parent action/goal? |
| 202 | + |
| 203 | +### Find Disconnected Nodes |
| 204 | +```bash |
| 205 | +# List nodes with no incoming edges (potential orphans) |
| 206 | +deciduous edges | cut -d'>' -f2 | cut -d' ' -f2 | sort -u > /tmp/has_parent.txt |
| 207 | +deciduous nodes | tail -n+3 | awk '{print $1}' | while read id; do |
| 208 | + grep -q "^$id$" /tmp/has_parent.txt || echo "CHECK: $id" |
| 209 | +done |
| 210 | +``` |
| 211 | +Note: Root goals are VALID orphans. Outcomes/actions/options usually are NOT. |
| 212 | + |
| 213 | +### Fix Missing Connections |
| 214 | +```bash |
| 215 | +deciduous link <parent_id> <child_id> -r "Retroactive connection - <why>" |
| 216 | +``` |
| 217 | + |
| 218 | +### When to Audit |
| 219 | +- Before every `deciduous sync` |
| 220 | +- After creating multiple nodes quickly |
| 221 | +- At session end |
| 222 | +- When the web UI graph looks disconnected |
| 223 | + |
| 224 | +## Multi-User Sync |
| 225 | + |
| 226 | +**Problem**: Multiple users work on the same codebase, each with a local `.deciduous/deciduous.db` (gitignored). How to share decisions? |
| 227 | + |
| 228 | +**Solution**: jj-inspired dual-ID model. Each node has: |
| 229 | +- `id` (integer): Local database primary key, different per machine |
| 230 | +- `change_id` (UUID): Globally unique, stable across all databases |
| 231 | + |
| 232 | +### Export Workflow |
| 233 | +```bash |
| 234 | +# Export nodes from your branch as a patch file |
| 235 | +deciduous diff export --branch feature-x -o .deciduous/patches/alice-feature.json |
| 236 | + |
| 237 | +# Or export specific node IDs |
| 238 | +deciduous diff export --nodes 172-188 -o .deciduous/patches/alice-feature.json --author alice |
| 239 | +``` |
| 240 | + |
| 241 | +### Apply Workflow |
| 242 | +```bash |
| 243 | +# Apply patches from teammates (idempotent - safe to re-apply) |
| 244 | +deciduous diff apply .deciduous/patches/*.json |
| 245 | + |
| 246 | +# Preview what would change |
| 247 | +deciduous diff apply --dry-run .deciduous/patches/bob-refactor.json |
| 248 | +``` |
| 249 | + |
| 250 | +### PR Workflow |
| 251 | +1. Create nodes locally while working |
| 252 | +2. Export: `deciduous diff export --branch my-feature -o .deciduous/patches/my-feature.json` |
| 253 | +3. Commit the patch file (NOT the database) |
| 254 | +4. Open PR with patch file included |
| 255 | +5. Teammates pull and apply: `deciduous diff apply .deciduous/patches/my-feature.json` |
| 256 | +6. **Idempotent**: Same patch applied twice = no duplicates |
| 257 | + |
| 258 | +### Patch Format (JSON) |
| 259 | +```json |
| 260 | +{ |
| 261 | + "version": "1.0", |
| 262 | + "author": "alice", |
| 263 | + "branch": "feature/auth", |
| 264 | + "nodes": [{ "change_id": "uuid...", "title": "...", ... }], |
| 265 | + "edges": [{ "from_change_id": "uuid1", "to_change_id": "uuid2", ... }] |
| 266 | +} |
| 267 | +``` |
| 268 | + |
| 269 | +## The Rule |
| 270 | + |
| 271 | +``` |
| 272 | +LOG BEFORE YOU CODE, NOT AFTER. |
| 273 | +CONNECT EVERY NODE TO ITS PARENT. |
| 274 | +AUDIT FOR ORPHANS REGULARLY. |
| 275 | +SYNC BEFORE YOU PUSH. |
| 276 | +EXPORT PATCHES FOR YOUR TEAMMATES. |
| 277 | +``` |
| 278 | + |
| 279 | +**Live graph**: https://notactuallytreyanastasio.github.io/deciduous/ |
0 commit comments