diff options
| author | soryu <soryu@soryu.co> | 2026-01-26 20:26:28 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-01-26 20:26:28 +0000 |
| commit | 3dd8f32bad2b3ba886f0b0ab4c4796fd67ec0bca (patch) | |
| tree | 8571846b2534d5ff3ec9335ed2aa75c07c4a176f /makima/src | |
| parent | 04e1e8f0dd85d19917ac5ba0b73cba65ebac8976 (diff) | |
| parent | 4c94ee44ca71eb2e80ed2bba3efb2f9cff581ae6 (diff) | |
| download | soryu-3dd8f32bad2b3ba886f0b0ab4c4796fd67ec0bca.tar.gz soryu-3dd8f32bad2b3ba886f0b0ab4c4796fd67ec0bca.zip | |
Phase 1.1: Add local_only flag to contracts
Diffstat (limited to 'makima/src')
| -rw-r--r-- | makima/src/db/models.rs | 15 | ||||
| -rw-r--r-- | makima/src/db/repository.rs | 19 | ||||
| -rw-r--r-- | makima/src/server/handlers/contract_chat.rs | 1 | ||||
| -rw-r--r-- | makima/src/server/handlers/contracts.rs | 4 | ||||
| -rw-r--r-- | makima/src/server/handlers/transcript_analysis.rs | 1 |
5 files changed, 33 insertions, 7 deletions
diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index 95517a1..21e5370 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -1326,6 +1326,10 @@ pub struct Contract { #[sqlx(json)] #[serde(default)] pub completed_deliverables: serde_json::Value, + /// When true, tasks do not auto-execute completion actions and work stays in worktrees. + /// Used for local-only workflows where changes are managed manually. + #[serde(default)] + pub local_only: bool, pub version: i32, pub created_at: DateTime<Utc>, pub updated_at: DateTime<Utc>, @@ -1441,6 +1445,9 @@ pub struct ContractSummary { pub status: String, /// Supervisor task ID for contract orchestration pub supervisor_task_id: Option<Uuid>, + /// When true, tasks do not auto-execute completion actions and work stays in worktrees. + #[serde(default)] + pub local_only: bool, pub file_count: i64, pub task_count: i64, pub repository_count: i64, @@ -1495,6 +1502,10 @@ pub struct CreateContractRequest { /// phase outputs before progressing to the next phase. #[serde(default)] pub phase_guard: Option<bool>, + /// Enable local-only mode for this contract. + /// When true, tasks do not auto-execute completion actions and work stays in worktrees. + #[serde(default)] + pub local_only: Option<bool>, } /// Request payload for updating a contract @@ -1516,6 +1527,10 @@ pub struct UpdateContractRequest { /// phase outputs before progressing to the next phase. #[serde(default)] pub phase_guard: Option<bool>, + /// Enable or disable local-only mode for this contract. + /// When true, tasks do not auto-execute completion actions and work stays in worktrees. + #[serde(default)] + pub local_only: Option<bool>, /// Version for optimistic locking pub version: Option<i32>, } diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs index b55b05e..6d6642b 100644 --- a/makima/src/db/repository.rs +++ b/makima/src/db/repository.rs @@ -2175,11 +2175,12 @@ pub async fn create_contract_for_owner( let autonomous_loop = req.autonomous_loop.unwrap_or(false); let phase_guard = req.phase_guard.unwrap_or(false); + let local_only = req.local_only.unwrap_or(false); sqlx::query_as::<_, Contract>( r#" - INSERT INTO contracts (owner_id, name, description, contract_type, phase, autonomous_loop, phase_guard) - VALUES ($1, $2, $3, $4, $5, $6, $7) + INSERT INTO contracts (owner_id, name, description, contract_type, phase, autonomous_loop, phase_guard, local_only) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING * "#, ) @@ -2190,6 +2191,7 @@ pub async fn create_contract_for_owner( .bind(phase) .bind(autonomous_loop) .bind(phase_guard) + .bind(local_only) .fetch_one(pool) .await } @@ -2222,7 +2224,7 @@ pub async fn list_contracts_for_owner( r#" SELECT c.id, c.name, c.description, c.contract_type, c.phase, c.status, - c.supervisor_task_id, c.version, c.created_at, + c.supervisor_task_id, c.local_only, c.version, c.created_at, (SELECT COUNT(*) FROM files WHERE contract_id = c.id) as file_count, (SELECT COUNT(*) FROM tasks WHERE contract_id = c.id) as task_count, (SELECT COUNT(*) FROM contract_repositories WHERE contract_id = c.id) as repository_count @@ -2246,7 +2248,7 @@ pub async fn get_contract_summary_for_owner( r#" SELECT c.id, c.name, c.description, c.contract_type, c.phase, c.status, - c.supervisor_task_id, c.version, c.created_at, + c.supervisor_task_id, c.local_only, c.version, c.created_at, (SELECT COUNT(*) FROM files WHERE contract_id = c.id) as file_count, (SELECT COUNT(*) FROM tasks WHERE contract_id = c.id) as task_count, (SELECT COUNT(*) FROM contract_repositories WHERE contract_id = c.id) as repository_count @@ -2290,14 +2292,15 @@ pub async fn update_contract_for_owner( let supervisor_task_id = req.supervisor_task_id.or(existing.supervisor_task_id); let autonomous_loop = req.autonomous_loop.unwrap_or(existing.autonomous_loop); let phase_guard = req.phase_guard.unwrap_or(existing.phase_guard); + let local_only = req.local_only.unwrap_or(existing.local_only); let result = if req.version.is_some() { sqlx::query_as::<_, Contract>( r#" UPDATE contracts SET name = $3, description = $4, phase = $5, status = $6, - supervisor_task_id = $7, autonomous_loop = $8, phase_guard = $9, version = version + 1, updated_at = NOW() - WHERE id = $1 AND owner_id = $2 AND version = $10 + supervisor_task_id = $7, autonomous_loop = $8, phase_guard = $9, local_only = $10, version = version + 1, updated_at = NOW() + WHERE id = $1 AND owner_id = $2 AND version = $11 RETURNING * "#, ) @@ -2310,6 +2313,7 @@ pub async fn update_contract_for_owner( .bind(supervisor_task_id) .bind(autonomous_loop) .bind(phase_guard) + .bind(local_only) .bind(req.version.unwrap()) .fetch_optional(pool) .await? @@ -2318,7 +2322,7 @@ pub async fn update_contract_for_owner( r#" UPDATE contracts SET name = $3, description = $4, phase = $5, status = $6, - supervisor_task_id = $7, autonomous_loop = $8, phase_guard = $9, version = version + 1, updated_at = NOW() + supervisor_task_id = $7, autonomous_loop = $8, phase_guard = $9, local_only = $10, version = version + 1, updated_at = NOW() WHERE id = $1 AND owner_id = $2 RETURNING * "#, @@ -2332,6 +2336,7 @@ pub async fn update_contract_for_owner( .bind(supervisor_task_id) .bind(autonomous_loop) .bind(phase_guard) + .bind(local_only) .fetch_optional(pool) .await? }; diff --git a/makima/src/server/handlers/contract_chat.rs b/makima/src/server/handlers/contract_chat.rs index e035368..8c5509e 100644 --- a/makima/src/server/handlers/contract_chat.rs +++ b/makima/src/server/handlers/contract_chat.rs @@ -2574,6 +2574,7 @@ async fn handle_contract_request( initial_phase: Some("research".to_string()), autonomous_loop: None, phase_guard: None, + local_only: None, }; let contract = match repository::create_contract_for_owner(pool, owner_id, contract_req).await { diff --git a/makima/src/server/handlers/contracts.rs b/makima/src/server/handlers/contracts.rs index de3164c..3498063 100644 --- a/makima/src/server/handlers/contracts.rs +++ b/makima/src/server/handlers/contracts.rs @@ -366,6 +366,7 @@ pub async fn create_contract( phase: contract.phase, status: contract.status, supervisor_task_id: contract.supervisor_task_id, + local_only: contract.local_only, file_count: 0, task_count: 0, repository_count: 0, @@ -387,6 +388,7 @@ pub async fn create_contract( phase: contract.phase, status: contract.status, supervisor_task_id: contract.supervisor_task_id, + local_only: contract.local_only, file_count: 0, task_count: 0, repository_count: 0, @@ -515,6 +517,7 @@ pub async fn update_contract( phase: contract.phase, status: contract.status, supervisor_task_id: contract.supervisor_task_id, + local_only: contract.local_only, file_count: 0, task_count: 0, repository_count: 0, @@ -1399,6 +1402,7 @@ pub async fn change_phase( phase: updated_contract.phase, status: updated_contract.status, supervisor_task_id: updated_contract.supervisor_task_id, + local_only: updated_contract.local_only, file_count: 0, task_count: 0, repository_count: 0, diff --git a/makima/src/server/handlers/transcript_analysis.rs b/makima/src/server/handlers/transcript_analysis.rs index 3b71eca..8eb50c7 100644 --- a/makima/src/server/handlers/transcript_analysis.rs +++ b/makima/src/server/handlers/transcript_analysis.rs @@ -278,6 +278,7 @@ pub async fn create_contract_from_analysis( initial_phase: Some("research".to_string()), autonomous_loop: None, phase_guard: None, + local_only: None, }; let contract = match repository::create_contract_for_owner(pool, auth.owner_id, contract_req).await { |
