cortexm 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. context_m.py +17 -0
  2. cortexm/__init__.py +45 -0
  3. cortexm/accel.py +403 -0
  4. cortexm/api/__init__.py +0 -0
  5. cortexm/api/chaos.py +118 -0
  6. cortexm/api/memory.py +635 -0
  7. cortexm/bench/__init__.py +0 -0
  8. cortexm/bench/abilities.py +311 -0
  9. cortexm/bench/baselines.py +89 -0
  10. cortexm/bench/beam_loader.py +317 -0
  11. cortexm/bench/generator.py +376 -0
  12. cortexm/bench/harness.py +211 -0
  13. cortexm/bench/messy.py +218 -0
  14. cortexm/bench/micro.py +251 -0
  15. cortexm/bench/ood.py +443 -0
  16. cortexm/bench/run.py +137 -0
  17. cortexm/bridge/__init__.py +0 -0
  18. cortexm/bridge/dates.py +178 -0
  19. cortexm/bridge/decoders.py +204 -0
  20. cortexm/bridge/enrich.py +255 -0
  21. cortexm/bridge/extractor.py +316 -0
  22. cortexm/bridge/fallback.py +332 -0
  23. cortexm/bridge/onnx_runtime.py +158 -0
  24. cortexm/bridge/patterns.py +760 -0
  25. cortexm/bridge/ppr.py +104 -0
  26. cortexm/bridge/prefilter.py +188 -0
  27. cortexm/bridge/query_extract.py +420 -0
  28. cortexm/bridge/reader.py +1174 -0
  29. cortexm/bridge/rerank.py +204 -0
  30. cortexm/bridge/writer.py +492 -0
  31. cortexm/cli.py +295 -0
  32. cortexm/cognition/__init__.py +53 -0
  33. cortexm/cognition/abstraction.py +192 -0
  34. cortexm/cognition/analogy.py +159 -0
  35. cortexm/cognition/engine.py +204 -0
  36. cortexm/cognition/gaps.py +365 -0
  37. cortexm/cognition/scanner.py +204 -0
  38. cortexm/config.py +375 -0
  39. cortexm/cortexm.py +8 -0
  40. cortexm/enterprise/__init__.py +0 -0
  41. cortexm/enterprise/audit.py +178 -0
  42. cortexm/enterprise/governance.py +239 -0
  43. cortexm/errors.py +35 -0
  44. cortexm/features/__init__.py +0 -0
  45. cortexm/features/git.py +204 -0
  46. cortexm/features/prefetch.py +88 -0
  47. cortexm/features/zk.py +105 -0
  48. cortexm/federation/__init__.py +39 -0
  49. cortexm/federation/crdt.py +275 -0
  50. cortexm/federation/fabric.py +109 -0
  51. cortexm/federation/hlc.py +80 -0
  52. cortexm/federation/node.py +145 -0
  53. cortexm/federation/schema_report.py +73 -0
  54. cortexm/federation/transport.py +164 -0
  55. cortexm/index/__init__.py +19 -0
  56. cortexm/index/nsg.py +386 -0
  57. cortexm/mcp/__init__.py +0 -0
  58. cortexm/mcp/server.py +985 -0
  59. cortexm/metrics.py +62 -0
  60. cortexm/migrate/__init__.py +0 -0
  61. cortexm/migrate/importers.py +192 -0
  62. cortexm/provenance/__init__.py +78 -0
  63. cortexm/provenance/agent.py +214 -0
  64. cortexm/provenance/cose.py +201 -0
  65. cortexm/provenance/scitt.py +258 -0
  66. cortexm/provenance/vc.py +250 -0
  67. cortexm/security/__init__.py +0 -0
  68. cortexm/security/crypto.py +162 -0
  69. cortexm/security/hashes.py +140 -0
  70. cortexm/security/injection.py +149 -0
  71. cortexm/security/mind.py +154 -0
  72. cortexm/security/pii.py +265 -0
  73. cortexm/security/rbac.py +169 -0
  74. cortexm/security/sandbox.py +131 -0
  75. cortexm/security/zk_hamming.py +142 -0
  76. cortexm/security/zk_sql.py +485 -0
  77. cortexm/server/__init__.py +0 -0
  78. cortexm/server/metrics.py +88 -0
  79. cortexm/server/rest.py +936 -0
  80. cortexm/server/sparql.py +984 -0
  81. cortexm/text/__init__.py +0 -0
  82. cortexm/text/dissim.py +252 -0
  83. cortexm/text/embedder.py +155 -0
  84. cortexm/text/fuzzy.py +218 -0
  85. cortexm/text/idiolect.py +253 -0
  86. cortexm/text/labse.py +374 -0
  87. cortexm/text/tokenizer.py +79 -0
  88. cortexm/trace/__init__.py +0 -0
  89. cortexm/trace/blob_arena.py +277 -0
  90. cortexm/trace/consolidate.py +337 -0
  91. cortexm/trace/contradictions.py +69 -0
  92. cortexm/trace/dedup.py +114 -0
  93. cortexm/trace/edges.py +214 -0
  94. cortexm/trace/fact.py +121 -0
  95. cortexm/trace/fade.py +245 -0
  96. cortexm/trace/lifecycle.py +112 -0
  97. cortexm/trace/rebuild.py +173 -0
  98. cortexm/trace/rules.py +171 -0
  99. cortexm/trace/store.py +680 -0
  100. cortexm/trace/structural.py +183 -0
  101. cortexm/trace/tmt.py +335 -0
  102. cortexm/util.py +148 -0
  103. cortexm/vsa/__init__.py +0 -0
  104. cortexm/vsa/attribution.py +149 -0
  105. cortexm/vsa/cleanup.py +161 -0
  106. cortexm/vsa/codecs.py +397 -0
  107. cortexm/vsa/hologram_overlay.py +139 -0
  108. cortexm/vsa/index.py +163 -0
  109. cortexm/vsa/ops.py +149 -0
  110. cortexm/vsa/palace.py +446 -0
  111. cortexm/vsa/role_vectors.py +236 -0
  112. cortexm/vsa/slb.py +78 -0
  113. cortexm/vsa/tlsh_trie.py +137 -0
  114. cortexm/vsa/working_memory.py +249 -0
  115. cortexm-0.3.0.dist-info/METADATA +482 -0
  116. cortexm-0.3.0.dist-info/RECORD +120 -0
  117. cortexm-0.3.0.dist-info/WHEEL +5 -0
  118. cortexm-0.3.0.dist-info/entry_points.txt +2 -0
  119. cortexm-0.3.0.dist-info/licenses/LICENSE +190 -0
  120. cortexm-0.3.0.dist-info/top_level.txt +2 -0
cortexm/trace/rules.py ADDED
@@ -0,0 +1,171 @@
1
+ """Datalog-lite rules engine — deterministic forward chaining.
2
+
3
+ The plan specifies a lightweight Datalog engine (not CLIPS) for
4
+ forward-chaining over the Trace. Rules use a tiny Datalog syntax::
5
+
6
+ head(X, Y) :- body1(X, Z), body2(Z, Y).
7
+
8
+ An atom ``rel(a, b)`` denotes the fact triple ``(a, rel, b)``.
9
+ Uppercase-initial tokens are variables. The engine joins body atoms
10
+ over active facts and materializes derived facts (``is_derived=True``)
11
+ which are themselves indexed in the VSA palace — inference bound into
12
+ the neuro-symbolic bridge, not bolted on.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import datetime as _dt
18
+ import re
19
+ from dataclasses import dataclass
20
+
21
+ from cortexm.trace.fact import Fact
22
+ from cortexm.trace.store import TraceStore
23
+ from cortexm.util import iso, new_id
24
+
25
+ RULE_RE = re.compile(r"^([\w]+)\s*\(([^)]*)\)\s*:-\s*(.+)$")
26
+ ATOM_RE = re.compile(r"([\w]+)\s*\(([^)]*)\)")
27
+ Arg = str
28
+ Atom = tuple[str, Arg, Arg] # (relation, subject_arg, value_arg)
29
+
30
+
31
+ def _mk_atom(rel: str, args: str) -> Atom:
32
+ parts = [p.strip() for p in args.split(",") if p.strip()]
33
+ if len(parts) == 1:
34
+ return (rel, parts[0], "_")
35
+ if len(parts) == 2:
36
+ return (rel, parts[0], parts[1])
37
+ # 3-arg form: rel(subject, relation, value) — relation arg must equal rel
38
+ return (rel, parts[0], parts[2])
39
+
40
+
41
+ def parse_rule(text: str) -> "Rule":
42
+ text = text.strip().rstrip(".")
43
+ m = RULE_RE.match(text)
44
+ if not m:
45
+ raise ValueError(f"invalid rule: {text!r}")
46
+ head = _mk_atom(m.group(1), m.group(2))
47
+ body = [_mk_atom(a.group(1), a.group(2)) for a in ATOM_RE.finditer(m.group(3))]
48
+ if not body:
49
+ raise ValueError(f"rule with empty body: {text!r}")
50
+ return Rule(head=head, body=body, source=text)
51
+
52
+
53
+ @dataclass
54
+ class Rule:
55
+ head: Atom
56
+ body: list[Atom]
57
+ source: str = ""
58
+
59
+ def render(self) -> str:
60
+ def atom(a):
61
+ return f"{a[0]}({a[1]}, {a[2]})"
62
+ return f"{atom(self.head)} :- {', '.join(atom(b) for b in self.body)}."
63
+
64
+
65
+ DEFAULT_RULES = [
66
+ parse_rule("reports_to(X, Y) :- manages(Y, X)."),
67
+ parse_rule("team_uses(X, L) :- member_of(X, T), uses(T, L)."),
68
+ parse_rule("lives_in(X, C) :- moved_to(X, C)."),
69
+ parse_rule("same_person(N, X) :- alias(X, N)."),
70
+ ]
71
+
72
+
73
+ class RuleEngine:
74
+ def __init__(self, store: TraceStore, rules: list[Rule] | None = None) -> None:
75
+ self.store = store
76
+ self.rules = rules if rules is not None else list(DEFAULT_RULES)
77
+ self._rel_cache: dict[str, list[Fact]] = {}
78
+
79
+ def _facts_of(self, rel: str) -> list[Fact]:
80
+ if rel not in self._rel_cache:
81
+ self._rel_cache[rel] = self.store.query_facts(relation=rel, active=True,
82
+ derived=False)
83
+ return self._rel_cache[rel]
84
+
85
+ def _join(self, rule: Rule) -> list[dict[str, str]]:
86
+ bindings: list[dict[str, str]] = [{}]
87
+ atoms = sorted(rule.body, key=lambda a: len(self._facts_of(a[0])))
88
+ for rel, s_arg, v_arg in atoms:
89
+ nxt: list[dict[str, str]] = []
90
+ for b in bindings:
91
+ for f in self._facts_of(rel):
92
+ # scope isolation: a rule joins premises from ONE user
93
+ # scope (None = global premise may join any scope).
94
+ bu = b.get("_user")
95
+ if bu is not None and f.user_id not in (None, bu):
96
+ continue
97
+ nb = dict(b)
98
+ if not self._bind(nb, s_arg, f.subject):
99
+ continue
100
+ if not self._bind(nb, v_arg, f.value):
101
+ continue
102
+ if f.user_id is not None:
103
+ nb["_user"] = f.user_id
104
+ nxt.append(nb)
105
+ bindings = nxt
106
+ if not bindings:
107
+ break
108
+ return bindings
109
+
110
+ @staticmethod
111
+ def _bind(b: dict[str, str], arg: str, val: str) -> bool:
112
+ if arg == "_":
113
+ return True
114
+ if arg[0].isupper():
115
+ if arg in b and b[arg] != val:
116
+ return False
117
+ b[arg] = val
118
+ return True
119
+ return arg == val
120
+
121
+ def _subst(self, head: Atom, b: dict[str, str]) -> tuple[str, str, str] | None:
122
+ rel, s_arg, v_arg = head
123
+ s = b.get(s_arg) if s_arg[0:1].isupper() else (s_arg if s_arg != "_" else None)
124
+ v = b.get(v_arg) if v_arg[0:1].isupper() else (v_arg if v_arg != "_" else None)
125
+ if not s or not v:
126
+ return None
127
+ return (s, rel, v)
128
+
129
+ def apply(self, now: _dt.datetime | None = None, max_iterations: int = 3) -> list[Fact]:
130
+ """Run rules to fixpoint; return newly derived facts.
131
+
132
+ Derived facts inherit the USER SCOPE of their premises — without
133
+ this, ``team_uses(X, L) :- member_of(X, T), uses(T, L)`` derives a
134
+ fact under ``default`` that user0's reader can never see (scope
135
+ filter drops it), silently losing every multi-hop answer."""
136
+ now = now or _dt.datetime.now(_dt.timezone.utc)
137
+ derived_new: list[Fact] = []
138
+ seen: set[tuple] = set()
139
+ for _ in range(max_iterations):
140
+ added = 0
141
+ for rule in self.rules:
142
+ for b in self._join(rule):
143
+ sub = self._subst(rule.head, b)
144
+ if not sub:
145
+ continue
146
+ scope = b.get("_user") or "default"
147
+ s, rel, v = sub
148
+ key = (s, rel, v, scope)
149
+ if key in seen:
150
+ continue
151
+ seen.add(key)
152
+ if self.store.query_facts(subject=s, relation=rel, value=v,
153
+ user_id=scope, active=True):
154
+ continue
155
+ f = Fact(
156
+ id=new_id(), subject=s, relation=rel, value=v,
157
+ valid_from=iso(now)[:10], tx_from=iso(now),
158
+ user_id=scope,
159
+ confidence=0.75, memory_type="long_term",
160
+ is_derived=True,
161
+ provenance={"rule": rule.source, "bindings": b})
162
+ self.store.insert_fact(f)
163
+ derived_new.append(f)
164
+ self._rel_cache.pop(rel, None)
165
+ added += 1
166
+ if added == 0:
167
+ break
168
+ return derived_new
169
+
170
+ def invalidate(self) -> None:
171
+ self._rel_cache.clear()