Coverage for little_loops / dependency_mapper / models.py: 100%
41 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-05-22 16:19 -0500
« prev ^ index » next coverage.py v7.12.0, created at 2026-05-22 16:19 -0500
1"""Dependency mapper data models.
3Dataclasses for cross-issue dependency discovery and validation.
4"""
6from __future__ import annotations
8from dataclasses import dataclass, field
11@dataclass
12class DependencyProposal:
13 """A proposed dependency relationship between two issues.
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 """
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
34@dataclass
35class ParallelSafePair:
36 """A pair of issues that share files but can safely run in parallel.
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 """
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 = ""
53@dataclass
54class ValidationResult:
55 """Result of validating existing dependency references.
57 Attributes:
58 broken_refs: (issue_id, missing_ref_id) pairs for broken blocked_by refs
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 broken_depends_on_refs: (issue_id, missing_ref_id) pairs for broken depends_on refs
63 broken_relates_to_refs: (issue_id, missing_ref_id) pairs for broken relates_to refs
64 """
66 broken_refs: list[tuple[str, str]] = field(default_factory=list)
67 missing_backlinks: list[tuple[str, str]] = field(default_factory=list)
68 cycles: list[list[str]] = field(default_factory=list)
69 stale_completed_refs: list[tuple[str, str]] = field(default_factory=list)
70 broken_depends_on_refs: list[tuple[str, str]] = field(default_factory=list)
71 broken_relates_to_refs: list[tuple[str, str]] = field(default_factory=list)
73 @property
74 def has_issues(self) -> bool:
75 """Return True if any validation problems were found."""
76 return bool(
77 self.broken_refs
78 or self.missing_backlinks
79 or self.cycles
80 or self.stale_completed_refs
81 or self.broken_depends_on_refs
82 or self.broken_relates_to_refs
83 )
86@dataclass
87class DependencyReport:
88 """Complete dependency analysis report.
90 Attributes:
91 proposals: Proposed new dependency relationships
92 parallel_safe: Pairs of issues that share files but can run in parallel
93 validation: Validation results for existing dependencies
94 issue_count: Total issues analyzed
95 existing_dep_count: Number of existing dependency edges
96 """
98 proposals: list[DependencyProposal] = field(default_factory=list)
99 parallel_safe: list[ParallelSafePair] = field(default_factory=list)
100 validation: ValidationResult = field(default_factory=ValidationResult)
101 issue_count: int = 0
102 existing_dep_count: int = 0
105@dataclass
106class FixResult:
107 """Result of auto-fixing dependency validation issues.
109 Attributes:
110 changes: Human-readable descriptions of each fix applied
111 modified_files: Set of file paths that were modified
112 skipped_cycles: Number of cycles skipped (out of scope for auto-fix)
113 """
115 changes: list[str] = field(default_factory=list)
116 modified_files: set[str] = field(default_factory=set)
117 skipped_cycles: int = 0