summaryrefslogtreecommitdiff
path: root/makima
diff options
context:
space:
mode:
Diffstat (limited to 'makima')
-rw-r--r--makima/migrations/20250119000000_add_phase_guard.sql9
-rw-r--r--makima/src/db/models.rs15
-rw-r--r--makima/src/db/repository.rs15
-rw-r--r--makima/src/server/handlers/contract_chat.rs1
-rw-r--r--makima/src/server/handlers/mesh.rs1
-rw-r--r--makima/src/server/handlers/transcript_analysis.rs1
6 files changed, 37 insertions, 5 deletions
diff --git a/makima/migrations/20250119000000_add_phase_guard.sql b/makima/migrations/20250119000000_add_phase_guard.sql
new file mode 100644
index 0000000..dfa642a
--- /dev/null
+++ b/makima/migrations/20250119000000_add_phase_guard.sql
@@ -0,0 +1,9 @@
+-- Add phase_guard column to contracts table
+-- When enabled, the supervisor will wait for user confirmation before progressing to the next phase.
+-- This allows users to review and potentially amend phase outputs (plans, requirements, etc.)
+-- before the contract continues to the next phase.
+
+ALTER TABLE contracts
+ADD COLUMN IF NOT EXISTS phase_guard BOOLEAN NOT NULL DEFAULT FALSE;
+
+COMMENT ON COLUMN contracts.phase_guard IS 'Whether to wait for user confirmation before progressing to the next phase';
diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs
index 72ba6f2..33ef52e 100644
--- a/makima/src/db/models.rs
+++ b/makima/src/db/models.rs
@@ -1264,6 +1264,11 @@ pub struct Contract {
/// without a COMPLETION_GATE indicating ready: true.
#[serde(default)]
pub autonomous_loop: bool,
+ /// Whether to wait for user confirmation before progressing to the next phase.
+ /// When enabled, the supervisor will pause and ask the user to review and approve
+ /// phase outputs (like plans, requirements, etc.) before continuing.
+ #[serde(default)]
+ pub phase_guard: bool,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
@@ -1389,6 +1394,11 @@ pub struct CreateContractRequest {
/// without a COMPLETION_GATE indicating ready: true.
#[serde(default)]
pub autonomous_loop: Option<bool>,
+ /// Enable phase guard mode for this contract.
+ /// When enabled, the supervisor will pause and ask the user to review and approve
+ /// phase outputs before progressing to the next phase.
+ #[serde(default)]
+ pub phase_guard: Option<bool>,
}
/// Request payload for updating a contract
@@ -1405,6 +1415,11 @@ pub struct UpdateContractRequest {
/// Enable or disable autonomous loop mode for tasks in this contract.
#[serde(default)]
pub autonomous_loop: Option<bool>,
+ /// Enable or disable phase guard mode for this contract.
+ /// When enabled, the supervisor will pause and ask the user to review and approve
+ /// phase outputs before progressing to the next phase.
+ #[serde(default)]
+ pub phase_guard: 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 43b8e3a..3d1efd1 100644
--- a/makima/src/db/repository.rs
+++ b/makima/src/db/repository.rs
@@ -2136,11 +2136,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);
sqlx::query_as::<_, Contract>(
r#"
- INSERT INTO contracts (owner_id, name, description, contract_type, phase, autonomous_loop)
- VALUES ($1, $2, $3, $4, $5, $6)
+ INSERT INTO contracts (owner_id, name, description, contract_type, phase, autonomous_loop, phase_guard)
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
RETURNING *
"#,
)
@@ -2150,6 +2151,7 @@ pub async fn create_contract_for_owner(
.bind(contract_type)
.bind(phase)
.bind(autonomous_loop)
+ .bind(phase_guard)
.fetch_one(pool)
.await
}
@@ -2249,14 +2251,15 @@ pub async fn update_contract_for_owner(
let status = req.status.unwrap_or(existing.status);
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 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, version = version + 1, updated_at = NOW()
- WHERE id = $1 AND owner_id = $2 AND version = $9
+ 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
RETURNING *
"#,
)
@@ -2268,6 +2271,7 @@ pub async fn update_contract_for_owner(
.bind(&status)
.bind(supervisor_task_id)
.bind(autonomous_loop)
+ .bind(phase_guard)
.bind(req.version.unwrap())
.fetch_optional(pool)
.await?
@@ -2276,7 +2280,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, version = version + 1, updated_at = NOW()
+ supervisor_task_id = $7, autonomous_loop = $8, phase_guard = $9, version = version + 1, updated_at = NOW()
WHERE id = $1 AND owner_id = $2
RETURNING *
"#,
@@ -2289,6 +2293,7 @@ pub async fn update_contract_for_owner(
.bind(&status)
.bind(supervisor_task_id)
.bind(autonomous_loop)
+ .bind(phase_guard)
.fetch_optional(pool)
.await?
};
diff --git a/makima/src/server/handlers/contract_chat.rs b/makima/src/server/handlers/contract_chat.rs
index 101b257..48dd864 100644
--- a/makima/src/server/handlers/contract_chat.rs
+++ b/makima/src/server/handlers/contract_chat.rs
@@ -2377,6 +2377,7 @@ async fn handle_contract_request(
contract_type: Some("specification".to_string()),
initial_phase: Some("research".to_string()),
autonomous_loop: None,
+ phase_guard: None,
};
let contract = match repository::create_contract_for_owner(pool, owner_id, contract_req).await {
diff --git a/makima/src/server/handlers/mesh.rs b/makima/src/server/handlers/mesh.rs
index 5a08a49..f8df69f 100644
--- a/makima/src/server/handlers/mesh.rs
+++ b/makima/src/server/handlers/mesh.rs
@@ -3239,6 +3239,7 @@ pub async fn create_adhoc_task(
contract_type: Some(CONTRACT_TYPE_TASK.to_string()),
initial_phase: Some("execute".to_string()), // Skip planning
autonomous_loop: Some(false),
+ phase_guard: None,
};
let contract = match repository::create_contract_for_owner(pool, auth.owner_id, contract_req).await {
diff --git a/makima/src/server/handlers/transcript_analysis.rs b/makima/src/server/handlers/transcript_analysis.rs
index 275905e..99f9ea7 100644
--- a/makima/src/server/handlers/transcript_analysis.rs
+++ b/makima/src/server/handlers/transcript_analysis.rs
@@ -277,6 +277,7 @@ pub async fn create_contract_from_analysis(
contract_type: Some("specification".to_string()),
initial_phase: Some("research".to_string()),
autonomous_loop: None,
+ phase_guard: None,
};
let contract = match repository::create_contract_for_owner(pool, auth.owner_id, contract_req).await {