Coverage for src / core / models.py: 100%
56 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-01-04 04:43 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-01-04 04:43 +0000
1"""Shared domain-agnostic dataclasses for mala.
3This module provides shared types that are used across multiple domains
4(logging, validation, orchestrator) to avoid circular dependencies.
6Types:
7- LockEventType: Enum for lock event types (acquired, waiting, released)
8- LockEvent: A lock event from an agent
9- ResolutionOutcome: Enum for issue resolution outcomes
10- IssueResolution: Records how an issue was resolved
11- ValidationArtifacts: Record of validation outputs for observability
12- UnmetCriterion: Individual gap identified during epic verification
13- EpicVerdict: Result of verifying an epic against its acceptance criteria
14- EpicVerificationResult: Summary of a verification run across multiple epics
15- RetryConfig: Configuration for retry behavior with exponential backoff
16"""
18from __future__ import annotations
20from dataclasses import dataclass
21from enum import Enum
22from typing import TYPE_CHECKING, Literal
24if TYPE_CHECKING:
25 from pathlib import Path
28class LockEventType(Enum):
29 """Types of lock events emitted by agents."""
31 ACQUIRED = "acquired"
32 WAITING = "waiting"
33 RELEASED = "released"
36@dataclass
37class LockEvent:
38 """A lock event from an agent.
40 Attributes:
41 event_type: Type of lock event.
42 agent_id: ID of the agent that emitted this event.
43 lock_path: Path to the lock file.
44 timestamp: Unix timestamp when the event occurred.
45 """
47 event_type: LockEventType
48 agent_id: str
49 lock_path: str
50 timestamp: float
53class ResolutionOutcome(Enum):
54 """Outcome of issue resolution."""
56 SUCCESS = "success"
57 NO_CHANGE = "no_change"
58 OBSOLETE = "obsolete"
59 ALREADY_COMPLETE = "already_complete"
62@dataclass(frozen=True)
63class IssueResolution:
64 """Records how an issue was resolved.
66 Attributes:
67 outcome: The resolution outcome (success, no_change, obsolete).
68 rationale: Explanation for the resolution.
69 """
71 outcome: ResolutionOutcome
72 rationale: str
75@dataclass
76class ValidationArtifacts:
77 """Record of validation outputs for observability.
79 Attributes:
80 log_dir: Directory containing validation logs.
81 worktree_path: Path to the worktree (if any).
82 worktree_state: State of the worktree ("kept" or "removed").
83 coverage_report: Path to coverage report.
84 e2e_fixture_path: Path to E2E fixture directory.
85 """
87 log_dir: Path
88 worktree_path: Path | None = None
89 worktree_state: Literal["kept", "removed"] | None = None
90 coverage_report: Path | None = None
91 e2e_fixture_path: Path | None = None
94@dataclass
95class UnmetCriterion:
96 """Individual gap identified during epic verification.
98 Attributes:
99 criterion: The acceptance criterion not met.
100 evidence: Why it's considered unmet.
101 priority: Issue priority matching Cerberus levels (0-3).
102 P0/P1 are blocking, P2/P3 are non-blocking (informational).
103 criterion_hash: SHA256 of criterion text, for deduplication.
104 """
106 criterion: str
107 evidence: str
108 priority: int # 0=P0 (blocking), 1=P1 (blocking), 2=P2 (non-blocking), 3=P3 (non-blocking)
109 criterion_hash: str
112@dataclass
113class EpicVerdict:
114 """Result of verifying an epic against its acceptance criteria.
116 Attributes:
117 passed: Whether all acceptance criteria were met.
118 unmet_criteria: List of criteria that were not satisfied.
119 confidence: Model confidence in the verdict (0.0 to 1.0).
120 reasoning: Explanation of the verification outcome.
121 """
123 passed: bool
124 unmet_criteria: list[UnmetCriterion]
125 confidence: float
126 reasoning: str
129@dataclass
130class EpicVerificationResult:
131 """Summary of a verification run across multiple epics.
133 Attributes:
134 verified_count: Number of epics verified.
135 passed_count: Number that passed verification.
136 failed_count: Number that failed verification.
137 verdicts: Mapping of epic_id to its verdict.
138 remediation_issues_created: Issue IDs created for remediation.
139 """
141 verified_count: int
142 passed_count: int
143 failed_count: int
144 verdicts: dict[str, EpicVerdict]
145 remediation_issues_created: list[str]
148@dataclass
149class RetryConfig:
150 """Configuration for retry behavior with exponential backoff.
152 Attributes:
153 max_retries: Total retry attempts.
154 initial_delay_ms: First retry delay in milliseconds.
155 backoff_multiplier: Exponential backoff multiplier.
156 max_delay_ms: Cap on retry delay in milliseconds.
157 timeout_ms: Per-attempt timeout in milliseconds.
158 """
160 max_retries: int = 2
161 initial_delay_ms: int = 1000
162 backoff_multiplier: float = 2.0
163 max_delay_ms: int = 30000
164 timeout_ms: int = 120000