summaryrefslogtreecommitdiff
path: root/makima/src/orchestration
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/orchestration')
-rw-r--r--makima/src/orchestration/directive.rs130
1 files changed, 112 insertions, 18 deletions
diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs
index bb573d4..ea8009d 100644
--- a/makima/src/orchestration/directive.rs
+++ b/makima/src/orchestration/directive.rs
@@ -699,33 +699,127 @@ fn build_planning_prompt(
let mut prompt = String::new();
if !existing_steps.is_empty() {
+ // ── RE-PLANNING header ──────────────────────────────────────
prompt.push_str(&format!(
- "EXISTING STEPS (generation {}):\n",
+ "⚠️ RE-PLANNING: The GOAL has been updated — you must re-evaluate ALL existing steps.\n\
+ Previous steps were planned for an earlier version of the goal. Some may no longer be \
+ relevant. Review each step below and act according to the instructions per status category.\n\n\
+ EXISTING STEPS (generation {}):\n",
generation - 1
));
- let mut last_completed_id: Option<Uuid> = None;
+
+ // Categorise steps by status
+ let mut completed: Vec<&crate::db::models::DirectiveStep> = Vec::new();
+ let mut running: Vec<&crate::db::models::DirectiveStep> = Vec::new();
+ let mut pending_ready: Vec<&crate::db::models::DirectiveStep> = Vec::new();
+ let mut failed: Vec<&crate::db::models::DirectiveStep> = Vec::new();
+ let mut skipped: Vec<&crate::db::models::DirectiveStep> = Vec::new();
+
for step in existing_steps {
- prompt.push_str(&format!(
- "- [{}] {} (id: {}): {}\n",
- step.status,
- step.name,
- step.id,
- step.description.as_deref().unwrap_or("(no description)")
- ));
- if step.status == "completed" {
+ match step.status.as_str() {
+ "completed" => completed.push(step),
+ "running" => running.push(step),
+ "pending" | "ready" => pending_ready.push(step),
+ "failed" => failed.push(step),
+ "skipped" => skipped.push(step),
+ _ => pending_ready.push(step),
+ }
+ }
+
+ // ── Completed steps ─────────────────────────────────────────
+ if !completed.is_empty() {
+ prompt.push_str("\n── COMPLETED steps (KEEP — work already done) ──\n");
+ prompt.push_str("These steps have finished. Their work is committed and available.\n");
+ prompt.push_str("Do NOT remove them. New steps can depend on them to inherit their changes.\n");
+ let mut last_completed_id: Option<Uuid> = None;
+ for step in &completed {
+ prompt.push_str(&format!(
+ " ✅ {} (id: {}): {}\n",
+ step.name,
+ step.id,
+ step.description.as_deref().unwrap_or("(no description)")
+ ));
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
+ ));
+ }
+ }
+
+ // ── Running steps ───────────────────────────────────────────
+ if !running.is_empty() {
+ prompt.push_str("\n── RUNNING steps (cannot remove — note if obsolete) ──\n");
+ prompt.push_str("These steps are currently executing and cannot be removed or skipped.\n");
+ prompt.push_str("If a running step is no longer relevant to the NEW goal, note it but do not attempt to remove it.\n");
+ for step in &running {
+ prompt.push_str(&format!(
+ " 🔄 {} (id: {}): {}\n",
+ step.name,
+ step.id,
+ step.description.as_deref().unwrap_or("(no description)")
+ ));
+ }
}
- 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
- ));
+
+ // ── Pending / Ready steps ───────────────────────────────────
+ if !pending_ready.is_empty() {
+ prompt.push_str("\n── PENDING/READY steps (EVALUATE — remove if no longer relevant) ──\n");
+ prompt.push_str("These steps have NOT started yet. Evaluate each against the NEW goal:\n");
+ prompt.push_str(" • If still relevant → leave it in place (no action needed).\n");
+ prompt.push_str(" • If NO LONGER relevant → remove it with: makima directive remove-step <step_id>\n");
+ for step in &pending_ready {
+ prompt.push_str(&format!(
+ " ⏳ [{}] {} (id: {}): {}\n",
+ step.status,
+ step.name,
+ step.id,
+ step.description.as_deref().unwrap_or("(no description)")
+ ));
+ }
+ }
+
+ // ── Failed steps ────────────────────────────────────────────
+ if !failed.is_empty() {
+ prompt.push_str("\n── FAILED steps (EVALUATE — remove if no longer relevant) ──\n");
+ prompt.push_str("These steps failed. Evaluate each against the NEW goal:\n");
+ prompt.push_str(" • If still relevant → remove the failed step and re-add a corrected version.\n");
+ prompt.push_str(" • If NO LONGER relevant → remove it with: makima directive remove-step <step_id>\n");
+ for step in &failed {
+ prompt.push_str(&format!(
+ " ❌ {} (id: {}): {}\n",
+ step.name,
+ step.id,
+ step.description.as_deref().unwrap_or("(no description)")
+ ));
+ }
}
+
+ // ── Skipped steps ───────────────────────────────────────────
+ if !skipped.is_empty() {
+ prompt.push_str("\n── SKIPPED steps (remove if no longer relevant) ──\n");
+ for step in &skipped {
+ prompt.push_str(&format!(
+ " ⏭️ {} (id: {}): {}\n",
+ step.name,
+ step.id,
+ step.description.as_deref().unwrap_or("(no description)")
+ ));
+ }
+ }
+
+ // ── Instructions ────────────────────────────────────────────
prompt.push_str(&format!(
- "\nAdd new steps that build on or complement existing work. Use generation {}.\n\n",
+ "\n── ACTION PLAN ──\n\
+ 1. First, remove any pending/ready/failed/skipped steps that are NOT relevant to the NEW goal:\n\
+ \x20 makima directive remove-step <step_id>\n\
+ 2. Then, add new steps for the updated goal. Use generation {}.\n\
+ 3. New steps that build on completed work MUST use --depends-on to inherit the worktree.\n\
+ 4. Ensure the new plan fully addresses the UPDATED goal.\n\n",
generation
));
}