summaryrefslogtreecommitdiff
path: root/makima/src/db
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/db')
-rw-r--r--makima/src/db/models.rs28
-rw-r--r--makima/src/db/repository.rs31
2 files changed, 55 insertions, 4 deletions
diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs
index 9c2d072..625a572 100644
--- a/makima/src/db/models.rs
+++ b/makima/src/db/models.rs
@@ -441,6 +441,12 @@ pub struct Task {
#[serde(default)]
pub is_supervisor: bool,
+ // Red team flag
+ /// True for red team monitor tasks. Red team tasks monitor work tasks
+ /// and can alert the supervisor about potential issues.
+ #[serde(default)]
+ pub is_red_team: bool,
+
// Daemon/container info
pub daemon_id: Option<Uuid>,
pub container_id: Option<String>,
@@ -627,6 +633,9 @@ pub struct CreateTaskRequest {
/// True for contract supervisor tasks. Only supervisors can spawn new tasks.
#[serde(default)]
pub is_supervisor: bool,
+ /// True for red team monitor tasks that watch work tasks.
+ #[serde(default)]
+ pub is_red_team: bool,
/// Priority (higher = more urgent)
#[serde(default)]
pub priority: i32,
@@ -1331,6 +1340,16 @@ pub struct Contract {
/// allowing users to manually handle code changes via patch files or other means.
#[serde(default)]
pub local_only: bool,
+ /// Whether to spawn a red team task to monitor work tasks.
+ /// When enabled, a parallel task monitors outputs and can alert
+ /// the supervisor about potential issues.
+ #[serde(default)]
+ pub red_team_enabled: bool,
+ /// Optional custom prompt/criteria for the red team to use
+ /// when evaluating task outputs. If not provided, uses default
+ /// quality criteria.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub red_team_prompt: Option<String>,
pub version: i32,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
@@ -1508,6 +1527,15 @@ pub struct CreateContractRequest {
/// allowing users to manually handle code changes via patch files or other means.
#[serde(default)]
pub local_only: Option<bool>,
+ /// Enable red team monitoring for this contract.
+ /// When enabled, a parallel task monitors work task outputs
+ /// and can alert the supervisor about potential issues.
+ #[serde(default)]
+ pub red_team_enabled: Option<bool>,
+ /// Optional custom criteria for the red team to evaluate.
+ /// Examples: "Focus on security vulnerabilities",
+ /// "Ensure all functions have tests", etc.
+ pub red_team_prompt: Option<String>,
}
/// Request payload for updating a contract
diff --git a/makima/src/db/repository.rs b/makima/src/db/repository.rs
index 6d6642b..0282984 100644
--- a/makima/src/db/repository.rs
+++ b/makima/src/db/repository.rs
@@ -1100,11 +1100,11 @@ pub async fn create_task_for_owner(
r#"
INSERT INTO tasks (
owner_id, contract_id, parent_task_id, depth, name, description, plan, priority,
- is_supervisor, repository_url, base_branch, target_branch, merge_mode,
+ is_supervisor, is_red_team, repository_url, base_branch, target_branch, merge_mode,
target_repo_path, completion_action, continue_from_task_id, copy_files,
branched_from_task_id, conversation_state
)
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)
RETURNING *
"#,
)
@@ -1117,6 +1117,7 @@ pub async fn create_task_for_owner(
.bind(&req.plan)
.bind(req.priority)
.bind(req.is_supervisor)
+ .bind(req.is_red_team)
.bind(&repo_url)
.bind(&base_branch)
.bind(&target_branch)
@@ -1131,6 +1132,24 @@ pub async fn create_task_for_owner(
.await
}
+/// Get the red team task for a contract, if one exists.
+pub async fn get_red_team_task_for_contract(
+ pool: &PgPool,
+ contract_id: Uuid,
+) -> Result<Option<Task>, sqlx::Error> {
+ sqlx::query_as::<_, Task>(
+ r#"
+ SELECT *
+ FROM tasks
+ WHERE contract_id = $1 AND is_red_team = true
+ LIMIT 1
+ "#,
+ )
+ .bind(contract_id)
+ .fetch_optional(pool)
+ .await
+}
+
/// Get a task by ID, scoped to owner.
pub async fn get_task_for_owner(
pool: &PgPool,
@@ -2176,11 +2195,13 @@ 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);
+ let red_team_enabled = req.red_team_enabled.unwrap_or(false);
+ let red_team_prompt = req.red_team_prompt.as_ref();
sqlx::query_as::<_, Contract>(
r#"
- 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)
+ INSERT INTO contracts (owner_id, name, description, contract_type, phase, autonomous_loop, phase_guard, local_only, red_team_enabled, red_team_prompt)
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
RETURNING *
"#,
)
@@ -2192,6 +2213,8 @@ pub async fn create_contract_for_owner(
.bind(autonomous_loop)
.bind(phase_guard)
.bind(local_only)
+ .bind(red_team_enabled)
+ .bind(red_team_prompt)
.fetch_one(pool)
.await
}