Coverage for little_loops/dependency_mapper/models.py: 0%

1"""Dependency mapper data models.

2

3 Dataclasses for cross-issue dependency discovery and validation.

4"""

5

6 from __future__ import annotations

7

8 from dataclasses import dataclass, field

9

10

11@dataclass

12 class DependencyProposal:

13 """A proposed dependency relationship between two issues.

14

15 Attributes:

16 source_id: Issue that would be blocked

17 target_id: Issue that would block (the blocker)

18 reason: Category of discovery method

19 confidence: Score from 0.0 to 1.0

20 rationale: Human-readable explanation

21 overlapping_files: Files referenced by both issues

22 conflict_score: Semantic conflict score from 0.0 to 1.0

23 """

24

25 source_id: str

26 target_id: str

27 reason: str

28 confidence: float

29 rationale: str

30 overlapping_files: list[str] = field(default_factory=list)

31 conflict_score: float = 0.5

32

33

34@dataclass

35 class ParallelSafePair:

36 """A pair of issues that share files but can safely run in parallel.

37

38 Attributes:

39 issue_a: First issue ID

40 issue_b: Second issue ID

41 shared_files: Files referenced by both issues

42 conflict_score: Semantic conflict score (< 0.4)

43 reason: Why these are parallel-safe

44 """

45

46 issue_a: str

47 issue_b: str

48 shared_files: list[str] = field(default_factory=list)

49 conflict_score: float = 0.0

50 reason: str = ""

51

52

53@dataclass

54 class ValidationResult:

55 """Result of validating existing dependency references.

56

57 Attributes:

58 broken_refs: (issue_id, missing_ref_id) pairs

59 missing_backlinks: (issue_id, should_have_backlink_from) pairs

60 cycles: Cycle paths from DependencyGraph.detect_cycles()

61 stale_completed_refs: (issue_id, completed_ref_id) pairs

62 """

63

64 broken_refs: list[tuple[str, str]] = field(default_factory=list)

65 missing_backlinks: list[tuple[str, str]] = field(default_factory=list)

66 cycles: list[list[str]] = field(default_factory=list)

67 stale_completed_refs: list[tuple[str, str]] = field(default_factory=list)

68

69 @property

70 def has_issues(self) -> bool:

71 """Return True if any validation problems were found."""

72 return bool(

73 self.broken_refs or self.missing_backlinks or self.cycles or self.stale_completed_refs

74 )

75

76

77@dataclass

78 class DependencyReport:

79 """Complete dependency analysis report.

80

81 Attributes:

82 proposals: Proposed new dependency relationships

83 parallel_safe: Pairs of issues that share files but can run in parallel

84 validation: Validation results for existing dependencies

85 issue_count: Total issues analyzed

86 existing_dep_count: Number of existing dependency edges

87 """

88

89 proposals: list[DependencyProposal] = field(default_factory=list)

90 parallel_safe: list[ParallelSafePair] = field(default_factory=list)

91 validation: ValidationResult = field(default_factory=ValidationResult)

92 issue_count: int = 0

93 existing_dep_count: int = 0

94

95

96@dataclass

97 class FixResult:

98 """Result of auto-fixing dependency validation issues.

99

100 Attributes:

101 changes: Human-readable descriptions of each fix applied

102 modified_files: Set of file paths that were modified

103 skipped_cycles: Number of cycles skipped (out of scope for auto-fix)

104 """

105

106 changes: list[str] = field(default_factory=list)

107 modified_files: set[str] = field(default_factory=set)

108 skipped_cycles: int = 0