summaryrefslogtreecommitdiff
path: root/makima/src/db/models.rs
diff options
context:
space:
mode:
Diffstat (limited to 'makima/src/db/models.rs')
-rw-r--r--makima/src/db/models.rs351
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
// =============================================================================