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.
Files changed (81) hide show
  1. codec_cortex-0.3.2.dist-info/METADATA +183 -0
  2. codec_cortex-0.3.2.dist-info/RECORD +81 -0
  3. codec_cortex-0.3.2.dist-info/WHEEL +5 -0
  4. codec_cortex-0.3.2.dist-info/entry_points.txt +2 -0
  5. codec_cortex-0.3.2.dist-info/licenses/LICENSE +21 -0
  6. codec_cortex-0.3.2.dist-info/scm_file_list.json +124 -0
  7. codec_cortex-0.3.2.dist-info/scm_version.json +8 -0
  8. codec_cortex-0.3.2.dist-info/top_level.txt +1 -0
  9. cortex/__init__.py +22 -0
  10. cortex/__main__.py +7 -0
  11. cortex/_version.py +24 -0
  12. cortex/cli/__init__.py +5 -0
  13. cortex/cli/commands/__init__.py +150 -0
  14. cortex/cli/commands/add.py +89 -0
  15. cortex/cli/commands/compile.py +31 -0
  16. cortex/cli/commands/delete.py +44 -0
  17. cortex/cli/commands/diagram.py +130 -0
  18. cortex/cli/commands/diff.py +135 -0
  19. cortex/cli/commands/doctor.py +74 -0
  20. cortex/cli/commands/format.py +29 -0
  21. cortex/cli/commands/get.py +45 -0
  22. cortex/cli/commands/glossary.py +98 -0
  23. cortex/cli/commands/list.py +44 -0
  24. cortex/cli/commands/micro.py +79 -0
  25. cortex/cli/commands/move.py +45 -0
  26. cortex/cli/commands/new.py +80 -0
  27. cortex/cli/commands/recover.py +90 -0
  28. cortex/cli/commands/render.py +93 -0
  29. cortex/cli/commands/update.py +81 -0
  30. cortex/cli/commands/v2_canonicalize.py +162 -0
  31. cortex/cli/commands/v2_compare.py +74 -0
  32. cortex/cli/commands/v2_convert.py +183 -0
  33. cortex/cli/commands/v2_explain_loss.py +97 -0
  34. cortex/cli/commands/v2_inspect.py +113 -0
  35. cortex/cli/commands/v2_roundtrip.py +104 -0
  36. cortex/cli/commands/v2_roundtrip_bidir.py +128 -0
  37. cortex/cli/commands/v2_verify_view.py +65 -0
  38. cortex/cli/commands/verify.py +119 -0
  39. cortex/cli/main.py +636 -0
  40. cortex/core/__init__.py +85 -0
  41. cortex/core/ast.py +313 -0
  42. cortex/core/compare.py +180 -0
  43. cortex/core/document_kind.py +525 -0
  44. cortex/core/errors.py +399 -0
  45. cortex/core/lexer.py +267 -0
  46. cortex/core/parser.py +671 -0
  47. cortex/core/validator.py +268 -0
  48. cortex/core/writer.py +249 -0
  49. cortex/crud/__init__.py +17 -0
  50. cortex/crud/mutations.py +342 -0
  51. cortex/crud/selectors.py +95 -0
  52. cortex/crud/transactions.py +213 -0
  53. cortex/glossary/__init__.py +21 -0
  54. cortex/glossary/contracts.py +37 -0
  55. cortex/glossary/minimal.py +94 -0
  56. cortex/glossary/model.py +77 -0
  57. cortex/glossary/resolver.py +96 -0
  58. cortex/hcortex/__init__.py +35 -0
  59. cortex/hcortex/edit_parser.py +489 -0
  60. cortex/hcortex/edit_renderer.py +158 -0
  61. cortex/hcortex/markdown_model.py +81 -0
  62. cortex/hcortex/profiles.py +166 -0
  63. cortex/hcortex/read_renderer.py +342 -0
  64. cortex/hcortex/recovery.py +782 -0
  65. cortex/py.typed +0 -0
  66. cortex/templates/__init__.py +8 -0
  67. cortex/templates/brain.py +118 -0
  68. cortex/templates/minimal_glossary.py +42 -0
  69. cortex/templates/package.py +91 -0
  70. cortex/templates/skill.py +91 -0
  71. cortex/v2/__init__.py +30 -0
  72. cortex/v2/diagnostics.py +57 -0
  73. cortex/v2/encoder.py +1106 -0
  74. cortex/v2/equivalence.py +323 -0
  75. cortex/v2/hcortex_parser.py +615 -0
  76. cortex/v2/hcortex_renderer.py +450 -0
  77. cortex/v2/ir.py +223 -0
  78. cortex/v2/parser.py +655 -0
  79. cortex/v2/view.py +425 -0
  80. cortex/v2/view_renderer.py +474 -0
  81. cortex/v2/writer.py +301 -0
@@ -0,0 +1,94 @@
1
+ """Minimal sigil sets per template kind.
2
+
3
+ Each function returns a list of :class:`~cortex.core.ast.SigilDef`
4
+ appropriate for the template (brain / skill / package / generic).
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import List
10
+
11
+ from ..core.ast import SigilDef
12
+
13
+
14
+ def brain_sigils() -> List[SigilDef]:
15
+ """Sigils for a ``brain.cortex`` template (Nivel 2 operativo)."""
16
+
17
+ return [
18
+ SigilDef("IDN", "identity", "attrs", "B", "Semantic", "Actor or memory identity"),
19
+ SigilDef("DOM", "domain", "attrs", "B", "Semantic", "Operating domain or scope"),
20
+ SigilDef("CNST","constraint", "attrs", "H", "Prefrontal", "Hard operational boundary"),
21
+ SigilDef("FCS", "focus", "attrs", "H", "Working", "Active attention anchor"),
22
+ SigilDef("OBJ", "objective", "attrs", "H", "Working", "Active goal with success criterion"),
23
+ SigilDef("WRK", "work", "attrs", "M", "Working", "Current operational state"),
24
+ SigilDef("STP", "step", "attrs", "M", "Working", "Immediate next action"),
25
+ SigilDef("NXT", "next", "attrs", "M", "Working", "Queued next action"),
26
+ SigilDef("RSK", "risk", "attrs", "M", "Prefrontal", "Risk and mitigation"),
27
+ SigilDef("AUD", "audit", "attrs", "M", "Prefrontal", "Audit or verification record"),
28
+ SigilDef("STAT","status", "attrs", "B", "Semantic", "Status or maturity declaration"),
29
+ SigilDef("REF", "reference", "attrs", "B", "Semantic", "File, object or source reference"),
30
+ SigilDef("KNW", "knowledge", "attrs", "B", "Semantic", "Stable or promoted knowledge"),
31
+ SigilDef("SES", "session", "attrs", "M", "Episodic", "Compressed episode I/O/R"),
32
+ SigilDef("LNG", "lesson", "attrs", "M", "Episodic", "Lesson or pattern"),
33
+ SigilDef("DIAG","diagram", "bloque", "M", "Episodic/Visual", "Verbatim diagram block"),
34
+ SigilDef("!", "rule", "attrs", "H", "Prefrontal", "Mandatory compact rule"),
35
+ ]
36
+
37
+
38
+ def skill_sigils() -> List[SigilDef]:
39
+ """Sigils for a ``SKILL.cortex`` template (Nivel 1)."""
40
+
41
+ return [
42
+ SigilDef("IDN", "identity", "attrs", "B", "Semantic", "Skill identity"),
43
+ SigilDef("DOM", "domain", "attrs", "B", "Semantic", "Adoption scope and context"),
44
+ SigilDef("AXM", "axiom", "cuerpo", "H", "Prefrontal", "Non-negotiable principle"),
45
+ SigilDef("CNST","constraint", "attrs", "H", "Prefrontal", "Hard operational boundary"),
46
+ SigilDef("KNW", "knowledge", "attrs", "B", "Semantic", "Protocol knowledge"),
47
+ SigilDef("HDL", "handler", "attrs-pos","M","Semantic", "Operation descriptor (positional)"),
48
+ SigilDef("STAT","status", "attrs", "B", "Semantic", "Status or maturity declaration"),
49
+ SigilDef("DIAG","diagram", "bloque", "M", "Episodic/Visual", "Normative diagram"),
50
+ SigilDef("REF", "reference", "attrs", "B", "Semantic", "Source or cross-reference"),
51
+ SigilDef("RSK", "risk", "attrs", "M", "Prefrontal", "Protocol risk and mitigation"),
52
+ SigilDef("AUD", "audit", "attrs", "M", "Prefrontal", "Spec audit record"),
53
+ SigilDef("!", "rule", "attrs", "H", "Prefrontal", "Mandatory compact rule"),
54
+ ]
55
+
56
+
57
+ def package_sigils() -> List[SigilDef]:
58
+ """Sigils for a Nivel 3 ``*.cortex`` package."""
59
+
60
+ return [
61
+ SigilDef("IDN", "identity", "attrs", "B", "Semantic", "Package identity"),
62
+ SigilDef("DOM", "domain", "attrs", "B", "Semantic", "Scope and purpose"),
63
+ SigilDef("KNW", "knowledge", "attrs", "B", "Semantic", "Compressed knowledge"),
64
+ SigilDef("REF", "reference", "attrs", "B", "Semantic", "Source or traceability reference"),
65
+ SigilDef("LIM", "limit", "attrs", "M", "Prefrontal", "Explicit operational limit"),
66
+ SigilDef("CLAIM","claim", "attrs", "M", "Prefrontal", "Verifiable assertion"),
67
+ SigilDef("DIAG","diagram", "bloque", "M", "Episodic/Visual", "Verbatim diagram block"),
68
+ SigilDef("STAT","status", "attrs", "B", "Semantic", "Status declaration"),
69
+ SigilDef("AUD", "audit", "attrs", "M", "Prefrontal", "Audit record"),
70
+ SigilDef("RSK", "risk", "attrs", "M", "Prefrontal", "Risk and mitigation"),
71
+ ]
72
+
73
+
74
+ def generic_sigils() -> List[SigilDef]:
75
+ """A superset sigil set for generic ``.cortex`` files."""
76
+
77
+ return brain_sigils() + [
78
+ SigilDef("AXM", "axiom", "cuerpo", "H", "Prefrontal", "Non-negotiable principle"),
79
+ SigilDef("CLAIM","claim", "attrs", "M", "Prefrontal", "Verifiable assertion"),
80
+ SigilDef("LIM", "limit", "attrs", "M", "Prefrontal", "Explicit operational limit"),
81
+ SigilDef("HDL", "handler", "attrs-pos","M","Semantic", "Operation descriptor (positional)"),
82
+ SigilDef("TAG", "tag", "attrs", "B", "Semantic", "Classification metadata"),
83
+ SigilDef("PFL", "pitfall", "attrs", "M", "Prefrontal", "Known antipattern"),
84
+ SigilDef("DEP", "dependency", "attrs", "M", "Semantic", "Cross-artefact dependency"),
85
+ SigilDef("DESC","description","cuerpo", "B", "Semantic", "Structured description"),
86
+ SigilDef("ERR", "error", "attrs", "M", "Prefrontal", "Known error with cause/solution"),
87
+ ]
88
+
89
+
90
+ def hdL_contract():
91
+ """Default positional contract for ``HDL`` (operation | status | requires)."""
92
+
93
+ from ..core.ast import AttrsPosContract
94
+ return AttrsPosContract(sigil="HDL", fields=["operation", "status", "requires"])
@@ -0,0 +1,77 @@
1
+ """Glossary model and helpers.
2
+
3
+ Wraps the :class:`~cortex.core.ast.Glossary` with convenience builders
4
+ and queries used by templates, the CRUD layer and the CLI.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Iterable
10
+
11
+ from ..core.ast import (
12
+ AttrsPosContract,
13
+ Glossary,
14
+ MicroDef,
15
+ SigilDef,
16
+ TypeDef,
17
+ )
18
+ from ..core.errors import CANONICAL_MICRO
19
+
20
+
21
+ def minimal_glossary() -> Glossary:
22
+ """Return a fresh glossary seeded with canonical types + micro-tokens.
23
+
24
+ Sigils are *not* added here; the caller picks the relevant sigil set
25
+ from :mod:`cortex.glossary.minimal` based on the template kind.
26
+ """
27
+
28
+ g = Glossary()
29
+ # Canonical types
30
+ for name, desc in [
31
+ ("attrs", "key:value pairs"),
32
+ ("attrs-pos", "positional with explicit contract"),
33
+ ("cuerpo", "free text body"),
34
+ ("bloque", "verbatim multiline block"),
35
+ ("relación", "causal A -> B form"),
36
+ ]:
37
+ g.add_type(TypeDef(name=name, description=desc))
38
+ # Canonical micro-tokens
39
+ for tok, val in CANONICAL_MICRO.items():
40
+ g.add_micro(MicroDef(token=tok, value=val))
41
+ return g
42
+
43
+
44
+ def add_sigil(glossary: Glossary, sigil: SigilDef) -> None:
45
+ """Add a sigil, rejecting silent redefinition of existing ones."""
46
+
47
+ existing = glossary.sigils.get(sigil.sigil)
48
+ if existing is not None and existing.to_dict() != sigil.to_dict():
49
+ from ..core.errors import ProtectedSigilError
50
+ raise ProtectedSigilError(sigil.sigil)
51
+ glossary.add_sigil(sigil)
52
+
53
+
54
+ def add_micro(glossary: Glossary, micro: MicroDef) -> None:
55
+ existing = glossary.micro.get(micro.token)
56
+ if existing is not None and existing.value != micro.value:
57
+ from ..core.errors import CortexError
58
+ raise CortexError(
59
+ "E021_INVALID_VALUE",
60
+ f"micro-token {micro.token!r} already declared with value {existing.value!r}",
61
+ )
62
+ glossary.add_micro(micro)
63
+
64
+
65
+ def add_contract(glossary: Glossary, contract: AttrsPosContract) -> None:
66
+ glossary.add_contract(contract)
67
+
68
+
69
+ def sigils_in_use(glossary: Glossary, entries: Iterable) -> dict:
70
+ """Return ``{sigil: count}`` for sigils used by ``entries``."""
71
+
72
+ counts: dict = {}
73
+ for e in entries:
74
+ if e.sigil in {"GSIG", "GTYP", "GMIC", "GCON"}:
75
+ continue
76
+ counts[e.sigil] = counts.get(e.sigil, 0) + 1
77
+ return counts
@@ -0,0 +1,96 @@
1
+ """Glossary resolver — runtime queries over a :class:`Glossary`.
2
+
3
+ Used by renderers, the validator and the CRUD layer to answer:
4
+ - "what is the type of sigil X?"
5
+ - "is this sigil declared?"
6
+ - "does this sigil have a positional contract?"
7
+ - "what is the expansion of this micro-token?"
8
+ - "is this token used by any entry?"
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Iterable, Optional
14
+
15
+ from ..core.ast import Entry, Glossary
16
+ from ..core.errors import CANONICAL_SIGILS
17
+
18
+
19
+ def is_canonical(sigil: str) -> bool:
20
+ return sigil in CANONICAL_SIGILS
21
+
22
+
23
+ def is_declared(glossary: Glossary, sigil: str) -> bool:
24
+ return sigil in glossary.sigils
25
+
26
+
27
+ def type_of(glossary: Glossary, sigil: str) -> Optional[str]:
28
+ sd = glossary.sigils.get(sigil)
29
+ return sd.type if sd else None
30
+
31
+
32
+ def contract_of(glossary: Glossary, sigil: str):
33
+ return glossary.contracts.get(sigil)
34
+
35
+
36
+ def expand_micro(glossary: Glossary, value: str) -> str:
37
+ """Expand micro-tokens in ``value`` if they are properly delimited.
38
+
39
+ Delimiters recognised: whitespace, ``,``, ``{``, ``}``, start/end.
40
+ Tokens inside words (e.g. ``param_cur``) are NOT expanded.
41
+ """
42
+
43
+ if not isinstance(value, str):
44
+ return value
45
+ out = []
46
+ i = 0
47
+ n = len(value)
48
+ while i < n:
49
+ ch = value[i]
50
+ if ch.isalnum() or ch == "_":
51
+ # consume identifier
52
+ j = i
53
+ while j < n and (value[j].isalnum() or value[j] == "_"):
54
+ j += 1
55
+ word = value[i:j]
56
+ # check if word matches a micro-token AND is delimited
57
+ prev_ch = value[i - 1] if i > 0 else ""
58
+ next_ch = value[j] if j < n else ""
59
+ left_delim = (prev_ch == "" or prev_ch in " ,{}\n\t")
60
+ right_delim = (next_ch == "" or next_ch in " ,{}\n\t")
61
+ if left_delim and right_delim and word in glossary.micro:
62
+ out.append(glossary.micro[word].value)
63
+ else:
64
+ out.append(word)
65
+ i = j
66
+ else:
67
+ out.append(ch)
68
+ i += 1
69
+ return "".join(out)
70
+
71
+
72
+ def sigil_usage_count(entries: Iterable[Entry]) -> dict:
73
+ counts: dict = {}
74
+ for e in entries:
75
+ if e.sigil in {"GSIG", "GTYP", "GMIC", "GCON"}:
76
+ continue
77
+ counts[e.sigil] = counts.get(e.sigil, 0) + 1
78
+ return counts
79
+
80
+
81
+ def is_micro_used(entries: Iterable[Entry], token: str) -> bool:
82
+ """Return True if any entry's value contains the micro-token.
83
+
84
+ Conservative check: scans string values for delimited occurrences.
85
+ """
86
+
87
+ for e in entries:
88
+ if e.type == "bloque":
89
+ continue # micro-tokens never expand inside bloque
90
+ if isinstance(e.value, dict):
91
+ for v in e.value.values():
92
+ if isinstance(v, str) and token in v.split():
93
+ return True
94
+ elif isinstance(e.value, str) and token in e.value.split():
95
+ return True
96
+ return False
@@ -0,0 +1,35 @@
1
+ """HCORTEX package — READ renderer, EDIT renderer, EDIT parser, profiles, recovery."""
2
+
3
+ from .profiles import (
4
+ Profile, PROFILES, DEFAULT_PROFILE,
5
+ resolve_profile, classify_entry, classify_doc,
6
+ filter_by_profile, sort_by_plevel, plevel_rank,
7
+ )
8
+ from .read_renderer import render_hcortex_read
9
+ from .edit_renderer import render_hcortex_edit
10
+ from .edit_parser import parse_hcortex_edit, parse_glossary_block
11
+ from .markdown_model import (
12
+ HCORTEX_READ_HEADER, HCORTEX_EDIT_HEADER,
13
+ EditHeader, is_hcortex_read, is_hcortex_edit,
14
+ )
15
+ from .recovery import (
16
+ RecoveryResult, recover_cortex, strip_preamble,
17
+ normalise_legacy_type_name, LEGACY_TYPE_ALIASES, LEGACY_COLUMN_ALIASES,
18
+ )
19
+
20
+ __all__ = [
21
+ # Profiles and priority classifier
22
+ "Profile", "PROFILES", "DEFAULT_PROFILE",
23
+ "resolve_profile", "classify_entry", "classify_doc",
24
+ "filter_by_profile", "sort_by_plevel", "plevel_rank",
25
+ # Renderers
26
+ "render_hcortex_read", "render_hcortex_edit",
27
+ # Parser
28
+ "parse_hcortex_edit", "parse_glossary_block",
29
+ # Markdown model
30
+ "HCORTEX_READ_HEADER", "HCORTEX_EDIT_HEADER",
31
+ "EditHeader", "is_hcortex_read", "is_hcortex_edit",
32
+ # Recovery
33
+ "RecoveryResult", "recover_cortex", "strip_preamble",
34
+ "normalise_legacy_type_name", "LEGACY_TYPE_ALIASES", "LEGACY_COLUMN_ALIASES",
35
+ ]