core-runtime-engine 11.5.1__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.
- core_runtime/__init__.py +10 -0
- core_runtime/__version__.py +17 -0
- core_runtime/cli/__init__.py +7 -0
- core_runtime/cli/__main__.py +22 -0
- core_runtime/cli/bump_version.py +176 -0
- core_runtime/cli/contract_preflight.py +69 -0
- core_runtime/cli/create_domain.py +66 -0
- core_runtime/cli/doctor.py +44 -0
- core_runtime/cli/inventory.py +85 -0
- core_runtime/cli/lint.py +8 -0
- core_runtime/cli/main.py +579 -0
- core_runtime/cli/release_check.py +65 -0
- core_runtime/cli/repair_artifact_paths.py +48 -0
- core_runtime/cli/sync_template.py +67 -0
- core_runtime/cli/validate.py +73 -0
- core_runtime/core/__init__.py +34 -0
- core_runtime/core/audit_event.py +760 -0
- core_runtime/core/audit_trail_index.py +100 -0
- core_runtime/core/canonicalization.py +55 -0
- core_runtime/core/contract_evaluator.py +945 -0
- core_runtime/core/contract_executability.py +307 -0
- core_runtime/core/contract_loader.py +57 -0
- core_runtime/core/contract_probes.py +630 -0
- core_runtime/core/contract_program.py +131 -0
- core_runtime/core/contract_program_registry.py +104 -0
- core_runtime/core/contract_program_v2.py +126 -0
- core_runtime/core/dsk_v3.py +142 -0
- core_runtime/core/explainability.py +2115 -0
- core_runtime/core/numeric_normalization.py +120 -0
- core_runtime/core/rule_anchor.py +1388 -0
- core_runtime/core/schema_fingerprint.py +69 -0
- core_runtime/core/sensor_evidence.py +548 -0
- core_runtime/data/contracts/CoreAnchor.sol +109 -0
- core_runtime/data/contracts/CoreRuleAnchor.abi.json +111 -0
- core_runtime/data/contracts/CoreRuleAnchor.bin +1 -0
- core_runtime/data/contracts/CoreRuleAnchor.build.json +20 -0
- core_runtime/data/contracts/CoreRuleAnchor.runtime.bin +1 -0
- core_runtime/data/contracts/CoreRuleAnchor.sol +74 -0
- core_runtime/data/package_data_manifest.v1.json +173 -0
- core_runtime/data/schemas/core/causal_trace.v1.json +141 -0
- core_runtime/data/schemas/core/context_gate.v1.json +38 -0
- core_runtime/data/schemas/core/context_threshold.v1.json +46 -0
- core_runtime/data/schemas/core/contract_program.v1.json +186 -0
- core_runtime/data/schemas/core/contract_program.v2.json +187 -0
- core_runtime/data/schemas/core/control_decision.v1.json +114 -0
- core_runtime/data/schemas/core/dsk.v3.json +105 -0
- core_runtime/data/schemas/core/effect_result.v1.json +39 -0
- core_runtime/data/schemas/core/entropy_signal.v1.json +108 -0
- core_runtime/data/schemas/core/execution_receipt.v1.json +93 -0
- core_runtime/data/schemas/core/frozen_release_manifest.v1.json +87 -0
- core_runtime/data/schemas/core/frozen_release_manifest.v2.json +72 -0
- core_runtime/data/schemas/core/frozen_release_manifest.v3.json +38 -0
- core_runtime/data/schemas/core/frozen_release_manifest.v4.json +72 -0
- core_runtime/data/schemas/core/frozen_release_manifest.v5.json +38 -0
- core_runtime/data/schemas/core/frozen_release_manifest.v6.json +116 -0
- core_runtime/data/schemas/core/frozen_release_manifest.v7.json +37 -0
- core_runtime/data/schemas/core/frozen_release_manifest.v8.json +114 -0
- core_runtime/data/schemas/core/frozen_rule_set.v1.json +282 -0
- core_runtime/data/schemas/core/memory_artifact.v1.json +120 -0
- core_runtime/data/schemas/core/memory_generation_result.v1.json +37 -0
- core_runtime/data/schemas/core/operational_learning_event.v1.json +63 -0
- core_runtime/data/schemas/core/pattern_candidate.v1.json +114 -0
- core_runtime/data/schemas/core/physical_safety_assurance_case.v1.json +676 -0
- core_runtime/data/schemas/core/policy_lifecycle.v1.json +99 -0
- core_runtime/data/schemas/core/retention_manifest.v1.json +53 -0
- core_runtime/data/schemas/core/reversibility_policy.v1.json +107 -0
- core_runtime/data/schemas/core/rule_anchor_batch.v1.json +93 -0
- core_runtime/data/schemas/core/rule_anchor_chain_evidence.v1.json +56 -0
- core_runtime/data/schemas/core/rule_approval.v1.json +49 -0
- core_runtime/data/schemas/core/rule_approval_request.v1.json +42 -0
- core_runtime/data/schemas/core/state_transition.v1.json +115 -0
- core_runtime/data/schemas/core/task_closeout.v1.json +47 -0
- core_runtime/data/schemas/core/template_promotion_candidate.v1.json +83 -0
- core_runtime/data/schemas/core/unsigned_rule_anchor_deployment.v1.json +106 -0
- core_runtime/data/schemas/core/unsigned_rule_anchor_transaction.v1.json +116 -0
- core_runtime/tooling/__init__.py +48 -0
- core_runtime/tooling/bump_version.py +900 -0
- core_runtime/tooling/contract_preflight.py +293 -0
- core_runtime/tooling/create_domain.py +254 -0
- core_runtime/tooling/diagnostics.py +129 -0
- core_runtime/tooling/doctor.py +482 -0
- core_runtime/tooling/file_inventory.py +182 -0
- core_runtime/tooling/json_checks.py +100 -0
- core_runtime/tooling/release_check.py +1017 -0
- core_runtime/tooling/repair_artifact_paths.py +458 -0
- core_runtime/tooling/report_writer.py +176 -0
- core_runtime/tooling/repository_inventory.py +399 -0
- core_runtime/tooling/safety_checks.py +172 -0
- core_runtime/tooling/sync_template.py +303 -0
- core_runtime/tooling/validation.py +507 -0
- core_runtime/tooling/version_inventory.py +256 -0
- core_runtime_engine-11.5.1.dist-info/METADATA +35 -0
- core_runtime_engine-11.5.1.dist-info/RECORD +96 -0
- core_runtime_engine-11.5.1.dist-info/WHEEL +5 -0
- core_runtime_engine-11.5.1.dist-info/entry_points.txt +2 -0
- core_runtime_engine-11.5.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"""Dry-run-first template synchronization planning for CORE tooling."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from core_runtime.tooling.create_domain import DomainScaffolder
|
|
10
|
+
from core_runtime.tooling.diagnostics import DiagnosticCollection
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class SyncTemplateItem:
|
|
15
|
+
"""A planned template sync artifact."""
|
|
16
|
+
|
|
17
|
+
kind: str
|
|
18
|
+
name: str
|
|
19
|
+
path: str
|
|
20
|
+
status: str
|
|
21
|
+
details: dict[str, Any] = field(default_factory=dict)
|
|
22
|
+
|
|
23
|
+
def to_dict(self) -> dict[str, Any]:
|
|
24
|
+
result = {
|
|
25
|
+
"kind": self.kind,
|
|
26
|
+
"name": self.name,
|
|
27
|
+
"path": self.path,
|
|
28
|
+
"status": self.status,
|
|
29
|
+
}
|
|
30
|
+
if self.details:
|
|
31
|
+
result["details"] = self.details
|
|
32
|
+
return result
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class SyncTemplateReport:
|
|
37
|
+
"""Normalized report for `core-runtime sync-template`."""
|
|
38
|
+
|
|
39
|
+
tool: str
|
|
40
|
+
command: str
|
|
41
|
+
status: str
|
|
42
|
+
mutation_performed: bool = False
|
|
43
|
+
summary: dict[str, Any] = field(default_factory=dict)
|
|
44
|
+
selection: dict[str, Any] | None = None
|
|
45
|
+
items: list[SyncTemplateItem] = field(default_factory=list)
|
|
46
|
+
diagnostics: DiagnosticCollection = field(default_factory=DiagnosticCollection)
|
|
47
|
+
|
|
48
|
+
def to_dict(self) -> dict[str, Any]:
|
|
49
|
+
counts = self.diagnostics.count_by_severity()
|
|
50
|
+
summary = dict(self.summary)
|
|
51
|
+
summary.setdefault("info", counts["info"])
|
|
52
|
+
summary.setdefault("warning", counts["warning"])
|
|
53
|
+
summary.setdefault("error", counts["error"])
|
|
54
|
+
summary.setdefault("blocked", counts["blocked"])
|
|
55
|
+
return {
|
|
56
|
+
"tool": self.tool,
|
|
57
|
+
"command": self.command,
|
|
58
|
+
"status": self.status,
|
|
59
|
+
"mutation_performed": self.mutation_performed,
|
|
60
|
+
"summary": summary,
|
|
61
|
+
"selection": self.selection,
|
|
62
|
+
"items": [item.to_dict() for item in self.items],
|
|
63
|
+
"diagnostics": [d.to_dict() for d in self.diagnostics.diagnostics],
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
def to_markdown(self) -> str:
|
|
67
|
+
counts = self.diagnostics.count_by_severity()
|
|
68
|
+
summary = dict(self.summary)
|
|
69
|
+
summary.setdefault("info", counts["info"])
|
|
70
|
+
summary.setdefault("warning", counts["warning"])
|
|
71
|
+
summary.setdefault("error", counts["error"])
|
|
72
|
+
summary.setdefault("blocked", counts["blocked"])
|
|
73
|
+
lines: list[str] = []
|
|
74
|
+
lines.append("# CORE sync-template plan")
|
|
75
|
+
lines.append("")
|
|
76
|
+
lines.append("## Summary")
|
|
77
|
+
lines.append("")
|
|
78
|
+
lines.append("| Metric | Value |")
|
|
79
|
+
lines.append("|--------|-------|")
|
|
80
|
+
lines.append("| Tool | {0} |".format(self.tool))
|
|
81
|
+
lines.append("| Command | {0} |".format(self.command))
|
|
82
|
+
lines.append("| Status | {0} |".format(self.status.upper()))
|
|
83
|
+
lines.append("| Mutation Performed | No |")
|
|
84
|
+
lines.append("| Items | {0} |".format(summary.get("item_count", len(self.items))))
|
|
85
|
+
lines.append("| Info | {0} |".format(counts["info"]))
|
|
86
|
+
lines.append("| Warning | {0} |".format(counts["warning"]))
|
|
87
|
+
lines.append("| Error | {0} |".format(counts["error"]))
|
|
88
|
+
lines.append("| Blocked | {0} |".format(counts["blocked"]))
|
|
89
|
+
lines.append("")
|
|
90
|
+
|
|
91
|
+
if self.selection is not None:
|
|
92
|
+
lines.append("## Selection")
|
|
93
|
+
lines.append("")
|
|
94
|
+
for key, value in self.selection.items():
|
|
95
|
+
lines.append("- **{0}**: {1}".format(key, value))
|
|
96
|
+
lines.append("")
|
|
97
|
+
|
|
98
|
+
if self.items:
|
|
99
|
+
lines.append("## Planned Changes")
|
|
100
|
+
lines.append("")
|
|
101
|
+
lines.append("| Kind | Name | Path | Status |")
|
|
102
|
+
lines.append("|------|------|------|--------|")
|
|
103
|
+
for item in self.items:
|
|
104
|
+
lines.append("| {0} | {1} | {2} | {3} |".format(item.kind, item.name, item.path, item.status))
|
|
105
|
+
lines.append("")
|
|
106
|
+
|
|
107
|
+
if self.diagnostics.diagnostics:
|
|
108
|
+
lines.append("## Diagnostics")
|
|
109
|
+
lines.append("")
|
|
110
|
+
lines.append("| Severity | Code | Path | Message |")
|
|
111
|
+
lines.append("|----------|------|------|---------|")
|
|
112
|
+
for diagnostic in self.diagnostics.diagnostics:
|
|
113
|
+
path = diagnostic.path or "-"
|
|
114
|
+
message = diagnostic.message.replace("|", "\\|")
|
|
115
|
+
lines.append(
|
|
116
|
+
"| {0} | {1} | {2} | {3} |".format(
|
|
117
|
+
diagnostic.severity.value.upper(),
|
|
118
|
+
diagnostic.code,
|
|
119
|
+
path,
|
|
120
|
+
message,
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
lines.append("")
|
|
124
|
+
|
|
125
|
+
return "\n".join(lines)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class TemplateSyncPlanner:
|
|
129
|
+
"""Compare existing domains against a canonical scaffold template."""
|
|
130
|
+
|
|
131
|
+
def __init__(self, repo_root: Path):
|
|
132
|
+
self.repo_root = repo_root
|
|
133
|
+
self.scaffolder = DomainScaffolder(repo_root)
|
|
134
|
+
|
|
135
|
+
def build_plan(
|
|
136
|
+
self,
|
|
137
|
+
domain: str | None = None,
|
|
138
|
+
all_domains: bool = False,
|
|
139
|
+
template: str = "generic",
|
|
140
|
+
diagnostics: DiagnosticCollection | None = None,
|
|
141
|
+
) -> SyncTemplateReport:
|
|
142
|
+
diagnostics = diagnostics or DiagnosticCollection()
|
|
143
|
+
if not domain and not all_domains:
|
|
144
|
+
diagnostics.add_blocked(
|
|
145
|
+
code="core.sync_template.mode_required",
|
|
146
|
+
message="sync-template requires --domain or --all",
|
|
147
|
+
path="sync-template",
|
|
148
|
+
expected="--domain <name> or --all",
|
|
149
|
+
actual="missing mode",
|
|
150
|
+
)
|
|
151
|
+
return SyncTemplateReport(
|
|
152
|
+
tool="core-runtime sync-template",
|
|
153
|
+
command="sync-template",
|
|
154
|
+
status="blocked",
|
|
155
|
+
summary={"mode": "missing", "item_count": 0},
|
|
156
|
+
selection={"mode": "missing"},
|
|
157
|
+
diagnostics=diagnostics,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
domain_names = self._domain_names(domain=domain, all_domains=all_domains)
|
|
161
|
+
if not domain_names:
|
|
162
|
+
diagnostics.add_blocked(
|
|
163
|
+
code="core.sync_template.domain_missing",
|
|
164
|
+
message="No domains available for template sync",
|
|
165
|
+
path="core_runtime/domains",
|
|
166
|
+
expected="at least one domain",
|
|
167
|
+
actual="empty",
|
|
168
|
+
)
|
|
169
|
+
return SyncTemplateReport(
|
|
170
|
+
tool="core-runtime sync-template",
|
|
171
|
+
command=self._command(domain=domain, all_domains=all_domains),
|
|
172
|
+
status="blocked",
|
|
173
|
+
summary={"mode": "missing", "item_count": 0},
|
|
174
|
+
selection={"mode": "missing"},
|
|
175
|
+
diagnostics=diagnostics,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
items: list[SyncTemplateItem] = []
|
|
179
|
+
additions = 0
|
|
180
|
+
preserved = 0
|
|
181
|
+
collisions = 0
|
|
182
|
+
for domain_name in domain_names:
|
|
183
|
+
plan_items, domain_additions, domain_preserved, domain_collisions = self._plan_domain(
|
|
184
|
+
domain_name, template, diagnostics
|
|
185
|
+
)
|
|
186
|
+
items.extend(plan_items)
|
|
187
|
+
additions += domain_additions
|
|
188
|
+
preserved += domain_preserved
|
|
189
|
+
collisions += domain_collisions
|
|
190
|
+
|
|
191
|
+
status = "pass"
|
|
192
|
+
if collisions:
|
|
193
|
+
status = "blocked"
|
|
194
|
+
elif additions or preserved:
|
|
195
|
+
status = "warning"
|
|
196
|
+
|
|
197
|
+
return SyncTemplateReport(
|
|
198
|
+
tool="core-runtime sync-template",
|
|
199
|
+
command=self._command(domain=domain, all_domains=all_domains),
|
|
200
|
+
status=status,
|
|
201
|
+
summary={
|
|
202
|
+
"mode": "all" if all_domains else "domain",
|
|
203
|
+
"item_count": len(items),
|
|
204
|
+
"planned_additions": additions,
|
|
205
|
+
"preserved_custom": preserved,
|
|
206
|
+
"collisions": collisions,
|
|
207
|
+
"template": template,
|
|
208
|
+
},
|
|
209
|
+
selection={"domain": domain, "all": all_domains, "template": template},
|
|
210
|
+
items=items,
|
|
211
|
+
diagnostics=diagnostics,
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
def _domain_names(self, domain: str | None, all_domains: bool) -> list[str]:
|
|
215
|
+
domains_dir = self.repo_root / "core_runtime" / "domains"
|
|
216
|
+
if all_domains:
|
|
217
|
+
if not domains_dir.is_dir():
|
|
218
|
+
return []
|
|
219
|
+
return sorted(
|
|
220
|
+
path.name
|
|
221
|
+
for path in domains_dir.iterdir()
|
|
222
|
+
if path.is_dir() and not path.name.startswith("__")
|
|
223
|
+
)
|
|
224
|
+
if domain is None:
|
|
225
|
+
return []
|
|
226
|
+
return [domain]
|
|
227
|
+
|
|
228
|
+
def _plan_domain(
|
|
229
|
+
self,
|
|
230
|
+
domain_name: str,
|
|
231
|
+
template: str,
|
|
232
|
+
diagnostics: DiagnosticCollection,
|
|
233
|
+
) -> tuple[list[SyncTemplateItem], int, int, int]:
|
|
234
|
+
expected_plan, _, _ = self.scaffolder._plan_items(domain_name, template)
|
|
235
|
+
expected_paths = {Path(item.path).as_posix() for item in expected_plan}
|
|
236
|
+
domain_dir = self.repo_root / "core_runtime" / "domains" / domain_name
|
|
237
|
+
items: list[SyncTemplateItem] = []
|
|
238
|
+
additions = 0
|
|
239
|
+
preserved = 0
|
|
240
|
+
collisions = 0
|
|
241
|
+
|
|
242
|
+
if not domain_dir.exists():
|
|
243
|
+
collisions += 1
|
|
244
|
+
diagnostics.add_blocked(
|
|
245
|
+
code="core.sync_template.domain_missing",
|
|
246
|
+
message="Domain not found for template sync",
|
|
247
|
+
path=str(domain_dir.relative_to(self.repo_root)),
|
|
248
|
+
expected="existing domain directory",
|
|
249
|
+
actual="missing",
|
|
250
|
+
)
|
|
251
|
+
items.append(
|
|
252
|
+
SyncTemplateItem(
|
|
253
|
+
kind="domain",
|
|
254
|
+
name=domain_name,
|
|
255
|
+
path=str(domain_dir.relative_to(self.repo_root)),
|
|
256
|
+
status="blocked",
|
|
257
|
+
details={"reason": "domain_missing"},
|
|
258
|
+
)
|
|
259
|
+
)
|
|
260
|
+
return items, additions, preserved, collisions
|
|
261
|
+
|
|
262
|
+
actual_files = sorted(
|
|
263
|
+
path for path in domain_dir.rglob("*") if path.is_file() and "__pycache__" not in path.parts
|
|
264
|
+
)
|
|
265
|
+
actual_paths = {path.relative_to(self.repo_root).as_posix() for path in actual_files}
|
|
266
|
+
|
|
267
|
+
for item in expected_plan:
|
|
268
|
+
exists = item.details.get("exists", False)
|
|
269
|
+
if exists:
|
|
270
|
+
preserved += 1
|
|
271
|
+
status = "preserved"
|
|
272
|
+
else:
|
|
273
|
+
additions += 1
|
|
274
|
+
status = "planned_addition"
|
|
275
|
+
items.append(
|
|
276
|
+
SyncTemplateItem(
|
|
277
|
+
kind=item.kind,
|
|
278
|
+
name=item.name,
|
|
279
|
+
path=item.path,
|
|
280
|
+
status=status,
|
|
281
|
+
details=item.details,
|
|
282
|
+
)
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
custom_paths = sorted(actual_paths - expected_paths)
|
|
286
|
+
for rel_path in custom_paths:
|
|
287
|
+
preserved += 1
|
|
288
|
+
items.append(
|
|
289
|
+
SyncTemplateItem(
|
|
290
|
+
kind="custom_file",
|
|
291
|
+
name=Path(rel_path).name,
|
|
292
|
+
path=rel_path,
|
|
293
|
+
status="preserved",
|
|
294
|
+
details={"reason": "custom_domain_file"},
|
|
295
|
+
)
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
return items, additions, preserved, collisions
|
|
299
|
+
|
|
300
|
+
def _command(self, domain: str | None, all_domains: bool) -> str:
|
|
301
|
+
if all_domains:
|
|
302
|
+
return "sync-template --all --dry-run"
|
|
303
|
+
return "sync-template --domain {0} --dry-run".format(domain or "")
|