Coverage for src/core/models.py: 100%

1"""Shared domain-agnostic dataclasses for mala.

2

3 This module provides shared types that are used across multiple domains

4(logging, validation, orchestrator) to avoid circular dependencies.

5

6 Types:

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"""

17

18 from __future__ import annotations

19

20 from dataclasses import dataclass

21 from enum import Enum

22 from typing import TYPE_CHECKING, Literal

23

24 if TYPE_CHECKING:

25 from pathlib import Path

26

27

28 class LockEventType(Enum):

29 """Types of lock events emitted by agents."""

30

31 ACQUIRED = "acquired"

32 WAITING = "waiting"

33 RELEASED = "released"

34

35

36@dataclass

37 class LockEvent:

38 """A lock event from an agent.

39

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 """

46

47 event_type: LockEventType

48 agent_id: str

49 lock_path: str

50 timestamp: float

51

52

53 class ResolutionOutcome(Enum):

54 """Outcome of issue resolution."""

55

56 SUCCESS = "success"

57 NO_CHANGE = "no_change"

58 OBSOLETE = "obsolete"

59 ALREADY_COMPLETE = "already_complete"

60

61

62@dataclass(frozen=True)

63 class IssueResolution:

64 """Records how an issue was resolved.

65

66 Attributes:

67 outcome: The resolution outcome (success, no_change, obsolete).

68 rationale: Explanation for the resolution.

69 """

70

71 outcome: ResolutionOutcome

72 rationale: str

73

74

75@dataclass

76 class ValidationArtifacts:

77 """Record of validation outputs for observability.

78

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 """

86

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

92

93

94@dataclass

95 class UnmetCriterion:

96 """Individual gap identified during epic verification.

97

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 """

105

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

110

111

112@dataclass

113 class EpicVerdict:

114 """Result of verifying an epic against its acceptance criteria.

115

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 """

122

123 passed: bool

124 unmet_criteria: list[UnmetCriterion]

125 confidence: float

126 reasoning: str

127

128

129@dataclass

130 class EpicVerificationResult:

131 """Summary of a verification run across multiple epics.

132

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 """

140

141 verified_count: int

142 passed_count: int

143 failed_count: int

144 verdicts: dict[str, EpicVerdict]

145 remediation_issues_created: list[str]

146

147

148@dataclass

149 class RetryConfig:

150 """Configuration for retry behavior with exponential backoff.

151

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 """

159

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