The Mission crate manages task execution with a state machine, atomic checkout (to prevent double-assignment), comment threads, and directive linkage.
Overview
Purpose: Task lifecycle with atomic assignment
LOC: ~350
Functions: 7 (create, checkout, release, transition, list, comment, comments)
Endpoints: 7 REST
Source: crates/mission/src/main.rs
Core Concepts
Mission Structure
struct Mission {
id : String , // "msn-{uuid}"
realm_id : String ,
directive_id : Option < String >, // Link to strategic goal
parent_id : Option < String >, // Parent mission for subtasks
title : String ,
description : Option < String >,
status : MissionStatus ,
priority : MissionPriority ,
assignee_id : Option < String >, // Current owner
created_by : Option < String >,
billing_code : Option < String >,
version : u32 ,
started_at : Option < String >,
completed_at : Option < String >,
created_at : String ,
updated_at : String ,
}
State Machine
Backlog → Queued → Active → Review → Complete
↓ ↓ ↓
Blocked Blocked Blocked
↓ ↓ ↓
Cancelled Cancelled Cancelled
Valid Transitions:
Backlog → Queued, Blocked, Cancelled
Queued → Active, Blocked, Cancelled
Active → Review, Blocked, Cancelled
Review → Complete, Active (rework), Cancelled
Blocked → Queued, Cancelled
Priority Levels
enum MissionPriority {
Critical , // P0: Drop everything
High , // P1: Next up
Normal , // P2: Regular work
Low , // P3: When time permits
}
Functions
mission::create
Create a new mission.
Parent mission for subtasks
“Critical”, “High”, “Normal”, “Low”
Agent or user who created this
Optional billing/project code
Example:
let mission = iii . trigger ( "mission::create" , json! ({
"realmId" : "r-1" ,
"title" : "Implement user authentication" ,
"description" : "Add JWT-based auth with refresh tokens" ,
"directiveId" : "dir-auth-system" ,
"priority" : "High" ,
"createdBy" : "agent-pm" ,
"billingCode" : "PROJ-2024-Q1"
})) . await ? ;
// Returns:
// {
// "id": "msn-xyz789",
// "status": "Backlog",
// "priority": "High",
// "assigneeId": null,
// ...
// }
REST Endpoint:
POST /api/missions
Content-Type: application/json
{
"realmId" : "r-1",
"title" : "Implement user authentication",
"priority" : "High"
}
mission::checkout
Atomically claim a mission for an agent.
Agent claiming the mission
Example:
let result = iii . trigger ( "mission::checkout" , json! ({
"realmId" : "r-1" ,
"id" : "msn-xyz789" ,
"agentId" : "agent-dev-1"
})) . await ? ;
// Success:
// {
// "id": "msn-xyz789",
// "status": "Active",
// "assigneeId": "agent-dev-1",
// "startedAt": "2024-03-09T10:30:00Z",
// ...
// }
// If already assigned:
// Error: "mission msn-xyz789 already checked out by agent-dev-2"
REST Endpoint:
POST /api/missions/msn-xyz789/checkout
Content-Type: application/json
{
"realmId" : "r-1",
"agentId" : "agent-dev-1"
}
Atomic Checkout Logic (mission/src/main.rs:85-123):
async fn checkout_mission ( iii : & III , req : CheckoutRequest ) -> Result < Value , IIIError > {
let mut mission = load_mission ( iii , & req . realm_id, & req . id) . await ? ;
// Check if already assigned
if mission . assignee_id . is_some () && mission . assignee_id . as_deref () != Some ( & req . agent_id) {
return Err ( IIIError :: Handler ( format! (
"mission {} already checked out by {}" ,
req . id,
mission . assignee_id . as_deref () . unwrap_or ( "unknown" )
)));
}
// Only allow checkout from certain states
if ! matches! ( mission . status, MissionStatus :: Backlog | MissionStatus :: Queued | MissionStatus :: Blocked ) {
return Err ( IIIError :: Handler ( format! (
"cannot checkout mission in {:?} status" ,
mission . status
)));
}
let expected_version = mission . version;
mission . assignee_id = Some ( req . agent_id . clone ());
mission . status = MissionStatus :: Active ;
mission . started_at = Some ( chrono :: Utc :: now () . to_rfc3339 ());
mission . version = expected_version + 1 ;
mission . updated_at = chrono :: Utc :: now () . to_rfc3339 ();
save_mission ( iii , & mission ) . await ? ;
// ...
}
mission::release
Release a mission back to the queue.
iii . trigger ( "mission::release" , json! ({
"realmId" : "r-1" ,
"id" : "msn-xyz789" ,
"agentId" : "agent-dev-1" // Must be current assignee
})) . await ? ;
// Returns:
// {
// "released": true,
// "missionId": "msn-xyz789"
// }
REST Endpoint:
POST /api/missions/msn-xyz789/release
mission::transition
Transition mission to a new status.
New status (must be valid transition)
Agent performing transition
Optional reason for transition
Example:
// Move to review
iii . trigger ( "mission::transition" , json! ({
"realmId" : "r-1" ,
"id" : "msn-xyz789" ,
"status" : "Review" ,
"agentId" : "agent-dev-1" ,
"reason" : "Implementation complete, ready for code review"
})) . await ? ;
// Mark complete
iii . trigger ( "mission::transition" , json! ({
"realmId" : "r-1" ,
"id" : "msn-xyz789" ,
"status" : "Complete" ,
"agentId" : "agent-reviewer"
})) . await ? ;
REST Endpoint:
PATCH /api/missions/msn-xyz789/status
Content-Type: application/json
{
"realmId" : "r-1",
"status" : "Review",
"reason" : "Ready for review"
}
State Validation (mission/src/main.rs:146-152):
if ! mission . status . can_transition_to ( & req . status) {
return Err ( IIIError :: Handler ( format! (
"invalid transition: {:?} -> {:?}" ,
mission . status, req . status
)));
}
mission::list
List missions with filtering.
Filter by linked directive
Example:
// Get all active missions
let active = iii . trigger ( "mission::list" , json! ({
"realmId" : "r-1" ,
"status" : "Active"
})) . await ? ;
// Get missions assigned to an agent
let my_missions = iii . trigger ( "mission::list" , json! ({
"realmId" : "r-1" ,
"assigneeId" : "agent-dev-1"
})) . await ? ;
// Get missions for a directive
let directive_missions = iii . trigger ( "mission::list" , json! ({
"realmId" : "r-1" ,
"directiveId" : "dir-auth-system"
})) . await ? ;
REST Endpoint:
GET /api/missions/r-1?status=Active
GET /api/missions/r-1?assigneeId=agent-dev-1
GET /api/missions/r-1?directiveId=dir-auth-system
Add a comment to a mission.
iii . trigger ( "mission::comment" , json! ({
"realmId" : "r-1" ,
"missionId" : "msn-xyz789" ,
"authorId" : "agent-reviewer" ,
"body" : "Looks good, but please add unit tests for the JWT validation."
})) . await ? ;
REST Endpoint:
POST /api/missions/msn-xyz789/comments
Content-Type: application/json
{
"authorId" : "agent-reviewer",
"body" : "Looks good, but please add unit tests"
}
List comments on a mission.
let comments = iii . trigger ( "mission::comments" , json! ({
"realmId" : "r-1" ,
"missionId" : "msn-xyz789"
})) . await ? ;
REST Endpoint:
GET /api/missions/r-1/msn-xyz789/comments
Storage Scopes
realm:{realmId}:missions - Mission metadata
realm:{realmId}:missions:{missionId}:comments - Comment threads
Events
Mission publishes to mission.lifecycle topic:
{
"type" : "created" | "checked_out" | "transitioned" ,
"missionId" : "msn-xyz789" ,
"realmId" : "r-1" ,
"agentId" : "agent-dev-1" ,
"from" : "active" ,
"to" : "review"
}
Use Cases
Task Queue Agents checkout missions from Queued state, work on them, then move to Review.
Kanban Board Map mission statuses to board columns: Backlog, Active, Review, Complete.
Subtask Breakdown Use parentId to create hierarchical task trees.
Billing Tracking Tag missions with billingCode to track work by project/customer.
Best Practices
Link to directives
Always set directiveId to connect tactical work to strategic goals.
Use checkout, not manual assignment
Always use mission::checkout to prevent double-assignment race conditions.
Add comments for collaboration
Use comment threads for reviews, questions, and status updates.
Track time with started_at/completed_at
Calculate cycle time by subtracting started_at from completed_at.
Handle blocked missions
Transition to Blocked with reason in comments, then back to Queued when unblocked.
Directive - Link missions to strategic directives
Ledger - Track spend per mission via billingCode
Pulse - Auto-assign missions based on agent availability