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
core_runtime/cli/main.py
ADDED
|
@@ -0,0 +1,579 @@
|
|
|
1
|
+
"""CLI argument parser and command dispatch."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from core_runtime.cli.bump_version import cmd_bump_version
|
|
9
|
+
from core_runtime.cli.create_domain import cmd_create_domain
|
|
10
|
+
from core_runtime.cli.contract_preflight import cmd_contract_preflight
|
|
11
|
+
from core_runtime.cli.doctor import cmd_doctor
|
|
12
|
+
from core_runtime.cli.inventory import cmd_info, cmd_list
|
|
13
|
+
from core_runtime.cli.release_check import cmd_release_check
|
|
14
|
+
from core_runtime.cli.repair_artifact_paths import cmd_repair_artifact_paths
|
|
15
|
+
from core_runtime.cli.sync_template import cmd_sync_template
|
|
16
|
+
from core_runtime.cli.validate import cmd_validate
|
|
17
|
+
from core_runtime.tooling.diagnostics import DiagnosticCollection
|
|
18
|
+
from core_runtime.tooling.file_inventory import FileInventory
|
|
19
|
+
from core_runtime.tooling.json_checks import JSONChecks
|
|
20
|
+
from core_runtime.tooling.report_writer import ReportWriter
|
|
21
|
+
from core_runtime.tooling.release_check import RELEASE_CHECK_PROFILES
|
|
22
|
+
from core_runtime.tooling.safety_checks import SafetyChecks
|
|
23
|
+
from core_runtime.tooling.version_inventory import VersionInventory
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
27
|
+
"""Build the argument parser with subcommands."""
|
|
28
|
+
parser = argparse.ArgumentParser(
|
|
29
|
+
prog="core-runtime",
|
|
30
|
+
description="CORE Runtime tooling commands",
|
|
31
|
+
)
|
|
32
|
+
subparsers = parser.add_subparsers(dest="command", metavar="COMMAND")
|
|
33
|
+
|
|
34
|
+
# lint subcommand
|
|
35
|
+
lint_parser = subparsers.add_parser("lint", help="Run tooling lint checks")
|
|
36
|
+
lint_parser.add_argument(
|
|
37
|
+
"--scope",
|
|
38
|
+
choices=["tooling"],
|
|
39
|
+
default="tooling",
|
|
40
|
+
help="Scope of lint checks (default: tooling)",
|
|
41
|
+
)
|
|
42
|
+
lint_parser.add_argument(
|
|
43
|
+
"--format",
|
|
44
|
+
choices=["json", "markdown"],
|
|
45
|
+
default="json",
|
|
46
|
+
help="Output format (default: json)",
|
|
47
|
+
)
|
|
48
|
+
lint_parser.add_argument(
|
|
49
|
+
"--output",
|
|
50
|
+
type=Path,
|
|
51
|
+
help="Write output to file instead of stdout",
|
|
52
|
+
)
|
|
53
|
+
lint_parser.set_defaults(func=cmd_lint)
|
|
54
|
+
|
|
55
|
+
# release-check subcommand
|
|
56
|
+
release_check_parser = subparsers.add_parser(
|
|
57
|
+
"release-check",
|
|
58
|
+
help="Run lint precheck and the authoritative release gate",
|
|
59
|
+
)
|
|
60
|
+
release_check_parser.add_argument(
|
|
61
|
+
"--target",
|
|
62
|
+
type=str,
|
|
63
|
+
default=None,
|
|
64
|
+
help="Release target (default: canonical version from core_runtime/__version__.py)",
|
|
65
|
+
)
|
|
66
|
+
release_check_parser.add_argument(
|
|
67
|
+
"--format",
|
|
68
|
+
choices=["json", "markdown"],
|
|
69
|
+
default="json",
|
|
70
|
+
help="Output format (default: json)",
|
|
71
|
+
)
|
|
72
|
+
release_check_parser.add_argument(
|
|
73
|
+
"--output",
|
|
74
|
+
type=Path,
|
|
75
|
+
help="Write output to file instead of stdout",
|
|
76
|
+
)
|
|
77
|
+
release_check_parser.add_argument(
|
|
78
|
+
"--skip-tooling-lint",
|
|
79
|
+
action="store_true",
|
|
80
|
+
default=False,
|
|
81
|
+
help="Skip the tooling lint precheck",
|
|
82
|
+
)
|
|
83
|
+
release_check_parser.add_argument(
|
|
84
|
+
"--timeout",
|
|
85
|
+
type=int,
|
|
86
|
+
default=120,
|
|
87
|
+
help="Maximum seconds for the release gate subprocess (default: 120)",
|
|
88
|
+
)
|
|
89
|
+
release_check_parser.add_argument(
|
|
90
|
+
"--preflight-only",
|
|
91
|
+
action="store_true",
|
|
92
|
+
default=False,
|
|
93
|
+
help="Run bounded preflight checks without the full release gate",
|
|
94
|
+
)
|
|
95
|
+
release_check_parser.add_argument(
|
|
96
|
+
"--group",
|
|
97
|
+
default=None,
|
|
98
|
+
help="Run a named release-gate group instead of the full gate",
|
|
99
|
+
)
|
|
100
|
+
release_check_parser.add_argument(
|
|
101
|
+
"--profile",
|
|
102
|
+
choices=sorted(RELEASE_CHECK_PROFILES),
|
|
103
|
+
default=None,
|
|
104
|
+
help="Run a named release-check profile preset",
|
|
105
|
+
)
|
|
106
|
+
release_check_parser.add_argument(
|
|
107
|
+
"--list-checks",
|
|
108
|
+
action="store_true",
|
|
109
|
+
default=False,
|
|
110
|
+
help="List available release-gate checks without executing them",
|
|
111
|
+
)
|
|
112
|
+
release_check_parser.add_argument(
|
|
113
|
+
"--plan",
|
|
114
|
+
action="store_true",
|
|
115
|
+
default=False,
|
|
116
|
+
help="Emit the release-gate execution plan without running checks",
|
|
117
|
+
)
|
|
118
|
+
release_check_parser.add_argument(
|
|
119
|
+
"--timing-json",
|
|
120
|
+
default=None,
|
|
121
|
+
help="Write deterministic release-gate timing output to a JSON file",
|
|
122
|
+
)
|
|
123
|
+
release_check_parser.add_argument(
|
|
124
|
+
"--debug",
|
|
125
|
+
action="store_true",
|
|
126
|
+
default=False,
|
|
127
|
+
help="Include debug details in the report",
|
|
128
|
+
)
|
|
129
|
+
release_check_parser.set_defaults(func=cmd_release_check)
|
|
130
|
+
|
|
131
|
+
# bump-version subcommand
|
|
132
|
+
bump_parser = subparsers.add_parser(
|
|
133
|
+
"bump-version",
|
|
134
|
+
help="Plan or apply a version bump",
|
|
135
|
+
)
|
|
136
|
+
bump_parser.add_argument(
|
|
137
|
+
"target_version",
|
|
138
|
+
help="Target version (e.g. 10.5.1)",
|
|
139
|
+
)
|
|
140
|
+
bump_parser.add_argument(
|
|
141
|
+
"--dry-run",
|
|
142
|
+
action="store_true",
|
|
143
|
+
default=False,
|
|
144
|
+
help="Dry-run mode (compute planned changes without mutation)",
|
|
145
|
+
)
|
|
146
|
+
bump_parser.add_argument(
|
|
147
|
+
"--apply",
|
|
148
|
+
action="store_true",
|
|
149
|
+
default=False,
|
|
150
|
+
help="Apply mode (perform the actual version mutation)",
|
|
151
|
+
)
|
|
152
|
+
bump_parser.add_argument(
|
|
153
|
+
"--confirm-current",
|
|
154
|
+
type=str,
|
|
155
|
+
default=None,
|
|
156
|
+
help="Confirm the current version before apply (required with --apply)",
|
|
157
|
+
)
|
|
158
|
+
bump_parser.add_argument(
|
|
159
|
+
"--format",
|
|
160
|
+
choices=["json", "markdown"],
|
|
161
|
+
default="json",
|
|
162
|
+
help="Output format (default: json)",
|
|
163
|
+
)
|
|
164
|
+
bump_parser.add_argument(
|
|
165
|
+
"--output",
|
|
166
|
+
type=Path,
|
|
167
|
+
help="Write output to file instead of stdout",
|
|
168
|
+
)
|
|
169
|
+
bump_parser.set_defaults(func=cmd_bump_version)
|
|
170
|
+
|
|
171
|
+
# list subcommand
|
|
172
|
+
list_parser = subparsers.add_parser("list", help="List read-only repository inventory items")
|
|
173
|
+
list_parser.add_argument(
|
|
174
|
+
"kind",
|
|
175
|
+
nargs="?",
|
|
176
|
+
default="schemas",
|
|
177
|
+
help="Inventory kind to list (schemas|contracts|adapters|domains; default: schemas)",
|
|
178
|
+
)
|
|
179
|
+
list_parser.add_argument(
|
|
180
|
+
"--format",
|
|
181
|
+
choices=["json", "markdown"],
|
|
182
|
+
default="json",
|
|
183
|
+
help="Output format (default: json)",
|
|
184
|
+
)
|
|
185
|
+
list_parser.add_argument(
|
|
186
|
+
"--output",
|
|
187
|
+
type=Path,
|
|
188
|
+
help="Write output to file instead of stdout",
|
|
189
|
+
)
|
|
190
|
+
list_parser.set_defaults(func=cmd_list)
|
|
191
|
+
|
|
192
|
+
# info subcommand
|
|
193
|
+
info_parser = subparsers.add_parser("info", help="Show repository inventory summary or item details")
|
|
194
|
+
info_parser.add_argument(
|
|
195
|
+
"kind",
|
|
196
|
+
nargs="?",
|
|
197
|
+
default=None,
|
|
198
|
+
help="Optional inventory kind to inspect (schema|schemas|contract|contracts|adapter|adapters|domain|domains)",
|
|
199
|
+
)
|
|
200
|
+
info_parser.add_argument(
|
|
201
|
+
"name",
|
|
202
|
+
nargs="?",
|
|
203
|
+
default=None,
|
|
204
|
+
help="Optional item name to inspect inside the selected kind",
|
|
205
|
+
)
|
|
206
|
+
info_parser.add_argument(
|
|
207
|
+
"--format",
|
|
208
|
+
choices=["json", "markdown"],
|
|
209
|
+
default="json",
|
|
210
|
+
help="Output format (default: json)",
|
|
211
|
+
)
|
|
212
|
+
info_parser.add_argument(
|
|
213
|
+
"--output",
|
|
214
|
+
type=Path,
|
|
215
|
+
help="Write output to file instead of stdout",
|
|
216
|
+
)
|
|
217
|
+
info_parser.set_defaults(func=cmd_info)
|
|
218
|
+
|
|
219
|
+
# validate subcommand
|
|
220
|
+
validate_parser = subparsers.add_parser("validate", help="Run read-only structural validation")
|
|
221
|
+
validate_parser.add_argument(
|
|
222
|
+
"kind",
|
|
223
|
+
nargs="?",
|
|
224
|
+
default="schemas",
|
|
225
|
+
help="Validation kind (schemas|examples|manifests|contracts|domain; default: schemas)",
|
|
226
|
+
)
|
|
227
|
+
validate_parser.add_argument(
|
|
228
|
+
"name",
|
|
229
|
+
nargs="?",
|
|
230
|
+
default=None,
|
|
231
|
+
help="Optional name for domain validation",
|
|
232
|
+
)
|
|
233
|
+
validate_parser.add_argument(
|
|
234
|
+
"--format",
|
|
235
|
+
choices=["json", "markdown"],
|
|
236
|
+
default="json",
|
|
237
|
+
help="Output format (default: json)",
|
|
238
|
+
)
|
|
239
|
+
validate_parser.add_argument(
|
|
240
|
+
"--output",
|
|
241
|
+
type=Path,
|
|
242
|
+
help="Write output to file instead of stdout",
|
|
243
|
+
)
|
|
244
|
+
validate_parser.set_defaults(func=cmd_validate)
|
|
245
|
+
|
|
246
|
+
# doctor subcommand
|
|
247
|
+
doctor_parser = subparsers.add_parser("doctor", help="Run read-only environment diagnostics")
|
|
248
|
+
doctor_parser.add_argument(
|
|
249
|
+
"--format",
|
|
250
|
+
choices=["json", "markdown"],
|
|
251
|
+
default="json",
|
|
252
|
+
help="Output format (default: json)",
|
|
253
|
+
)
|
|
254
|
+
doctor_parser.add_argument(
|
|
255
|
+
"--output",
|
|
256
|
+
type=Path,
|
|
257
|
+
help="Write output to file instead of stdout",
|
|
258
|
+
)
|
|
259
|
+
doctor_parser.set_defaults(func=cmd_doctor)
|
|
260
|
+
|
|
261
|
+
# contract-preflight subcommand
|
|
262
|
+
contract_preflight_parser = subparsers.add_parser(
|
|
263
|
+
"contract-preflight",
|
|
264
|
+
help="Run advisory-only contract candidate review",
|
|
265
|
+
)
|
|
266
|
+
mode_group = contract_preflight_parser.add_mutually_exclusive_group(required=True)
|
|
267
|
+
mode_group.add_argument(
|
|
268
|
+
"--candidate",
|
|
269
|
+
type=str,
|
|
270
|
+
default=None,
|
|
271
|
+
help="Review a known contract candidate by name",
|
|
272
|
+
)
|
|
273
|
+
mode_group.add_argument(
|
|
274
|
+
"--compare",
|
|
275
|
+
nargs=2,
|
|
276
|
+
metavar=("LEFT", "RIGHT"),
|
|
277
|
+
default=None,
|
|
278
|
+
help="Compare two known contract candidates",
|
|
279
|
+
)
|
|
280
|
+
contract_preflight_parser.add_argument(
|
|
281
|
+
"--format",
|
|
282
|
+
choices=["json", "markdown"],
|
|
283
|
+
default="json",
|
|
284
|
+
help="Output format (default: json)",
|
|
285
|
+
)
|
|
286
|
+
contract_preflight_parser.add_argument(
|
|
287
|
+
"--output",
|
|
288
|
+
type=Path,
|
|
289
|
+
help="Write output to file instead of stdout",
|
|
290
|
+
)
|
|
291
|
+
contract_preflight_parser.set_defaults(func=cmd_contract_preflight)
|
|
292
|
+
|
|
293
|
+
# create-domain subcommand
|
|
294
|
+
create_domain_parser = subparsers.add_parser(
|
|
295
|
+
"create-domain",
|
|
296
|
+
help="Plan a new domain scaffold (dry-run only in this slice)",
|
|
297
|
+
)
|
|
298
|
+
create_domain_parser.add_argument(
|
|
299
|
+
"name",
|
|
300
|
+
help="Domain name to scaffold",
|
|
301
|
+
)
|
|
302
|
+
create_domain_parser.add_argument(
|
|
303
|
+
"--template",
|
|
304
|
+
default="generic",
|
|
305
|
+
help="Template name to use for the plan (default: generic)",
|
|
306
|
+
)
|
|
307
|
+
create_domain_parser.add_argument(
|
|
308
|
+
"--dry-run",
|
|
309
|
+
action="store_true",
|
|
310
|
+
default=False,
|
|
311
|
+
help="Required for this slice; emit plan without mutating files",
|
|
312
|
+
)
|
|
313
|
+
create_domain_parser.add_argument(
|
|
314
|
+
"--format",
|
|
315
|
+
choices=["json", "markdown"],
|
|
316
|
+
default="json",
|
|
317
|
+
help="Output format (default: json)",
|
|
318
|
+
)
|
|
319
|
+
create_domain_parser.add_argument(
|
|
320
|
+
"--output",
|
|
321
|
+
type=Path,
|
|
322
|
+
help="Write output to file instead of stdout",
|
|
323
|
+
)
|
|
324
|
+
create_domain_parser.set_defaults(func=cmd_create_domain)
|
|
325
|
+
|
|
326
|
+
# sync-template subcommand
|
|
327
|
+
sync_template_parser = subparsers.add_parser(
|
|
328
|
+
"sync-template",
|
|
329
|
+
help="Compare domains against the canonical scaffold template",
|
|
330
|
+
)
|
|
331
|
+
sync_mode_group = sync_template_parser.add_mutually_exclusive_group(required=True)
|
|
332
|
+
sync_mode_group.add_argument(
|
|
333
|
+
"--domain",
|
|
334
|
+
type=str,
|
|
335
|
+
default=None,
|
|
336
|
+
help="Sync a single domain against the template",
|
|
337
|
+
)
|
|
338
|
+
sync_mode_group.add_argument(
|
|
339
|
+
"--all",
|
|
340
|
+
action="store_true",
|
|
341
|
+
default=False,
|
|
342
|
+
help="Sync all discovered domains against the template",
|
|
343
|
+
)
|
|
344
|
+
sync_template_parser.add_argument(
|
|
345
|
+
"--template",
|
|
346
|
+
default="generic",
|
|
347
|
+
help="Template name to compare against (default: generic)",
|
|
348
|
+
)
|
|
349
|
+
sync_template_parser.add_argument(
|
|
350
|
+
"--dry-run",
|
|
351
|
+
action="store_true",
|
|
352
|
+
default=False,
|
|
353
|
+
help="Required for this slice; emit plan without mutating files",
|
|
354
|
+
)
|
|
355
|
+
sync_template_parser.add_argument(
|
|
356
|
+
"--format",
|
|
357
|
+
choices=["json", "markdown"],
|
|
358
|
+
default="json",
|
|
359
|
+
help="Output format (default: json)",
|
|
360
|
+
)
|
|
361
|
+
sync_template_parser.add_argument(
|
|
362
|
+
"--output",
|
|
363
|
+
type=Path,
|
|
364
|
+
help="Write output to file instead of stdout",
|
|
365
|
+
)
|
|
366
|
+
sync_template_parser.set_defaults(func=cmd_sync_template)
|
|
367
|
+
|
|
368
|
+
# repair-artifact-paths subcommand
|
|
369
|
+
repair_parser = subparsers.add_parser(
|
|
370
|
+
"repair-artifact-paths",
|
|
371
|
+
help="Plan repairs for migrated artifact path references",
|
|
372
|
+
)
|
|
373
|
+
repair_parser.add_argument(
|
|
374
|
+
"--from",
|
|
375
|
+
dest="source_path",
|
|
376
|
+
default=None,
|
|
377
|
+
help="Source path or prefix to replace",
|
|
378
|
+
)
|
|
379
|
+
repair_parser.add_argument(
|
|
380
|
+
"--to",
|
|
381
|
+
dest="destination_path",
|
|
382
|
+
default=None,
|
|
383
|
+
help="Destination path or prefix to use",
|
|
384
|
+
)
|
|
385
|
+
repair_parser.add_argument(
|
|
386
|
+
"--manifest",
|
|
387
|
+
type=Path,
|
|
388
|
+
default=None,
|
|
389
|
+
help="Optional migration manifest to drive repair rules",
|
|
390
|
+
)
|
|
391
|
+
repair_parser.add_argument(
|
|
392
|
+
"--dry-run",
|
|
393
|
+
action="store_true",
|
|
394
|
+
default=False,
|
|
395
|
+
help="Required in this slice; emit a repair plan without mutating files",
|
|
396
|
+
)
|
|
397
|
+
repair_parser.add_argument(
|
|
398
|
+
"--apply",
|
|
399
|
+
action="store_true",
|
|
400
|
+
default=False,
|
|
401
|
+
help="Reserved for a later guarded mutation slice",
|
|
402
|
+
)
|
|
403
|
+
repair_parser.add_argument(
|
|
404
|
+
"--format",
|
|
405
|
+
choices=["json", "markdown"],
|
|
406
|
+
default="json",
|
|
407
|
+
help="Output format (default: json)",
|
|
408
|
+
)
|
|
409
|
+
repair_parser.add_argument(
|
|
410
|
+
"--output",
|
|
411
|
+
type=Path,
|
|
412
|
+
help="Write output to file instead of stdout",
|
|
413
|
+
)
|
|
414
|
+
repair_parser.set_defaults(func=cmd_repair_artifact_paths)
|
|
415
|
+
|
|
416
|
+
return parser
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
def cmd_lint(args: argparse.Namespace) -> int:
|
|
420
|
+
"""Execute the lint command."""
|
|
421
|
+
repo_root = Path(__file__).resolve().parents[2] # core_runtime/cli/ -> core_runtime/ -> repo_root
|
|
422
|
+
|
|
423
|
+
# Initialize checkers
|
|
424
|
+
version_inv = VersionInventory(repo_root)
|
|
425
|
+
file_inv = FileInventory(repo_root)
|
|
426
|
+
json_checks = JSONChecks(repo_root)
|
|
427
|
+
safety_checks = SafetyChecks(repo_root)
|
|
428
|
+
report_writer = ReportWriter(repo_root)
|
|
429
|
+
|
|
430
|
+
from core_runtime.tooling.diagnostics import DiagnosticCollection
|
|
431
|
+
|
|
432
|
+
diagnostics = DiagnosticCollection()
|
|
433
|
+
|
|
434
|
+
# 1. Version inventory and consistency
|
|
435
|
+
version_sources = version_inv.check_consistency(diagnostics)
|
|
436
|
+
version_inv.check_changelog_latest(diagnostics)
|
|
437
|
+
version_inv.check_release_note(diagnostics)
|
|
438
|
+
|
|
439
|
+
# 2. Required file inventory
|
|
440
|
+
file_results = file_inv.check_all(diagnostics)
|
|
441
|
+
|
|
442
|
+
# 3. Script compilation checks
|
|
443
|
+
check_script_compilation(repo_root, diagnostics)
|
|
444
|
+
|
|
445
|
+
# 4. JSON parse checks
|
|
446
|
+
schema_checked, schema_errors = json_checks.check_schemas(diagnostics)
|
|
447
|
+
example_checked, example_errors = json_checks.check_examples(diagnostics)
|
|
448
|
+
lock_ok = json_checks.check_requirements_lock(diagnostics)
|
|
449
|
+
|
|
450
|
+
json_results = {
|
|
451
|
+
"schemas_checked": schema_checked,
|
|
452
|
+
"schemas_errors": schema_errors,
|
|
453
|
+
"examples_checked": example_checked,
|
|
454
|
+
"examples_errors": example_errors,
|
|
455
|
+
"requirements_lock_readable": lock_ok,
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
# 5. Stale documentation checks (warnings)
|
|
459
|
+
check_stale_docs(repo_root, diagnostics)
|
|
460
|
+
|
|
461
|
+
# 6. Safety checks
|
|
462
|
+
safety_checks.check_private_path_leakage(diagnostics)
|
|
463
|
+
safety_checks.check_proposal_execution_safety(diagnostics)
|
|
464
|
+
safety_checks.check_todo_templates(diagnostics)
|
|
465
|
+
|
|
466
|
+
safety_results = {
|
|
467
|
+
"private_path_scan": "completed",
|
|
468
|
+
"proposal_safety_scan": "completed",
|
|
469
|
+
"template_scan": "completed",
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
# Write output
|
|
473
|
+
if args.format == "json":
|
|
474
|
+
report = report_writer.write_json(
|
|
475
|
+
diagnostics=diagnostics,
|
|
476
|
+
scope=args.scope,
|
|
477
|
+
output_path=args.output,
|
|
478
|
+
version_sources=version_sources,
|
|
479
|
+
file_inventory=file_results,
|
|
480
|
+
json_checks=json_results,
|
|
481
|
+
safety_checks=safety_results,
|
|
482
|
+
)
|
|
483
|
+
if not args.output:
|
|
484
|
+
import json
|
|
485
|
+
print(json.dumps(report, indent=2, ensure_ascii=False))
|
|
486
|
+
else:
|
|
487
|
+
markdown = report_writer.write_markdown(
|
|
488
|
+
diagnostics=diagnostics,
|
|
489
|
+
scope=args.scope,
|
|
490
|
+
output_path=args.output,
|
|
491
|
+
version_sources=version_sources,
|
|
492
|
+
file_inventory=file_results,
|
|
493
|
+
json_checks=json_results,
|
|
494
|
+
safety_checks=safety_results,
|
|
495
|
+
)
|
|
496
|
+
if not args.output:
|
|
497
|
+
print(markdown)
|
|
498
|
+
|
|
499
|
+
# Return exit code
|
|
500
|
+
return diagnostics.compute_exit_code().value
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
def check_script_compilation(repo_root: Path, diagnostics: DiagnosticCollection) -> dict:
|
|
504
|
+
"""Check that key scripts compile without errors."""
|
|
505
|
+
import py_compile
|
|
506
|
+
|
|
507
|
+
scripts = [
|
|
508
|
+
"scripts/verify_release.py",
|
|
509
|
+
"scripts/check_version_consistency.py",
|
|
510
|
+
"scripts/bump_version.py",
|
|
511
|
+
"scripts/generate_requirements_lock.py",
|
|
512
|
+
]
|
|
513
|
+
|
|
514
|
+
results = {}
|
|
515
|
+
for script in scripts:
|
|
516
|
+
script_path = repo_root / script
|
|
517
|
+
if not script_path.exists():
|
|
518
|
+
diagnostics.add_error(
|
|
519
|
+
code="core.script.missing",
|
|
520
|
+
message="Required script not found: {0}".format(script),
|
|
521
|
+
path=script,
|
|
522
|
+
expected="exists",
|
|
523
|
+
actual="missing",
|
|
524
|
+
)
|
|
525
|
+
results[script] = False
|
|
526
|
+
continue
|
|
527
|
+
|
|
528
|
+
try:
|
|
529
|
+
py_compile.compile(str(script_path), doraise=True)
|
|
530
|
+
results[script] = True
|
|
531
|
+
except py_compile.PyCompileError as e:
|
|
532
|
+
# e.args = (message, (filename, lineno, offset, text))
|
|
533
|
+
lineno = e.args[1][1] if len(e.args) > 1 and len(e.args[1]) > 1 else "unknown"
|
|
534
|
+
diagnostics.add_error(
|
|
535
|
+
code="core.script.compile_error",
|
|
536
|
+
message="Script compilation failed: {0}".format(e.msg),
|
|
537
|
+
path=script,
|
|
538
|
+
details="line {0}: {1}".format(lineno, e.msg),
|
|
539
|
+
)
|
|
540
|
+
results[script] = False
|
|
541
|
+
except Exception as e:
|
|
542
|
+
diagnostics.add_error(
|
|
543
|
+
code="core.script.compile_error",
|
|
544
|
+
message="Script compilation error: {0}".format(e),
|
|
545
|
+
path=script,
|
|
546
|
+
)
|
|
547
|
+
results[script] = False
|
|
548
|
+
|
|
549
|
+
return results
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def check_stale_docs(repo_root: Path, diagnostics: DiagnosticCollection) -> None:
|
|
553
|
+
"""Check for known stale documentation references."""
|
|
554
|
+
def _is_historical_reference(text: str) -> bool:
|
|
555
|
+
return "historical" in text.lower()
|
|
556
|
+
|
|
557
|
+
# VERSIONING_POLICY.md - v4.x compatibility matrix
|
|
558
|
+
vpolicy = repo_root / "docs" / "VERSIONING_POLICY.md"
|
|
559
|
+
if vpolicy.exists():
|
|
560
|
+
text = vpolicy.read_text(encoding="utf-8")
|
|
561
|
+
if "v4." in text and "compatibility" in text.lower() and not _is_historical_reference(text):
|
|
562
|
+
diagnostics.add_warning(
|
|
563
|
+
code="core.docs.stale_compatibility_matrix",
|
|
564
|
+
message="VERSIONING_POLICY.md contains v4.x-era compatibility matrix",
|
|
565
|
+
path="docs/VERSIONING_POLICY.md",
|
|
566
|
+
details="Should be updated for current versioning",
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
# QUALITY_GATE.md - v4.4.0-rc1 reference
|
|
570
|
+
qgate = repo_root / "docs" / "QUALITY_GATE.md"
|
|
571
|
+
if qgate.exists():
|
|
572
|
+
text = qgate.read_text(encoding="utf-8")
|
|
573
|
+
if ("v4.4.0-rc1" in text or "4.4.0-rc1" in text) and not _is_historical_reference(text):
|
|
574
|
+
diagnostics.add_warning(
|
|
575
|
+
code="core.docs.stale_quality_gate",
|
|
576
|
+
message="QUALITY_GATE.md references v4.4.0-rc1",
|
|
577
|
+
path="docs/QUALITY_GATE.md",
|
|
578
|
+
details="Should reference current version",
|
|
579
|
+
)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""CLI command for release-check — wrapper around verify_release.py."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from core_runtime.tooling.diagnostics import ExitCode
|
|
9
|
+
from core_runtime.tooling.release_check import ReleaseCheckRunner
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def cmd_release_check(args: object) -> int:
|
|
13
|
+
"""Execute the release-check command."""
|
|
14
|
+
target = getattr(args, "target", None)
|
|
15
|
+
fmt: str = getattr(args, "format", "json")
|
|
16
|
+
output = getattr(args, "output", None)
|
|
17
|
+
skip_tooling_lint: bool = getattr(args, "skip_tooling_lint", False)
|
|
18
|
+
timeout_seconds: int = int(getattr(args, "timeout", 120))
|
|
19
|
+
preflight_only: bool = getattr(args, "preflight_only", False)
|
|
20
|
+
debug: bool = getattr(args, "debug", False)
|
|
21
|
+
group = getattr(args, "group", None)
|
|
22
|
+
profile = getattr(args, "profile", None)
|
|
23
|
+
list_checks: bool = getattr(args, "list_checks", False)
|
|
24
|
+
plan: bool = getattr(args, "plan", False)
|
|
25
|
+
timing_json = getattr(args, "timing_json", None)
|
|
26
|
+
|
|
27
|
+
repo_root = Path(__file__).resolve().parents[2]
|
|
28
|
+
runner = ReleaseCheckRunner(repo_root)
|
|
29
|
+
report = runner.run(
|
|
30
|
+
target=target,
|
|
31
|
+
skip_tooling_lint=skip_tooling_lint,
|
|
32
|
+
timeout_seconds=timeout_seconds,
|
|
33
|
+
preflight_only=preflight_only,
|
|
34
|
+
debug=debug,
|
|
35
|
+
group=group,
|
|
36
|
+
profile=profile,
|
|
37
|
+
list_checks=list_checks,
|
|
38
|
+
plan=plan,
|
|
39
|
+
timing_json=timing_json,
|
|
40
|
+
)
|
|
41
|
+
output_path = Path(output) if output else None
|
|
42
|
+
|
|
43
|
+
if fmt == "json":
|
|
44
|
+
payload = report.to_dict()
|
|
45
|
+
if output_path:
|
|
46
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
47
|
+
output_path.write_text(json.dumps(payload, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
48
|
+
else:
|
|
49
|
+
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
50
|
+
else:
|
|
51
|
+
markdown = report.to_markdown()
|
|
52
|
+
if output_path:
|
|
53
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
54
|
+
output_path.write_text(markdown, encoding="utf-8")
|
|
55
|
+
else:
|
|
56
|
+
print(markdown)
|
|
57
|
+
|
|
58
|
+
status_to_exit = {
|
|
59
|
+
"pass": ExitCode.OK.value,
|
|
60
|
+
"warning": ExitCode.OK.value,
|
|
61
|
+
"error": ExitCode.ERROR.value,
|
|
62
|
+
"blocked": ExitCode.BLOCKED.value,
|
|
63
|
+
"internal_error": ExitCode.INTERNAL_ERROR.value,
|
|
64
|
+
}
|
|
65
|
+
return status_to_exit.get(report.status, ExitCode.INTERNAL_ERROR.value)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""CLI command for artifact path repair preflight."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from core_runtime.tooling.diagnostics import ExitCode
|
|
9
|
+
from core_runtime.tooling.repair_artifact_paths import ArtifactPathRepairPlanner
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _emit_report(report, fmt: str, output) -> None:
|
|
13
|
+
payload = report.to_dict()
|
|
14
|
+
if fmt == "json":
|
|
15
|
+
text = json.dumps(payload, indent=2, ensure_ascii=False)
|
|
16
|
+
else:
|
|
17
|
+
text = report.to_markdown()
|
|
18
|
+
if output:
|
|
19
|
+
output_path = Path(output)
|
|
20
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
21
|
+
output_path.write_text(text + ("\n" if fmt == "json" else ""), encoding="utf-8")
|
|
22
|
+
else:
|
|
23
|
+
print(text)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def cmd_repair_artifact_paths(args: object) -> int:
|
|
27
|
+
"""Plan artifact path repairs without mutating the repository."""
|
|
28
|
+
repo_root = Path(__file__).resolve().parents[2]
|
|
29
|
+
planner = ArtifactPathRepairPlanner(repo_root)
|
|
30
|
+
|
|
31
|
+
report = planner.build_plan(
|
|
32
|
+
dry_run=getattr(args, "dry_run", False),
|
|
33
|
+
source=getattr(args, "source_path", None),
|
|
34
|
+
destination=getattr(args, "destination_path", None),
|
|
35
|
+
manifest_path=getattr(args, "manifest", None),
|
|
36
|
+
apply=getattr(args, "apply", False),
|
|
37
|
+
)
|
|
38
|
+
fmt: str = getattr(args, "format", "json")
|
|
39
|
+
output = getattr(args, "output", None)
|
|
40
|
+
_emit_report(report, fmt, output)
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
"pass": ExitCode.OK.value,
|
|
44
|
+
"warning": ExitCode.OK.value,
|
|
45
|
+
"error": ExitCode.ERROR.value,
|
|
46
|
+
"blocked": ExitCode.BLOCKED.value,
|
|
47
|
+
"internal_error": ExitCode.INTERNAL_ERROR.value,
|
|
48
|
+
}.get(report.status, ExitCode.INTERNAL_ERROR.value)
|