summaryrefslogtreecommitdiff
path: root/makima/docs
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-11 05:52:14 +0000
committersoryu <soryu@soryu.co>2026-01-15 00:21:16 +0000
commit87044a747b47bd83249d61a45842c7f7b2eae56d (patch)
treeef2000ce79ffcc2723ef841acef5aa1deb1d5378 /makima/docs
parent077820c4167c168072d217a1b01df840463a12a8 (diff)
downloadsoryu-87044a747b47bd83249d61a45842c7f7b2eae56d.tar.gz
soryu-87044a747b47bd83249d61a45842c7f7b2eae56d.zip
Contract system
Diffstat (limited to 'makima/docs')
-rw-r--r--makima/docs/PLAN-task-branching.md197
1 files changed, 197 insertions, 0 deletions
diff --git a/makima/docs/PLAN-task-branching.md b/makima/docs/PLAN-task-branching.md
new file mode 100644
index 0000000..cd35bc6
--- /dev/null
+++ b/makima/docs/PLAN-task-branching.md
@@ -0,0 +1,197 @@
+# Task Branching Feature for Makima
+
+## Overview
+
+Add the ability to branch/spin off tasks that resume from where another task ended, preserving both worktree state (file changes) and conversation context (what Claude discussed/discovered).
+
+**Key requirement:** The branched task should "remember" what was previously discussed, enabling exploration of alternative approaches from the same starting point.
+
+## Integration with Contracts
+
+Tasks are grouped under **contracts** - organizational units with phases (research → specify → plan → execute → review). When branching:
+
+- **Inherit contract**: Branched tasks stay in the same contract as the source task by default
+- **Optional override**: User can choose to place the branch in a different contract
+- **Phase awareness**: The branch inherits the contract's current phase context
+
+## Architecture Summary
+
+Since Claude Code is stateless (each invocation is fresh), we cannot replay the actual conversation. Instead, we:
+1. Capture and store conversation turns (user messages + assistant responses)
+2. When branching, inject a formatted transcript as context in the new task's plan
+3. Copy the worktree state using existing `continue_from_task_id` mechanism
+
+## Implementation Plan
+
+### Phase 1: Capture Conversation History
+
+**1.1 Database Migration**
+
+Create `makima/migrations/20250111000000_add_task_conversations.sql`:
+
+```sql
+CREATE TABLE IF NOT EXISTS task_conversations (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
+ turn_index INTEGER NOT NULL,
+ role VARCHAR(32) NOT NULL, -- 'user', 'assistant'
+ content TEXT NOT NULL,
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
+);
+CREATE INDEX idx_task_conversations_task_id ON task_conversations(task_id);
+```
+
+**1.2 Capture User Messages**
+
+Modify `makima/daemon/src/task/manager.rs`:
+- When sending initial plan to Claude, emit a `ConversationTurn` message to server
+- When forwarding user messages from `input_rx`, emit a `ConversationTurn` message
+
+**1.3 Capture Assistant Responses**
+
+Modify `makima/src/server/handlers/mesh_daemon.rs`:
+- Aggregate `TaskOutputEntry` messages with `message_type='assistant'` into conversation turns
+- Store in `task_conversations` table when a user message arrives (marks end of assistant turn)
+
+**1.4 New Protocol Message**
+
+Add to `makima/daemon/src/ws/protocol.rs` and `makima/src/server/protocol.rs`:
+```rust
+ConversationTurn {
+ task_id: Uuid,
+ turn_index: i32,
+ role: String, // "user" or "assistant"
+ content: String,
+}
+```
+
+### Phase 2: Branching Infrastructure
+
+**2.1 Database Migration**
+
+Create `makima/migrations/20250111000001_add_branching_fields.sql`:
+
+```sql
+ALTER TABLE tasks ADD COLUMN branched_from_task_id UUID REFERENCES tasks(id) ON DELETE SET NULL;
+CREATE INDEX idx_tasks_branched_from ON tasks(branched_from_task_id) WHERE branched_from_task_id IS NOT NULL;
+```
+
+**2.2 Update Task Model**
+
+Modify `makima/src/db/models.rs`:
+```rust
+pub struct Task {
+ // ... existing fields ...
+ pub branched_from_task_id: Option<Uuid>,
+}
+
+pub struct BranchTaskRequest {
+ pub name: Option<String>,
+ pub plan: String,
+ pub include_conversation: bool, // default true
+ pub include_worktree: bool, // default true
+ pub contract_id: Option<Uuid>, // if None, inherit from source task
+}
+```
+
+**2.3 New Branch Endpoint**
+
+Add to `makima/src/server/handlers/mesh.rs`:
+- `POST /api/v1/mesh/tasks/{id}/branch` handler
+- Validates source task exists and user has permission
+- Fetches conversation history from `task_conversations`
+- Creates new task with:
+ - `branched_from_task_id` = source task ID
+ - `continue_from_task_id` = source task ID (for worktree copying)
+ - `contract_id` = request.contract_id OR source task's contract_id
+ - Plan = formatted conversation context + new instructions
+
+### Phase 3: Context Injection
+
+**3.1 Format Conversation Transcript**
+
+Add helper function in `makima/src/server/handlers/mesh.rs`:
+```rust
+fn format_conversation_context(turns: Vec<ConversationTurn>) -> String {
+ // Format as:
+ // ## Previous Conversation Context
+ //
+ // **User:** {message}
+ // **Assistant:** {response}
+ // ...
+ //
+ // ---
+}
+```
+
+**3.2 Prepend to Branched Task Plan**
+
+When creating a branched task, construct the plan as:
+```
+{formatted_conversation_context}
+
+## New Instructions
+
+{user's new plan}
+```
+
+### Phase 4: Frontend Integration
+
+**4.1 API Client**
+
+Add to `makima/frontend/src/lib/api.ts`:
+```typescript
+branchTask(id: string, request: BranchTaskRequest): Promise<Task>
+```
+
+**4.2 Branch Button**
+
+Add to `makima/frontend/src/components/mesh/TaskDetail.tsx`:
+- "Branch" button in task actions
+- Opens dialog to enter new instructions
+- Checkboxes for "Include conversation" and "Include file changes"
+- Contract selector (defaults to current contract, allows choosing another)
+
+**4.3 Tree Visualization (Optional)**
+
+Show `branched_from_task_id` relationships in task list to visualize the branch tree.
+
+**4.4 Contract Tasks View**
+
+Update `makima/frontend/src/components/contracts/ContractDetail.tsx`:
+- Show branched tasks in the Tasks tab with visual indicators
+- Display branch relationships (e.g., "Branched from: Task X")
+
+## Files to Modify
+
+### Backend (Server)
+- `makima/src/db/models.rs` - Add `BranchTaskRequest`, extend `Task`
+- `makima/src/db/repository.rs` - Add conversation CRUD, branch query
+- `makima/src/server/handlers/mesh.rs` - Add `branch_task` handler
+- `makima/src/server/handlers/mesh_daemon.rs` - Store conversation turns
+- `makima/src/server/protocol.rs` - Add `ConversationTurn` message
+
+### Backend (Daemon)
+- `makima/daemon/src/ws/protocol.rs` - Add `ConversationTurn` message
+- `makima/daemon/src/task/manager.rs` - Emit user messages as conversation turns
+
+### Migrations
+- `makima/migrations/20250111000000_add_task_conversations.sql`
+- `makima/migrations/20250111000001_add_branching_fields.sql`
+
+### Frontend
+- `makima/frontend/src/lib/api.ts` - Add `branchTask()` method and types
+- `makima/frontend/src/components/mesh/TaskDetail.tsx` - Add Branch button/dialog
+- `makima/frontend/src/components/contracts/ContractDetail.tsx` - Show branch relationships in Tasks tab
+
+## Key Design Decisions
+
+1. **Conversation as context, not replay** - We prepend a transcript to the plan rather than trying to inject messages into Claude Code (which only accepts user messages)
+
+2. **Separate from parent-child hierarchy** - Using `branched_from_task_id` instead of `parent_task_id` to distinguish from orchestrator/subtask relationships
+
+3. **Reuse existing worktree mechanism** - Set `continue_from_task_id` to copy files from source task
+
+4. **Opt-in conversation/worktree** - Both are configurable per-branch request
+
+5. **Contract inheritance** - Branched tasks inherit the source task's contract by default, but can be placed in a different contract if needed (e.g., branching research findings into a new execute-phase contract)