codec-cortex 0.3.2__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.
- codec_cortex-0.3.2.dist-info/METADATA +183 -0
- codec_cortex-0.3.2.dist-info/RECORD +81 -0
- codec_cortex-0.3.2.dist-info/WHEEL +5 -0
- codec_cortex-0.3.2.dist-info/entry_points.txt +2 -0
- codec_cortex-0.3.2.dist-info/licenses/LICENSE +21 -0
- codec_cortex-0.3.2.dist-info/scm_file_list.json +124 -0
- codec_cortex-0.3.2.dist-info/scm_version.json +8 -0
- codec_cortex-0.3.2.dist-info/top_level.txt +1 -0
- cortex/__init__.py +22 -0
- cortex/__main__.py +7 -0
- cortex/_version.py +24 -0
- cortex/cli/__init__.py +5 -0
- cortex/cli/commands/__init__.py +150 -0
- cortex/cli/commands/add.py +89 -0
- cortex/cli/commands/compile.py +31 -0
- cortex/cli/commands/delete.py +44 -0
- cortex/cli/commands/diagram.py +130 -0
- cortex/cli/commands/diff.py +135 -0
- cortex/cli/commands/doctor.py +74 -0
- cortex/cli/commands/format.py +29 -0
- cortex/cli/commands/get.py +45 -0
- cortex/cli/commands/glossary.py +98 -0
- cortex/cli/commands/list.py +44 -0
- cortex/cli/commands/micro.py +79 -0
- cortex/cli/commands/move.py +45 -0
- cortex/cli/commands/new.py +80 -0
- cortex/cli/commands/recover.py +90 -0
- cortex/cli/commands/render.py +93 -0
- cortex/cli/commands/update.py +81 -0
- cortex/cli/commands/v2_canonicalize.py +162 -0
- cortex/cli/commands/v2_compare.py +74 -0
- cortex/cli/commands/v2_convert.py +183 -0
- cortex/cli/commands/v2_explain_loss.py +97 -0
- cortex/cli/commands/v2_inspect.py +113 -0
- cortex/cli/commands/v2_roundtrip.py +104 -0
- cortex/cli/commands/v2_roundtrip_bidir.py +128 -0
- cortex/cli/commands/v2_verify_view.py +65 -0
- cortex/cli/commands/verify.py +119 -0
- cortex/cli/main.py +636 -0
- cortex/core/__init__.py +85 -0
- cortex/core/ast.py +313 -0
- cortex/core/compare.py +180 -0
- cortex/core/document_kind.py +525 -0
- cortex/core/errors.py +399 -0
- cortex/core/lexer.py +267 -0
- cortex/core/parser.py +671 -0
- cortex/core/validator.py +268 -0
- cortex/core/writer.py +249 -0
- cortex/crud/__init__.py +17 -0
- cortex/crud/mutations.py +342 -0
- cortex/crud/selectors.py +95 -0
- cortex/crud/transactions.py +213 -0
- cortex/glossary/__init__.py +21 -0
- cortex/glossary/contracts.py +37 -0
- cortex/glossary/minimal.py +94 -0
- cortex/glossary/model.py +77 -0
- cortex/glossary/resolver.py +96 -0
- cortex/hcortex/__init__.py +35 -0
- cortex/hcortex/edit_parser.py +489 -0
- cortex/hcortex/edit_renderer.py +158 -0
- cortex/hcortex/markdown_model.py +81 -0
- cortex/hcortex/profiles.py +166 -0
- cortex/hcortex/read_renderer.py +342 -0
- cortex/hcortex/recovery.py +782 -0
- cortex/py.typed +0 -0
- cortex/templates/__init__.py +8 -0
- cortex/templates/brain.py +118 -0
- cortex/templates/minimal_glossary.py +42 -0
- cortex/templates/package.py +91 -0
- cortex/templates/skill.py +91 -0
- cortex/v2/__init__.py +30 -0
- cortex/v2/diagnostics.py +57 -0
- cortex/v2/encoder.py +1106 -0
- cortex/v2/equivalence.py +323 -0
- cortex/v2/hcortex_parser.py +615 -0
- cortex/v2/hcortex_renderer.py +450 -0
- cortex/v2/ir.py +223 -0
- cortex/v2/parser.py +655 -0
- cortex/v2/view.py +425 -0
- cortex/v2/view_renderer.py +474 -0
- cortex/v2/writer.py +301 -0
cortex/cli/main.py
ADDED
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
"""CODEC-CORTEX CLI entry point.
|
|
2
|
+
|
|
3
|
+
Usage (canonical commands):
|
|
4
|
+
cortex new brain --out brain.cortex
|
|
5
|
+
cortex render brain.cortex --format hcortex --mode edit --out brain.hcortex.edit.md
|
|
6
|
+
cortex compile brain.hcortex.edit.md --out brain.cortex
|
|
7
|
+
cortex verify brain.cortex --roundtrip hcortex-edit
|
|
8
|
+
cortex list brain.cortex
|
|
9
|
+
cortex get brain.cortex FCS:primary --format json
|
|
10
|
+
cortex add brain.cortex --section $2 --sigil FCS --name primary --value 'what:"x"'
|
|
11
|
+
cortex update brain.cortex FCS:primary --set what="new"
|
|
12
|
+
cortex delete brain.cortex FCS:secondary
|
|
13
|
+
cortex move brain.cortex FCS:primary --to-section $3
|
|
14
|
+
cortex glossary list brain.cortex
|
|
15
|
+
cortex micro list brain.cortex
|
|
16
|
+
cortex doctor brain.cortex
|
|
17
|
+
cortex diff a.cortex b.cortex
|
|
18
|
+
cortex format brain.cortex
|
|
19
|
+
cortex recover legacy.cortex --out legacy.fixed.cortex
|
|
20
|
+
cortex diagram list brain.cortex
|
|
21
|
+
cortex diagram extract brain.cortex --name flow
|
|
22
|
+
|
|
23
|
+
v2 commands (canonical names since v0.3.2; v2-* aliases are deprecated):
|
|
24
|
+
cortex roundtrip <file> # was v2-roundtrip
|
|
25
|
+
cortex convert <file> ... # was v2-convert
|
|
26
|
+
cortex roundtrip-bidir <file> # was v2-roundtrip-bidir
|
|
27
|
+
cortex compare <a> <b> # was v2-compare
|
|
28
|
+
cortex verify-view <file> # was v2-verify-view
|
|
29
|
+
cortex explain-loss <file> # was v2-explain-loss
|
|
30
|
+
cortex canonicalize <file> # was v2-canonicalize (now VIEW-aware)
|
|
31
|
+
cortex inspect <file> # was v2-inspect
|
|
32
|
+
|
|
33
|
+
Aliases (Section 22.2 of SKILL.md):
|
|
34
|
+
cortex decode = cortex render (decode .cortex to a view)
|
|
35
|
+
cortex encode = cortex compile (encode a view back to .cortex)
|
|
36
|
+
cortex patch_add = cortex add
|
|
37
|
+
cortex patch_update = cortex update
|
|
38
|
+
cortex patch_remove = cortex delete
|
|
39
|
+
|
|
40
|
+
Deprecated aliases (still accepted, will be removed in v1.0.0):
|
|
41
|
+
v2-roundtrip, v2-convert, v2-roundtrip-bidir, v2-compare,
|
|
42
|
+
v2-verify-view, v2-explain-loss, v2-canonicalize, v2-inspect
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from __future__ import annotations
|
|
46
|
+
|
|
47
|
+
import argparse
|
|
48
|
+
import json
|
|
49
|
+
import sys
|
|
50
|
+
from typing import List, Optional
|
|
51
|
+
|
|
52
|
+
from .. import __version__
|
|
53
|
+
from .commands import (
|
|
54
|
+
new as cmd_new,
|
|
55
|
+
render as cmd_render,
|
|
56
|
+
compile as cmd_compile,
|
|
57
|
+
verify as cmd_verify,
|
|
58
|
+
get as cmd_get,
|
|
59
|
+
list as cmd_list,
|
|
60
|
+
add as cmd_add,
|
|
61
|
+
update as cmd_update,
|
|
62
|
+
delete as cmd_delete,
|
|
63
|
+
move as cmd_move,
|
|
64
|
+
glossary as cmd_glossary,
|
|
65
|
+
micro as cmd_micro,
|
|
66
|
+
doctor as cmd_doctor,
|
|
67
|
+
diff as cmd_diff,
|
|
68
|
+
format as cmd_format,
|
|
69
|
+
recover as cmd_recover,
|
|
70
|
+
diagram as cmd_diagram,
|
|
71
|
+
v2_roundtrip as cmd_v2_roundtrip,
|
|
72
|
+
v2_convert as cmd_v2_convert,
|
|
73
|
+
v2_roundtrip_bidir as cmd_v2_roundtrip_bidir,
|
|
74
|
+
v2_compare as cmd_v2_compare,
|
|
75
|
+
v2_verify_view as cmd_v2_verify_view,
|
|
76
|
+
v2_explain_loss as cmd_v2_explain_loss,
|
|
77
|
+
v2_canonicalize as cmd_v2_canonicalize,
|
|
78
|
+
v2_inspect as cmd_v2_inspect,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
83
|
+
p = argparse.ArgumentParser(
|
|
84
|
+
prog="cortex",
|
|
85
|
+
description=(
|
|
86
|
+
"CODEC-CORTEX CLI — modular deterministic processor for .cortex files. "
|
|
87
|
+
f"v{__version__}"
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
p.add_argument("--version", action="version", version=f"cortex {__version__}")
|
|
91
|
+
p.add_argument(
|
|
92
|
+
"--json", action="store_true",
|
|
93
|
+
help="emit machine-readable JSON where supported",
|
|
94
|
+
)
|
|
95
|
+
sub = p.add_subparsers(dest="command", required=True)
|
|
96
|
+
|
|
97
|
+
# ------------------------------------------------------------------
|
|
98
|
+
# new
|
|
99
|
+
# ------------------------------------------------------------------
|
|
100
|
+
sp = sub.add_parser("new", help="create a new .cortex file from a template")
|
|
101
|
+
sp.add_argument("kind", choices=["brain", "skill", "package", "generic"])
|
|
102
|
+
sp.add_argument("--out", required=True, help="output file path")
|
|
103
|
+
sp.add_argument("--name", default=None)
|
|
104
|
+
sp.add_argument("--version", dest="doc_version", default=None)
|
|
105
|
+
sp.add_argument("--domain", default=None)
|
|
106
|
+
sp.add_argument("--owner", default=None)
|
|
107
|
+
sp.add_argument("--language", default="en")
|
|
108
|
+
sp.add_argument("--template", choices=["minimal", "standard", "enterprise"], default="standard")
|
|
109
|
+
sp.add_argument("--with-diagrams", action="store_true")
|
|
110
|
+
sp.add_argument("--force", action="store_true")
|
|
111
|
+
sp.set_defaults(func=cmd_new.run)
|
|
112
|
+
|
|
113
|
+
# ------------------------------------------------------------------
|
|
114
|
+
# render (alias: decode)
|
|
115
|
+
# ------------------------------------------------------------------
|
|
116
|
+
# v1.1.3 P2-8: `decode <file>` (alias) defaults to --mode readable
|
|
117
|
+
# so the planned `cortex decode <file>` UX works without flags.
|
|
118
|
+
sp = sub.add_parser("render", help="render .cortex to HCORTEX markdown", aliases=["decode"])
|
|
119
|
+
sp.add_argument("input")
|
|
120
|
+
sp.add_argument("--format", choices=["hcortex"], default="hcortex")
|
|
121
|
+
sp.add_argument(
|
|
122
|
+
"--mode", choices=["read", "edit", "readable", "audit", "recovery", "full"],
|
|
123
|
+
default=None,
|
|
124
|
+
help="read=readable, edit=editable; recovery/full are profile aliases; "
|
|
125
|
+
"default=readable (v1.1.3 P2-8)",
|
|
126
|
+
)
|
|
127
|
+
sp.add_argument("--profile", choices=["min", "recovery", "work", "full"], default=None,
|
|
128
|
+
help="HCORTEX profile (MIN/RECOVERY/WORK/FULL)")
|
|
129
|
+
sp.add_argument(
|
|
130
|
+
"--layout", choices=["priority", "section"], default=None,
|
|
131
|
+
help="priority=global P0→P5 order; section=preserve section grouping; "
|
|
132
|
+
"auto-selects based on profile/mode",
|
|
133
|
+
)
|
|
134
|
+
sp.add_argument("--out", default=None)
|
|
135
|
+
sp.add_argument("--with-source", action="store_true",
|
|
136
|
+
help="include source column in READ mode (audit mode)")
|
|
137
|
+
sp.add_argument("--force", action="store_true")
|
|
138
|
+
sp.set_defaults(func=cmd_render.run)
|
|
139
|
+
|
|
140
|
+
# ------------------------------------------------------------------
|
|
141
|
+
# compile (alias: encode)
|
|
142
|
+
# ------------------------------------------------------------------
|
|
143
|
+
sp = sub.add_parser("compile", help="compile HCORTEX-EDIT markdown back to .cortex",
|
|
144
|
+
aliases=["encode"])
|
|
145
|
+
sp.add_argument("input")
|
|
146
|
+
sp.add_argument("--out", required=True)
|
|
147
|
+
sp.add_argument("--force", action="store_true")
|
|
148
|
+
sp.set_defaults(func=cmd_compile.run)
|
|
149
|
+
|
|
150
|
+
# ------------------------------------------------------------------
|
|
151
|
+
# verify (with --strict and --kind)
|
|
152
|
+
# ------------------------------------------------------------------
|
|
153
|
+
sp = sub.add_parser("verify", help="validate a .cortex file (optionally with roundtrip)")
|
|
154
|
+
sp.add_argument("input")
|
|
155
|
+
sp.add_argument("--roundtrip", choices=["hcortex-edit", "cortex"], default=None)
|
|
156
|
+
sp.add_argument("--strict", action="store_true",
|
|
157
|
+
help="promote warnings to errors (cognitive governance)")
|
|
158
|
+
sp.add_argument("--kind", choices=["brain", "skill", "package", "generic"], default=None,
|
|
159
|
+
help="explicit document kind for level-policy checks")
|
|
160
|
+
sp.set_defaults(func=cmd_verify.run)
|
|
161
|
+
|
|
162
|
+
# ------------------------------------------------------------------
|
|
163
|
+
# get
|
|
164
|
+
# ------------------------------------------------------------------
|
|
165
|
+
sp = sub.add_parser("get", help="get a single entry by selector")
|
|
166
|
+
sp.add_argument("input")
|
|
167
|
+
sp.add_argument("selector")
|
|
168
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
169
|
+
sp.set_defaults(func=cmd_get.run)
|
|
170
|
+
|
|
171
|
+
# ------------------------------------------------------------------
|
|
172
|
+
# list
|
|
173
|
+
# ------------------------------------------------------------------
|
|
174
|
+
sp = sub.add_parser("list", help="list entries in a .cortex file")
|
|
175
|
+
sp.add_argument("input")
|
|
176
|
+
sp.add_argument("--section", default=None)
|
|
177
|
+
sp.add_argument("--sigil", default=None)
|
|
178
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
179
|
+
sp.set_defaults(func=cmd_list.run)
|
|
180
|
+
|
|
181
|
+
# ------------------------------------------------------------------
|
|
182
|
+
# add (alias: patch_add)
|
|
183
|
+
# ------------------------------------------------------------------
|
|
184
|
+
sp = sub.add_parser("add", help="add a new entry to a .cortex file",
|
|
185
|
+
aliases=["patch_add"])
|
|
186
|
+
sp.add_argument("input")
|
|
187
|
+
sp.add_argument("--section", required=True)
|
|
188
|
+
sp.add_argument("--sigil", required=True)
|
|
189
|
+
sp.add_argument("--name", required=True)
|
|
190
|
+
sp.add_argument("--value", required=True, help='attrs body e.g. \'what:"x", priority:"high"\'')
|
|
191
|
+
sp.add_argument("--create-section", action="store_true")
|
|
192
|
+
sp.add_argument("--allow-duplicate", action="store_true")
|
|
193
|
+
sp.add_argument(
|
|
194
|
+
"--allow-unknown-sigil", action="store_true",
|
|
195
|
+
help="permit adding entries with sigils not declared in $0 (recovery/debug)",
|
|
196
|
+
)
|
|
197
|
+
sp.add_argument(
|
|
198
|
+
"--no-validate-write", action="store_true",
|
|
199
|
+
help="skip post-mutation validation before persisting (default: validate)",
|
|
200
|
+
)
|
|
201
|
+
sp.add_argument(
|
|
202
|
+
"--strict-write", action="store_true",
|
|
203
|
+
help="require strict validation (warnings also block write)",
|
|
204
|
+
)
|
|
205
|
+
sp.add_argument(
|
|
206
|
+
"--unsafe-allow-secret-forensics", action="store_true",
|
|
207
|
+
help="FORENSIC ONLY: bypass E031_SECRET_NOT_BYPASSABLE for secret "
|
|
208
|
+
"scanning. Use with extreme caution; --force alone cannot "
|
|
209
|
+
"override the no-clear-text-secrets rule (SKILL.md §16.1).",
|
|
210
|
+
)
|
|
211
|
+
sp.add_argument("--dry-run", action="store_true")
|
|
212
|
+
sp.add_argument("--force", action="store_true")
|
|
213
|
+
sp.set_defaults(func=cmd_add.run)
|
|
214
|
+
|
|
215
|
+
# ------------------------------------------------------------------
|
|
216
|
+
# update (alias: patch_update)
|
|
217
|
+
# ------------------------------------------------------------------
|
|
218
|
+
sp = sub.add_parser("update", help="update an existing entry",
|
|
219
|
+
aliases=["patch_update"])
|
|
220
|
+
sp.add_argument("input")
|
|
221
|
+
sp.add_argument("selector")
|
|
222
|
+
sp.add_argument("--set", dest="set_pairs", action="append", default=[],
|
|
223
|
+
help='key="value" (can repeat)')
|
|
224
|
+
sp.add_argument("--body", default=None, help="replace cuerpo/bloque body")
|
|
225
|
+
sp.add_argument("--append", action="store_true")
|
|
226
|
+
sp.add_argument(
|
|
227
|
+
"--no-validate-write", action="store_true",
|
|
228
|
+
help="skip post-mutation validation before persisting (default: validate)",
|
|
229
|
+
)
|
|
230
|
+
sp.add_argument(
|
|
231
|
+
"--strict-write", action="store_true",
|
|
232
|
+
help="require strict validation (warnings also block write)",
|
|
233
|
+
)
|
|
234
|
+
sp.add_argument("--dry-run", action="store_true")
|
|
235
|
+
sp.add_argument("--force", action="store_true")
|
|
236
|
+
sp.set_defaults(func=cmd_update.run)
|
|
237
|
+
|
|
238
|
+
# ------------------------------------------------------------------
|
|
239
|
+
# delete (alias: patch_remove)
|
|
240
|
+
# ------------------------------------------------------------------
|
|
241
|
+
sp = sub.add_parser("delete", help="delete an entry",
|
|
242
|
+
aliases=["patch_remove"])
|
|
243
|
+
sp.add_argument("input")
|
|
244
|
+
sp.add_argument("selector")
|
|
245
|
+
sp.add_argument(
|
|
246
|
+
"--no-validate-write", action="store_true",
|
|
247
|
+
help="skip post-mutation validation before persisting (default: validate)",
|
|
248
|
+
)
|
|
249
|
+
sp.add_argument(
|
|
250
|
+
"--strict-write", action="store_true",
|
|
251
|
+
help="require strict validation (warnings also block write)",
|
|
252
|
+
)
|
|
253
|
+
sp.add_argument("--force", action="store_true")
|
|
254
|
+
sp.add_argument("--dry-run", action="store_true")
|
|
255
|
+
sp.set_defaults(func=cmd_delete.run)
|
|
256
|
+
|
|
257
|
+
# ------------------------------------------------------------------
|
|
258
|
+
# move
|
|
259
|
+
# ------------------------------------------------------------------
|
|
260
|
+
sp = sub.add_parser("move", help="move an entry to another section")
|
|
261
|
+
sp.add_argument("input")
|
|
262
|
+
sp.add_argument("selector")
|
|
263
|
+
sp.add_argument("--to-section", required=True)
|
|
264
|
+
sp.add_argument(
|
|
265
|
+
"--no-validate-write", action="store_true",
|
|
266
|
+
help="skip post-mutation validation before persisting (default: validate)",
|
|
267
|
+
)
|
|
268
|
+
sp.add_argument(
|
|
269
|
+
"--strict-write", action="store_true",
|
|
270
|
+
help="require strict validation (warnings also block write)",
|
|
271
|
+
)
|
|
272
|
+
sp.add_argument("--dry-run", action="store_true")
|
|
273
|
+
sp.add_argument("--force", action="store_true")
|
|
274
|
+
sp.set_defaults(func=cmd_move.run)
|
|
275
|
+
|
|
276
|
+
# ------------------------------------------------------------------
|
|
277
|
+
# glossary
|
|
278
|
+
# ------------------------------------------------------------------
|
|
279
|
+
sp = sub.add_parser("glossary", help="glossary CRUD")
|
|
280
|
+
g_sub = sp.add_subparsers(dest="glossary_command", required=True)
|
|
281
|
+
|
|
282
|
+
gsp = g_sub.add_parser("list", help="list sigils in $0")
|
|
283
|
+
gsp.add_argument("input")
|
|
284
|
+
gsp.add_argument("--format", choices=["text", "json"], default="text")
|
|
285
|
+
gsp.set_defaults(func=cmd_glossary.run_list)
|
|
286
|
+
|
|
287
|
+
gsp = g_sub.add_parser("add", help="add a sigil to $0")
|
|
288
|
+
gsp.add_argument("input")
|
|
289
|
+
gsp.add_argument("--sigil", required=True)
|
|
290
|
+
gsp.add_argument("--name", required=True)
|
|
291
|
+
gsp.add_argument("--type", required=True)
|
|
292
|
+
gsp.add_argument("--risk", default="M")
|
|
293
|
+
gsp.add_argument("--layer", default="Semantic")
|
|
294
|
+
gsp.add_argument("--description", required=True)
|
|
295
|
+
gsp.add_argument("--force-governance", action="store_true")
|
|
296
|
+
gsp.add_argument("--dry-run", action="store_true")
|
|
297
|
+
gsp.set_defaults(func=cmd_glossary.run_add)
|
|
298
|
+
|
|
299
|
+
gsp = g_sub.add_parser("update", help="update a sigil's metadata")
|
|
300
|
+
gsp.add_argument("input")
|
|
301
|
+
gsp.add_argument("--sigil", required=True)
|
|
302
|
+
gsp.add_argument("--description", default=None)
|
|
303
|
+
gsp.add_argument("--risk", default=None)
|
|
304
|
+
gsp.add_argument("--layer", default=None)
|
|
305
|
+
gsp.add_argument("--force-governance", action="store_true")
|
|
306
|
+
gsp.add_argument("--dry-run", action="store_true")
|
|
307
|
+
gsp.set_defaults(func=cmd_glossary.run_update)
|
|
308
|
+
|
|
309
|
+
gsp = g_sub.add_parser("delete", help="remove a sigil from $0")
|
|
310
|
+
gsp.add_argument("input")
|
|
311
|
+
gsp.add_argument("--sigil", required=True)
|
|
312
|
+
gsp.add_argument("--force", action="store_true")
|
|
313
|
+
gsp.add_argument("--dry-run", action="store_true")
|
|
314
|
+
gsp.set_defaults(func=cmd_glossary.run_delete)
|
|
315
|
+
|
|
316
|
+
# ------------------------------------------------------------------
|
|
317
|
+
# micro
|
|
318
|
+
# ------------------------------------------------------------------
|
|
319
|
+
sp = sub.add_parser("micro", help="micro-token CRUD")
|
|
320
|
+
m_sub = sp.add_subparsers(dest="micro_command", required=True)
|
|
321
|
+
|
|
322
|
+
msp = m_sub.add_parser("list", help="list micro-tokens")
|
|
323
|
+
msp.add_argument("input")
|
|
324
|
+
msp.add_argument("--format", choices=["text", "json"], default="text")
|
|
325
|
+
msp.set_defaults(func=cmd_micro.run_list)
|
|
326
|
+
|
|
327
|
+
msp = m_sub.add_parser("add", help="add a micro-token")
|
|
328
|
+
msp.add_argument("input")
|
|
329
|
+
msp.add_argument("--token", required=True)
|
|
330
|
+
msp.add_argument("--value", required=True)
|
|
331
|
+
msp.add_argument("--dry-run", action="store_true")
|
|
332
|
+
msp.set_defaults(func=cmd_micro.run_add)
|
|
333
|
+
|
|
334
|
+
msp = m_sub.add_parser("update", help="update a micro-token")
|
|
335
|
+
msp.add_argument("input")
|
|
336
|
+
msp.add_argument("--token", required=True)
|
|
337
|
+
msp.add_argument("--value", required=True)
|
|
338
|
+
msp.add_argument("--dry-run", action="store_true")
|
|
339
|
+
msp.set_defaults(func=cmd_micro.run_update)
|
|
340
|
+
|
|
341
|
+
msp = m_sub.add_parser("delete", help="remove a micro-token")
|
|
342
|
+
msp.add_argument("input")
|
|
343
|
+
msp.add_argument("--token", required=True)
|
|
344
|
+
msp.add_argument("--force", action="store_true")
|
|
345
|
+
msp.add_argument("--dry-run", action="store_true")
|
|
346
|
+
msp.set_defaults(func=cmd_micro.run_delete)
|
|
347
|
+
|
|
348
|
+
# ------------------------------------------------------------------
|
|
349
|
+
# doctor (with --strict and --kind)
|
|
350
|
+
# ------------------------------------------------------------------
|
|
351
|
+
sp = sub.add_parser("doctor", help="deep diagnostic of a .cortex file")
|
|
352
|
+
sp.add_argument("input")
|
|
353
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
354
|
+
sp.add_argument("--strict", action="store_true",
|
|
355
|
+
help="promote warnings to errors (cognitive governance)")
|
|
356
|
+
sp.add_argument("--kind", choices=["brain", "skill", "package", "generic"], default=None,
|
|
357
|
+
help="explicit document kind for level-policy checks")
|
|
358
|
+
sp.set_defaults(func=cmd_doctor.run)
|
|
359
|
+
|
|
360
|
+
# ------------------------------------------------------------------
|
|
361
|
+
# diff (with --profile)
|
|
362
|
+
# ------------------------------------------------------------------
|
|
363
|
+
sp = sub.add_parser("diff", help="structural diff between two .cortex files")
|
|
364
|
+
sp.add_argument("left")
|
|
365
|
+
sp.add_argument("right")
|
|
366
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
367
|
+
sp.add_argument(
|
|
368
|
+
"--profile", choices=["structural", "semantic", "governance"], default="structural",
|
|
369
|
+
help="structural=AST diff, semantic=values+glossary, governance=+level policy",
|
|
370
|
+
)
|
|
371
|
+
sp.set_defaults(func=cmd_diff.run)
|
|
372
|
+
|
|
373
|
+
# ------------------------------------------------------------------
|
|
374
|
+
# format
|
|
375
|
+
# ------------------------------------------------------------------
|
|
376
|
+
sp = sub.add_parser("format", help="re-serialize a .cortex file canonically")
|
|
377
|
+
sp.add_argument("input")
|
|
378
|
+
sp.add_argument("--out", default=None)
|
|
379
|
+
sp.add_argument("--dry-run", action="store_true")
|
|
380
|
+
sp.add_argument("--force", action="store_true")
|
|
381
|
+
sp.set_defaults(func=cmd_format.run)
|
|
382
|
+
|
|
383
|
+
# ------------------------------------------------------------------
|
|
384
|
+
# recover (new — audit gap H-06)
|
|
385
|
+
# ------------------------------------------------------------------
|
|
386
|
+
sp = sub.add_parser("recover", help="recover a legacy or non-conforming .cortex file")
|
|
387
|
+
sp.add_argument("input")
|
|
388
|
+
sp.add_argument("--out", default=None,
|
|
389
|
+
help="write the recovered .cortex to this path (default: stdout)")
|
|
390
|
+
sp.add_argument("--strict", action="store_true")
|
|
391
|
+
sp.add_argument(
|
|
392
|
+
"--embed-aud-rsk", action="store_true",
|
|
393
|
+
help="embed AUD and RSK entries in the recovered .cortex so the "
|
|
394
|
+
"artefact itself carries the recovery trace (re-audit M-RA-03)",
|
|
395
|
+
)
|
|
396
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
397
|
+
sp.set_defaults(func=cmd_recover.run)
|
|
398
|
+
|
|
399
|
+
# ------------------------------------------------------------------
|
|
400
|
+
# diagram (new — audit gap B-010)
|
|
401
|
+
# ------------------------------------------------------------------
|
|
402
|
+
sp = sub.add_parser("diagram", help="diagram operations (DIAG sigil)")
|
|
403
|
+
d_sub = sp.add_subparsers(dest="diagram_command", required=True)
|
|
404
|
+
|
|
405
|
+
dsp = d_sub.add_parser("list", help="list DIAG entries")
|
|
406
|
+
dsp.add_argument("input")
|
|
407
|
+
dsp.add_argument("--format", choices=["text", "json"], default="text")
|
|
408
|
+
dsp.set_defaults(func=cmd_diagram.run_list)
|
|
409
|
+
|
|
410
|
+
dsp = d_sub.add_parser("extract", help="extract a DIAG bloque verbatim")
|
|
411
|
+
dsp.add_argument("input")
|
|
412
|
+
dsp.add_argument("--name", required=True, help="DIAG entry name")
|
|
413
|
+
dsp.add_argument("--out", default=None, help="output file (default: stdout)")
|
|
414
|
+
dsp.add_argument(
|
|
415
|
+
"--print-newline", action="store_true",
|
|
416
|
+
help="add a trailing newline on stdout output (terminal-friendly; "
|
|
417
|
+
"default: write exactly the bytes)",
|
|
418
|
+
)
|
|
419
|
+
dsp.set_defaults(func=cmd_diagram.run_extract)
|
|
420
|
+
|
|
421
|
+
dsp = d_sub.add_parser("validate", help="validate DIAG bloque integrity")
|
|
422
|
+
dsp.add_argument("input")
|
|
423
|
+
dsp.add_argument("--name", default=None, help="specific DIAG name (default: all)")
|
|
424
|
+
dsp.add_argument("--format", choices=["text", "json"], default="text")
|
|
425
|
+
dsp.set_defaults(func=cmd_diagram.run_validate)
|
|
426
|
+
|
|
427
|
+
# ------------------------------------------------------------------
|
|
428
|
+
# roundtrip (canonical; alias: v2-roundtrip — deprecated)
|
|
429
|
+
# v2.0.0: CORTEX v2 byte-identical roundtrip.
|
|
430
|
+
# v0.3.2: rename v2-roundtrip → roundtrip (canonical).
|
|
431
|
+
# ------------------------------------------------------------------
|
|
432
|
+
sp = sub.add_parser(
|
|
433
|
+
"roundtrip",
|
|
434
|
+
help="verify CORTEX v2 roundtrip fidelity (byte-identical)",
|
|
435
|
+
aliases=["v2-roundtrip"],
|
|
436
|
+
)
|
|
437
|
+
sp.add_argument("input", help="CORTEX v2 file to test")
|
|
438
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
439
|
+
sp.set_defaults(func=cmd_v2_roundtrip.run)
|
|
440
|
+
|
|
441
|
+
# ------------------------------------------------------------------
|
|
442
|
+
# convert (canonical; alias: v2-convert — deprecated)
|
|
443
|
+
# v2.1.0: CORTEX ⇄ HCORTEX conversion.
|
|
444
|
+
# v0.3.2: rename v2-convert → convert (canonical).
|
|
445
|
+
# ------------------------------------------------------------------
|
|
446
|
+
sp = sub.add_parser(
|
|
447
|
+
"convert",
|
|
448
|
+
help="convert between CORTEX v2 and HCORTEX v2",
|
|
449
|
+
aliases=["v2-convert"],
|
|
450
|
+
)
|
|
451
|
+
sp.add_argument("input", help="input file")
|
|
452
|
+
sp.add_argument("--from", dest="from_format", choices=["cortex", "hcortex", "hcortex-r"], required=True,
|
|
453
|
+
help="source format")
|
|
454
|
+
sp.add_argument("--to", dest="to_format", choices=["cortex", "hcortex", "hcortex-r"], required=True,
|
|
455
|
+
help="target format")
|
|
456
|
+
sp.add_argument("--out", default=None, help="output file (default: stdout)")
|
|
457
|
+
sp.add_argument(
|
|
458
|
+
"--force-write-on-error", action="store_true",
|
|
459
|
+
help="v2.2.2: write --out even when E_VIEW_* errors occur. "
|
|
460
|
+
"Default: skip writing --out if any E_VIEW_* error is present "
|
|
461
|
+
"(prevents invalid artefacts on disk).",
|
|
462
|
+
)
|
|
463
|
+
sp.add_argument(
|
|
464
|
+
"--strict", action="store_true",
|
|
465
|
+
help="v2.2.2: promote W_VIEW_* warnings to errors (rc=1).",
|
|
466
|
+
)
|
|
467
|
+
sp.add_argument(
|
|
468
|
+
"--mode", choices=["normal", "strict", "audit", "recovery", "display"], default="normal",
|
|
469
|
+
help="v2.2.3 PRE-05: operating mode. 'display' produces Markdown without "
|
|
470
|
+
"reversible contract (not canonical HCORTEX).",
|
|
471
|
+
)
|
|
472
|
+
sp.set_defaults(func=cmd_v2_convert.run)
|
|
473
|
+
|
|
474
|
+
# ------------------------------------------------------------------
|
|
475
|
+
# roundtrip-bidir (canonical; alias: v2-roundtrip-bidir — deprecated)
|
|
476
|
+
# v2.3.0: CORTEX ⇄ HCORTEX bidirectional roundtrip.
|
|
477
|
+
# v0.3.2: rename v2-roundtrip-bidir → roundtrip-bidir (canonical).
|
|
478
|
+
# ------------------------------------------------------------------
|
|
479
|
+
sp = sub.add_parser(
|
|
480
|
+
"roundtrip-bidir",
|
|
481
|
+
help="validate CORTEX ⇄ HCORTEX bidirectional roundtrip",
|
|
482
|
+
aliases=["v2-roundtrip-bidir"],
|
|
483
|
+
)
|
|
484
|
+
sp.add_argument("input", help="CORTEX or HCORTEX file")
|
|
485
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
486
|
+
sp.set_defaults(func=cmd_v2_roundtrip_bidir.run)
|
|
487
|
+
|
|
488
|
+
# ------------------------------------------------------------------
|
|
489
|
+
# compare (canonical; alias: v2-compare — deprecated)
|
|
490
|
+
# v2.3.0: compare two CORTEX/HCORTEX artefacts.
|
|
491
|
+
# v0.3.2: rename v2-compare → compare (canonical).
|
|
492
|
+
# ------------------------------------------------------------------
|
|
493
|
+
sp = sub.add_parser(
|
|
494
|
+
"compare",
|
|
495
|
+
help="compare two CORTEX/HCORTEX artefacts (byte/AST/semantic/content)",
|
|
496
|
+
aliases=["v2-compare"],
|
|
497
|
+
)
|
|
498
|
+
sp.add_argument("left", help="left file")
|
|
499
|
+
sp.add_argument("right", help="right file")
|
|
500
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
501
|
+
sp.add_argument("--verbose", action="store_true", help="show first 20 diffs in detail")
|
|
502
|
+
sp.set_defaults(func=cmd_v2_compare.run)
|
|
503
|
+
|
|
504
|
+
# ------------------------------------------------------------------
|
|
505
|
+
# verify-view (canonical; alias: v2-verify-view — deprecated)
|
|
506
|
+
# v2.3.0: validate VIEW coverage, reversibility, consistency.
|
|
507
|
+
# v0.3.2: rename v2-verify-view → verify-view (canonical).
|
|
508
|
+
# ------------------------------------------------------------------
|
|
509
|
+
sp = sub.add_parser(
|
|
510
|
+
"verify-view",
|
|
511
|
+
help="validate VIEW coverage, reversibility, consistency",
|
|
512
|
+
aliases=["v2-verify-view"],
|
|
513
|
+
)
|
|
514
|
+
sp.add_argument("input", help="CORTEX file")
|
|
515
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
516
|
+
sp.add_argument("--strict", action="store_true", help="warnings also cause non-zero rc")
|
|
517
|
+
sp.set_defaults(func=cmd_v2_verify_view.run)
|
|
518
|
+
|
|
519
|
+
# ------------------------------------------------------------------
|
|
520
|
+
# explain-loss (canonical; alias: v2-explain-loss — deprecated)
|
|
521
|
+
# v2.3.0: explain loss, omission, or non-reversible content.
|
|
522
|
+
# v0.3.2: rename v2-explain-loss → explain-loss (canonical).
|
|
523
|
+
# ------------------------------------------------------------------
|
|
524
|
+
sp = sub.add_parser(
|
|
525
|
+
"explain-loss",
|
|
526
|
+
help="explain loss, omission, or non-reversible content",
|
|
527
|
+
aliases=["v2-explain-loss"],
|
|
528
|
+
)
|
|
529
|
+
sp.add_argument("input", help="CORTEX or HCORTEX file")
|
|
530
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
531
|
+
sp.set_defaults(func=cmd_v2_explain_loss.run)
|
|
532
|
+
|
|
533
|
+
# ------------------------------------------------------------------
|
|
534
|
+
# canonicalize (canonical; alias: v2-canonicalize — deprecated)
|
|
535
|
+
# v2.3.0: normalize artefact without changing semantics.
|
|
536
|
+
# v0.3.2: rename v2-canonicalize → canonicalize (canonical).
|
|
537
|
+
# Adds --preserve flag and VIEW-aware behavior (B-01/B-05 fix):
|
|
538
|
+
# - If the artefact has no VIEW directives, emit a warning and
|
|
539
|
+
# only normalize whitespace/section ordering (no structural
|
|
540
|
+
# rewrite). This preserves v1-render compatibility.
|
|
541
|
+
# - --preserve forces this behavior even when VIEW directives
|
|
542
|
+
# are present.
|
|
543
|
+
# ------------------------------------------------------------------
|
|
544
|
+
sp = sub.add_parser(
|
|
545
|
+
"canonicalize",
|
|
546
|
+
help="normalize artefact without changing semantics (VIEW-aware)",
|
|
547
|
+
aliases=["v2-canonicalize"],
|
|
548
|
+
)
|
|
549
|
+
sp.add_argument("input", help="CORTEX or HCORTEX file")
|
|
550
|
+
sp.add_argument("--out", default=None, help="output file (default: stdout)")
|
|
551
|
+
sp.add_argument(
|
|
552
|
+
"--preserve", action="store_true",
|
|
553
|
+
help="v0.3.2: preserve original structure even if VIEW directives "
|
|
554
|
+
"are present. Only normalize whitespace and section ordering. "
|
|
555
|
+
"Forces v1-render compatibility.",
|
|
556
|
+
)
|
|
557
|
+
sp.set_defaults(func=cmd_v2_canonicalize.run)
|
|
558
|
+
|
|
559
|
+
# ------------------------------------------------------------------
|
|
560
|
+
# inspect (canonical; alias: v2-inspect — deprecated)
|
|
561
|
+
# v2.3.0: inspect AST, sections, sigils, VIEW coverage, errors.
|
|
562
|
+
# v0.3.2: rename v2-inspect → inspect (canonical).
|
|
563
|
+
# ------------------------------------------------------------------
|
|
564
|
+
sp = sub.add_parser(
|
|
565
|
+
"inspect",
|
|
566
|
+
help="inspect AST, sections, sigils, VIEW coverage, errors",
|
|
567
|
+
aliases=["v2-inspect"],
|
|
568
|
+
)
|
|
569
|
+
sp.add_argument("input", help="CORTEX or HCORTEX file")
|
|
570
|
+
sp.add_argument("--format", choices=["text", "json"], default="text")
|
|
571
|
+
sp.set_defaults(func=cmd_v2_inspect.run)
|
|
572
|
+
|
|
573
|
+
return p
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def main(argv: Optional[List[str]] = None) -> int:
|
|
577
|
+
parser = build_parser()
|
|
578
|
+
args = parser.parse_args(argv)
|
|
579
|
+
if not getattr(args, "func", None):
|
|
580
|
+
parser.print_help()
|
|
581
|
+
return 2
|
|
582
|
+
|
|
583
|
+
# v0.3.2 — Deprecation warning for v2-* aliases.
|
|
584
|
+
# The canonical names (roundtrip, convert, ...) should be used instead.
|
|
585
|
+
# The v2-* forms are still accepted for backward compatibility but will
|
|
586
|
+
# be removed in v1.0.0.
|
|
587
|
+
_DEPRECATED_ALIASES = {
|
|
588
|
+
"v2-roundtrip", "v2-convert", "v2-roundtrip-bidir", "v2-compare",
|
|
589
|
+
"v2-verify-view", "v2-explain-loss", "v2-canonicalize", "v2-inspect",
|
|
590
|
+
}
|
|
591
|
+
invoked_command = None
|
|
592
|
+
if argv:
|
|
593
|
+
# Skip global flags before the subcommand name
|
|
594
|
+
for token in argv:
|
|
595
|
+
if token.startswith("-"):
|
|
596
|
+
continue
|
|
597
|
+
invoked_command = token
|
|
598
|
+
break
|
|
599
|
+
elif sys.argv and len(sys.argv) > 1:
|
|
600
|
+
for token in sys.argv[1:]:
|
|
601
|
+
if token.startswith("-"):
|
|
602
|
+
continue
|
|
603
|
+
invoked_command = token
|
|
604
|
+
break
|
|
605
|
+
if invoked_command in _DEPRECATED_ALIASES:
|
|
606
|
+
canonical = invoked_command.removeprefix("v2-")
|
|
607
|
+
print(
|
|
608
|
+
f"WARNING: `cortex {invoked_command}` is deprecated since v0.3.2; "
|
|
609
|
+
f"use `cortex {canonical}` instead. The `v2-` prefix will be "
|
|
610
|
+
f"removed in v1.0.0.",
|
|
611
|
+
file=sys.stderr,
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
# Normalise --json: stash it on args so subcommands can read it (audit L-03)
|
|
615
|
+
json_mode = getattr(args, "json", False) or ("--json" in (argv or sys.argv))
|
|
616
|
+
args._json_mode = json_mode # type: ignore[attr-defined]
|
|
617
|
+
|
|
618
|
+
try:
|
|
619
|
+
rc = args.func(args)
|
|
620
|
+
return int(rc or 0)
|
|
621
|
+
except Exception as e:
|
|
622
|
+
if json_mode:
|
|
623
|
+
print(json.dumps({
|
|
624
|
+
"ok": False,
|
|
625
|
+
"error": {
|
|
626
|
+
"code": getattr(e, "code", "E000_UNKNOWN"),
|
|
627
|
+
"message": str(e),
|
|
628
|
+
},
|
|
629
|
+
}, indent=2, ensure_ascii=False))
|
|
630
|
+
else:
|
|
631
|
+
print(f"error: {e}", file=sys.stderr)
|
|
632
|
+
return 1
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
if __name__ == "__main__":
|
|
636
|
+
sys.exit(main())
|