diff --git a/.claude/commands/issue/execute.md b/.claude/commands/issue/execute.md index a47dffb4..edeeb8ea 100644 --- a/.claude/commands/issue/execute.md +++ b/.claude/commands/issue/execute.md @@ -1,7 +1,7 @@ --- name: execute description: Execute queue with codex using DAG-based parallel orchestration (solution-level) -argument-hint: "" +argument-hint: "[--worktree] [--queue ]" allowed-tools: TodoWrite(*), Bash(*), Read(*), AskUserQuestion(*) --- @@ -17,31 +17,41 @@ Minimal orchestrator that dispatches **solution IDs** to executors. Each executo - `done ` → update solution completion status - No race conditions: status changes only via `done` - **Executor handles all tasks within a solution sequentially** +- **Worktree isolation**: Each executor can work in its own git worktree ## Usage ```bash -/issue:execute +/issue:execute # Execute active queue(s) +/issue:execute --queue QUE-xxx # Execute specific queue +/issue:execute --worktree # Use git worktrees for parallel isolation +/issue:execute --worktree --queue QUE-xxx ``` **Parallelism**: Determined automatically by task dependency DAG (no manual control) **Executor & Dry-run**: Selected via interactive prompt (AskUserQuestion) +**Worktree**: Creates isolated git worktrees for each parallel executor ## Execution Flow ``` +Phase 0 (if --worktree): Setup Worktree Base + └─ Ensure .worktrees directory exists + Phase 1: Get DAG & User Selection - ├─ ccw issue queue dag → { parallel_batches: [["S-1","S-2"], ["S-3"]] } - └─ AskUserQuestion → executor type (codex|gemini|agent), dry-run mode + ├─ ccw issue queue dag [--queue QUE-xxx] → { parallel_batches: [["S-1","S-2"], ["S-3"]] } + └─ AskUserQuestion → executor type (codex|gemini|agent), dry-run mode, worktree mode Phase 2: Dispatch Parallel Batch (DAG-driven) ├─ Parallelism determined by DAG (no manual limit) ├─ For each solution ID in batch (parallel - all at once): + │ ├─ (if worktree) Create isolated worktree: git worktree add │ ├─ Executor calls: ccw issue detail (READ-ONLY) │ ├─ Executor gets FULL SOLUTION with all tasks │ ├─ Executor implements all tasks sequentially (T1 → T2 → T3) │ ├─ Executor tests + commits per task - │ └─ Executor calls: ccw issue done + │ ├─ Executor calls: ccw issue done + │ └─ (if worktree) Cleanup: merge branch, remove worktree └─ Wait for batch completion Phase 3: Next Batch @@ -93,12 +103,22 @@ const answer = AskUserQuestion({ { label: 'Execute (Recommended)', description: 'Run all ready solutions' }, { label: 'Dry-run', description: 'Show DAG and batches without executing' } ] + }, + { + question: 'Use git worktrees for parallel isolation?', + header: 'Worktree', + multiSelect: false, + options: [ + { label: 'Yes (Recommended for parallel)', description: 'Each executor works in isolated worktree branch' }, + { label: 'No', description: 'Work directly in current directory (serial only)' } + ] } ] }); const executor = answer['Executor'].toLowerCase().split(' ')[0]; // codex|gemini|agent const isDryRun = answer['Mode'].includes('Dry-run'); +const useWorktree = answer['Worktree'].includes('Yes'); // Dry run mode if (isDryRun) { @@ -128,10 +148,15 @@ TodoWrite({ console.log(`\n### Executing Solutions (DAG batch 1): ${batch.join(', ')}`); +// Setup worktree base directory if needed +if (useWorktree) { + Bash('mkdir -p ../.worktrees'); +} + // Launch ALL solutions in batch in parallel (DAG guarantees no conflicts) const executions = batch.map(solutionId => { updateTodo(solutionId, 'in_progress'); - return dispatchExecutor(solutionId, executor); + return dispatchExecutor(solutionId, executor, useWorktree); }); await Promise.all(executions); @@ -141,13 +166,32 @@ batch.forEach(id => updateTodo(id, 'completed')); ### Executor Dispatch ```javascript -function dispatchExecutor(solutionId, executorType) { - // Executor fetches FULL SOLUTION via READ-ONLY detail command - // Executor handles all tasks within solution sequentially - // Then reports completion via done command +function dispatchExecutor(solutionId, executorType, useWorktree = false) { + // Worktree setup commands (if enabled) + const worktreeSetup = useWorktree ? ` +### Step 0: Setup Isolated Worktree +\`\`\`bash +WORKTREE_NAME="exec-${solutionId}-$(date +%H%M%S)" +WORKTREE_PATH="../.worktrees/\${WORKTREE_NAME}" +git worktree add "\${WORKTREE_PATH}" -b "\${WORKTREE_NAME}" +cd "\${WORKTREE_PATH}" +\`\`\` +` : ''; + + const worktreeCleanup = useWorktree ? ` +### Step 4: Cleanup Worktree +\`\`\`bash +# Return to main repo and merge +cd - +git merge --no-ff "\${WORKTREE_NAME}" -m "Merge solution ${solutionId}" +git worktree remove "\${WORKTREE_PATH}" +git branch -d "\${WORKTREE_NAME}" +\`\`\` +` : ''; + const prompt = ` ## Execute Solution ${solutionId} - +${worktreeSetup} ### Step 1: Get Solution (read-only) \`\`\`bash ccw issue detail ${solutionId} @@ -171,9 +215,9 @@ ccw issue done ${solutionId} --result '{"summary": "...", "files_modified": [... If any task failed: \`\`\`bash -ccw issue done ${solutionId} --fail --reason "Task TX failed: ..." +ccw issue done ${solutionId} --fail --reason '{"task_id": "TX", "error_type": "test_failure", "message": "..."}' \`\`\` -`; +${worktreeCleanup}`; if (executorType === 'codex') { return Bash( diff --git a/.codex/prompts/issue-execute.md b/.codex/prompts/issue-execute.md index 17dcba24..9ccd514c 100644 --- a/.codex/prompts/issue-execute.md +++ b/.codex/prompts/issue-execute.md @@ -1,6 +1,6 @@ --- description: Execute all solutions from issue queue with git commit after each task -argument-hint: "" +argument-hint: "[--worktree] [--queue ]" --- # Issue Execute (Codex Version) @@ -9,6 +9,39 @@ argument-hint: "" **Serial Execution**: Execute solutions ONE BY ONE from the issue queue via `ccw issue next`. For each solution, complete all tasks sequentially (implement → test → commit per task). Continue autonomously until queue is empty. +## Worktree Mode (Recommended for Parallel Execution) + +When `--worktree` is specified, create a separate git worktree to isolate work: + +```bash +# Step 0: Setup worktree before starting +WORKTREE_NAME="issue-exec-$(date +%Y%m%d-%H%M%S)" +WORKTREE_PATH="../.worktrees/${WORKTREE_NAME}" + +# Create worktree from current branch +git worktree add "${WORKTREE_PATH}" -b "${WORKTREE_NAME}" + +# Change to worktree directory +cd "${WORKTREE_PATH}" + +# Now execute in isolated worktree... +``` + +**Benefits:** +- Parallel executors don't conflict with each other +- Main working directory stays clean +- Easy cleanup after execution + +**Cleanup after completion:** +```bash +# Return to main repo +cd - + +# Remove worktree +git worktree remove "${WORKTREE_PATH}" +git branch -d "${WORKTREE_NAME}" +``` + ## Execution Flow ``` @@ -341,9 +374,11 @@ When `ccw issue next` returns `{ "status": "empty" }`: | Command | Purpose | |---------|---------| -| `ccw issue next` | Fetch next solution from queue | -| `ccw issue done ` | Mark solution complete with result | -| `ccw issue done --fail` | Mark solution failed with reason | +| `ccw issue next` | Fetch next solution from queue (auto-selects from active queues) | +| `ccw issue next --queue QUE-xxx` | Fetch from specific queue | +| `ccw issue done ` | Mark solution complete with result (auto-detects queue) | +| `ccw issue done --fail --reason "..."` | Mark solution failed with structured reason | +| `ccw issue retry --queue QUE-xxx` | Reset failed items in specific queue | ## Start Execution diff --git a/.codex/prompts/issue-queue.md b/.codex/prompts/issue-queue.md index c13be7c2..2003fee2 100644 --- a/.codex/prompts/issue-queue.md +++ b/.codex/prompts/issue-queue.md @@ -183,10 +183,12 @@ Group assignment: ```json { "active_queue_id": "QUE-20251228-120000", + "active_queue_ids": ["QUE-20251228-120000"], "queues": [ { "id": "QUE-20251228-120000", "status": "active", + "priority": 1, "issue_ids": ["ISS-001", "ISS-002"], "total_solutions": 3, "completed_solutions": 0, @@ -196,6 +198,26 @@ Group assignment: } ``` +## Multi-Queue Management + +Multiple queues can be active simultaneously. The system executes queues in priority order (lower = higher priority). + +**Activate multiple queues:** +```bash +ccw issue queue activate QUE-001,QUE-002,QUE-003 +``` + +**Set queue priority:** +```bash +ccw issue queue priority QUE-001 --priority 1 +ccw issue queue priority QUE-002 --priority 2 +``` + +**Execution behavior with multi-queue:** +- `ccw issue next` automatically selects from active queues in priority order +- Complete all items in Q1 before moving to Q2 (serialized execution) +- Use `--queue QUE-xxx` to target a specific queue + ### Step 7: Update Issue Statuses **MUST use CLI command** (NOT direct file operations):