engineering-platform 2.2.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.
Files changed (130) hide show
  1. engineering_platform/ENGINEERING_PLATFORM_CONFIG.json +32 -0
  2. engineering_platform/ENGINEERING_PLATFORM_VERSION.json +15 -0
  3. engineering_platform/__init__.py +1 -0
  4. engineering_platform/__main__.py +7 -0
  5. engineering_platform/agent_state.py +530 -0
  6. engineering_platform/agent_trust.py +174 -0
  7. engineering_platform/assets/dashboard.css +1317 -0
  8. engineering_platform/assets/dashboard.js +8534 -0
  9. engineering_platform/assets/dashboard_locales.mjs +4049 -0
  10. engineering_platform/assets/dashboard_status_store.mjs +41 -0
  11. engineering_platform/assets/operations-console/apple-touch-icon-dark.png +0 -0
  12. engineering_platform/assets/operations-console/apple-touch-icon-light.png +0 -0
  13. engineering_platform/assets/operations-console/icon-dark.png +0 -0
  14. engineering_platform/assets/operations-console/icon-light.png +0 -0
  15. engineering_platform/assets/operations-console/icon-transparent.png +0 -0
  16. engineering_platform/assets/operations-console/manifest.webmanifest +11 -0
  17. engineering_platform/capability_preflight.py +285 -0
  18. engineering_platform/capability_review.py +261 -0
  19. engineering_platform/central_data_transfer.py +195 -0
  20. engineering_platform/central_database.py +245 -0
  21. engineering_platform/central_store_migration.py +1672 -0
  22. engineering_platform/codex_capacity.py +81 -0
  23. engineering_platform/codex_chat.py +226 -0
  24. engineering_platform/codex_observability.py +153 -0
  25. engineering_platform/component_lock.py +40 -0
  26. engineering_platform/component_logging.py +420 -0
  27. engineering_platform/console_presentation.py +14 -0
  28. engineering_platform/console_route_ownership.py +83 -0
  29. engineering_platform/contracts/__init__.py +38 -0
  30. engineering_platform/contracts/ep_consumer.py +391 -0
  31. engineering_platform/contracts/models.py +105 -0
  32. engineering_platform/contracts/projection.py +401 -0
  33. engineering_platform/dashboard_browser_validation.py +206 -0
  34. engineering_platform/dashboard_state.py +630 -0
  35. engineering_platform/dashboard_supervisor.swift +105 -0
  36. engineering_platform/dashboard_translation.py +129 -0
  37. engineering_platform/dependabot_producer.py +349 -0
  38. engineering_platform/drift_diagnostics.py +144 -0
  39. engineering_platform/emergency_recovery.py +268 -0
  40. engineering_platform/engineering_memory.py +139 -0
  41. engineering_platform/ep_consumer_credentials.py +473 -0
  42. engineering_platform/evidence_projection.py +213 -0
  43. engineering_platform/execution_activity.py +218 -0
  44. engineering_platform/execution_context.py +132 -0
  45. engineering_platform/execution_errors.py +42 -0
  46. engineering_platform/execution_evidence.py +24 -0
  47. engineering_platform/execution_executor.py +730 -0
  48. engineering_platform/execution_finalization.py +44 -0
  49. engineering_platform/execution_host.py +3306 -0
  50. engineering_platform/execution_lease.py +365 -0
  51. engineering_platform/execution_lifecycle.py +447 -0
  52. engineering_platform/execution_models.py +43 -0
  53. engineering_platform/execution_readiness.py +166 -0
  54. engineering_platform/execution_reporting.py +1607 -0
  55. engineering_platform/execution_repository.py +253 -0
  56. engineering_platform/execution_timeout_policy.py +56 -0
  57. engineering_platform/execution_timing.py +440 -0
  58. engineering_platform/execution_transaction.py +28 -0
  59. engineering_platform/external_producer_binding.py +235 -0
  60. engineering_platform/file_inbox.py +249 -0
  61. engineering_platform/forensic_attribution.py +338 -0
  62. engineering_platform/forensic_attribution_v2.py +134 -0
  63. engineering_platform/forensic_delta.py +299 -0
  64. engineering_platform/golden_scenario.py +63 -0
  65. engineering_platform/historical_dashboard_configuration.py +171 -0
  66. engineering_platform/host_admin.py +199 -0
  67. engineering_platform/host_preflight.py +231 -0
  68. engineering_platform/installation_relocation.py +122 -0
  69. engineering_platform/investigation_ledger.py +89 -0
  70. engineering_platform/legacy_inbox_migration.py +79 -0
  71. engineering_platform/lifecycle_worker.py +223 -0
  72. engineering_platform/live_status.py +267 -0
  73. engineering_platform/local_api.py +209 -0
  74. engineering_platform/local_api_keychain.py +51 -0
  75. engineering_platform/local_repository_binding.py +138 -0
  76. engineering_platform/managed_autonomy.py +509 -0
  77. engineering_platform/managed_codex_runtime.py +105 -0
  78. engineering_platform/parity_context.py +203 -0
  79. engineering_platform/parity_lifecycle_dispatcher.py +488 -0
  80. engineering_platform/platform_admin.py +13 -0
  81. engineering_platform/platform_api.py +428 -0
  82. engineering_platform/platform_bootstrap.py +385 -0
  83. engineering_platform/platform_components.py +65 -0
  84. engineering_platform/platform_version.py +171 -0
  85. engineering_platform/pr_check_repair.py +276 -0
  86. engineering_platform/pr_evidence_backfill.py +278 -0
  87. engineering_platform/producer.py +209 -0
  88. engineering_platform/project_agent.py +366 -0
  89. engineering_platform/project_agent_service.py +244 -0
  90. engineering_platform/project_topology.py +126 -0
  91. engineering_platform/prompt_history.py +591 -0
  92. engineering_platform/provider_context.py +136 -0
  93. engineering_platform/provider_context_benchmark.py +41 -0
  94. engineering_platform/provider_context_scope.py +90 -0
  95. engineering_platform/provider_interruption.py +168 -0
  96. engineering_platform/provider_process_identity.py +80 -0
  97. engineering_platform/provider_readiness.py +138 -0
  98. engineering_platform/provider_recovery.py +647 -0
  99. engineering_platform/provider_usage.py +497 -0
  100. engineering_platform/providers.py +471 -0
  101. engineering_platform/qualification.py +220 -0
  102. engineering_platform/recommendation_handoff.py +238 -0
  103. engineering_platform/report_analysis.py +193 -0
  104. engineering_platform/repository_attachment.py +171 -0
  105. engineering_platform/repository_handoff.py +95 -0
  106. engineering_platform/resources.py +38 -0
  107. engineering_platform/reviewer_evidence.py +70 -0
  108. engineering_platform/schemas/repository-attachment.schema.json +61 -0
  109. engineering_platform/server.py +3679 -0
  110. engineering_platform/server_console_services.py +2024 -0
  111. engineering_platform/server_relay.py +172 -0
  112. engineering_platform/server_service.py +122 -0
  113. engineering_platform/status_model.py +135 -0
  114. engineering_platform/status_reconciliation.py +34 -0
  115. engineering_platform/storage.py +2440 -0
  116. engineering_platform/submission_cli.py +77 -0
  117. engineering_platform/submission_intake.py +45 -0
  118. engineering_platform/submission_service.py +317 -0
  119. engineering_platform/telemetry.py +951 -0
  120. engineering_platform/templates/workspace-config.json +25 -0
  121. engineering_platform/validation_identity.py +50 -0
  122. engineering_platform/validation_profile.py +211 -0
  123. engineering_platform/workspace_preflight.py +263 -0
  124. engineering_platform/worktree_provenance.py +147 -0
  125. engineering_platform/worktree_tooling.py +18 -0
  126. engineering_platform-2.2.0.dist-info/METADATA +18 -0
  127. engineering_platform-2.2.0.dist-info/RECORD +130 -0
  128. engineering_platform-2.2.0.dist-info/WHEEL +5 -0
  129. engineering_platform-2.2.0.dist-info/entry_points.txt +6 -0
  130. engineering_platform-2.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,32 @@
1
+ {
2
+ "schema_version": 2,
3
+ "platform": {
4
+ "id": "engineering-platform",
5
+ "name": "Engineering Platform",
6
+ "version": "2.2.0",
7
+ "generation": 2,
8
+ "documentation_namespace": "engineering-platform",
9
+ "capability_registry_version": 1
10
+ },
11
+ "workspace": {
12
+ "id": "engineering-platform",
13
+ "name": "Engineering Platform",
14
+ "repository": {"provider": "github", "owner": "pcvantol", "name": "engineering-platform", "default_branch": "main"},
15
+ "branding": {"dashboard_title": "EP Operations"},
16
+ "workspace_authorization": {
17
+ "allowed_roots": [],
18
+ "allowed_repositories": [],
19
+ "denied_repositories": [],
20
+ "symlink_policy": "reject",
21
+ "case_sensitivity": "host"
22
+ }
23
+ },
24
+ "providers": {
25
+ "runtime": "codex_cli",
26
+ "repository": "github",
27
+ "service_manager": "launchd",
28
+ "remote_submission": "icloud_inbox",
29
+ "private_remote_access": "tailscale",
30
+ "dashboard": "private_http"
31
+ }
32
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "bootstrap_contract": "2026.12",
3
+ "checkpoint_format": 1,
4
+ "dashboard_version": "2.2.0",
5
+ "handoff_protocol": 1,
6
+ "memory_format": 2,
7
+ "minimum_codex_cli": "0.146.0",
8
+ "inbox_protocol": 1,
9
+ "platform_version": "2.2.0",
10
+ "report_format": 2,
11
+ "runner_version": "2.2.0",
12
+ "status_model": 1,
13
+ "storage_schema": 41,
14
+ "watcher_version": "2.2.0"
15
+ }
@@ -0,0 +1 @@
1
+ """Local-only, repository-grounded engineering transaction runner."""
@@ -0,0 +1,7 @@
1
+ """Module entry point for the provider-neutral Engineering Execution Host."""
2
+
3
+ from .execution_host import main
4
+
5
+
6
+ if __name__ == "__main__":
7
+ raise SystemExit(main())
@@ -0,0 +1,530 @@
1
+ """Validated, atomic local checkpoints for bounded engineering transactions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import asdict, dataclass
6
+ import json
7
+ import os
8
+ from pathlib import Path
9
+ import re
10
+ import sqlite3
11
+ import tempfile
12
+
13
+ from .storage import (
14
+ CENTRAL_OPERATIONAL_DATABASE_ENVIRONMENT,
15
+ EngineeringStorageError,
16
+ open_storage,
17
+ )
18
+
19
+
20
+ SCHEMA_VERSION = 1
21
+ PHASES = frozenset({"INITIALIZE", "CAPABILITY_REVIEW", "EXECUTE_AGENT", "LOCAL_REPOSITORY_VALIDATION", "QUALITY_CONTROL_AGENT", "REPAIR_AGENT", "FINALIZE_AGENT", "RECONCILE_AGENT", "WAIT_FOR_TERMINAL_EVIDENCE", "WAIT_FOR_OPERATOR_MERGE", "REPOSITORY_CLEANUP", "COMPLETE", "BLOCKED", "FAILED"})
22
+ RUN_ID_PATTERN = re.compile(r"^[a-z0-9][a-z0-9-]{0,63}$")
23
+ MAX_DIAGNOSTIC_LENGTH = 500
24
+ MAX_COMMIT_EVIDENCE_RECORDS = 48
25
+ COMMIT_EVIDENCE_FIELDS = frozenset({"phase", "observed_at", "commit_sha", "description"})
26
+ COMMIT_EVIDENCE_TIMESTAMP_PATTERN = re.compile(
27
+ r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?\+00:00"
28
+ )
29
+ MUTATING_COMMIT_PHASES = frozenset({
30
+ "EXECUTE_AGENT",
31
+ "LOCAL_REPOSITORY_VALIDATION",
32
+ "QUALITY_CONTROL_AGENT",
33
+ "REPAIR_AGENT",
34
+ "FINALIZE_AGENT",
35
+ "RECONCILE_AGENT",
36
+ "WAIT_FOR_OPERATOR_MERGE",
37
+ })
38
+ COMMIT_EVIDENCE_DESCRIPTIONS = frozenset({
39
+ "implementation_agent_commit_verified",
40
+ "genesis_implementation_commit_verified",
41
+ "local_repository_validation_commit_verified",
42
+ "quality_control_commit_verified",
43
+ "pull_request_repair_commit_verified",
44
+ "finalization_commit_verified",
45
+ "end_reconciliation_commit_verified",
46
+ "implementation_merge_verified",
47
+ "finalization_merge_verified",
48
+ "reconciliation_merge_verified",
49
+ })
50
+ SENSITIVE_DIAGNOSTIC_PATTERN = re.compile(
51
+ r"(?i)\b(api[_ -]?key|oauth|access[_ -]?token|refresh[_ -]?token|secret|cookie|authorization|password)\b\s*[:=]\s*\S+|\bbearer\s+\S+|\b[A-Z][A-Z0-9_]{2,}\s*=\s*\S+"
52
+ )
53
+
54
+
55
+ class StateError(ValueError):
56
+ """Raised when local advisory state is missing, malformed, or unsafe."""
57
+
58
+
59
+ def redact_diagnostic(value: str, *, limit: int = MAX_DIAGNOSTIC_LENGTH) -> str:
60
+ """Return bounded human-readable text that is safe to display or persist."""
61
+ if not isinstance(value, str):
62
+ return "Diagnostic omitted because it was not valid text."
63
+ compact = " ".join(value.replace("\x00", " ").split())
64
+ compact = SENSITIVE_DIAGNOSTIC_PATTERN.sub("[REDACTED]", compact)
65
+ return compact[:limit]
66
+
67
+
68
+ def is_valid_commit_evidence_record(value: object) -> bool:
69
+ """Return whether one persisted commit-timeline record is strict and safe.
70
+
71
+ This is deliberately the sole schema predicate for the append-only commit
72
+ timeline. Runtime writers and read-only dashboard projections share it, so
73
+ merge, repair and other mutating phases cannot drift into incompatible
74
+ evidence shapes.
75
+ """
76
+ return (
77
+ isinstance(value, dict)
78
+ and set(value) == COMMIT_EVIDENCE_FIELDS
79
+ and value.get("phase") in MUTATING_COMMIT_PHASES
80
+ and isinstance(value.get("observed_at"), str)
81
+ and bool(COMMIT_EVIDENCE_TIMESTAMP_PATTERN.fullmatch(value["observed_at"]))
82
+ and isinstance(value.get("commit_sha"), str)
83
+ and bool(re.fullmatch(r"[0-9a-f]{40}", value["commit_sha"]))
84
+ and isinstance(value.get("description"), str)
85
+ and value["description"] in COMMIT_EVIDENCE_DESCRIPTIONS
86
+ and len(value["description"]) <= MAX_DIAGNOSTIC_LENGTH
87
+ and value["description"] == redact_diagnostic(value["description"])
88
+ )
89
+
90
+
91
+ def verified_commit_evidence_record(
92
+ *, phase: str, observed_at: str, commit_sha: str, description: str
93
+ ) -> dict[str, str]:
94
+ """Build one canonical verified-commit record or reject unsafe evidence."""
95
+ record = {
96
+ "phase": phase,
97
+ "observed_at": observed_at,
98
+ "commit_sha": commit_sha,
99
+ "description": description,
100
+ }
101
+ if not is_valid_commit_evidence_record(record):
102
+ raise StateError("commit evidence record is invalid or unsafe")
103
+ return record
104
+
105
+
106
+ @dataclass(frozen=True)
107
+ class TransactionState:
108
+ run_id: str
109
+ repository: str
110
+ prompt_path: str
111
+ phase: str
112
+ branch: str | None = None
113
+ pull_request: int | None = None
114
+ last_verified_sha: str | None = None
115
+ next_action: str = "invoke_agent"
116
+ terminal_condition: str = "repository_reconciled"
117
+ diagnostic: str | None = None
118
+ owner_authorized: bool = False
119
+ transaction_kind: str = "IMPLEMENTATION"
120
+ execution_mode: str = "MANAGED"
121
+ action_intent: str = "MUTATING_DELIVERY"
122
+ genesis_repository_path: str | None = None
123
+ genesis_commit_sha: str | None = None
124
+ implementation_branch: str | None = None
125
+ implementation_pull_request: int | None = None
126
+ implementation_head_sha: str | None = None
127
+ implementation_merge_commit: str | None = None
128
+ finalization_branch: str | None = None
129
+ finalization_pull_request: int | None = None
130
+ finalization_head_sha: str | None = None
131
+ finalization_merge_commit: str | None = None
132
+ reconciliation_pull_request: int | None = None
133
+ latest_repository_evidence: str | None = None
134
+ latest_github_evidence: str | None = None
135
+ agent_execution_seconds: float | None = None
136
+ validation_evidence: tuple[dict[str, str], ...] = ()
137
+ quality_evidence: tuple[dict[str, str], ...] = ()
138
+ repair_iterations: int = 0
139
+ repair_audit: tuple[dict[str, str], ...] = ()
140
+ local_validation_iterations: int = 0
141
+ local_validation_audit: tuple[dict[str, str], ...] = ()
142
+ commit_evidence: tuple[dict[str, str], ...] = ()
143
+ waiting_for_merge_since: str | None = None
144
+ auth_recovery_phase: str | None = None
145
+ auth_recovery_next_action: str | None = None
146
+ auth_recovery_providers: tuple[str, ...] = ()
147
+ admission_decision: str = "NOT_STARTED"
148
+ admission_completed_at: str | None = None
149
+ admission_evidence_source: str | None = None
150
+ # A run-bound, append-only record of the one automatic provider restart.
151
+ # This is checkpoint data, not a database migration: old rows simply read
152
+ # with an empty ledger.
153
+ provider_recovery_attempts: tuple[dict[str, str], ...] = ()
154
+ terminal: bool = False
155
+ schema_version: int = SCHEMA_VERSION
156
+
157
+ @classmethod
158
+ def from_dict(cls, raw: object) -> "TransactionState":
159
+ if not isinstance(raw, dict):
160
+ raise StateError("checkpoint must be a JSON object")
161
+ expected = {field.name for field in cls.__dataclass_fields__.values()}
162
+ defaults = {
163
+ "diagnostic": None, "owner_authorized": False, "transaction_kind": "IMPLEMENTATION",
164
+ "execution_mode": "MANAGED", "genesis_repository_path": None, "genesis_commit_sha": None,
165
+ "action_intent": "MUTATING_DELIVERY",
166
+ "implementation_branch": None, "implementation_pull_request": None,
167
+ "implementation_head_sha": None, "implementation_merge_commit": None,
168
+ "finalization_branch": None, "finalization_pull_request": None,
169
+ "finalization_head_sha": None, "finalization_merge_commit": None,
170
+ "reconciliation_pull_request": None,
171
+ "latest_repository_evidence": None, "latest_github_evidence": None,
172
+ "agent_execution_seconds": None,
173
+ "validation_evidence": (),
174
+ "quality_evidence": (),
175
+ "repair_iterations": 0,
176
+ "repair_audit": (),
177
+ "local_validation_iterations": 0,
178
+ "local_validation_audit": (),
179
+ "commit_evidence": (),
180
+ "waiting_for_merge_since": None,
181
+ "auth_recovery_phase": None,
182
+ "auth_recovery_next_action": None,
183
+ "auth_recovery_providers": (),
184
+ "admission_decision": "NOT_STARTED",
185
+ "admission_completed_at": None,
186
+ "admission_evidence_source": None,
187
+ "provider_recovery_attempts": (),
188
+ }
189
+ if set(raw).issubset(expected) and set(raw) | set(defaults) == expected:
190
+ raw = {**defaults, **raw}
191
+ elif set(raw) != expected:
192
+ raise StateError("checkpoint fields are incompatible")
193
+ if isinstance(raw.get("validation_evidence"), list):
194
+ raw = {**raw, "validation_evidence": tuple(raw["validation_evidence"])}
195
+ if isinstance(raw.get("quality_evidence"), list):
196
+ raw = {**raw, "quality_evidence": tuple(raw["quality_evidence"])}
197
+ if isinstance(raw.get("repair_audit"), list):
198
+ raw = {**raw, "repair_audit": tuple(raw["repair_audit"])}
199
+ if isinstance(raw.get("local_validation_audit"), list):
200
+ raw = {**raw, "local_validation_audit": tuple(raw["local_validation_audit"])}
201
+ if isinstance(raw.get("commit_evidence"), list):
202
+ raw = {**raw, "commit_evidence": tuple(raw["commit_evidence"])}
203
+ if isinstance(raw.get("auth_recovery_providers"), list):
204
+ raw = {**raw, "auth_recovery_providers": tuple(raw["auth_recovery_providers"])}
205
+ if isinstance(raw.get("provider_recovery_attempts"), list):
206
+ raw = {**raw, "provider_recovery_attempts": tuple(raw["provider_recovery_attempts"])}
207
+ try:
208
+ state = cls(**raw)
209
+ except TypeError as error:
210
+ raise StateError("checkpoint fields are invalid") from error
211
+ if state.schema_version != SCHEMA_VERSION:
212
+ raise StateError("unsupported checkpoint schema version")
213
+ if not RUN_ID_PATTERN.fullmatch(state.run_id):
214
+ raise StateError("checkpoint run_id is invalid")
215
+ if not all(isinstance(value, str) and value for value in (state.repository, state.prompt_path, state.phase, state.next_action, state.terminal_condition)):
216
+ raise StateError("checkpoint identity or phase is invalid")
217
+ if state.phase not in PHASES or (state.branch is not None and not isinstance(state.branch, str)):
218
+ raise StateError("checkpoint phase or branch is invalid")
219
+ if state.pull_request is not None and (not isinstance(state.pull_request, int) or state.pull_request < 1):
220
+ raise StateError("checkpoint pull_request is invalid")
221
+ if state.last_verified_sha is not None and not re.fullmatch(r"[0-9a-f]{40}", state.last_verified_sha):
222
+ raise StateError("checkpoint last_verified_sha is invalid")
223
+ if state.diagnostic is not None and (not isinstance(state.diagnostic, str) or not state.diagnostic or state.diagnostic != redact_diagnostic(state.diagnostic)):
224
+ raise StateError("checkpoint diagnostic is invalid or unsafe")
225
+ if not isinstance(state.owner_authorized, bool) or state.transaction_kind not in {"IMPLEMENTATION", "FINALIZATION", "RECONCILIATION"} or state.execution_mode not in {"MANAGED", "GENESIS"} or state.action_intent not in {"MUTATING_DELIVERY", "VALIDATION_ONLY"}:
226
+ raise StateError("checkpoint authorization or transaction kind is invalid")
227
+ if state.admission_decision not in {"NOT_STARTED", "PASS", "FAIL", "BLOCKED", "UNAVAILABLE"}:
228
+ raise StateError("checkpoint admission decision is invalid")
229
+ if state.admission_decision == "PASS" and not isinstance(state.admission_completed_at, str):
230
+ raise StateError("passed admission requires a completion timestamp")
231
+ if state.admission_completed_at is not None and not isinstance(state.admission_completed_at, str):
232
+ raise StateError("checkpoint admission completion timestamp is invalid")
233
+ if state.admission_evidence_source is not None and state.admission_evidence_source not in {"WATCHER", "RUNNER"}:
234
+ raise StateError("checkpoint admission evidence source is invalid")
235
+ recovery_fields = {"original_invocation_id", "replacement_invocation_id", "phase", "classification", "eligibility", "result", "requested_at", "started_at", "completed_at"}
236
+ if (
237
+ not isinstance(state.provider_recovery_attempts, tuple)
238
+ or len(state.provider_recovery_attempts) > 1
239
+ or any(
240
+ not isinstance(item, dict) or set(item) != recovery_fields
241
+ or any(not isinstance(value, str) or not value or len(value) > 160 or value != redact_diagnostic(value, limit=160) for value in item.values())
242
+ or item["classification"] != "provider_turn_interrupted"
243
+ or item["eligibility"] not in {"ELIGIBLE", "INELIGIBLE", "PRECHECK_FAILED", "CANCELLED"}
244
+ or item["result"] not in {"RECOVERY_AVAILABLE", "ACTIVE", "RECOVERED", "INTERRUPTED_AGAIN", "INELIGIBLE", "PRECHECK_FAILED", "CANCELLED", "PROVIDER_FAILED"}
245
+ for item in state.provider_recovery_attempts
246
+ )
247
+ ):
248
+ raise StateError("checkpoint provider recovery ledger is invalid or unsafe")
249
+ if state.genesis_repository_path is not None and (not isinstance(state.genesis_repository_path, str) or not Path(state.genesis_repository_path).is_absolute()):
250
+ raise StateError("genesis repository path is invalid")
251
+ if state.genesis_commit_sha is not None and (not isinstance(state.genesis_commit_sha, str) or not re.fullmatch(r"[0-9a-f]{40}", state.genesis_commit_sha)):
252
+ raise StateError("genesis commit SHA is invalid")
253
+ optional_sha_fields = (state.implementation_head_sha, state.implementation_merge_commit, state.finalization_head_sha, state.finalization_merge_commit)
254
+ if any(value is not None and (not isinstance(value, str) or not re.fullmatch(r"[0-9a-f]{40}", value)) for value in optional_sha_fields):
255
+ raise StateError("checkpoint lifecycle SHA is invalid")
256
+ optional_pr_fields = (state.implementation_pull_request, state.finalization_pull_request, state.reconciliation_pull_request)
257
+ if any(value is not None and (not isinstance(value, int) or value < 1) for value in optional_pr_fields):
258
+ raise StateError("checkpoint lifecycle pull request is invalid")
259
+ if not isinstance(state.repair_iterations, int) or state.repair_iterations < 0:
260
+ raise StateError("checkpoint repair iteration count is invalid")
261
+ audit_fields = {"iteration", "observed_at", "failed_checks", "proposed_action", "agent_summary", "commit_sha", "outcome"}
262
+ if not isinstance(state.local_validation_iterations, int) or not 0 <= state.local_validation_iterations <= 3:
263
+ raise StateError("checkpoint local validation iteration count is invalid")
264
+ if (
265
+ not isinstance(state.local_validation_audit, tuple)
266
+ or len(state.local_validation_audit) > 3
267
+ or any(
268
+ not isinstance(item, dict) or set(item) != audit_fields
269
+ or not all(isinstance(value, str) and value and len(value) <= MAX_DIAGNOSTIC_LENGTH and value == redact_diagnostic(value) for value in item.values())
270
+ or not item["iteration"].isdigit() or int(item["iteration"]) < 1
271
+ or item["outcome"] not in {"validated", "validation_failed", "agent_failed"}
272
+ or (item["commit_sha"] != "not_recorded" and not re.fullmatch(r"[0-9a-f]{40}", item["commit_sha"]))
273
+ for item in state.local_validation_audit
274
+ )
275
+ ):
276
+ raise StateError("checkpoint local validation audit is invalid or unsafe")
277
+ if (
278
+ not isinstance(state.repair_audit, tuple)
279
+ or len(state.repair_audit) > 3
280
+ or any(
281
+ not isinstance(item, dict) or set(item) != audit_fields
282
+ or not all(isinstance(value, str) and value and len(value) <= MAX_DIAGNOSTIC_LENGTH and value == redact_diagnostic(value) for value in item.values())
283
+ or not item["iteration"].isdigit() or int(item["iteration"]) < 1
284
+ or item["outcome"] not in {"planned", "submitted_for_recheck", "agent_failed", "agent_timed_out"}
285
+ or (item["commit_sha"] != "not_recorded" and not re.fullmatch(r"[0-9a-f]{40}", item["commit_sha"]))
286
+ for item in state.repair_audit
287
+ )
288
+ ):
289
+ raise StateError("checkpoint repair audit is invalid or unsafe")
290
+ if (
291
+ not isinstance(state.commit_evidence, tuple)
292
+ or len(state.commit_evidence) > MAX_COMMIT_EVIDENCE_RECORDS
293
+ or any(
294
+ not is_valid_commit_evidence_record(item)
295
+ for item in state.commit_evidence
296
+ )
297
+ or len({(item["phase"], item["commit_sha"]) for item in state.commit_evidence}) != len(state.commit_evidence)
298
+ ):
299
+ raise StateError("checkpoint commit evidence is invalid or unsafe")
300
+ if state.waiting_for_merge_since is not None and (
301
+ not isinstance(state.waiting_for_merge_since, str)
302
+ or len(state.waiting_for_merge_since) > 80
303
+ ):
304
+ raise StateError("checkpoint merge wait timestamp is invalid")
305
+ if state.auth_recovery_phase is not None and state.auth_recovery_phase not in PHASES:
306
+ raise StateError("checkpoint auth recovery phase is invalid")
307
+ if state.auth_recovery_next_action is not None and (
308
+ not isinstance(state.auth_recovery_next_action, str) or not state.auth_recovery_next_action
309
+ ):
310
+ raise StateError("checkpoint auth recovery action is invalid")
311
+ if (
312
+ not isinstance(state.auth_recovery_providers, tuple)
313
+ or any(provider not in {"CODEX", "GITHUB"} for provider in state.auth_recovery_providers)
314
+ or len(set(state.auth_recovery_providers)) != len(state.auth_recovery_providers)
315
+ or (state.auth_recovery_phase is None) != (not state.auth_recovery_providers)
316
+ ):
317
+ raise StateError("checkpoint auth recovery providers are invalid")
318
+ for value in (state.latest_repository_evidence, state.latest_github_evidence):
319
+ if value is not None and (not isinstance(value, str) or len(value) > MAX_DIAGNOSTIC_LENGTH or value != redact_diagnostic(value)):
320
+ raise StateError("checkpoint evidence is invalid or unsafe")
321
+ if state.agent_execution_seconds is not None and (
322
+ isinstance(state.agent_execution_seconds, bool)
323
+ or not isinstance(state.agent_execution_seconds, (int, float))
324
+ or not 0 <= state.agent_execution_seconds <= 86_400
325
+ ):
326
+ raise StateError("checkpoint agent execution duration is invalid")
327
+ if (
328
+ not isinstance(state.validation_evidence, tuple)
329
+ or len(state.validation_evidence) > 12
330
+ or any(
331
+ not isinstance(item, dict)
332
+ or set(item) != {"command", "result"}
333
+ or any(
334
+ not isinstance(value, str)
335
+ or not value
336
+ or len(value) > 240
337
+ or value != redact_diagnostic(value, limit=240)
338
+ for value in item.values()
339
+ )
340
+ for item in state.validation_evidence
341
+ )
342
+ ):
343
+ raise StateError("checkpoint validation evidence is invalid or unsafe")
344
+ quality_activities = {"REFACTOR", "TEST_COVERAGE", "DOCUMENTATION", "VALIDATION", "NO_CHANGE_REQUIRED"}
345
+ if (
346
+ not isinstance(state.quality_evidence, tuple)
347
+ or len(state.quality_evidence) > 8
348
+ or any(
349
+ not isinstance(item, dict)
350
+ or set(item) != {"activity", "result"}
351
+ or item["activity"] not in quality_activities
352
+ or not isinstance(item["result"], str)
353
+ or not item["result"]
354
+ or len(item["result"]) > 240
355
+ or item["result"] != redact_diagnostic(item["result"], limit=240)
356
+ for item in state.quality_evidence
357
+ )
358
+ ):
359
+ raise StateError("checkpoint quality evidence is invalid or unsafe")
360
+ if not isinstance(state.terminal, bool) or state.terminal != (state.phase in {"COMPLETE", "BLOCKED", "FAILED"}):
361
+ raise StateError("checkpoint terminal flag conflicts with phase")
362
+ return state
363
+
364
+ def to_dict(self) -> dict[str, object]:
365
+ return asdict(self)
366
+
367
+
368
+ class StateStore:
369
+ """Stores canonical transaction state in SQLite and emits JSON projections.
370
+
371
+ The run JSON files are intentionally retained for recovery tooling and
372
+ operator inspection, but are never consulted for normal lifecycle reads.
373
+ """
374
+
375
+ def __init__(
376
+ self,
377
+ directory: Path,
378
+ *,
379
+ central_database: Path | None = None,
380
+ emit_local_projection: bool = True,
381
+ ) -> None:
382
+ self.directory = directory
383
+ # A CENTRAL lifecycle is deliberately bound to a database by its
384
+ # composition root. It must never rediscover that authority from the
385
+ # execution checkout. The directory remains only a compatibility
386
+ # location for legacy JSON projections.
387
+ self.central_database = central_database.resolve() if central_database else None
388
+ self.emit_local_projection = emit_local_projection
389
+
390
+ def path_for(self, run_id: str) -> Path:
391
+ if not RUN_ID_PATTERN.fullmatch(run_id):
392
+ raise StateError("run_id must use lowercase letters, digits, and hyphens")
393
+ return self.directory / f"{run_id}.json"
394
+
395
+ @property
396
+ def root(self) -> Path:
397
+ # StateStore is constructed with ``<root>/.engineering/engineering-runs``.
398
+ return self.directory.parent.parent
399
+
400
+ def _open(self, *, create: bool) -> sqlite3.Connection:
401
+ if self.central_database is None:
402
+ return open_storage(self.root, create=create)
403
+ if not self.central_database.is_file():
404
+ raise StateError("CENTRAL lifecycle database is unavailable")
405
+ try:
406
+ connection = sqlite3.connect(
407
+ self.central_database if create else f"file:{self.central_database}?mode=rw",
408
+ uri=not create,
409
+ isolation_level=None,
410
+ )
411
+ connection.execute("PRAGMA foreign_keys=ON")
412
+ connection.execute("PRAGMA busy_timeout=10000")
413
+ return connection
414
+ except sqlite3.DatabaseError as error:
415
+ raise StateError("CENTRAL lifecycle database is unavailable") from error
416
+
417
+ def run_ids(self) -> tuple[str, ...]:
418
+ """Return canonical run identities without consulting JSON shadows."""
419
+ try:
420
+ connection = self._open(create=False)
421
+ try:
422
+ return tuple(str(row[0]) for row in connection.execute(
423
+ "SELECT run_id FROM engineering_transactions ORDER BY updated_at,run_id"
424
+ ))
425
+ finally:
426
+ connection.close()
427
+ except (EngineeringStorageError, StateError, sqlite3.DatabaseError) as error:
428
+ raise StateError("canonical engineering storage is unavailable") from error
429
+
430
+ def load(self, run_id: str) -> TransactionState:
431
+ try:
432
+ connection = self._open(create=False)
433
+ try:
434
+ row = connection.execute(
435
+ "SELECT payload FROM engineering_transactions WHERE run_id=?", (run_id,)
436
+ ).fetchone()
437
+ finally:
438
+ connection.close()
439
+ except EngineeringStorageError as error:
440
+ raise StateError("canonical engineering storage is unavailable") from error
441
+ if not row:
442
+ raise StateError(f"no checkpoint exists for run_id {run_id}")
443
+ try:
444
+ return TransactionState.from_dict(json.loads(row[0]))
445
+ except (TypeError, json.JSONDecodeError) as error:
446
+ raise StateError("canonical checkpoint is corrupt") from error
447
+
448
+ def save(self, state: TransactionState) -> Path:
449
+ path = self.path_for(state.run_id)
450
+ canonical = json.dumps(state.to_dict(), separators=(",", ":"), sort_keys=True)
451
+ try:
452
+ connection = self._open(create=True)
453
+ try:
454
+ connection.execute("BEGIN IMMEDIATE")
455
+ connection.execute(
456
+ "INSERT INTO engineering_transactions(run_id,payload,phase,updated_at) VALUES(?,?,?,CURRENT_TIMESTAMP) "
457
+ "ON CONFLICT(run_id) DO UPDATE SET payload=excluded.payload,phase=excluded.phase,updated_at=excluded.updated_at",
458
+ (state.run_id, canonical, state.phase),
459
+ )
460
+ connection.execute(
461
+ "INSERT OR IGNORE INTO execution_lifecycle_events(run_id,phase,checkpoint,recorded_at) VALUES(?,?,?,CURRENT_TIMESTAMP)",
462
+ (state.run_id, state.phase, canonical),
463
+ )
464
+ connection.execute("COMMIT")
465
+ except Exception:
466
+ connection.execute("ROLLBACK")
467
+ raise
468
+ finally:
469
+ connection.close()
470
+ except (EngineeringStorageError, OSError) as error:
471
+ raise StateError("canonical engineering storage could not save checkpoint") from error
472
+ # CENTRAL runs must not create a repository-local checkpoint shadow.
473
+ # The database row above is the sole durable state and is sufficient
474
+ # for restart, recovery and Console/history projections.
475
+ if (
476
+ self.central_database is not None
477
+ or not self.emit_local_projection
478
+ # Compatibility only for a preserved legacy runner injected by a
479
+ # caller that has not yet accepted an explicit store binding.
480
+ or os.environ.get(CENTRAL_OPERATIONAL_DATABASE_ENVIRONMENT)
481
+ ):
482
+ return path
483
+ self.directory.mkdir(mode=0o700, parents=True, exist_ok=True)
484
+ encoded = (json.dumps(state.to_dict(), indent=2, sort_keys=True) + "\n").encode("utf-8")
485
+ descriptor, temporary = tempfile.mkstemp(prefix=f".{state.run_id}.", suffix=".tmp", dir=self.directory)
486
+ try:
487
+ os.fchmod(descriptor, 0o600)
488
+ with os.fdopen(descriptor, "wb") as handle:
489
+ handle.write(encoded)
490
+ handle.flush()
491
+ os.fsync(handle.fileno())
492
+ os.replace(temporary, path)
493
+ os.chmod(path, 0o600)
494
+ except OSError:
495
+ try:
496
+ os.unlink(temporary)
497
+ except FileNotFoundError:
498
+ pass
499
+ raise
500
+ if state.phase == "COMPLETE":
501
+ self._prune_completed_history()
502
+ return path
503
+
504
+ def remove(self, run_id: str) -> None:
505
+ path = self.path_for(run_id)
506
+ try:
507
+ connection = self._open(create=False)
508
+ try:
509
+ connection.execute("DELETE FROM engineering_transactions WHERE run_id=?", (run_id,))
510
+ finally:
511
+ connection.close()
512
+ except EngineeringStorageError as error:
513
+ raise StateError("canonical engineering storage is unavailable") from error
514
+ if self.emit_local_projection and self.central_database is None and path.exists():
515
+ path.unlink()
516
+
517
+ def _prune_completed_history(self) -> None:
518
+ try:
519
+ connection = self._open(create=False)
520
+ try:
521
+ rows = connection.execute(
522
+ "SELECT run_id FROM engineering_transactions WHERE phase='COMPLETE' ORDER BY updated_at DESC, run_id DESC LIMIT -1 OFFSET 10"
523
+ ).fetchall()
524
+ finally:
525
+ connection.close()
526
+ except EngineeringStorageError:
527
+ return
528
+ # Removing a compatibility projection must never erase canonical state.
529
+ for (run_id,) in rows:
530
+ self.path_for(str(run_id)).unlink(missing_ok=True)