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
@@ -0,0 +1,249 @@
1
+ """Holographic working memory — compress top-k facts into a single HRR.
2
+
3
+ The strategic plan calls for compressing the top-k retrieved facts
4
+ into a single HRR superposition injected into the LLM system prompt.
5
+ The LLM unbinds specific facts on demand. This is a 5-10× token
6
+ reduction for the context window.
7
+
8
+ Mechanism (VSA / HRR algebra, Plate 1995):
9
+ - For each fact (S, R, V), compute its binding:
10
+ fact_holo = bind(S, role_vec("S")) + bind(R, role_vec("R"))
11
+ + bind(V, role_vec("V"))
12
+ where each component is the L2-normalized embedding of the
13
+ fact's subject / relation / value text, and `bind` is the VSA's
14
+ role-seeded permutation (mode="perm") or circular-convolution
15
+ (mode="conv").
16
+ - The full working memory hologram is the normalized superposition
17
+ of all fact_holo vectors. Adding more facts to the same superposition
18
+ is the standard HRR "memory" operation — every fact is added into
19
+ one vector, with overlap (cross-talk) controlled by the orthogonality
20
+ of the role vectors.
21
+
22
+ To RECALL a specific fact given a query, the LLM (or the host agent)
23
+ asks us to UNBIND — e.g. "what is Alice's job?" → we unbind the "S"
24
+ role on the hologram with role_vec("S") permuted against the query
25
+ "Alice", then nearest-neighbor lookup against the fact corpus. The
26
+ beauty of HRR is that this is a pure vector operation — no learned
27
+ weights, μ=0.
28
+
29
+ For the system-prompt injection use case we keep it simple:
30
+ - Compress top-k retrieved facts into one HRR vector + a short
31
+ textual preamble describing the available "fact slots" (S/R/V
32
+ bindings present).
33
+ - The LLM can ask us to "extract" a specific fact from the hologram
34
+ via the `extract_from_hologram` MCP tool / REST endpoint, which
35
+ does the unbind + nearest-neighbor lookup.
36
+
37
+ Net effect: instead of injecting 10 facts × ~30 tokens each = ~300
38
+ tokens into the system prompt, we inject ~30 tokens of preamble +
39
+ the HRR vector (which an LLM doesn't see directly — it sees the
40
+ preamble). The savings are on RETRIEVAL repetition across turns: a
41
+ chat with 10 turns that re-fetches the same 10 facts each turn saves
42
+ ~2700 tokens vs naive injection. HRR vectors are also constant-size
43
+ memory of arbitrary depth.
44
+
45
+ For now, we provide the compression + extraction primitives. The
46
+ agent-side "ask the hologram" loop is left to the host app; the
47
+ hologram is the substrate.
48
+ """
49
+ from __future__ import annotations
50
+
51
+ from dataclasses import dataclass, field
52
+ from typing import Iterable
53
+
54
+ import numpy as np
55
+
56
+
57
+ @dataclass
58
+ class HolographicWM:
59
+ """A compressed working-memory representation of top-k facts.
60
+
61
+ Attributes:
62
+ hrr: the superposed HRR vector (dims,). L2-normalized.
63
+ n_facts: how many facts were superposed.
64
+ roles_present: which role bindings are present (subset of
65
+ {"S","R","V"}). Lets the host LLM know what it can ask
66
+ the hologram to unbind.
67
+ fact_ids: list of fact ids that were superposed, in superposition
68
+ order. Used by extract_from_hologram to look up the answer
69
+ after unbinding.
70
+ preamble: a short textual description suitable for injection
71
+ into an LLM system prompt. ~30-50 tokens. Tells the LLM
72
+ "you have N facts compressed as a hologram; ask the
73
+ contextm_hologram_extract tool to recall any of them".
74
+ """
75
+ hrr: np.ndarray
76
+ n_facts: int
77
+ roles_present: set[str] = field(default_factory=set)
78
+ fact_ids: list[str] = field(default_factory=list)
79
+ preamble: str = ""
80
+
81
+ def to_dict(self) -> dict:
82
+ return {
83
+ "n_facts": self.n_facts,
84
+ "roles_present": sorted(self.roles_present),
85
+ "fact_ids": self.fact_ids,
86
+ "preamble": self.preamble,
87
+ # hrr vector is large; serialize as hex of packed bytes
88
+ # only when explicitly requested via to_dict_with_vec
89
+ }
90
+
91
+ def to_dict_with_vec(self) -> dict:
92
+ d = self.to_dict()
93
+ d["hrr_b64"] = _vec_to_b64(self.hrr)
94
+ return d
95
+
96
+
97
+ def _vec_to_b64(v: np.ndarray) -> str:
98
+ import base64
99
+ return base64.b64encode(v.tobytes()).decode("ascii")
100
+
101
+
102
+ def _vec_from_b64(s: str, dtype=np.float32) -> np.ndarray:
103
+ import base64
104
+ return np.frombuffer(base64.b64decode(s), dtype=dtype)
105
+
106
+
107
+ # ---------------------------------------------------------------------------
108
+ # Build / extract
109
+ # ---------------------------------------------------------------------------
110
+
111
+ def build_holographic_wm(facts: Iterable, vsa,
112
+ embedder, *, max_facts: int = 12,
113
+ roles: tuple[str, ...] = ("S", "R", "V"),
114
+ normalize: bool = True) -> HolographicWM:
115
+ """Compress top-k facts into a single HRR superposition.
116
+
117
+ Parameters
118
+ ----------
119
+ facts : iterable of fact-like objects with .subject, .relation,
120
+ .value, .id
121
+ vsa : a cortexm.vsa.ops.VSA instance (provides role_vec, bind,
122
+ superpose). The same instance the palace uses — ensures role
123
+ vectors match between encode and unbind.
124
+ embedder : a HashingEmbedder or compatible, for embedding the
125
+ subject/relation/value text.
126
+ max_facts : cap on the number of facts superposed. Beyond ~24 the
127
+ cross-talk noise starts to degrade extraction accuracy.
128
+ roles : which bindings to include in each fact hologram.
129
+
130
+ Returns a HolographicWM with the superposed HRR + metadata.
131
+ """
132
+ facts = list(facts)[:max_facts]
133
+ if not facts:
134
+ return HolographicWM(hrr=np.zeros(vsa.dims, dtype=np.float32),
135
+ n_facts=0, roles_present=set(),
136
+ fact_ids=[], preamble="(no facts in memory)")
137
+
138
+ roles_present: set[str] = set()
139
+ fact_ids: list[str] = []
140
+ acc = np.zeros(vsa.dims, dtype=np.float32)
141
+
142
+ for f in facts:
143
+ subj = getattr(f, "subject", "") or ""
144
+ rel = getattr(f, "relation", "") or ""
145
+ val = getattr(f, "value", "") or ""
146
+ fid = getattr(f, "id", "") or ""
147
+ fact_ids.append(fid)
148
+ # bind each component against its role vector
149
+ if "S" in roles and subj:
150
+ roles_present.add("S")
151
+ s_emb = embedder.embed(subj)
152
+ acc += vsa.bind("S", s_emb)
153
+ if "R" in roles and rel:
154
+ roles_present.add("R")
155
+ r_emb = embedder.embed(rel.replace("_", " "))
156
+ acc += vsa.bind("R", r_emb)
157
+ if "V" in roles and val:
158
+ roles_present.add("V")
159
+ v_emb = embedder.embed(val)
160
+ acc += vsa.bind("V", v_emb)
161
+
162
+ if normalize:
163
+ n = float(np.linalg.norm(acc))
164
+ if n > 0:
165
+ acc = acc / n
166
+
167
+ preamble = _build_preamble(facts, roles_present)
168
+ return HolographicWM(hrr=acc.astype(np.float32), n_facts=len(facts),
169
+ roles_present=roles_present,
170
+ fact_ids=fact_ids, preamble=preamble)
171
+
172
+
173
+ def extract_from_hologram(hwm: HolographicWM, role: str, query_vec,
174
+ vsa, candidate_embs: np.ndarray,
175
+ candidate_ids: list[str],
176
+ top_k: int = 3) -> list[tuple[str, float]]:
177
+ """Unbind a role from the hologram and nearest-neighbor lookup.
178
+
179
+ The classic HRR recall: given a hologram H and a role r, the
180
+ unbound vector U = unbind(r, H) is approximately the filler that
181
+ was bound to r in H (averaged across all superposed facts). We then
182
+ find the nearest neighbor of U in the candidate embedding matrix.
183
+
184
+ Parameters
185
+ ----------
186
+ hwm : the HolographicWM returned by build_holographic_wm
187
+ role : "S", "R", or "V" — which role to unbind
188
+ query_vec : NOT USED in this simple variant; kept for forward-compat
189
+ with a query-conditional unbind mode.
190
+ vsa : the same VSA instance used to build the hologram
191
+ candidate_embs : (N, dims) matrix of candidate fact-component embeddings
192
+ candidate_ids : list of N ids parallel to candidate_embs
193
+ top_k : how many candidates to return
194
+
195
+ Returns a list of (id, score) sorted desc by score. Empty if the
196
+ hologram is empty or role was not present at build time.
197
+ """
198
+ if hwm.n_facts == 0 or role not in hwm.roles_present:
199
+ return []
200
+ if candidate_embs is None or len(candidate_embs) == 0:
201
+ return []
202
+ unbound = vsa.unbind(role, hwm.hrr)
203
+ # cosine sim against every candidate (batched)
204
+ cands = np.asarray(candidate_embs, dtype=np.float32)
205
+ norms = np.linalg.norm(cands, axis=1) + 1e-9
206
+ sims = (cands @ unbound) / norms
207
+ # take top-k indices
208
+ if len(sims) <= top_k:
209
+ idxs = np.argsort(-sims)
210
+ else:
211
+ idxs = np.argpartition(-sims, top_k)[:top_k]
212
+ idxs = idxs[np.argsort(-sims[idxs])]
213
+ out = [(candidate_ids[i], float(sims[i])) for i in idxs]
214
+ return out
215
+
216
+
217
+ # ---------------------------------------------------------------------------
218
+ # Preamble builder — what gets injected into the LLM system prompt.
219
+ # ---------------------------------------------------------------------------
220
+
221
+ def _build_preamble(facts: list, roles_present: set[str]) -> str:
222
+ """Build a short (~30-50 token) LLM-ready description of the hologram.
223
+
224
+ The LLM sees this preamble and knows it can ask for unbind queries
225
+ against the hologram. The actual HRR vector is opaque to the LLM
226
+ (it's a vector, not text); the host app routes "what was Alice's
227
+ job?" type questions through the extract_from_hologram endpoint.
228
+ """
229
+ n = len(facts)
230
+ roles_str = "/".join(sorted(roles_present)) if roles_present else "none"
231
+ subjects = [getattr(f, "subject", "") for f in facts]
232
+ # dedupe subjects
233
+ seen = set()
234
+ unique_subjects = [s for s in subjects
235
+ if s and not (s in seen or seen.add(s))]
236
+ sub_str = ", ".join(unique_subjects[:5])
237
+ if len(unique_subjects) > 5:
238
+ sub_str += f", ... (+{len(unique_subjects) - 5} more)"
239
+ return (f"[Working Memory Hologram] {n} fact(s) compressed "
240
+ f"as HRR over roles ({roles_str}). Subjects: {sub_str}. "
241
+ f"Ask the contextm_hologram_extract tool to recall any "
242
+ f"specific (subject, relation) pair.")
243
+
244
+
245
+ __all__ = [
246
+ "HolographicWM",
247
+ "build_holographic_wm",
248
+ "extract_from_hologram",
249
+ ]