continuum-toolkit 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cli/__init__.py +12 -0
- cli/main.py +415 -0
- confidence/__init__.py +13 -0
- confidence/calculator.py +308 -0
- confidence/models.py +40 -0
- context/__init__.py +17 -0
- context/models.py +108 -0
- context/pruner.py +228 -0
- context/selector.py +193 -0
- continuum_toolkit-1.0.0.dist-info/METADATA +511 -0
- continuum_toolkit-1.0.0.dist-info/RECORD +72 -0
- continuum_toolkit-1.0.0.dist-info/WHEEL +5 -0
- continuum_toolkit-1.0.0.dist-info/entry_points.txt +2 -0
- continuum_toolkit-1.0.0.dist-info/licenses/LICENSE +21 -0
- continuum_toolkit-1.0.0.dist-info/top_level.txt +13 -0
- contradictions/__init__.py +19 -0
- contradictions/detector.py +442 -0
- contradictions/models.py +75 -0
- core/__init__.py +97 -0
- core/enums.py +130 -0
- core/evidence.py +117 -0
- core/interfaces.py +209 -0
- core/schema.py +391 -0
- core/serializer.py +84 -0
- core/state_models.py +530 -0
- daemon/__init__.py +12 -0
- daemon/service.py +170 -0
- extractors/__init__.py +51 -0
- extractors/base.py +117 -0
- extractors/config/parsers.py +288 -0
- extractors/config/secret_sanitizer.py +91 -0
- extractors/config_extractor.py +172 -0
- extractors/conversation/analyzers.py +193 -0
- extractors/conversation/models.py +148 -0
- extractors/conversation_extractor.py +166 -0
- extractors/git_extractor.py +305 -0
- extractors/parsers/base.py +91 -0
- extractors/parsers/comment_parser.py +51 -0
- extractors/parsers/js_ts_parser.py +171 -0
- extractors/parsers/python_parser.py +180 -0
- extractors/verification/runners.py +278 -0
- extractors/verification_extractor.py +263 -0
- extractors/workspace_extractor.py +221 -0
- graph/__init__.py +24 -0
- graph/diff.py +109 -0
- graph/manager.py +473 -0
- graph/models.py +62 -0
- graph/propagator.py +194 -0
- graph/query.py +86 -0
- graph/snapshot.py +85 -0
- handoff/__init__.py +28 -0
- handoff/adapters/__init__.py +45 -0
- handoff/adapters/base.py +90 -0
- handoff/adapters/claude_adapter.py +176 -0
- handoff/adapters/codex_gpt_adapter.py +151 -0
- handoff/adapters/gemini_adapter.py +151 -0
- handoff/adapters/local_model_adapter.py +130 -0
- handoff/models.py +88 -0
- handoff/packager.py +288 -0
- pipeline/__init__.py +9 -0
- pipeline/orchestrator.py +260 -0
- resolution/__init__.py +15 -0
- resolution/resolver.py +311 -0
- storage/__init__.py +18 -0
- storage/hooks.py +125 -0
- storage/manager.py +127 -0
- storage/models.py +39 -0
- storage/recovery.py +98 -0
- watcher/__init__.py +17 -0
- watcher/detector.py +136 -0
- watcher/models.py +62 -0
- watcher/updater.py +163 -0
core/enums.py
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Project Continuum - Canonical Enums and Ontological Types
|
|
3
|
+
=========================================================
|
|
4
|
+
Defines the core enumerations, evidence types, evidence hierarchy levels,
|
|
5
|
+
status states, node types, and relationship types across the system.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from enum import Enum, IntEnum, auto
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Status(str, Enum):
|
|
12
|
+
"""
|
|
13
|
+
Standard status system used across all entities in Project Continuum.
|
|
14
|
+
Represents the verified lifecycle state of components, tasks, and requirements.
|
|
15
|
+
"""
|
|
16
|
+
PENDING = "PENDING"
|
|
17
|
+
IN_PROGRESS = "IN_PROGRESS"
|
|
18
|
+
PARTIAL = "PARTIAL"
|
|
19
|
+
VERIFIED = "VERIFIED"
|
|
20
|
+
UNVERIFIED = "UNVERIFIED"
|
|
21
|
+
BLOCKED = "BLOCKED"
|
|
22
|
+
FAILED = "FAILED"
|
|
23
|
+
STALE = "STALE"
|
|
24
|
+
UNKNOWN = "UNKNOWN"
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def is_terminal_success(cls, status: "Status") -> bool:
|
|
28
|
+
return status == cls.VERIFIED
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def is_actionable(cls, status: "Status") -> bool:
|
|
32
|
+
return status in {cls.PENDING, cls.IN_PROGRESS, cls.PARTIAL, cls.BLOCKED, cls.FAILED, cls.STALE}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class EvidenceType(str, Enum):
|
|
36
|
+
"""
|
|
37
|
+
Canonical types of evidence harvested from the workspace, environment,
|
|
38
|
+
verification pipelines, or conversations.
|
|
39
|
+
"""
|
|
40
|
+
SOURCE_CODE = "SOURCE_CODE"
|
|
41
|
+
AST_SYMBOL = "AST_SYMBOL"
|
|
42
|
+
GIT_COMMIT = "GIT_COMMIT"
|
|
43
|
+
GIT_DIFF = "GIT_DIFF"
|
|
44
|
+
GIT_STATUS = "GIT_STATUS"
|
|
45
|
+
TEST_RUN = "TEST_RUN"
|
|
46
|
+
BUILD_LOG = "BUILD_LOG"
|
|
47
|
+
CONFIG_FILE = "CONFIG_FILE"
|
|
48
|
+
DOCUMENTATION = "DOCUMENTATION"
|
|
49
|
+
RUNTIME_LOG = "RUNTIME_LOG"
|
|
50
|
+
CONVERSATION_ASSERTION = "CONVERSATION_ASSERTION"
|
|
51
|
+
USER_REQUIREMENT = "USER_REQUIREMENT"
|
|
52
|
+
AGENT_CLAIM = "AGENT_CLAIM"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class EvidenceLevel(IntEnum):
|
|
56
|
+
"""
|
|
57
|
+
The Evidence Hierarchy Matrix:
|
|
58
|
+
Strict seniority ranking for truth arbitration.
|
|
59
|
+
Lower numerical value indicates HIGHER priority / ground truth authority.
|
|
60
|
+
|
|
61
|
+
Level 1: Runtime status & automated test execution exit codes (Highest)
|
|
62
|
+
Level 2: AST structure, symbol exports, and physical source files
|
|
63
|
+
Level 3: Git working tree diffs, staged index, and commit history
|
|
64
|
+
Level 4: Architecture documentation, inline comments, and READMEs
|
|
65
|
+
Level 5: Conversational statements and agent assertions (Lowest)
|
|
66
|
+
"""
|
|
67
|
+
LEVEL_1_RUNTIME_TEST = 1
|
|
68
|
+
LEVEL_2_CODE_AST = 2
|
|
69
|
+
LEVEL_3_GIT_STATE = 3
|
|
70
|
+
LEVEL_4_DOCUMENTATION = 4
|
|
71
|
+
LEVEL_5_CONVERSATION = 5
|
|
72
|
+
|
|
73
|
+
@classmethod
|
|
74
|
+
def get_level_for_type(cls, evidence_type: EvidenceType) -> "EvidenceLevel":
|
|
75
|
+
"""Maps an evidence type to its fundamental hierarchy seniority level."""
|
|
76
|
+
mapping = {
|
|
77
|
+
EvidenceType.TEST_RUN: cls.LEVEL_1_RUNTIME_TEST,
|
|
78
|
+
EvidenceType.BUILD_LOG: cls.LEVEL_1_RUNTIME_TEST,
|
|
79
|
+
EvidenceType.RUNTIME_LOG: cls.LEVEL_1_RUNTIME_TEST,
|
|
80
|
+
EvidenceType.SOURCE_CODE: cls.LEVEL_2_CODE_AST,
|
|
81
|
+
EvidenceType.AST_SYMBOL: cls.LEVEL_2_CODE_AST,
|
|
82
|
+
EvidenceType.CONFIG_FILE: cls.LEVEL_2_CODE_AST,
|
|
83
|
+
EvidenceType.GIT_COMMIT: cls.LEVEL_3_GIT_STATE,
|
|
84
|
+
EvidenceType.GIT_DIFF: cls.LEVEL_3_GIT_STATE,
|
|
85
|
+
EvidenceType.GIT_STATUS: cls.LEVEL_3_GIT_STATE,
|
|
86
|
+
EvidenceType.DOCUMENTATION: cls.LEVEL_4_DOCUMENTATION,
|
|
87
|
+
EvidenceType.CONVERSATION_ASSERTION: cls.LEVEL_5_CONVERSATION,
|
|
88
|
+
EvidenceType.USER_REQUIREMENT: cls.LEVEL_5_CONVERSATION,
|
|
89
|
+
EvidenceType.AGENT_CLAIM: cls.LEVEL_5_CONVERSATION,
|
|
90
|
+
}
|
|
91
|
+
return mapping.get(evidence_type, cls.LEVEL_5_CONVERSATION)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class NodeType(str, Enum):
|
|
95
|
+
"""
|
|
96
|
+
Types of entities present in the Canonical State Graph (DAG).
|
|
97
|
+
"""
|
|
98
|
+
MILESTONE = "MILESTONE"
|
|
99
|
+
PHASE = "PHASE"
|
|
100
|
+
REQUIREMENT = "REQUIREMENT"
|
|
101
|
+
MODULE = "MODULE"
|
|
102
|
+
SERVICE = "SERVICE"
|
|
103
|
+
API = "API"
|
|
104
|
+
TASK = "TASK"
|
|
105
|
+
TEST = "TEST"
|
|
106
|
+
COMPONENT = "COMPONENT"
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class RelationType(str, Enum):
|
|
110
|
+
"""
|
|
111
|
+
Directed relationship types connecting nodes in the Canonical State Graph.
|
|
112
|
+
"""
|
|
113
|
+
DEPENDS_ON = "DEPENDS_ON"
|
|
114
|
+
IMPLEMENTS = "IMPLEMENTS"
|
|
115
|
+
VERIFIES = "VERIFIES"
|
|
116
|
+
BLOCKS = "BLOCKS"
|
|
117
|
+
IMPORTS = "IMPORTS"
|
|
118
|
+
REQUIRES = "REQUIRES"
|
|
119
|
+
INVALIDATES = "INVALIDATES"
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class TargetModel(str, Enum):
|
|
123
|
+
"""
|
|
124
|
+
Target AI model families supported by specialized handoff adapters.
|
|
125
|
+
"""
|
|
126
|
+
CLAUDE = "CLAUDE"
|
|
127
|
+
CODEX_GPT = "CODEX_GPT"
|
|
128
|
+
GEMINI = "GEMINI"
|
|
129
|
+
LOCAL_LLM = "LOCAL_LLM"
|
|
130
|
+
UNIVERSAL = "UNIVERSAL"
|
core/evidence.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Project Continuum - Canonical Evidence Model & Provenance
|
|
3
|
+
=========================================================
|
|
4
|
+
Implements the canonical Evidence data structure used by every extractor
|
|
5
|
+
and resolver across Project Continuum.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass, field, asdict
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
import hashlib
|
|
11
|
+
import json
|
|
12
|
+
from typing import Any, Dict, List, Optional
|
|
13
|
+
import uuid
|
|
14
|
+
|
|
15
|
+
from core.enums import EvidenceType, EvidenceLevel
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class EvidenceProvenance:
|
|
20
|
+
"""
|
|
21
|
+
Detailed audit trace explaining how and where evidence was obtained.
|
|
22
|
+
"""
|
|
23
|
+
extractor_name: str
|
|
24
|
+
source_uri: str
|
|
25
|
+
locator: str # e.g., "line:42-88", "symbol:AuthService.verify", "git:a1b2c3d", "turn:4"
|
|
26
|
+
collected_at: str = field(default_factory=lambda: datetime.now(timezone.utc).isoformat())
|
|
27
|
+
environment_info: Dict[str, Any] = field(default_factory=dict)
|
|
28
|
+
|
|
29
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
30
|
+
return asdict(self)
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def from_dict(cls, data: Dict[str, Any]) -> "EvidenceProvenance":
|
|
34
|
+
return cls(
|
|
35
|
+
extractor_name=data.get("extractor_name", "unknown_extractor"),
|
|
36
|
+
source_uri=data.get("source_uri", ""),
|
|
37
|
+
locator=data.get("locator", ""),
|
|
38
|
+
collected_at=data.get("collected_at", datetime.now(timezone.utc).isoformat()),
|
|
39
|
+
environment_info=data.get("environment_info", {})
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class Evidence:
|
|
45
|
+
"""
|
|
46
|
+
The canonical unit of proof in Project Continuum.
|
|
47
|
+
Every conclusion, confidence score, and status assessment must be grounded
|
|
48
|
+
in verifiable Evidence records.
|
|
49
|
+
"""
|
|
50
|
+
id: str = field(default_factory=lambda: f"ev_{uuid.uuid4().hex[:12]}")
|
|
51
|
+
type: EvidenceType = EvidenceType.SOURCE_CODE
|
|
52
|
+
level: EvidenceLevel = EvidenceLevel.LEVEL_2_CODE_AST
|
|
53
|
+
raw_payload: Dict[str, Any] = field(default_factory=dict)
|
|
54
|
+
summary: str = ""
|
|
55
|
+
provenance: Optional[EvidenceProvenance] = None
|
|
56
|
+
checksum: str = ""
|
|
57
|
+
created_at: str = field(default_factory=lambda: datetime.now(timezone.utc).isoformat())
|
|
58
|
+
metadata: Dict[str, Any] = field(default_factory=dict)
|
|
59
|
+
|
|
60
|
+
def __post_init__(self):
|
|
61
|
+
# Normalize types if strings were passed
|
|
62
|
+
if isinstance(self.type, str):
|
|
63
|
+
self.type = EvidenceType(self.type)
|
|
64
|
+
if isinstance(self.level, int) and not isinstance(self.level, EvidenceLevel):
|
|
65
|
+
self.level = EvidenceLevel(self.level)
|
|
66
|
+
elif self.level is None:
|
|
67
|
+
self.level = EvidenceLevel.get_level_for_type(self.type)
|
|
68
|
+
|
|
69
|
+
# Auto-calculate checksum of raw_payload if empty
|
|
70
|
+
if not self.checksum:
|
|
71
|
+
self.checksum = self.calculate_checksum()
|
|
72
|
+
|
|
73
|
+
def calculate_checksum(self) -> str:
|
|
74
|
+
"""Calculates deterministic SHA-256 hash of the evidence payload & summary."""
|
|
75
|
+
normalized_dict = {
|
|
76
|
+
"type": self.type.value if hasattr(self.type, "value") else str(self.type),
|
|
77
|
+
"summary": self.summary,
|
|
78
|
+
"raw_payload": self.raw_payload,
|
|
79
|
+
"provenance": self.provenance.to_dict() if self.provenance else None
|
|
80
|
+
}
|
|
81
|
+
serialized = json.dumps(normalized_dict, sort_keys=True, default=str)
|
|
82
|
+
return hashlib.sha256(serialized.encode("utf-8")).hexdigest()
|
|
83
|
+
|
|
84
|
+
def verify_integrity(self) -> bool:
|
|
85
|
+
"""Checks if current payload matches recorded checksum."""
|
|
86
|
+
return self.checksum == self.calculate_checksum()
|
|
87
|
+
|
|
88
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
89
|
+
return {
|
|
90
|
+
"id": self.id,
|
|
91
|
+
"type": self.type.value,
|
|
92
|
+
"level": int(self.level.value),
|
|
93
|
+
"summary": self.summary,
|
|
94
|
+
"raw_payload": self.raw_payload,
|
|
95
|
+
"provenance": self.provenance.to_dict() if self.provenance else None,
|
|
96
|
+
"checksum": self.checksum,
|
|
97
|
+
"created_at": self.created_at,
|
|
98
|
+
"metadata": self.metadata
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@classmethod
|
|
102
|
+
def from_dict(cls, data: Dict[str, Any]) -> "Evidence":
|
|
103
|
+
ev_type = EvidenceType(data["type"])
|
|
104
|
+
ev_level = EvidenceLevel(data.get("level", EvidenceLevel.get_level_for_type(ev_type).value))
|
|
105
|
+
provenance = EvidenceProvenance.from_dict(data["provenance"]) if data.get("provenance") else None
|
|
106
|
+
|
|
107
|
+
return cls(
|
|
108
|
+
id=data.get("id", f"ev_{uuid.uuid4().hex[:12]}"),
|
|
109
|
+
type=ev_type,
|
|
110
|
+
level=ev_level,
|
|
111
|
+
summary=data.get("summary", ""),
|
|
112
|
+
raw_payload=data.get("raw_payload", {}),
|
|
113
|
+
provenance=provenance,
|
|
114
|
+
checksum=data.get("checksum", ""),
|
|
115
|
+
created_at=data.get("created_at", datetime.now(timezone.utc).isoformat()),
|
|
116
|
+
metadata=data.get("metadata", {})
|
|
117
|
+
)
|
core/interfaces.py
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Project Continuum - Architectural Interfaces and Contracts
|
|
3
|
+
===========================================================
|
|
4
|
+
Defines the abstract Protocols / Interfaces for all major subsystems
|
|
5
|
+
across Project Continuum:
|
|
6
|
+
1. IEvidenceExtractor (Phases 1-5)
|
|
7
|
+
2. IEvidenceResolver (Phase 6)
|
|
8
|
+
3. IContradictionDetector (Phase 7)
|
|
9
|
+
4. IConfidenceCalculator (Phase 8)
|
|
10
|
+
5. IStateGraphManager (Phases 9-11)
|
|
11
|
+
6. IContextSelector (Phases 12-13)
|
|
12
|
+
7. IModelAdapter (Phases 14-15)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import Any, Dict, List, Optional, Protocol, Tuple, runtime_checkable
|
|
16
|
+
|
|
17
|
+
from core.enums import EvidenceType, Status, TargetModel
|
|
18
|
+
from core.evidence import Evidence
|
|
19
|
+
from core.state_models import (
|
|
20
|
+
CanonicalProjectState,
|
|
21
|
+
ContradictionRecord,
|
|
22
|
+
GraphEdge,
|
|
23
|
+
GraphNode,
|
|
24
|
+
ProjectState,
|
|
25
|
+
ConversationalState,
|
|
26
|
+
AgentExecutionState
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# ==============================================================================
|
|
31
|
+
# 1. EVIDENCE EXTRACTOR INTERFACE
|
|
32
|
+
# ==============================================================================
|
|
33
|
+
|
|
34
|
+
@runtime_checkable
|
|
35
|
+
class IEvidenceExtractor(Protocol):
|
|
36
|
+
"""
|
|
37
|
+
Contract implemented by all evidence extractors (Workspace/AST, Config,
|
|
38
|
+
Git, Verification/Tests, Conversation).
|
|
39
|
+
"""
|
|
40
|
+
@property
|
|
41
|
+
def extractor_name(self) -> str:
|
|
42
|
+
"""Unique identifier for this extractor."""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def supported_evidence_types(self) -> List[EvidenceType]:
|
|
47
|
+
"""Evidence types this extractor produces."""
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
def can_extract(self, target_path_or_input: str) -> bool:
|
|
51
|
+
"""Determines if this extractor is applicable to the target."""
|
|
52
|
+
...
|
|
53
|
+
|
|
54
|
+
def extract(self, target_path_or_input: str, context: Optional[Dict[str, Any]] = None) -> List[Evidence]:
|
|
55
|
+
"""Harvests verifiable evidence from the target."""
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# ==============================================================================
|
|
60
|
+
# 2. EVIDENCE RESOLUTION INTERFACE
|
|
61
|
+
# ==============================================================================
|
|
62
|
+
|
|
63
|
+
@runtime_checkable
|
|
64
|
+
class IEvidenceResolver(Protocol):
|
|
65
|
+
"""
|
|
66
|
+
Contract for arbitrating conflicting evidence according to the Evidence Hierarchy Matrix.
|
|
67
|
+
"""
|
|
68
|
+
def resolve_status(
|
|
69
|
+
self,
|
|
70
|
+
target_id: str,
|
|
71
|
+
evidence_list: List[Evidence],
|
|
72
|
+
claims: Optional[List[Dict[str, Any]]] = None
|
|
73
|
+
) -> Tuple[Status, Optional[Evidence], str]:
|
|
74
|
+
"""
|
|
75
|
+
Resolves candidate evidence into a final status.
|
|
76
|
+
Returns (Status, WinningEvidence, RationaleExplanation).
|
|
77
|
+
"""
|
|
78
|
+
...
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# ==============================================================================
|
|
82
|
+
# 3. CONTRADICTION DETECTOR INTERFACE
|
|
83
|
+
# ==============================================================================
|
|
84
|
+
|
|
85
|
+
@runtime_checkable
|
|
86
|
+
class IContradictionDetector(Protocol):
|
|
87
|
+
"""
|
|
88
|
+
Contract for finding mismatches between claims/docs and physical reality.
|
|
89
|
+
"""
|
|
90
|
+
def detect_contradictions(
|
|
91
|
+
self,
|
|
92
|
+
project_state: ProjectState,
|
|
93
|
+
conversational_state: ConversationalState,
|
|
94
|
+
evidence_pool: Dict[str, Evidence]
|
|
95
|
+
) -> List[ContradictionRecord]:
|
|
96
|
+
"""Analyzes all state dimensions and returns detected contradictions."""
|
|
97
|
+
...
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# ==============================================================================
|
|
101
|
+
# 4. CONFIDENCE CALCULATOR INTERFACE
|
|
102
|
+
# ==============================================================================
|
|
103
|
+
|
|
104
|
+
@runtime_checkable
|
|
105
|
+
class IConfidenceCalculator(Protocol):
|
|
106
|
+
"""
|
|
107
|
+
Contract for calculating explainable confidence scores (0.0% to 100.0%)
|
|
108
|
+
grounded in physical proof and capped by contradictions.
|
|
109
|
+
"""
|
|
110
|
+
def calculate_node_confidence(
|
|
111
|
+
self,
|
|
112
|
+
node: GraphNode,
|
|
113
|
+
evidence_pool: Dict[str, Evidence],
|
|
114
|
+
contradictions: List[ContradictionRecord]
|
|
115
|
+
) -> Tuple[float, Dict[str, Any]]:
|
|
116
|
+
"""
|
|
117
|
+
Calculates confidence score for a node and returns (Score, ExplanationDict).
|
|
118
|
+
"""
|
|
119
|
+
...
|
|
120
|
+
|
|
121
|
+
def calculate_project_confidence(
|
|
122
|
+
self,
|
|
123
|
+
canonical_state: CanonicalProjectState
|
|
124
|
+
) -> Tuple[float, Dict[str, Any]]:
|
|
125
|
+
"""Calculates global aggregate project confidence."""
|
|
126
|
+
...
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# ==============================================================================
|
|
130
|
+
# 5. STATE GRAPH MANAGER INTERFACE
|
|
131
|
+
# ==============================================================================
|
|
132
|
+
|
|
133
|
+
@runtime_checkable
|
|
134
|
+
class IStateGraphManager(Protocol):
|
|
135
|
+
"""
|
|
136
|
+
Contract for managing the Directed Acyclic Graph (DAG) of the project.
|
|
137
|
+
"""
|
|
138
|
+
def add_node(self, node: GraphNode) -> None:
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
def add_edge(self, edge: GraphEdge) -> None:
|
|
142
|
+
...
|
|
143
|
+
|
|
144
|
+
def get_dependencies(self, node_id: str, recursive: bool = False) -> List[GraphNode]:
|
|
145
|
+
...
|
|
146
|
+
|
|
147
|
+
def get_dependents(self, node_id: str, recursive: bool = False) -> List[GraphNode]:
|
|
148
|
+
...
|
|
149
|
+
|
|
150
|
+
def detect_cycles(self) -> List[List[str]]:
|
|
151
|
+
...
|
|
152
|
+
|
|
153
|
+
def propagate_invalidation(self, changed_node_id: str) -> List[str]:
|
|
154
|
+
"""Marks downstream dependent nodes STALE or BLOCKED and returns affected IDs."""
|
|
155
|
+
...
|
|
156
|
+
|
|
157
|
+
def export_mermaid(self) -> str:
|
|
158
|
+
"""Generates Mermaid diagram string representing the DAG."""
|
|
159
|
+
...
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# ==============================================================================
|
|
163
|
+
# 6. CONTEXT SELECTOR INTERFACE
|
|
164
|
+
# ==============================================================================
|
|
165
|
+
|
|
166
|
+
@runtime_checkable
|
|
167
|
+
class IContextSelector(Protocol):
|
|
168
|
+
"""
|
|
169
|
+
Contract for pruning unnecessary context and extracting the targeted subgraph
|
|
170
|
+
for the next task.
|
|
171
|
+
"""
|
|
172
|
+
def select_context_for_task(
|
|
173
|
+
self,
|
|
174
|
+
task_description: str,
|
|
175
|
+
canonical_state: CanonicalProjectState,
|
|
176
|
+
token_budget: Optional[int] = None
|
|
177
|
+
) -> Dict[str, Any]:
|
|
178
|
+
"""
|
|
179
|
+
Returns targeted subgraph, relevant files, test references, constraints,
|
|
180
|
+
and an audit of omitted items.
|
|
181
|
+
"""
|
|
182
|
+
...
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# ==============================================================================
|
|
186
|
+
# 7. MODEL ADAPTER INTERFACE
|
|
187
|
+
# ==============================================================================
|
|
188
|
+
|
|
189
|
+
@runtime_checkable
|
|
190
|
+
class IModelAdapter(Protocol):
|
|
191
|
+
"""
|
|
192
|
+
Contract for generating model-specific handoff packages (Claude, Codex, Gemini, Local).
|
|
193
|
+
"""
|
|
194
|
+
@property
|
|
195
|
+
def target_model(self) -> TargetModel:
|
|
196
|
+
...
|
|
197
|
+
|
|
198
|
+
def generate_handoff(
|
|
199
|
+
self,
|
|
200
|
+
canonical_state: CanonicalProjectState,
|
|
201
|
+
context_selection: Optional[Dict[str, Any]] = None
|
|
202
|
+
) -> Dict[str, str]:
|
|
203
|
+
"""
|
|
204
|
+
Synthesizes the handoff files:
|
|
205
|
+
- "handoff.md": continuation briefing
|
|
206
|
+
- "project-context.md": architectural narrative
|
|
207
|
+
- "project-state.json": machine-readable payload
|
|
208
|
+
"""
|
|
209
|
+
...
|