summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-15 11:34:06 +0000
committersoryu <soryu@soryu.co>2026-01-15 11:34:06 +0000
commit1f853a39334cc80bb7a27142076c64ad0214c037 (patch)
tree07452cce86ff15928ac0d265bb2a7b945612d956
parentf432cd73e17ae3470349431ab344d9168be4d580 (diff)
downloadsoryu-1f853a39334cc80bb7a27142076c64ad0214c037.tar.gz
soryu-1f853a39334cc80bb7a27142076c64ad0214c037.zip
Advance stages of a contract
-rw-r--r--makima/src/bin/makima.rs8
-rw-r--r--makima/src/daemon/api/supervisor.rs17
-rw-r--r--makima/src/daemon/cli/mod.rs3
-rw-r--r--makima/src/daemon/cli/supervisor.rs26
-rw-r--r--makima/src/daemon/task/manager.rs49
-rw-r--r--makima/src/db/repository.rs4
-rw-r--r--makima/src/server/handlers/mesh_chat.rs2
7 files changed, 100 insertions, 9 deletions
diff --git a/makima/src/bin/makima.rs b/makima/src/bin/makima.rs
index 5c71885..4fc331c 100644
--- a/makima/src/bin/makima.rs
+++ b/makima/src/bin/makima.rs
@@ -339,6 +339,14 @@ async fn run_supervisor(
.await?;
println!("{}", serde_json::to_string(&result.0)?);
}
+ SupervisorCommand::AdvancePhase(args) => {
+ let client = ApiClient::new(args.common.api_url, args.common.api_key)?;
+ eprintln!("Advancing contract to phase: {}...", args.phase);
+ let result = client
+ .supervisor_advance_phase(args.common.contract_id, &args.phase)
+ .await?;
+ println!("{}", serde_json::to_string(&result.0)?);
+ }
}
Ok(())
diff --git a/makima/src/daemon/api/supervisor.rs b/makima/src/daemon/api/supervisor.rs
index a1e8682..0a68980 100644
--- a/makima/src/daemon/api/supervisor.rs
+++ b/makima/src/daemon/api/supervisor.rs
@@ -211,4 +211,21 @@ impl ApiClient {
};
self.post("/api/v1/mesh/supervisor/questions", &req).await
}
+
+ /// Advance contract to a new phase.
+ pub async fn supervisor_advance_phase(
+ &self,
+ contract_id: Uuid,
+ phase: &str,
+ ) -> Result<JsonValue, ApiError> {
+ #[derive(Serialize)]
+ struct AdvancePhaseRequest {
+ phase: String,
+ }
+ let req = AdvancePhaseRequest {
+ phase: phase.to_string(),
+ };
+ self.post(&format!("/api/v1/contracts/{}/phase", contract_id), &req)
+ .await
+ }
}
diff --git a/makima/src/daemon/cli/mod.rs b/makima/src/daemon/cli/mod.rs
index 66c7941..1a49399 100644
--- a/makima/src/daemon/cli/mod.rs
+++ b/makima/src/daemon/cli/mod.rs
@@ -77,6 +77,9 @@ pub enum SupervisorCommand {
/// Get contract status
Status(SupervisorArgs),
+ /// Advance the contract to the next phase
+ AdvancePhase(supervisor::AdvancePhaseArgs),
+
/// Ask a question and wait for user feedback
Ask(supervisor::AskArgs),
}
diff --git a/makima/src/daemon/cli/supervisor.rs b/makima/src/daemon/cli/supervisor.rs
index ebfb4bc..dc534b5 100644
--- a/makima/src/daemon/cli/supervisor.rs
+++ b/makima/src/daemon/cli/supervisor.rs
@@ -7,19 +7,19 @@ use uuid::Uuid;
#[derive(Args, Debug, Clone)]
pub struct SupervisorArgs {
/// API URL
- #[arg(long, env = "MAKIMA_API_URL", default_value = "http://localhost:8080", global = true)]
+ #[arg(long, env = "MAKIMA_API_URL", default_value = "http://localhost:8080")]
pub api_url: String,
/// API key for authentication
- #[arg(long, env = "MAKIMA_API_KEY", global = true)]
+ #[arg(long, env = "MAKIMA_API_KEY")]
pub api_key: String,
/// Current task ID (optional)
- #[arg(long, env = "MAKIMA_TASK_ID", global = true)]
+ #[arg(long, env = "MAKIMA_TASK_ID")]
pub task_id: Option<Uuid>,
/// Contract ID
- #[arg(long, env = "MAKIMA_CONTRACT_ID", global = true)]
+ #[arg(long, env = "MAKIMA_CONTRACT_ID")]
pub contract_id: Uuid,
}
@@ -181,3 +181,21 @@ pub struct AskArgs {
#[arg(long, default_value = "3600")]
pub timeout: i32,
}
+
+/// Arguments for status command (get contract status including phase).
+#[derive(Args, Debug)]
+pub struct StatusArgs {
+ #[command(flatten)]
+ pub common: SupervisorArgs,
+}
+
+/// Arguments for advance-phase command.
+#[derive(Args, Debug)]
+pub struct AdvancePhaseArgs {
+ #[command(flatten)]
+ pub common: SupervisorArgs,
+
+ /// The phase to advance to (specify, plan, execute, review)
+ #[arg(index = 1)]
+ pub phase: String,
+}
diff --git a/makima/src/daemon/task/manager.rs b/makima/src/daemon/task/manager.rs
index e6a4e29..4ccedb2 100644
--- a/makima/src/daemon/task/manager.rs
+++ b/makima/src/daemon/task/manager.rs
@@ -708,10 +708,13 @@ makima supervisor checkpoint "Checkpoint message"
makima supervisor checkpoints [task_id]
```
-### Contract
+### Contract & Phase Management
```bash
-# Get contract status
+# Get contract status (including current phase)
makima supervisor status
+
+# Advance to the next phase (specify, plan, execute, review)
+makima supervisor advance-phase <phase>
```
### User Feedback
@@ -759,6 +762,48 @@ The ask command will block until the user responds (or timeout). Use this to:
### For "Specification" contracts (Research → Specify → Plan → Execute → Review):
Progress through each phase, spawning tasks as needed and asking for user feedback.
+## Phase Management Commands
+
+Check contract status (including current phase):
+```bash
+makima supervisor status
+```
+
+Advance to the next phase:
+```bash
+makima supervisor advance-phase <phase>
+```
+
+Valid phases: `specify`, `plan`, `execute`, `review`
+
+## When to Advance Phases
+
+**IMPORTANT**: You MUST advance the contract phase as you complete work in each phase!
+
+### Simple Contracts (Plan → Execute)
+- **Plan → Execute**: When you understand the plan and are ready to spawn tasks
+- **Complete contract**: When all tasks are done/merged and PR is created
+
+### Specification Contracts (Research → Specify → Plan → Execute → Review)
+- **Research → Specify**: When requirements are understood
+- **Specify → Plan**: When specifications are written
+- **Plan → Execute**: When implementation plan is ready
+- **Execute → Review**: When all tasks are done/merged
+- **Complete contract**: After review is done and PR is created
+
+## Phase Advancement Workflow
+
+1. Complete work for current phase (spawn tasks, wait, merge)
+2. Check status: `makima supervisor status`
+3. Ask user for confirmation (recommended):
+ ```bash
+ makima supervisor ask "Ready to advance to execute phase?" --choices "Yes,Not yet"
+ ```
+4. Advance: `makima supervisor advance-phase execute`
+5. Continue with next phase work
+
+**DO NOT forget to advance phases!** The user needs to see the contract progressing.
+
## Key Points
1. **Create a makima branch first** - use `branch "makima/{name}"` for the contract's work
diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs
index 2f28c1a..0e85be1 100644
--- a/makima/src/db/repository.rs
+++ b/makima/src/db/repository.rs
@@ -6,10 +6,10 @@ use uuid::Uuid;
use super::models::{
Contract, ContractChatConversation, ContractChatMessageRecord, ContractEvent, ContractRepository,
- ContractSummary, CreateCheckpointRequest, CreateContractRequest, CreateFileRequest,
+ ContractSummary, CreateContractRequest, CreateFileRequest,
CreateTaskRequest, Daemon, DaemonTaskAssignment, DaemonWithCapacity, File, FileSummary,
FileVersion, MeshChatConversation, MeshChatMessageRecord, SupervisorState, Task, TaskCheckpoint,
- TaskEvent, TaskSummary, UpdateContractRequest, UpdateFileRequest, UpdateSupervisorStateRequest,
+ TaskEvent, TaskSummary, UpdateContractRequest, UpdateFileRequest,
UpdateTaskRequest,
};
diff --git a/makima/src/server/handlers/mesh_chat.rs b/makima/src/server/handlers/mesh_chat.rs
index 3f650bc..9936ffc 100644
--- a/makima/src/server/handlers/mesh_chat.rs
+++ b/makima/src/server/handlers/mesh_chat.rs
@@ -2060,7 +2060,7 @@ async fn handle_mesh_request(
data: None,
}
}
- MeshToolRequest::SpawnTask { name, plan, parent_task_id, checkpoint_sha, .. } => {
+ MeshToolRequest::SpawnTask { name, .. } => {
MeshRequestResult {
success: false,
message: format!(