# 9plan Data Flow Diagrams Visual documentation of how data moves through the system during key operations. --- ## Storage Overview ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ Session Directory │ │ ~/.9plan/sessions/{session-name}/ │ │ │ │ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ │ │ session.db │ │ plans/ │ │ │ │ (SQLite) │ │ (Flat Files) │ │ │ │ │ │ │ │ │ │ ┌───────────────────────┐ │ │ ┌───────────────────────┐ │ │ │ │ │ metadata │ │ │ │ {plan-id}.txt │ │ │ │ │ │ - task_description │ │ │ │ - Context │ │ │ │ │ │ - created_at │ │ │ │ - Goal │ │ │ │ │ └───────────────────────┘ │ │ │ - Inputs │ │ │ │ │ │ │ │ - Outputs │ │ │ │ │ ┌───────────────────────┐ │ │ │ - Approach │ │ │ │ │ │ queue │ │ │ │ - Success Criteria │ │ │ │ │ │ - ordered plan IDs │ │ │ │ - Notes │ │ │ │ │ │ - active plan ref │ │ │ └───────────────────────┘ │ │ │ │ └───────────────────────┘ │ │ │ │ │ │ │ │ (Only queued + active │ │ │ │ ┌───────────────────────┐ │ │ plans have files) │ │ │ │ │ history (FTS5) │ │ │ │ │ │ │ │ - completed plans │ │ └─────────────────────────────┘ │ │ │ │ - full content │ │ │ │ │ │ - outcomes │ │ │ │ │ └───────────────────────┘ │ │ │ │ │ │ │ └─────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────┘ ``` --- ## Session Creation Flow ``` 9plan_session_create(task_description) │ ▼ ┌─────────────────────┐ │ Generate Session │ │ Name (3 words) │ │ e.g. "amber-quiet- │ │ river" │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Check for │ │ Collision │◄─── Regenerate if exists └──────────┬──────────┘ │ (unique) ▼ ┌─────────────────────┐ │ Create Directory │ │ sessions/amber- │ │ quiet-river/ │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Initialize SQLite │ │ session.db │ │ - Create tables │ │ - Insert metadata │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Create plans/ │ │ subdirectory │ └──────────┬──────────┘ │ ▼ Return: session_name, session_path ``` --- ## Plan Addition Flow ``` 9plan_queue_add(context, goal, approach, success_criteria, inputs?, outputs?, position?) │ ▼ ┌─────────────────────┐ │ Validate Plan │ │ (required fields) │──── Error if invalid └──────────┬──────────┘ │ (valid) ▼ ┌─────────────────────┐ │ Generate Plan ID │ │ (alphanumeric, │ │ 5+ chars) │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Check for │ │ Collision │◄─── Regenerate if exists └──────────┬──────────┘ │ (unique) ▼ ┌───────────────────────────────────────────────────┐ │ PARALLEL │ │ ┌──────────────────┐ ┌──────────────────────┐ │ │ │ Write Plan File │ │ Insert DB Record │ │ │ │ plans/{id}.txt │ │ - plan metadata │ │ │ │ - Full content │ │ - queue position │ │ │ │ - Empty Notes │ │ - status: queued │ │ │ └──────────────────┘ └──────────────────────┘ │ └───────────────────────────────────────────────────┘ │ ▼ Return: plan_id, plan_path, queue_position ``` **Position Logic:** ``` position = "front" position = "back" (default) Queue: [B, C, D] Queue: [B, C, D] Add A at front Add A at back Queue: [A, B, C, D] Queue: [B, C, D, A] ``` --- ## Plan Pull Flow ``` 9plan_queue_pull() │ ▼ ┌─────────────────────┐ │ Check Active Plan │ │ Exists? │ └──────────┬──────────┘ │ ┌───────┴───────┐ ▼ ▼ (yes) (no) │ │ ▼ ▼ ERROR: ┌─────────────────────┐ "Plan │ Check Queue │ already │ Empty? │ active" └──────────┬──────────┘ │ ┌───────┴───────┐ ▼ ▼ (yes) (no) │ │ ▼ ▼ "Queue empty, ┌─────────────────────┐ task │ Get Front Plan ID │ complete" └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Update DB │ │ - Remove from queue│ │ - Mark as active │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Verify Plan File │ │ Exists │ └──────────┬──────────┘ │ ▼ Return: plan_id, plan_path Agent then reads plans/{id}.txt via filesystem tools ``` --- ## Plan Completion Flow ``` 9plan_plan_complete(outcome) │ ▼ ┌─────────────────────┐ │ Get Active Plan │ │ from DB │──── Error if none active └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Read Plan File │ │ plans/{id}.txt │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Index into │ │ History (FTS5) │ │ - Full plan content│ │ - Outcome │ │ - Timestamp │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Delete Plan File │ │ plans/{id}.txt │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Clear Active Plan │ │ in DB │ └──────────┬──────────┘ │ ▼ Return: success, "pull next plan" ``` **Data Migration on Completion:** ``` BEFORE: AFTER: plans/k7f3m.txt ─────────┐ plans/k7f3m.txt # Context │ (DELETED) Building Ghost... │ # Goal │ session.db Create API client... │ history table: # Notes │ ┌────────────────────┐ Progress: done auth │ │ id: k7f3m │ ▼ │ content: (full) │ completion │ outcome: Created │ process │ ghost_client... │ │ │ completed_at: ... │ └────────────►└────────────────────┘ (searchable via FTS5) ``` --- ## Plan Deferral Flow ``` 9plan_plan_defer(reason, position?) │ ▼ ┌─────────────────────┐ │ Get Active Plan │ │ from DB │──── Error if none active └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Append to Notes │ │ in Plan File │ │ [timestamp] reason │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Add Back to Queue │ │ (front or back) │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Clear Active Plan │ │ in DB │ └──────────┬──────────┘ │ ▼ Return: success, new queue position ``` **State Change:** ``` BEFORE: AFTER: Active: k7f3m Active: (none) Queue: [m2x9p, p4r2k] Queue: [m2x9p, p4r2k, k7f3m] (if position=back) plans/k7f3m.txt # Notes plans/k7f3m.txt (empty) # Notes [2024-01-15 14:30] Deferred: Waiting for auth dependency ``` --- ## Decomposition Flow ``` Agent pulls plan, decides to decompose 1. Agent updates Notes in plan file: "Decomposing into: A.1, A.2, A.3" 2. Agent adds subplans (reverse order for correct execution): 9plan_queue_add(A.3) → front Queue: [A.3, B, C] 9plan_queue_add(A.2) → front Queue: [A.2, A.3, B, C] 9plan_queue_add(A.1) → front Queue: [A.1, A.2, A.3, B, C] 3. Agent defers parent: 9plan_plan_defer("Decomposed into A.1, A.2, A.3", back) Result: Queue: [A.1, A.2, A.3, B, C, A] │ └── Parent at back 4. Execution proceeds: - A.1 executes, completes - A.2 executes, completes - A.3 executes, completes - B executes, completes - C executes, completes - A (parent) pulled again for aggregation ``` --- ## History Search Flow ``` 9plan_history_search(query) │ ▼ ┌─────────────────────┐ │ FTS5 Query on │ │ history table │ │ │ │ Searches: │ │ - context │ │ - goal │ │ - inputs │ │ - outputs │ │ - approach │ │ - outcome │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Rank Results by │ │ Relevance │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Return Top N │ │ Matches │ │ │ │ For each: │ │ - plan_id │ │ - goal │ │ - outcome │ └──────────┬──────────┘ │ ▼ Agent uses results to resolve inputs ``` **Example Search:** ``` Query: "ghost client API authentication" History: ┌─────────────────────────────────────────────────────────┐ │ k7f3m: "Create authenticated Ghost API client module" │ │ Outcome: "Created ghost_client module in src/lib/..." │ ← MATCH ├─────────────────────────────────────────────────────────┤ │ m2x9p: "Implement response caching system" │ │ Outcome: "Created caching layer..." │ ← no match ├─────────────────────────────────────────────────────────┤ │ x5k9m: "Create PostList UI component" │ │ Outcome: "Created PostList component..." │ ← no match └─────────────────────────────────────────────────────────┘ Returns: [{id: k7f3m, goal: "Create authenticated...", outcome: "..."}] ``` --- ## Session Resume Flow ``` 9plan_session_resume(session_name) │ ▼ ┌─────────────────────┐ │ Find Session │ │ Directory │──── Error if not found └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Open session.db │ └──────────┬──────────┘ │ ▼ ┌───────────────────────────────────────────────────┐ │ GATHER STATE │ │ │ │ ┌────────────────┐ ┌────────────────────────┐ │ │ │ Read metadata │ │ Read queue │ │ │ │ - task desc │ │ - ordered plan IDs │ │ │ └────────────────┘ │ - goals for each │ │ │ └────────────────────────┘ │ │ ┌────────────────┐ ┌────────────────────────┐ │ │ │ Get active │ │ Count completed │ │ │ │ plan (if any) │ │ plans in history │ │ │ └────────────────┘ └────────────────────────┘ │ │ │ └───────────────────────────────────────────────────┘ │ ▼ Return: session_name, session_path, task_description, queue (id + goal for each), active_plan (if any), completed_count ``` --- ## Tool Response Prefix Pattern All tool responses include the session name as a prefix: ``` ┌─────────────────────────────────────────────────────────────┐ │ Tool Response │ │ │ │ [Session: amber-quiet-river] ◄── Always present │ │ │ │ Plan added: k7f3m │ │ Path: /Users/dev/.9plan/sessions/amber-quiet-river/... │ │ Queue position: 1 │ │ │ └─────────────────────────────────────────────────────────────┘ Purpose: Keep session name fresh in context for recovery after context compaction ``` --- ## File System States by Plan Status ``` ┌─────────────────────────────────────────────────────────────┐ │ Plan Status │ ├──────────────┬──────────────┬──────────────┬───────────────┤ │ QUEUED │ ACTIVE │ COMPLETED │ DISCARDED │ ├──────────────┼──────────────┼──────────────┼───────────────┤ │ DB: queue[] │ DB: active │ DB: history │ DB: (removed) │ │ File: YES │ File: YES │ File: NO │ File: NO │ ├──────────────┼──────────────┼──────────────┼───────────────┤ │ plans/ │ plans/ │ (deleted) │ (deleted) │ │ {id}.txt │ {id}.txt │ │ │ │ │ │ Content in │ No record │ │ │ │ session.db │ preserved │ └──────────────┴──────────────┴──────────────┴───────────────┘ ```