anima-python 0.13.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.
@@ -0,0 +1,129 @@
1
+ # ==========================================================================
2
+ # ⛔ ENGINE-INTERNAL / DEPRECATED py-MIRROR — DO NOT RUN OR SCORE DIRECTLY
3
+ # 측정/학습/서빙/직렬화는 cli/ 단일진입만: anima eval | train | serialize
4
+ # (canonical = hexa core/*.hexa 단일 SSOT; py 미러는 2026-06-28 폐기, DIRECTIONAL).
5
+ # 이 파일을 `python3 core/engine_g.py` 로 직접 실행하거나 side-harness로 import-채점하면
6
+ # = 단일진입 우회(#2603 위반) + terminal verdict 불가. cli/가 import하는 경로만 허용.
7
+ # ==========================================================================
8
+ import sys as _anima_entry_guard
9
+ if __name__ == "__main__":
10
+ _anima_entry_guard.exit("⛔ engine_g.py 직접 실행 금지 — cli/ 단일진입(anima eval/train/serialize, canonical=hexa) 경유. #2603")
11
+
12
+ """core/engine_g.py — PY PRODUCTION ENGINE: byte-faithful 1:1 port of
13
+ core/engine_g.hexa (Engine G — motivation + emit gate).
14
+
15
+ Per CLAUDE.md a_two_production_mirror. Closed-form spontaneous machinery: the
16
+ 8-factor weighted motivation_score + emit/safety predicates. Values are
17
+ byte-identical to the anima_alive PROACTIVE_THRESHOLD / weights (sum=1.0) lineage,
18
+ so CORE and the chat daemon share one behaviour. brain.py couples this (G) with
19
+ Engine A (pure_field.py). No external math builtins — pure float arithmetic.
20
+ """
21
+
22
+ # ── thresholds (anima_alive carry) ──
23
+ def spont_im_threshold():
24
+ return 0.3 # PROACTIVE_THRESHOLD
25
+
26
+
27
+ def spont_interrupt_threshold():
28
+ return 0.6 # talker interrupt
29
+
30
+
31
+ def spont_idle_speak_after():
32
+ return 30.0 # IDLE_SPEAK_AFTER
33
+
34
+
35
+ def spont_min_emit_interval():
36
+ return 30.0 # rate-limit convention
37
+
38
+
39
+ # ── 8 weights (sum = 1.00 closed conservation) ──
40
+ def spont_weight_relevance():
41
+ return 0.20
42
+
43
+
44
+ def spont_weight_info_gap():
45
+ return 0.10
46
+
47
+
48
+ def spont_weight_curiosity():
49
+ return 0.15
50
+
51
+
52
+ def spont_weight_pain():
53
+ return 0.10
54
+
55
+
56
+ def spont_weight_coherence():
57
+ return 0.10
58
+
59
+
60
+ def spont_weight_originality():
61
+ return 0.10
62
+
63
+
64
+ def spont_weight_balance():
65
+ return 0.15
66
+
67
+
68
+ def spont_weight_dynamics():
69
+ return 0.10
70
+
71
+
72
+ # ── motivation_score (linear weighted sum) ──
73
+ def motivation_score(rel, gap, cur, pain, coh, orig, bal, dyn_v):
74
+ return (spont_weight_relevance() * rel
75
+ + spont_weight_info_gap() * gap
76
+ + spont_weight_curiosity() * cur
77
+ + spont_weight_pain() * pain
78
+ + spont_weight_coherence() * coh
79
+ + spont_weight_originality() * orig
80
+ + spont_weight_balance() * bal
81
+ + spont_weight_dynamics() * dyn_v)
82
+
83
+
84
+ # ── emission predicates ──
85
+ def should_emit(score):
86
+ return score > spont_im_threshold()
87
+
88
+
89
+ def should_interrupt(score):
90
+ return score > spont_interrupt_threshold()
91
+
92
+
93
+ # ── safety predicates (4-way AND closure) ──
94
+ def safety_kill_switch_on(env_off):
95
+ return env_off == False
96
+
97
+
98
+ def safety_rate_limit_ok(seconds_since_last):
99
+ return seconds_since_last >= spont_min_emit_interval()
100
+
101
+
102
+ def safety_phi_ratchet_ok(phi, ratchet):
103
+ """Engine A's live Φ vs its ratchet peak (the A->G coupling gate)."""
104
+ return phi > ratchet / 2.0
105
+
106
+
107
+ def safety_content_ok(content_clean):
108
+ return content_clean
109
+
110
+
111
+ def safety_combined(kill, rate, phi_r, content):
112
+ return kill and rate and phi_r and content
113
+
114
+
115
+ if __name__ == "__main__":
116
+ # smoke: 8-factor score + predicates (matches _eg_parity.hexa oracle).
117
+ lo = motivation_score(0.1, 0.0, 0.0, 0.0, 0.1, 0.0, 0.1, 0.0)
118
+ hi = motivation_score(0.9, 0.6, 0.8, 0.0, 0.7, 0.5, 0.6, 1.0)
119
+ mid = motivation_score(0.5, 0.3, 0.2, 0.0, 0.4, 0.2, 0.3, 0.2)
120
+ print("score_lo=%.17g" % lo)
121
+ print("score_hi=%.17g" % hi)
122
+ print("score_mid=%.17g" % mid)
123
+ print("emit_lo=%s" % str(should_emit(lo)).lower())
124
+ print("emit_hi=%s" % str(should_emit(hi)).lower())
125
+ print("interrupt_hi=%s" % str(should_interrupt(hi)).lower())
126
+ print("rate_5=%s" % str(safety_rate_limit_ok(5.0)).lower())
127
+ print("rate_60=%s" % str(safety_rate_limit_ok(60.0)).lower())
128
+ print("phi_ratchet=%s" % str(safety_phi_ratchet_ok(0.118, 0.148)).lower())
129
+ print("combined=%s" % str(safety_combined(True, True, True, True)).lower())
@@ -0,0 +1,318 @@
1
+ # ==========================================================================
2
+ # ⛔ ENGINE-INTERNAL / DEPRECATED py-MIRROR — DO NOT RUN OR SCORE DIRECTLY
3
+ # 측정/학습/서빙/직렬화는 cli/ 단일진입만: anima eval | train | serialize
4
+ # (canonical = hexa core/*.hexa 단일 SSOT; py 미러는 2026-06-28 폐기, DIRECTIONAL).
5
+ # 이 파일을 `python3 core/generator.py` 로 직접 실행하거나 side-harness로 import-채점하면
6
+ # = 단일진입 우회(#2603 위반) + terminal verdict 불가. cli/가 import하는 경로만 허용.
7
+ # ==========================================================================
8
+ import sys as _anima_entry_guard
9
+ if __name__ == "__main__":
10
+ _anima_entry_guard.exit("⛔ generator.py 직접 실행 금지 — cli/ 단일진입(anima eval/train/serialize, canonical=hexa) 경유. #2603")
11
+
12
+ """core/generator.py — PY PRODUCTION ENGINE: byte-faithful 1:1 mirror of the
13
+ L3 MOUTH-DISPATCH surface of core/generator.hexa.
14
+
15
+ Per CLAUDE.md a_two_production_mirror / a_core_engine_map: hexa + py are TWO
16
+ co-equal production engines kept at byte-parity. generator.hexa is the SINGLE L3
17
+ typed mouth slot — it sniffs a ckpt header and dispatches to ONE of two mouth
18
+ ARCHITECTURES (conv .clm via the CONV mouth, ByteGPT .bin via the BYTE mouth). This
19
+ module is the py mirror of that dispatcher; it routes to the already-parity-proven
20
+ core/decode.py (the unified decoder that merges the former clm_decode.py +
21
+ bytegpt_decode.py 1:1, itself a port of core/decode.hexa). NO torch in the path —
22
+ stdlib + numpy (via the decoder) only.
23
+
24
+ Scope: this mirrors generator.hexa's PUBLIC dispatch surface (a_core_engine_map):
25
+ gen_mouth_kind generator.hexa:628 header-sniff CLM\\x01 / 5xu32 / unknown
26
+ gen_auto_backend generator.hexa:641 -> gen_bytegpt_backend | gen_clm_backend
27
+ gen_auto_chat generator.hexa:684 -> gen_bytegpt_chat | gen_clm_chat
28
+ gen_auto_ideate generator.hexa:750 -> gen_bytegpt_ideate | gen_clm_ideate
29
+ plus the per-architecture single entries each dispatcher picks between:
30
+ gen_null_backend :74 gen_clm_backend :101 gen_bytegpt_backend :175
31
+ gen_clm_chat :599 gen_bytegpt_chat :664
32
+ gen_clm_ideate :697 gen_clm_ideate_W :713 gen_bytegpt_ideate :728
33
+ and the header helpers they reuse:
34
+ _gen_is_bytegpt :148 _gen_clm_probe_header :224 _gen_rd_u32 :792
35
+
36
+ NOTE the sniff is reproduced VERBATIM from generator.hexa (NOT the looser ranges
37
+ in decode.bg_is_bytegpt): generator.hexa::_gen_is_bytegpt requires
38
+ vocab==256, n_layer in 1..64, n_head divides d, block in 1..8192 — these tighter
39
+ bounds are the dispatcher's actual edge-case behavior and must be mirrored exactly.
40
+
41
+ The VERDICT path stays engine-native (hexa); this is the parity-proven py mirror.
42
+ """
43
+
44
+ import os
45
+ import sys
46
+
47
+ _HERE = os.path.dirname(os.path.abspath(__file__))
48
+ if _HERE not in sys.path:
49
+ sys.path.insert(0, _HERE)
50
+
51
+ import decode as _clm # core/decode.py (unified) — ConvMoE .clm mouth API
52
+ import decode as _bg # same module; both aliases resolve the union public API (ByteGPT .bin mouth)
53
+
54
+
55
+ # ════════════════════════════════════════════════════════════════════════
56
+ # header helpers — 1:1 from generator.hexa
57
+ # ════════════════════════════════════════════════════════════════════════
58
+
59
+ def _gen_rd_u32(rb, off):
60
+ """generator.hexa:792 _gen_rd_u32 — little-endian u32 from a byte buffer."""
61
+ return rb[off] + rb[off + 1] * 0x100 + rb[off + 2] * 0x10000 + rb[off + 3] * 0x1000000
62
+
63
+
64
+ def _gen_path_is_file(p):
65
+ """generator.hexa:245 _gen_path_is_file — empty path -> false, else isfile."""
66
+ if len(p) == 0:
67
+ return False
68
+ return os.path.isfile(p)
69
+
70
+
71
+ def _gen_is_bytegpt(p):
72
+ """generator.hexa:148 _gen_is_bytegpt — true iff `p` is a ByteGPT flat binary,
73
+ NOT a .clm. Reject the CLM\\x01 magic; then require a SANE 5xu32 header:
74
+ vocab==256, n_layer in 1..64, n_head divides d, block in 1..8192. Edge-safe
75
+ (missing/short file -> false). Bounds are tighter than decode.bg_is_bytegpt;
76
+ these are the dispatcher's verbatim discriminator (mirror exactly)."""
77
+ if len(p) == 0:
78
+ return False
79
+ if not _gen_path_is_file(p):
80
+ return False
81
+ try:
82
+ rb = open(p, 'rb').read()
83
+ except Exception:
84
+ return False
85
+ if len(rb) < 20:
86
+ return False
87
+ # reject the .clm magic outright (CLM\x01 = 67,76,77,1)
88
+ if rb[0] == 67 and rb[1] == 76 and rb[2] == 77 and rb[3] == 1:
89
+ return False
90
+ vocab = _gen_rd_u32(rb, 0)
91
+ d = _gen_rd_u32(rb, 4)
92
+ nlay = _gen_rd_u32(rb, 8)
93
+ nh = _gen_rd_u32(rb, 12)
94
+ block = _gen_rd_u32(rb, 16)
95
+ if vocab != 256:
96
+ return False
97
+ if nlay < 1 or nlay > 64:
98
+ return False
99
+ if nh < 1 or d < 1:
100
+ return False
101
+ if (d // nh) * nh != d: # n_head must divide d
102
+ return False
103
+ if block < 1 or block > 8192:
104
+ return False
105
+ return True
106
+
107
+
108
+ def _gen_clm_probe_header(p):
109
+ """generator.hexa:224 _gen_clm_probe_header — verify the CLM\\x01 header.
110
+ Returns {exists, valid, nblocks}. Edge-safe: missing/empty/truncated -> valid=False."""
111
+ if len(p) == 0:
112
+ return {"exists": False, "valid": False, "nblocks": 0}
113
+ if not _gen_path_is_file(p):
114
+ return {"exists": False, "valid": False, "nblocks": 0}
115
+ rb = open(p, 'rb').read()
116
+ # need at least MAGIC(4) + nblocks(1) = 5 bytes
117
+ if len(rb) < 5:
118
+ return {"exists": True, "valid": False, "nblocks": 0}
119
+ magic_ok = rb[0] == 67 and rb[1] == 76 and rb[2] == 77 and rb[3] == 1
120
+ if not magic_ok:
121
+ return {"exists": True, "valid": False, "nblocks": 0}
122
+ nblocks = rb[4]
123
+ return {"exists": True, "valid": True, "nblocks": nblocks}
124
+
125
+
126
+ # ════════════════════════════════════════════════════════════════════════
127
+ # §1 backend constructors (the pluggable "vtable" records)
128
+ # ════════════════════════════════════════════════════════════════════════
129
+
130
+ def gen_null_backend():
131
+ """generator.hexa:74 gen_null_backend — always-ready deterministic placeholder."""
132
+ return {"kind": "null", "loaded": True, "ckpt": ""}
133
+
134
+
135
+ def gen_clm_backend(ckpt_path):
136
+ """generator.hexa:101 gen_clm_backend — parse the .clm header at the single L3
137
+ entry; surface loaded (header admit) + decodable (v0.2 CLMX trailer present)."""
138
+ probe = _gen_clm_probe_header(ckpt_path)
139
+ exists = probe["exists"]
140
+ valid = probe["valid"]
141
+ nblk = probe["nblocks"]
142
+ loaded = valid
143
+ decodable = valid and _clm.clm_decodable(ckpt_path)
144
+ if not exists:
145
+ reason = "no ckpt at path"
146
+ elif not valid:
147
+ reason = "file present but not a valid .clm (bad CLM\\x01 magic)"
148
+ else:
149
+ reason = ("valid .clm admitted + LOADED (magic+structure OK, nblocks="
150
+ + str(nblk)
151
+ + "); decode forward LANDED + descends CORE-mounted at d=768 (loaded=valid)")
152
+ return {"kind": "clm", "loaded": loaded, "decodable": decodable, "valid": valid,
153
+ "ckpt": ckpt_path, "ckpt_exists": exists, "nblocks": nblk, "reason": reason}
154
+
155
+
156
+ def gen_bytegpt_backend(ckpt_path):
157
+ """generator.hexa:175 gen_bytegpt_backend — parse the 5xu32 ByteGPT header at the
158
+ single L3 entry. ByteGPT-format file => valid+loaded+decodable=True; else honest
159
+ rejection (valid=False) so generate() falls through to null (no garbage)."""
160
+ if not _gen_is_bytegpt(ckpt_path):
161
+ exists = _gen_path_is_file(ckpt_path)
162
+ reason = ("no ckpt at path" if not exists
163
+ else "file present but not a ByteGPT flat binary (bad 5xu32 header)")
164
+ return {"kind": "bytegpt", "loaded": False, "decodable": False, "valid": False,
165
+ "ckpt": ckpt_path, "ckpt_exists": exists, "nlayer": 0, "d": 0, "reason": reason}
166
+ rb = open(ckpt_path, 'rb').read()
167
+ vocab = _gen_rd_u32(rb, 0); d = _gen_rd_u32(rb, 4)
168
+ nlay = _gen_rd_u32(rb, 8); nh = _gen_rd_u32(rb, 12)
169
+ block = _gen_rd_u32(rb, 16)
170
+ reason = ("valid ByteGPT flat binary admitted + LOADED (vocab=" + str(vocab)
171
+ + " d=" + str(d) + " n_layer=" + str(nlay) + " n_head=" + str(nh)
172
+ + " block=" + str(block) + "); decode forward = full-24-layer BYTE-EXACT-argmax "
173
+ + "parity with torch ByteGPT (H_1157 R1, G1 inherited)")
174
+ return {"kind": "bytegpt", "loaded": True, "decodable": True, "valid": True,
175
+ "ckpt": ckpt_path, "ckpt_exists": True, "vocab": vocab, "d": d,
176
+ "nlayer": nlay, "nhead": nh, "block": block, "reason": reason}
177
+
178
+
179
+ # ════════════════════════════════════════════════════════════════════════
180
+ # MOUTH-TYPE DISPATCHER — generator.hexa §"MOUTH-TYPE DISPATCHER" (609+)
181
+ # ════════════════════════════════════════════════════════════════════════
182
+
183
+ def gen_mouth_kind(ckpt_path):
184
+ """generator.hexa:628 gen_mouth_kind — sniff a ckpt and report the mouth
185
+ ARCHITECTURE: "bytegpt" | "clm" | "unknown". ByteGPT checked FIRST (its magic
186
+ is the ABSENCE of CLM\\x01 + a sane 5xu32 header, strictly disjoint from a .clm)."""
187
+ if _gen_is_bytegpt(ckpt_path):
188
+ return "bytegpt"
189
+ probe = _gen_clm_probe_header(ckpt_path)
190
+ if probe["valid"]:
191
+ return "clm"
192
+ return "unknown"
193
+
194
+
195
+ def gen_auto_backend(ckpt_path):
196
+ """generator.hexa:641 gen_auto_backend — THE mouth dispatcher. Sniff and return
197
+ the right backend record; "clm"/"unknown" both go to gen_clm_backend (it self-
198
+ reports valid=False for a non-.clm/absent file -> generate() falls through to null)."""
199
+ kind = gen_mouth_kind(ckpt_path)
200
+ if kind == "bytegpt":
201
+ return gen_bytegpt_backend(ckpt_path)
202
+ return gen_clm_backend(ckpt_path)
203
+
204
+
205
+ # ════════════════════════════════════════════════════════════════════════
206
+ # CHAT entries — greedy byte-continuation of a composed dialogue seed
207
+ # ════════════════════════════════════════════════════════════════════════
208
+
209
+ def gen_clm_chat(ckpt_path, seed, max_new):
210
+ """generator.hexa:599 gen_clm_chat — thin caller of the ONE .clm decode mouth
211
+ (clm_decode_argmax). ok=False with reason for a v0.1 (non-decodable) file."""
212
+ if not _clm.clm_decodable(ckpt_path):
213
+ return {"ok": False, "text": "",
214
+ "reason": "ckpt not v0.2-decodable (no CLMX trailer; embed/GN absent)"}
215
+ r = _clm.clm_decode_argmax(ckpt_path, seed, max_new)
216
+ return {"ok": r["ok"], "text": r["text"],
217
+ "reason": "decoded via clm_decode_argmax (CLMConvMoE int4 forward)"}
218
+
219
+
220
+ def gen_bytegpt_chat(ckpt_path, seed, max_new):
221
+ """generator.hexa:664 gen_bytegpt_chat — thin caller of the ONE ByteGPT decode
222
+ mouth (bytegpt_decode_argmax_ranged, OOM-safe ranged load). seed string -> byte
223
+ ids (vocab256 byte LM), exactly as the hexa builds sids via ord(substring(...))."""
224
+ if gen_mouth_kind(ckpt_path) != "bytegpt":
225
+ return {"ok": False, "text": "",
226
+ "reason": "ckpt not a ByteGPT flat binary (bad 5xu32 [256,d,L,H,block] header)"}
227
+ sids = list(seed.encode('utf-8', 'surrogateescape'))
228
+ r = _bg.bytegpt_decode_argmax_ranged(ckpt_path, sids, max_new)
229
+ return {"ok": r["ok"], "text": r["text"],
230
+ "reason": "decoded via bytegpt_decode_argmax_ranged (24-layer GPT-2-class byte forward)"}
231
+
232
+
233
+ def gen_auto_chat(ckpt_path, seed, max_new):
234
+ """generator.hexa:684 gen_auto_chat — mouth-dispatched chat. Same {ok,text,reason}
235
+ shape for both mouths so the chat loop is mouth-agnostic."""
236
+ if gen_mouth_kind(ckpt_path) == "bytegpt":
237
+ return gen_bytegpt_chat(ckpt_path, seed, max_new)
238
+ return gen_clm_chat(ckpt_path, seed, max_new)
239
+
240
+
241
+ # ════════════════════════════════════════════════════════════════════════
242
+ # IDEATE entries — the seeded-sampling siblings (ρ·fan best-of-K source · ideation · former G6)
243
+ # ════════════════════════════════════════════════════════════════════════
244
+
245
+ def gen_clm_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng):
246
+ """generator.hexa:697 gen_clm_ideate — seeded top-k sampler on the .clm mouth
247
+ (clm_decode_topk_sampled). HARD-BOUNDED by max_new."""
248
+ if not _clm.clm_decodable(ckpt_path):
249
+ return {"ok": False, "text": "",
250
+ "reason": "ckpt not v0.2-decodable (no CLMX trailer; embed/GN absent)"}
251
+ r = _clm.clm_decode_topk_sampled(ckpt_path, seed, max_new, top_k, temp, seed_rng)
252
+ return {"ok": r["ok"], "text": r["text"],
253
+ "reason": "ideated via clm_decode_topk_sampled (seeded top-k, best-of-K source)"}
254
+
255
+
256
+ def gen_clm_ideate_W(W, seed, max_new, top_k, temp, seed_rng):
257
+ """generator.hexa:713 gen_clm_ideate_W — SAME mouth off a PRE-LOADED weight map
258
+ (clm_load_weights) so a multi-decode driver loads the 303M ConvMoE ONCE."""
259
+ r = _clm.clm_decode_topk_sampled_W(W, seed, max_new, top_k, temp, seed_rng)
260
+ return {"ok": r["ok"], "text": r["text"],
261
+ "reason": "ideated via clm_decode_topk_sampled_W (loaded-W, seeded top-k)"}
262
+
263
+
264
+ def gen_bytegpt_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng):
265
+ """generator.hexa:728 gen_bytegpt_ideate — seeded top-k sampler on the ByteGPT
266
+ mouth (bytegpt_decode_topk_sampled_ranged, OOM-safe). HARD-BOUNDED by max_new."""
267
+ if gen_mouth_kind(ckpt_path) != "bytegpt":
268
+ return {"ok": False, "text": "",
269
+ "reason": "ckpt not a ByteGPT flat binary (bad 5xu32 [256,d,L,H,block] header)"}
270
+ sids = list(seed.encode('utf-8', 'surrogateescape'))
271
+ r = _bg.bytegpt_decode_topk_sampled_ranged(ckpt_path, sids, max_new, top_k, temp, seed_rng)
272
+ return {"ok": r["ok"], "text": r["text"],
273
+ "reason": "ideated via bytegpt_decode_topk_sampled_ranged (seeded top-k, OOM-safe)"}
274
+
275
+
276
+ def gen_auto_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng):
277
+ """generator.hexa:750 gen_auto_ideate — mouth-dispatched ideate (the seeded-sampling
278
+ sibling of gen_auto_chat). Same {ok,text,reason} contract for both mouths so the
279
+ ρ-AXON reach scorers (former G0-G6) run on EITHER mouth via this ONE typed entry (mouth-agnostic)."""
280
+ if gen_mouth_kind(ckpt_path) == "bytegpt":
281
+ return gen_bytegpt_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng)
282
+ return gen_clm_ideate(ckpt_path, seed, max_new, top_k, temp, seed_rng)
283
+
284
+
285
+ # ════════════════════════════════════════════════════════════════════════
286
+ # CLI — for the byte-parity harness (mirror of a hexa main calling the same)
287
+ # ════════════════════════════════════════════════════════════════════════
288
+
289
+ def _main(argv):
290
+ if len(argv) < 2:
291
+ print("usage: generator.py <cmd> ...", file=sys.stderr)
292
+ return 2
293
+ cmd = argv[1]
294
+ if cmd == "kind":
295
+ print("KIND:" + gen_mouth_kind(argv[2]))
296
+ return 0
297
+ if cmd == "ideate":
298
+ # ideate <ckpt> <seed> <gen> <top_k> <temp> <seed_rng>
299
+ ck, seed, gen = argv[2], argv[3], int(argv[4])
300
+ top_k = int(argv[5]); temp = float(argv[6]); rng = int(argv[7])
301
+ r = gen_auto_ideate(ck, seed, gen, top_k, temp, rng)
302
+ sys.stdout.buffer.write(b"KIND:" + gen_mouth_kind(ck).encode() + b"\n")
303
+ sys.stdout.buffer.write(b"OK:" + (b"true" if r["ok"] else b"false") + b"\n")
304
+ sys.stdout.buffer.write(b"TEXT:" + r["text"].encode('utf-8', 'surrogateescape') + b"\n")
305
+ return 0
306
+ if cmd == "chat":
307
+ ck, seed, gen = argv[2], argv[3], int(argv[4])
308
+ r = gen_auto_chat(ck, seed, gen)
309
+ sys.stdout.buffer.write(b"KIND:" + gen_mouth_kind(ck).encode() + b"\n")
310
+ sys.stdout.buffer.write(b"OK:" + (b"true" if r["ok"] else b"false") + b"\n")
311
+ sys.stdout.buffer.write(b"TEXT:" + r["text"].encode('utf-8', 'surrogateescape') + b"\n")
312
+ return 0
313
+ print("unknown cmd", cmd, file=sys.stderr)
314
+ return 2
315
+
316
+
317
+ if __name__ == "__main__":
318
+ sys.exit(_main(sys.argv))
@@ -0,0 +1,133 @@
1
+ #!/usr/bin/env python3
2
+ # ==========================================================================
3
+ # core/hippo_lane.py — L5 HIPPOCAMPAL ASSOCIATIVE-STORE lane (numpy 2-production).
4
+ #
5
+ # H_9129 rung-3. A DISJOINT store-side lane over the .kosmos anchor store:
6
+ # pattern-separated (DG kWTA) sparse coding of anima representations + a CA3
7
+ # heteroassociative store that does MULTI-STEP pattern completion (transitive
8
+ # chaining). This is a READ-ONLY relatedness READOUT — it never mutates the
9
+ # emit-drive lane (Ψ / motivation / recall_thr / generator). Adding/consulting
10
+ # it therefore cannot change generation bytes (a_substrate_disjoint: separation
11
+ # = preservation). The byte-parity hexa twin lives in core/kosmos_io.hexa
12
+ # (hippo_kwta / hippo_build_store / hippo_relatedness).
13
+ #
14
+ # This module is a pure library (NO __main__ execution of the engine) — the
15
+ # rep→code encoding uses the real ByteGPT-303M forward via core/decode.py in the
16
+ # py-canonical measurement path (== anima-python evaluate ops, a_eval_py_canonical);
17
+ # the store + completion here is arch-independent arithmetic (no FFI, no torch).
18
+ # ==========================================================================
19
+ import numpy as np
20
+
21
+
22
+ # ── DG de-anisotropy (rung-2 GREEN lens: center_zscore) ─────────────────────
23
+ def dg_decorrelate(reps, mode="center_zscore"):
24
+ """Whiten anisotropic anima reps before pattern separation. Raw single-token
25
+ 303M reps are near-collinear (a dominant shared direction) which masquerades
26
+ as a substrate wall; center/z-score removes it (rung-2 pre-registered lens)."""
27
+ R = np.asarray(reps, dtype=np.float64)
28
+ if mode == "raw":
29
+ return R
30
+ mu = R.mean(axis=0, keepdims=True)
31
+ Rc = R - mu
32
+ if mode == "center":
33
+ return Rc
34
+ if mode == "center_zscore":
35
+ sd = Rc.std(axis=0, keepdims=True) + 1e-6
36
+ return Rc / sd
37
+ raise ValueError(mode)
38
+
39
+
40
+ # ── DG pattern separation: fixed (untrained) random projection → kWTA sparse code ──
41
+ def hippo_kwta(v, k):
42
+ """k-winners-take-all cleanup → sparse binary attractor state (CA3 cleanup)."""
43
+ v = np.asarray(v, dtype=np.float64)
44
+ if k >= v.size:
45
+ return (v > 0).astype(np.float32)
46
+ idx = np.argpartition(v, -k)[-k:]
47
+ out = np.zeros_like(v, dtype=np.float32)
48
+ pos = idx[v[idx] > 0]
49
+ out[pos] = 1.0
50
+ return out
51
+
52
+
53
+ def dg_codes(reps, dim, active, seed):
54
+ """Pattern separation. Fixed seeded random projection (DG expansion) of each
55
+ rep → kWTA sparse binary code. Projection is UNTRAINED (no handed advantage);
56
+ correlated reps → overlapping codes (crosstalk preserved = honest test)."""
57
+ reps = np.asarray(reps, dtype=np.float64)
58
+ n, dm = reps.shape
59
+ rng = np.random.default_rng(seed)
60
+ P = rng.standard_normal((dim, dm)).astype(np.float32) / np.sqrt(dm)
61
+ R = reps / (np.linalg.norm(reps, axis=1, keepdims=True) + 1e-9)
62
+ drive = R @ P.T
63
+ return np.stack([hippo_kwta(drive[i], active) for i in range(n)])
64
+
65
+
66
+ # ── CA3 heteroassociative store + multi-step pattern completion ─────────────
67
+ def hippo_build_store(codes, edges, dim):
68
+ """Heteroassociative CA3 store: W = Σ outer(code[nxt], code[cur]) over the
69
+ DIRECTED premise edges only. edges = list of (cur, nxt) index pairs."""
70
+ W = np.zeros((dim, dim), dtype=np.float32)
71
+ codes = np.asarray(codes, dtype=np.float32)
72
+ for cur, nxt in edges:
73
+ W += np.outer(codes[nxt], codes[cur])
74
+ return W
75
+
76
+
77
+ def hippo_relatedness(W, codes, i, j, steps, kwta):
78
+ """READ-OUT (no mouth): seed the lane with code[i], run CA3 completion `steps`
79
+ times, return the max overlap between any visited attractor state and code[j].
80
+ Multi-step ⇒ transitive chaining i→i+1→…→j iff a stored relation path exists."""
81
+ codes = np.asarray(codes, dtype=np.float32)
82
+ x = codes[i].copy().astype(np.float64)
83
+ cj = codes[j].astype(np.float64)
84
+ cjn = np.linalg.norm(cj) + 1e-9
85
+ best = 0.0
86
+ for _ in range(steps):
87
+ x = hippo_kwta(W @ x, kwta).astype(np.float64)
88
+ ov = float(x @ cj) / ((np.linalg.norm(x) + 1e-9) * cjn)
89
+ if ov > best:
90
+ best = ov
91
+ return best
92
+
93
+
94
+ # ── deterministic fixture (byte-parity oracle for the kosmos_io.hexa twin) ──
95
+ def fixture_codes(n, dim, active, seed):
96
+ """Deterministic sparse binary codes WITHOUT any float RNG divergence across
97
+ languages: bit b is active for item i iff ((i*step + b*mul) % dim) < active
98
+ band — a pure integer construction so hexa and py agree byte-for-byte."""
99
+ codes = np.zeros((n, dim), dtype=np.float32)
100
+ for i in range(n):
101
+ picked = set()
102
+ b = 0
103
+ h = (i * 2654435761 + seed) & 0xFFFFFFFF
104
+ while len(picked) < active:
105
+ h = (h * 1664525 + 1013904223) & 0xFFFFFFFF
106
+ picked.add(h % dim)
107
+ b += 1
108
+ for idx in picked:
109
+ codes[i, idx] = 1.0
110
+ return codes
111
+
112
+
113
+ def _fixture_report():
114
+ """Print a deterministic small-scale CA3 report for hexa byte-parity.
115
+ 8 items in one chain 0→1→…→7; reachable = (0,k) k>=2 chain via completion;
116
+ unreachable = a disconnected item. Also a lesion (remove edge 3→4)."""
117
+ N, DIM, ACTIVE, STEPS, KWTA = 8, 64, 4, 8, 4
118
+ codes = fixture_codes(N, DIM, ACTIVE, 20260705)
119
+ edges = [(p, p + 1) for p in range(N - 1)] # chain 0→1→...→7
120
+ W = hippo_build_store(codes, edges, DIM)
121
+ # reachable 2-hop (0,2) and 3-hop (0,3); adjacent stored (0,1); self-far (0,7)
122
+ for (i, j, tag) in [(0, 1, "recall_1hop"), (0, 2, "novel_2hop"),
123
+ (0, 3, "novel_3hop"), (0, 7, "novel_7hop")]:
124
+ r = hippo_relatedness(W, codes, i, j, STEPS, KWTA)
125
+ print("py %s(0,%d)=%.6f" % (tag, j, r))
126
+ # lesion: remove edge 3→4 ; pair (0,5) path crosses it → must collapse
127
+ Wl = hippo_build_store(codes, [(p, p + 1) for p in range(N - 1) if p != 3], DIM)
128
+ print("py lesion_broken(0,5)=%.6f" % hippo_relatedness(Wl, codes, 0, 5, STEPS, KWTA))
129
+ print("py lesion_intact(0,2)=%.6f" % hippo_relatedness(Wl, codes, 0, 2, STEPS, KWTA))
130
+
131
+
132
+ if __name__ == "__main__":
133
+ _fixture_report()