diff options
| author | soryu <soryu@soryu.co> | 2026-02-05 01:42:59 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-05 01:42:59 +0000 |
| commit | 6a0c912a3fbd8e9b3e87ef40e960803d819d966d (patch) | |
| tree | b2c50c490811286d163e40f8d624ee8d43c0ce43 /makima/src/db/models.rs | |
| parent | 0302b4596e14210884df5d645df9a179d8f0c1c6 (diff) | |
| download | soryu-6a0c912a3fbd8e9b3e87ef40e960803d819d966d.tar.gz soryu-6a0c912a3fbd8e9b3e87ef40e960803d819d966d.zip | |
Add makima directives
Diffstat (limited to 'makima/src/db/models.rs')
| -rw-r--r-- | makima/src/db/models.rs | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/makima/src/db/models.rs b/makima/src/db/models.rs index 30e1603..392d019 100644 --- a/makima/src/db/models.rs +++ b/makima/src/db/models.rs @@ -1449,6 +1449,13 @@ pub struct Contract { /// Chain ID if this contract is part of a chain (DAG of contracts) #[serde(skip_serializing_if = "Option::is_none")] pub chain_id: Option<Uuid>, + /// Reference to chain spawned by this directive contract + #[serde(skip_serializing_if = "Option::is_none")] + pub spawned_chain_id: Option<Uuid>, + /// Whether this contract is a chain directive orchestrator + #[serde(default)] + #[sqlx(default)] + pub is_chain_directive: bool, pub version: i32, pub created_at: DateTime<Utc>, pub updated_at: DateTime<Utc>, @@ -2652,12 +2659,28 @@ pub struct Chain { pub loop_current_iteration: Option<i32>, /// Progress check prompt/criteria for evaluating loop completion pub loop_progress_check: Option<String>, + /// Reference to the directive contract that created/orchestrates this chain + pub directive_contract_id: Option<Uuid>, + /// The directive document text (formal specification) + pub directive_document: Option<String>, + /// Whether LLM evaluation is enabled after contract completion + #[serde(default = "default_evaluation_enabled")] + #[sqlx(default)] + pub evaluation_enabled: bool, + /// Default pass threshold for evaluations (0.0-1.0) + pub default_pass_threshold: Option<f64>, + /// Default max retry attempts for evaluations + pub default_max_retries: Option<i32>, /// Version for optimistic locking pub version: i32, pub created_at: DateTime<Utc>, pub updated_at: DateTime<Utc>, } +fn default_evaluation_enabled() -> bool { + true +} + /// Chain repository record from the database #[derive(Debug, Clone, FromRow, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] @@ -2709,9 +2732,37 @@ pub struct ChainContract { pub editor_x: Option<f64>, /// Y position for GUI editor pub editor_y: Option<f64>, + /// Evaluation status: pending, evaluating, passed, failed, rework, escalated + #[serde(default = "default_evaluation_status")] + #[sqlx(default)] + pub evaluation_status: String, + /// Number of evaluation retry attempts + #[serde(default)] + #[sqlx(default)] + pub evaluation_retry_count: i32, + /// Maximum evaluation retry attempts (default: 3) + #[serde(default = "default_max_evaluation_retries")] + #[sqlx(default)] + pub max_evaluation_retries: i32, + /// Reference to the last evaluation result + pub last_evaluation_id: Option<Uuid>, + /// Rework feedback/instructions from failed evaluation + pub rework_feedback: Option<String>, + /// When rework was started + pub rework_started_at: Option<DateTime<Utc>>, + /// When contract originally completed (before rework) + pub original_completion_at: Option<DateTime<Utc>>, pub created_at: DateTime<Utc>, } +fn default_evaluation_status() -> String { + "pending".to_string() +} + +fn default_max_evaluation_retries() -> i32 { + 3 +} + /// Chain event for audit trail #[derive(Debug, Clone, FromRow, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] @@ -2765,6 +2816,15 @@ pub struct ChainContractDetail { pub order_index: i32, pub editor_x: Option<f64>, pub editor_y: Option<f64>, + /// Evaluation status: pending, passed, failed, rework + #[sqlx(default)] + pub evaluation_status: Option<String>, + /// Number of evaluation retries + #[sqlx(default)] + pub evaluation_retry_count: i32, + /// Maximum evaluation retry attempts + #[sqlx(default)] + pub max_evaluation_retries: i32, } /// DAG graph structure for visualization @@ -3058,6 +3118,19 @@ pub struct ChainContractDefinition { pub deliverables: Option<serde_json::Value>, /// Validation configuration for checkpoint contracts (JSON) pub validation: Option<serde_json::Value>, + /// Requirement IDs this contract addresses (for traceability) + #[sqlx(default)] + #[serde(default)] + pub requirement_ids: Vec<String>, + /// Acceptance criteria for this contract (JSON array) + #[serde(default)] + pub acceptance_criteria: Option<serde_json::Value>, + /// Whether LLM evaluation is enabled for this contract + #[serde(default = "default_evaluation_enabled")] + #[sqlx(default)] + pub evaluation_enabled: bool, + /// Pass threshold for evaluation (0.0-1.0) + pub pass_threshold: Option<f64>, /// Position in GUI editor pub editor_x: Option<f64>, pub editor_y: Option<f64>, @@ -3154,6 +3227,284 @@ pub struct ChainDefinitionGraphResponse { } // ============================================================================= +// Chain Directives (formal specification documents for directive-driven chains) +// ============================================================================= + +/// Chain directive - formal specification document that drives chain creation and evaluation +#[derive(Debug, Clone, FromRow, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ChainDirective { + pub id: Uuid, + pub chain_id: Uuid, + pub version: i32, + /// Requirements as JSON: [{ id, title, description, priority, category, parentId? }] + #[sqlx(json)] + pub requirements: serde_json::Value, + /// Acceptance criteria as JSON: [{ id, requirementIds[], description, testable, verificationMethod }] + #[sqlx(json)] + pub acceptance_criteria: serde_json::Value, + /// Constraints as JSON: [{ id, type, description, impact }] + #[sqlx(json)] + pub constraints: serde_json::Value, + /// External dependencies as JSON: [{ id, name, type, status, requiredBy[] }] + #[sqlx(json)] + pub external_dependencies: serde_json::Value, + /// Source type: 'manual', 'llm_generated', 'imported' + pub source_type: String, + pub created_at: DateTime<Utc>, + pub updated_at: DateTime<Utc>, +} + +/// Requirement in a directive +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct DirectiveRequirement { + pub id: String, + pub title: String, + pub description: String, + /// Priority: 'must', 'should', 'could', 'wont' + pub priority: String, + /// Category: 'feature', 'infrastructure', 'testing', etc. + pub category: Option<String>, + /// Parent requirement ID for hierarchical requirements + pub parent_id: Option<String>, +} + +/// Acceptance criterion in a directive +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct DirectiveAcceptanceCriterion { + pub id: String, + /// Requirement IDs this criterion validates + pub requirement_ids: Vec<String>, + pub description: String, + pub testable: bool, + /// Verification method: 'automated', 'manual', 'review', 'llm' + pub verification_method: String, +} + +/// Constraint in a directive +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct DirectiveConstraint { + pub id: String, + /// Type: 'technical', 'business', 'time', 'resource' + #[serde(rename = "type")] + pub constraint_type: String, + pub description: String, + /// Impact: 'high', 'medium', 'low' + pub impact: String, +} + +/// External dependency in a directive +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct DirectiveExternalDependency { + pub id: String, + pub name: String, + /// Type: 'api', 'service', 'library', 'data' + #[serde(rename = "type")] + pub dependency_type: String, + /// Status: 'available', 'pending', 'blocked' + pub status: String, + /// Requirement IDs that need this dependency + pub required_by: Vec<String>, +} + +/// Request to create or update a chain directive +#[derive(Debug, Clone, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct CreateChainDirectiveRequest { + pub requirements: Option<Vec<DirectiveRequirement>>, + pub acceptance_criteria: Option<Vec<DirectiveAcceptanceCriterion>>, + pub constraints: Option<Vec<DirectiveConstraint>>, + pub external_dependencies: Option<Vec<DirectiveExternalDependency>>, + pub source_type: Option<String>, +} + +/// Request to initialize a directive-driven chain +#[derive(Debug, Clone, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct InitChainRequest { + /// High-level goal/description for the directive contract + pub goal: String, + /// Repository URL for chain contracts + pub repository_url: Option<String>, + /// Local path for chain contracts + pub local_path: Option<String>, + /// Whether to enable phase guard (user approval between phases) + #[serde(default)] + pub phase_guard: bool, +} + +/// Response from initializing a directive-driven chain +#[derive(Debug, Clone, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct InitChainResponse { + pub chain_id: Uuid, + pub directive_contract_id: Uuid, + pub supervisor_task_id: Option<Uuid>, +} + +// ============================================================================= +// Contract Evaluations (LLM evaluation results for completed contracts) +// ============================================================================= + +/// Evaluation status for chain contracts +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "snake_case")] +pub enum EvaluationStatus { + /// Not yet evaluated + Pending, + /// Currently being evaluated + Evaluating, + /// Evaluation passed + Passed, + /// Evaluation failed + Failed, + /// Contract is being reworked after failed evaluation + Rework, + /// Max retries exceeded, escalated to user + Escalated, + /// User approved despite partial failure + ApprovedWithIssues, +} + +impl std::fmt::Display for EvaluationStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Pending => write!(f, "pending"), + Self::Evaluating => write!(f, "evaluating"), + Self::Passed => write!(f, "passed"), + Self::Failed => write!(f, "failed"), + Self::Rework => write!(f, "rework"), + Self::Escalated => write!(f, "escalated"), + Self::ApprovedWithIssues => write!(f, "approved_with_issues"), + } + } +} + +impl std::str::FromStr for EvaluationStatus { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s.to_lowercase().as_str() { + "pending" => Ok(Self::Pending), + "evaluating" => Ok(Self::Evaluating), + "passed" => Ok(Self::Passed), + "failed" => Ok(Self::Failed), + "rework" => Ok(Self::Rework), + "escalated" => Ok(Self::Escalated), + "approved_with_issues" => Ok(Self::ApprovedWithIssues), + _ => Err(format!("Unknown evaluation status: {}", s)), + } + } +} + +/// Contract evaluation - LLM evaluation result after contract completion +#[derive(Debug, Clone, FromRow, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ContractEvaluation { + pub id: Uuid, + pub contract_id: Uuid, + pub chain_id: Option<Uuid>, + pub chain_contract_id: Option<Uuid>, + /// Evaluation attempt number (1-based) + pub evaluation_number: i32, + /// Model used for evaluation + pub evaluator_model: Option<String>, + /// Whether the evaluation passed + pub passed: bool, + /// Overall score (0.0-1.0) + pub overall_score: Option<f64>, + /// Per-criterion results as JSON + #[sqlx(json)] + pub criteria_results: serde_json::Value, + /// Summary feedback from the evaluator + pub summary_feedback: String, + /// Instructions for rework if evaluation failed + pub rework_instructions: Option<String>, + /// Snapshot of directive at evaluation time + pub directive_snapshot: Option<serde_json::Value>, + /// Snapshot of deliverables at evaluation time + pub deliverables_snapshot: Option<serde_json::Value>, + pub started_at: DateTime<Utc>, + pub completed_at: Option<DateTime<Utc>>, + pub created_at: DateTime<Utc>, +} + +/// Per-criterion evaluation result +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct EvaluationCriterionResult { + pub criterion_id: String, + pub criterion_text: String, + pub passed: bool, + /// Score (0.0-1.0) + pub score: f64, + pub feedback: String, + /// Evidence supporting the evaluation + pub evidence: Vec<String>, +} + +/// Request to create a contract evaluation +#[derive(Debug, Clone, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct CreateContractEvaluationRequest { + pub contract_id: Uuid, + pub chain_id: Option<Uuid>, + pub chain_contract_id: Option<Uuid>, + pub evaluator_model: Option<String>, + pub passed: bool, + pub overall_score: Option<f64>, + pub criteria_results: Vec<EvaluationCriterionResult>, + pub summary_feedback: String, + pub rework_instructions: Option<String>, +} + +/// Summary of contract evaluation for list views +#[derive(Debug, Clone, FromRow, Serialize, Deserialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ContractEvaluationSummary { + pub id: Uuid, + pub contract_id: Uuid, + pub evaluation_number: i32, + pub passed: bool, + pub overall_score: Option<f64>, + pub summary_feedback: String, + pub created_at: DateTime<Utc>, +} + +/// Response listing evaluations for a chain or contract +#[derive(Debug, Clone, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct ContractEvaluationsResponse { + pub evaluations: Vec<ContractEvaluationSummary>, + pub total: i64, +} + +/// Traceability matrix entry - maps requirements to contracts +#[derive(Debug, Clone, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct TraceabilityEntry { + pub requirement_id: String, + pub requirement_title: String, + pub contract_definition_ids: Vec<Uuid>, + pub contract_definition_names: Vec<String>, + pub acceptance_criteria_ids: Vec<String>, +} + +/// Response for directive traceability +#[derive(Debug, Clone, Serialize, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct DirectiveTraceabilityResponse { + pub chain_id: Uuid, + pub entries: Vec<TraceabilityEntry>, + /// Requirements not mapped to any contract + pub uncovered_requirements: Vec<String>, +} + +// ============================================================================= // Unit Tests // ============================================================================= |
