diff options
| author | soryu <soryu@soryu.co> | 2026-02-13 00:57:34 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-13 00:57:34 +0000 |
| commit | 639b4c6bc3b3964c00cdfc64c4f262c61ee22fc7 (patch) | |
| tree | 6ba4c1cd323f728453b95e19b9215e40974d1377 /makima/src/orchestration | |
| parent | 39df770ea4ae37f3f9e30c5be5274b741e7ecf7b (diff) | |
| download | soryu-639b4c6bc3b3964c00cdfc64c4f262c61ee22fc7.tar.gz soryu-639b4c6bc3b3964c00cdfc64c4f262c61ee22fc7.zip | |
Make sure directive tasks inherit worktrees
Diffstat (limited to 'makima/src/orchestration')
| -rw-r--r-- | makima/src/orchestration/directive.rs | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs index d2fcbfd..344bdf5 100644 --- a/makima/src/orchestration/directive.rs +++ b/makima/src/orchestration/directive.rs @@ -101,7 +101,42 @@ impl DirectiveOrchestrator { // Resolve dependency steps to their task IDs for worktree continuation let dep_tasks = repository::get_step_dependency_tasks(&self.pool, &step.depends_on).await?; - let continue_from_task_id = dep_tasks.first().map(|d| d.task_id); + let mut continue_from_task_id = dep_tasks.first().map(|d| d.task_id); + + // If no dependency tasks resolved, try to continue from previous work: + // 1) Use the directive's PR branch as base (contains all previous merged work) + // 2) Fall back to the last completed step's task for worktree continuation + let effective_base_branch = if continue_from_task_id.is_none() { + if step.pr_branch.is_some() { + tracing::info!( + step_id = %step.step_id, + pr_branch = ?step.pr_branch, + "Step has no deps — using directive PR branch as base" + ); + step.pr_branch.as_deref() + } else { + // No PR branch yet — try to continue from the last completed step's worktree + match repository::get_last_completed_step_task_id( + &self.pool, + step.directive_id, + ) + .await + { + Ok(Some(task_id)) => { + tracing::info!( + step_id = %step.step_id, + continue_from = %task_id, + "Step has no deps, no PR branch — continuing from last completed task" + ); + continue_from_task_id = Some(task_id); + step.base_branch.as_deref() + } + _ => step.base_branch.as_deref(), + } + } + } else { + step.base_branch.as_deref() + }; let task_plan = step .task_plan @@ -180,7 +215,7 @@ impl DirectiveOrchestrator { format!("{}: {}", step.directive_title, step.step_name), plan, step.repository_url.as_deref(), - step.base_branch.as_deref(), + effective_base_branch, continue_from_task_id, ) .await @@ -746,13 +781,26 @@ fn build_planning_prompt( "EXISTING STEPS (generation {}):\n", generation - 1 )); + let mut last_completed_id: Option<Uuid> = None; for step in existing_steps { prompt.push_str(&format!( - "- {} [{}]: {}\n", - step.name, + "- [{}] {} (id: {}): {}\n", step.status, + step.name, + step.id, step.description.as_deref().unwrap_or("(no description)") )); + if step.status == "completed" { + last_completed_id = Some(step.id); + } + } + if let Some(last_id) = last_completed_id { + prompt.push_str(&format!( + "\nNew steps that build on previous work SHOULD use --depends-on \"{}\" (the last completed step) \ + so their worktree inherits all prior changes. Without this dependency, new steps start from a \ + fresh checkout and won't see any of the work done by previous steps.\n", + last_id + )); } prompt.push_str(&format!( "\nAdd new steps that build on or complement existing work. Use generation {}.\n\n", @@ -789,9 +837,21 @@ Or batch: makima directive batch-add-steps --json '[{{"name":"...","description":"...","taskPlan":"...","dependsOn":[],"orderIndex":0}}]' DEPENDENCY WORKTREE CONTINUATION: -When a step has dependsOn, it automatically continues from the first dependency's worktree (inheriting -committed and uncommitted changes). If there are multiple dependencies, the first provides the base worktree -and additional dependency branches are merged in before work starts. Use this for incremental work chains. +Each step runs in its own git worktree. How that worktree is initialised depends on dependsOn: +- With dependsOn: the step continues from the first dependency's worktree (inheriting all committed and + uncommitted changes). Additional dependencies are merged in as branches before work starts. +- Without dependsOn: the step starts from a FRESH worktree based on the base branch (or the PR branch if + a PR already exists from previous completions). + +Because of this, you MUST chain steps using dependsOn whenever one step's work builds on another's. +If step B modifies files created/changed by step A, step B MUST list step A in its dependsOn — otherwise +step B will start from a blank worktree and won't see step A's changes at all. + +Guidelines: +- For sequential work, create a linear chain: step1 → step2 → step3 (each depends on the previous). +- Only omit dependsOn for truly independent steps that can start from a fresh checkout. +- Parallel steps that share no files can omit mutual dependencies, but if they both build on a prior step + they should BOTH list that prior step in dependsOn. IMPORTANT: Each step's taskPlan must be self-contained. The executing instance won't have your planning context. "#, |
