@hviana/sema 0.1.0

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 (110) hide show
  1. package/AGENTS.md +470 -0
  2. package/AUTHORS.md +12 -0
  3. package/COMMERCIAL-LICENSE.md +19 -0
  4. package/CONTRIBUTING.md +15 -0
  5. package/HOW_IT_WORKS.md +4210 -0
  6. package/LICENSE.md +117 -0
  7. package/README.md +290 -0
  8. package/TRADEMARKS.md +19 -0
  9. package/example/demo.ts +46 -0
  10. package/example/train_base.ts +2675 -0
  11. package/index.html +893 -0
  12. package/package.json +25 -0
  13. package/src/alphabet.ts +34 -0
  14. package/src/alu/README.md +332 -0
  15. package/src/alu/src/alu.ts +541 -0
  16. package/src/alu/src/expr.ts +339 -0
  17. package/src/alu/src/index.ts +115 -0
  18. package/src/alu/src/kernel-arith.ts +377 -0
  19. package/src/alu/src/kernel-bits.ts +199 -0
  20. package/src/alu/src/kernel-logic.ts +102 -0
  21. package/src/alu/src/kernel-nd.ts +235 -0
  22. package/src/alu/src/kernel-numeric.ts +466 -0
  23. package/src/alu/src/operation.ts +344 -0
  24. package/src/alu/src/parser.ts +574 -0
  25. package/src/alu/src/resonance.ts +161 -0
  26. package/src/alu/src/text.ts +83 -0
  27. package/src/alu/src/value.ts +327 -0
  28. package/src/alu/test/alu.test.ts +1004 -0
  29. package/src/bytes.ts +62 -0
  30. package/src/config.ts +227 -0
  31. package/src/derive/README.md +295 -0
  32. package/src/derive/src/deduction.ts +263 -0
  33. package/src/derive/src/index.ts +24 -0
  34. package/src/derive/src/priority-queue.ts +70 -0
  35. package/src/derive/src/rewrite.ts +127 -0
  36. package/src/derive/src/trie.ts +242 -0
  37. package/src/derive/test/derive.test.ts +137 -0
  38. package/src/extension.ts +42 -0
  39. package/src/geometry.ts +511 -0
  40. package/src/index.ts +38 -0
  41. package/src/ingest-cache.ts +224 -0
  42. package/src/mind/articulation.ts +137 -0
  43. package/src/mind/attention.ts +1061 -0
  44. package/src/mind/canonical.ts +107 -0
  45. package/src/mind/graph-search.ts +1100 -0
  46. package/src/mind/index.ts +18 -0
  47. package/src/mind/junction.ts +347 -0
  48. package/src/mind/learning.ts +246 -0
  49. package/src/mind/match.ts +507 -0
  50. package/src/mind/mechanisms/alu.ts +33 -0
  51. package/src/mind/mechanisms/cast.ts +568 -0
  52. package/src/mind/mechanisms/confluence.ts +268 -0
  53. package/src/mind/mechanisms/cover.ts +248 -0
  54. package/src/mind/mechanisms/extraction.ts +422 -0
  55. package/src/mind/mechanisms/recall.ts +241 -0
  56. package/src/mind/mind.ts +483 -0
  57. package/src/mind/pipeline-mechanism.ts +326 -0
  58. package/src/mind/pipeline.ts +300 -0
  59. package/src/mind/primitives.ts +201 -0
  60. package/src/mind/rationale.ts +275 -0
  61. package/src/mind/reasoning.ts +198 -0
  62. package/src/mind/recognition.ts +234 -0
  63. package/src/mind/resonance.ts +0 -0
  64. package/src/mind/trace.ts +108 -0
  65. package/src/mind/traverse.ts +556 -0
  66. package/src/mind/types.ts +281 -0
  67. package/src/rabitq-hnsw/README.md +303 -0
  68. package/src/rabitq-hnsw/src/database.ts +492 -0
  69. package/src/rabitq-hnsw/src/heap.ts +90 -0
  70. package/src/rabitq-hnsw/src/hnsw.ts +514 -0
  71. package/src/rabitq-hnsw/src/index.ts +15 -0
  72. package/src/rabitq-hnsw/src/prng.ts +39 -0
  73. package/src/rabitq-hnsw/src/rabitq.ts +308 -0
  74. package/src/rabitq-hnsw/src/store.ts +994 -0
  75. package/src/rabitq-hnsw/test/hnsw.test.ts +1213 -0
  76. package/src/store-sqlite.ts +928 -0
  77. package/src/store.ts +2148 -0
  78. package/src/vec.ts +124 -0
  79. package/test/00-extract.test.mjs +151 -0
  80. package/test/01-floor.test.mjs +20 -0
  81. package/test/02-roundtrip.test.mjs +83 -0
  82. package/test/03-recall.test.mjs +98 -0
  83. package/test/04-think.test.mjs +627 -0
  84. package/test/05-concepts.test.mjs +84 -0
  85. package/test/08-storage.test.mjs +948 -0
  86. package/test/09-edges.test.mjs +65 -0
  87. package/test/11-universality.test.mjs +180 -0
  88. package/test/13-conversation.test.mjs +228 -0
  89. package/test/14-scaling.test.mjs +503 -0
  90. package/test/15-decomposition-gap.test.mjs +0 -0
  91. package/test/16-bridge.test.mjs +250 -0
  92. package/test/17-intelligence.test.mjs +240 -0
  93. package/test/18-alu.test.mjs +209 -0
  94. package/test/19-nd.test.mjs +254 -0
  95. package/test/20-stability.test.mjs +489 -0
  96. package/test/21-partial.test.mjs +158 -0
  97. package/test/22-multihop.test.mjs +130 -0
  98. package/test/23-rationale.test.mjs +316 -0
  99. package/test/24-generalization.test.mjs +416 -0
  100. package/test/25-embedding.test.mjs +75 -0
  101. package/test/26-cooperative.test.mjs +89 -0
  102. package/test/27-saturation-drop.test.mjs +637 -0
  103. package/test/28-unknowable.test.mjs +88 -0
  104. package/test/29-counterfactual.test.mjs +476 -0
  105. package/test/30-conflict-resolution.test.mjs +166 -0
  106. package/test/31-audit.test.mjs +288 -0
  107. package/test/32-confluence.test.mjs +173 -0
  108. package/test/33-multi-candidate.test.mjs +222 -0
  109. package/test/34-cross-region.test.mjs +252 -0
  110. package/tsconfig.json +16 -0
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@hviana/sema",
3
+ "version": "0.1.0",
4
+ "description": "An elementary, recursive, weight-free multimodal mind: one structure, two verbs, one memory. Zero runtime dependencies, pure web standards.",
5
+ "type": "module",
6
+ "main": "dist/src/index.js",
7
+ "types": "dist/src/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "demo": "tsc && node dist/example/demo.js",
11
+ "test": "tsc && node --test test/**/*.test.mjs"
12
+ },
13
+ "license": "PolyForm-Noncommercial-1.0.0",
14
+ "devDependencies": {
15
+ "@types/node": "^25.9.3",
16
+ "typescript": "^5.5.0"
17
+ },
18
+ "dependencies": {
19
+ "hyparquet": "^1.26.2",
20
+ "hyparquet-compressors": "^1.1.1"
21
+ },
22
+ "publishConfig": {
23
+ "access": "public"
24
+ }
25
+ }
@@ -0,0 +1,34 @@
1
+ // alphabet.ts — the byte→vector mapping.
2
+ //
3
+ // 256 unit vectors, one per byte value, built by recursive refinement:
4
+ // 16 coarse directions → 64 mids → 256 fines. Same-fine neighbours
5
+ // resonate; far-apart values are quasi-orthogonal.
6
+
7
+ import { addInto, copy, normalize, randomUnit, rng, Vec } from "./vec.js";
8
+ import type { AlphabetConfig } from "./config.js";
9
+
10
+ export class Alphabet {
11
+ readonly vecs: Vec[] = [];
12
+ readonly config: AlphabetConfig;
13
+
14
+ constructor(seed: number, D: number, config?: Partial<AlphabetConfig>) {
15
+ this.config = {
16
+ roughness: config?.roughness ?? 0.65,
17
+ seedMask: config?.seedMask ?? 0xa1fa17,
18
+ };
19
+ const rand = rng((seed ^ this.config.seedMask) >>> 0);
20
+ const refine = (parent: Vec): Vec => {
21
+ const v = copy(parent);
22
+ for (let i = 0; i < v.length; i++) {
23
+ v[i] *= Math.sqrt(1 - this.config.roughness);
24
+ }
25
+ addInto(v, randomUnit(D, rand), Math.sqrt(this.config.roughness));
26
+ return normalize(v);
27
+ };
28
+ const coarse: Vec[] = [];
29
+ for (let i = 0; i < 16; i++) coarse.push(randomUnit(D, rand));
30
+ const mid: Vec[] = [];
31
+ for (let i = 0; i < 64; i++) mid.push(refine(coarse[i >> 2]));
32
+ for (let b = 0; b < 256; b++) this.vecs.push(refine(mid[b >> 2]));
33
+ }
34
+ }
@@ -0,0 +1,332 @@
1
+ # alu
2
+
3
+ A small, dependency-free **ALU**: a tiny irreducible kernel from which
4
+ arithmetic, logical, and numerical computation are all _derived_. It is the
5
+ manual-rules counterpart to `derive`'s learned rules — the operations a mind
6
+ should not have to learn one number at a time (how to add 2 and 2, how to negate
7
+ a truth value) are declared here once.
8
+
9
+ It joins the mind as a `PipelineMechanism`
10
+ ([`../mind/pipeline-mechanism.ts`](../mind/pipeline-mechanism.ts)) whose only
11
+ special role is the optional `parse(query)` method every mechanism may
12
+ implement. The mind knows nothing about what the ALU computes; it only knows
13
+ that `parse` returns `ComputedSpan[]`, which enter the one lightest-derivation
14
+ search as authoritative axioms (at `STEP` cost, like a learned edge).
15
+
16
+ It has no dependency on the rest of the codebase except the pure byte helpers in
17
+ `../bytes.ts`, and is intended to be reused as a self-contained sublibrary in
18
+ the spirit of `derive/` and `rabitq-hnsw/`.
19
+
20
+ ## The thesis: one tiny kernel, everything else is a rewrite
21
+
22
+ Each stratum bootstraps the next, so the ALU only _declares_ the irreducible
23
+ primitive(s) of each layer; everything else is a derivation rule layered on top.
24
+
25
+ ### 1. Logic — the completeness layer (`kernel-logic.ts`)
26
+
27
+ One primitive: **`nand`** (functionally complete on its own). `not`, `and`, `or`
28
+ are exposed for ergonomics but are themselves derived. Fully derived: `nor`,
29
+ `xor`, `xnor`, `implies`, `iff`, and **`mux(s, a, b)`** — the bridge to control
30
+ flow (conditional selection, and with recursion, looping).
31
+
32
+ ```
33
+ not(a) = nand(a, a)
34
+ and(a, b) = not(nand(a, b))
35
+ or(a, b) = nand(not a, not b)
36
+ xor(a, b) = or(and(a, not b), and(not a, b))
37
+ mux(s, a, b) = or(and(not s, a), and(s, b))
38
+ ```
39
+
40
+ ### 2. Arithmetic — the field-and-order layer (`kernel-arith.ts`, `kernel-bits.ts`)
41
+
42
+ Identities `0`, `1`; primitives `add`, `negate`, `multiply`, `reciprocal`,
43
+ `sign` (plus optional `floor` / `mod` for integer number theory). Derived:
44
+ `subtract = add ∘ negate`, `divide = multiply ∘ reciprocal`, every comparison
45
+ `= sign ∘ subtract`, then `abs`, `min`, `max`, `power`, `gcd`, and the array
46
+ routines `polyEval`, `dot`, `matMul`, `linsolve` (Gaussian elimination — just
47
+ structured arithmetic, _not_ a new primitive).
48
+
49
+ **The bit-vector bootstrap is exact and exercised.** `kernel-bits.ts` builds
50
+ `full_adder` from the `xor`/`and`/`or` of layer 1, and from it derives ripple
51
+ `add` → two's-complement `negate` → shift-add `multiply` → `sign` → `compare`,
52
+ all on exact `bigint`. This is the literal proof that "add … everything derives
53
+ from nand"; the tests cross-check each against native `bigint`. It runs under a
54
+ `bits.` namespace so it is a separately-testable _exhibit_, never silently the
55
+ substrate of a real-number computation.
56
+
57
+ The arithmetic primitives are **polymorphic over the numeric domains**: when all
58
+ operands are exact (`bit`/`int`) they run on `bigint` and agree with the
59
+ bootstrap; the moment a `real` appears the expression lifts to IEEE doubles,
60
+ which is what the limit layer needs.
61
+
62
+ ### 3. Numerical — the limit layer (`kernel-numeric.ts`)
63
+
64
+ One primitive: **`converge(step, tol)`** — iterate a refinement until successive
65
+ results agree within ε. This is the _only_ thing that makes the engine numerical
66
+ rather than a classical (exact, finite) ALU. Exposed: `diff`, `integrate`,
67
+ `solve`; derived: `exp`, `log`, `sin`, `cos`, `sqrt`, `optimize`
68
+ (`= solve(diff
69
+ f)`), `odeSolve`, `regress` (`= linsolve` on the normal
70
+ equations), `interpolate`, `powerEig` / `topSingular` (power iteration
71
+ `= converge`).
72
+
73
+ ### 4. N-dimensional — the list layer (`kernel-nd.ts`)
74
+
75
+ A value may also be an **`nd`**: an ordered list whose elements are _themselves_
76
+ values of any domain — a scalar, or another `nd`. That one recursive case is the
77
+ whole generalisation: a matrix is an `nd` of `nd`s, a ragged table is an `nd` of
78
+ unequal-length `nd`s, a heterogeneous row mixes a number, a symbol, and a
79
+ sub-list. There is no separate vector/matrix type and no new primitive per rank.
80
+
81
+ Three structural primitives — the only ops that touch a list's elements:
82
+
83
+ ```
84
+ nd(a, b, …) pack operands into a list (construct)
85
+ length(xs) the top-level element count (measure)
86
+ at(xs, i) the i-th element, ±from end (project)
87
+ ```
88
+
89
+ Everything else derives from those three plus the scalar kernels. The
90
+ higher-order ops take an **operation as their argument**, resolved by the _same_
91
+ machinery any operator is (a surface form, else its resonant meaning — see
92
+ `OpContext.resolveOp`), so the fold/transform/predicate is **any operation the
93
+ kernel already has**, never a bespoke table:
94
+
95
+ ```
96
+ map(xs, f) = nd( f(at xs i) for i in 0…length xs )
97
+ filter(xs, p) = the elements where p holds
98
+ reduce(xs, f[,z]) = f(… f(f(z, at xs 0), at xs 1) …) reduce(xs,+)=sum, (xs,*)=product, (xs,max)=maximum
99
+ find(xs, p) = the first element where p holds, else the empty nd
100
+ ```
101
+
102
+ plus `concat`, `reverse`, `flatten`, `zip`, `range`, `rank` (nesting depth),
103
+ `shape`. Because `reduce`'s `f(acc, elem)` re-enters `apply`, a `reduce(rows,+)`
104
+ broadcasts `+` over the row-lists — a column sum falls out, no matrix code.
105
+
106
+ ## The irreducible kernel
107
+
108
+ - one gate — `nand`
109
+ - two identities + six ops — `0, 1, add, negate, multiply, reciprocal, sign` (+
110
+ optional `floor`/`mod`)
111
+ - one limit operator — `converge`
112
+ - three structural ops — `nd, length, at`
113
+
114
+ Everything else is a rewrite rule over those.
115
+
116
+ ## Values: byte-native, multimodal, and n-dimensional
117
+
118
+ SEMA computes on bytes of any modality, so ALU's value is a tagged union
119
+ (`value.ts`) — four scalar domains plus the recursive container:
120
+
121
+ ```ts
122
+ type Value =
123
+ | { domain: "bit"; b: 0 | 1 }
124
+ | { domain: "int"; n: bigint }
125
+ | { domain: "real"; x: number }
126
+ | { domain: "symbol"; bytes: Uint8Array }
127
+ | { domain: "nd"; items: Value[] }; // recursive: a list of any-domain values
128
+ ```
129
+
130
+ A **`symbol`** is an opaque byte span — text, an image region, an audio
131
+ fragment, any learned form. ALU never interprets it; it is the carrier for the
132
+ **polymorphic inverse**: the inverse of a number is its negation, but the
133
+ inverse of a symbol is its _resonant opposite_, found in the resonance space,
134
+ not by arithmetic. That single `inverse` op dispatches on the operand's domain —
135
+ so "the inverse of 3 is −3" and "the opposite of ‹a learned form› is ‹its
136
+ resonant opposite›" are one operation.
137
+
138
+ An **`nd`** is the recursive container above. The default codec spells it as a
139
+ bracket literal `[e0,e1,…]` (nestable, heterogeneous) that round-trips through
140
+ `parseValue`; a symbol element keeps its raw bytes, so a list of any modality
141
+ survives.
142
+
143
+ ### Every operation supports `nd`, via one mechanism: **broadcast**
144
+
145
+ A scalar op applied to a list lifts over it element-wise, and because each
146
+ element re-enters `apply`, nesting recurses with no extra code — `add`, `sin`,
147
+ `nand`, and the polymorphic `inverse` all broadcast for free:
148
+
149
+ ```
150
+ add([1,2,3], [4,5,6]) = [5,7,9] two lists zip
151
+ add([1,2,3], 10) = [11,12,13] a scalar is held constant
152
+ add([[1,2],[3,4]], …) recurses a matrix op is the same op
153
+ inverse([large,3,tall]) = [small,-3,short] numbers negate, symbols resonate
154
+ ```
155
+
156
+ This is implemented in exactly one place (`OperationRegistry.context`). The list
157
+ layer's own ops are marked **structural** (broadcast-exempt) — a `reduce` must
158
+ see the whole list, not be lifted across the very elements it folds. The two
159
+ halves of "all operations support nd" — scalar ops broadcasting _down_ into
160
+ lists, structural ops consuming lists _whole_ — meet exactly there.
161
+
162
+ ## How it joins the SEMA search
163
+
164
+ The ALU is completely decoupled from Sema. It joins the mind through
165
+ `aluToMechanism` ([`../mind/mechanisms/alu.ts`](../mind/mechanisms/alu.ts),
166
+ re-exported from [`../mind/pipeline.ts`](../mind/pipeline.ts)), a thin adapter
167
+ that wraps the ALU's `parse` in a `PipelineMechanism` — the same uniform
168
+ interface every grounding mechanism (CAST, confluence, cover, extraction,
169
+ recall) implements, so nothing about the ALU is special-cased in the pipeline.
170
+
171
+ ### The contract
172
+
173
+ `PipelineMechanism`'s `parse` is the part the ALU actually uses:
174
+
175
+ ```ts
176
+ interface PipelineMechanism {
177
+ parse?(query: Uint8Array): Promise<ComputedSpan[]>;
178
+ floor(ctx, query, pre): Promise<number | null>;
179
+ run(ctx, query, pre): Promise<MechanismResult[]>;
180
+ }
181
+ ```
182
+
183
+ A `ComputedSpan` is `{ i, j, bytes }` — a half-open byte range and the
184
+ authoritative result bytes computed for it.
185
+
186
+ At construction, every extension factory receives an `ExtensionHost` — four
187
+ neutral capabilities the mind already has for its own purposes:
188
+
189
+ ```ts
190
+ interface ExtensionHost {
191
+ meaningOf(
192
+ bytes: Uint8Array,
193
+ anchors: ReadonlyArray<{ name: string; form: Uint8Array }>,
194
+ ): Promise<string | null>;
195
+ continuation(bytes: Uint8Array): Promise<Uint8Array | null>;
196
+ segment(bytes: Uint8Array): Array<{ i: number; j: number }>;
197
+ reach: number;
198
+ }
199
+ ```
200
+
201
+ The host port knows nothing about ALU. The ALU adapts it into the specialised
202
+ `AluResonance` ([`resonance.ts`](src/resonance.ts)) it needs:
203
+
204
+ - `meaningOf` → `recogniseOp` — which registered operation does a span mean?
205
+ - `continuation` → `opposite` — the polymorphic inverse of a symbol
206
+
207
+ ### The parser
208
+
209
+ The `QueryParser` ([`parser.ts`](src/parser.ts)) scans the raw query bytes for
210
+ two kinds of computation:
211
+
212
+ **Infix arithmetic** — literal numbers and symbolic operators (`"2+3*4"`). The
213
+ parser uses an expression grammar with precedence climbing
214
+ ([`expr.ts`](src/expr.ts)) and byte-class constants ([`text.ts`](src/text.ts))
215
+ that are independent of the river's content-defined chunking, so a multi-digit
216
+ number the river would split across groups is still read whole. Each run is
217
+ evaluated through the kernel and emitted as a `ComputedSpan`.
218
+
219
+ **Operations by meaning** — a term may name an operation not by a literal
220
+ surface form (`"sqrt"`) but by _resonance_: its gist lands on a learned concept
221
+ anchor that was registered as an operation's meaning. This is the only path that
222
+ needs the host. The ALU also carries a `STRUCTURAL_HOST` constant — a host that
223
+ knows nothing beyond structure (whitespace-only segmentation, unbounded reach,
224
+ no resonance). Without a real host, the parser still reads literal notation;
225
+ only meaning-based paths stay silent.
226
+
227
+ ### Pre-resolution — async to sync
228
+
229
+ Two of the parser's needs are asynchronous in Sema (they hit the resonance
230
+ index): recognising an operation by meaning, and finding the polymorphic inverse
231
+ of a symbol. The ALU uses the same async-to-sync prefetch pattern that the mind
232
+ uses for concept hops:
233
+
234
+ ```ts
235
+ const sync = await prefetchResonance(resonance, spans);
236
+ // sync.ops: Map<bytes, OperationRecord> — operation by meaning
237
+ // sync.syms: Map<bytes, Uint8Array> — symbolic inverses
238
+ ```
239
+
240
+ The synchronous op callbacks never await — they read from the pre-resolved
241
+ snapshots. The public `Mind.compute(name, operands)` path pre-resolves every
242
+ symbol span before the synchronous kernel runs, using the same discipline.
243
+
244
+ ### The mind loop
245
+
246
+ `think()` collects every mechanism's `parse` result before the grounding loop
247
+ runs:
248
+
249
+ ```ts
250
+ for (const m of mechanisms) {
251
+ if (m.parse) out.push(...await m.parse(query));
252
+ }
253
+ ```
254
+
255
+ Each result is grounded into an `Out` item with `rec = true` (authoritative,
256
+ like a learned edge) at `STEP` cost. Then — crucially — any recognised site
257
+ whose span overlaps a computed span is **masked** before the search. This is the
258
+ "computation always wins" policy: a deliberately-trained `2+2 → 5` is masked;
259
+ the computed `4` is the cover's sole completion there. The search itself stays a
260
+ neutral cost engine (a computed `Out` and a learned edge both cost `STEP`);
261
+ precedence lives entirely in the masking step, which is in
262
+ `src/mind/pipeline.ts`, not in the search and not in the ALU.
263
+
264
+ A computation and an _unrelated_ rewrite still compose in one answer
265
+ (`"ice 2+2"` → `"cold 4"`) because the masking is scoped to the colliding span
266
+ only.
267
+
268
+ ### The complete decoupling
269
+
270
+ ```
271
+ src/mind/mind.ts alu/
272
+ └── mechanisms: PipelineMechanism[]
273
+ └── parse(query) ← the part the ALU uses
274
+ ↑ aluToMechanism(alu) wraps
275
+ Alu ← plain class, no mechanism shape
276
+ ↑ receives at construction
277
+ ExtensionHost port ← 4 neutral capabilities
278
+ ↑ mind.extensionHost()
279
+ AluResonance adapter ← specialised reading
280
+ ↑ parser.ts QueryParser
281
+ ```
282
+
283
+ The ALU imports nothing from the mind except `../../bytes.js`. The mind imports
284
+ nothing from the ALU beyond its `Alu` class and the `PipelineMechanism`
285
+ contract. Each remains independently testable (the ALU test suite runs with zero
286
+ Sema dependency) and replaceable. A user-supplied extension — a CAS, a type
287
+ checker, a domain-specific solver — joins through the same `mechanismFactories`
288
+ hook (`MindOptions.mechanismFactories`), receives the same host port, and its
289
+ computed spans mask recall with the same precedence.
290
+
291
+ ## Adding an operation
292
+
293
+ One declarative call, in the relevant kernel file or by the host:
294
+
295
+ ```ts
296
+ registry.derive("hypot", 2, ["hypot"], (args, ctx) =>
297
+ ctx.apply("sqrt", [
298
+ ctx.apply("add", [
299
+ ctx.apply("multiply", [args[0], args[0]]),
300
+ ctx.apply("multiply", [args[1], args[1]]),
301
+ ]),
302
+ ]));
303
+ ```
304
+
305
+ No kernel edit, no graph-search edit, no resonance edit — name it, list its
306
+ surface forms, write the body in terms of existing ops. A scalar op broadcasts
307
+ over `nd` automatically; pass `structural = true` (the trailing flag on
308
+ `prim`/`derive`) only for an op that consumes a list _whole_, like the `nd`
309
+ kernel's own.
310
+
311
+ ## Layout
312
+
313
+ ```
314
+ alu/
315
+ ├── README.md this file
316
+ ├── src/
317
+ │ ├── value.ts the Value union, parse, the byte⇄value codec
318
+ │ ├── operation.ts the Operation record + registry (derivations compose by name)
319
+ │ ├── parser.ts QueryParser: lexer, infix arithmetic, operation-by-meaning
320
+ │ ├── expr.ts expression grammar (precedence climbing), tokenizer
321
+ │ ├── text.ts byte-class constants (digit, whitespace, bracket, etc.)
322
+ │ ├── resonance.ts AluResonance (host-injected) + the async→sync prefetch
323
+ │ ├── kernel-logic.ts nand → not/and/or/nor/xor/xnor/implies/iff/mux
324
+ │ ├── kernel-bits.ts the exact full_adder→add→multiply bootstrap (bigint)
325
+ │ ├── kernel-arith.ts identities + add/negate/multiply/reciprocal/sign + derived
326
+ │ ├── kernel-numeric.ts converge → diff/integrate/solve → exp/log/sin/cos/sqrt/…
327
+ │ ├── kernel-nd.ts nd/length/at → map/reduce/filter/find/concat/zip/rank/shape
328
+ │ ├── alu.ts the assembled Alu: exposes parse(), owns the parser
329
+ │ └── index.ts public surface
330
+ └── test/
331
+ └── alu.test.ts self-contained tests (no Sema dependency)
332
+ ```