@hviana/sema 0.9.4 → 0.9.5

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 (45) hide show
  1. package/AGENTS.md +16 -7
  2. package/dist/src/mind/learning.js +11 -12
  3. package/dist/src/mind/mind.js +4 -4
  4. package/dist/src/mind/types.d.ts +10 -15
  5. package/dist/src/store.d.ts +10 -10
  6. package/dist/src/store.js +5 -5
  7. package/docs/INDEX.md +62 -63
  8. package/docs/INVARIANTS.md +36 -18
  9. package/docs/architecture/bounded-reads.md +31 -71
  10. package/docs/architecture/caches.md +61 -81
  11. package/docs/architecture/closure.md +88 -107
  12. package/docs/architecture/commonality.md +47 -38
  13. package/docs/architecture/cost-model.md +57 -79
  14. package/docs/architecture/determinism.md +43 -55
  15. package/docs/architecture/evidence.md +158 -235
  16. package/docs/architecture/exact-vs-approximate.md +41 -35
  17. package/docs/architecture/factored-machinery.md +34 -20
  18. package/docs/architecture/fold-contract.md +110 -118
  19. package/docs/architecture/halo-sketch.md +105 -96
  20. package/docs/architecture/match-project.md +51 -42
  21. package/docs/architecture/mechanism-market.md +87 -91
  22. package/docs/architecture/memoization.md +60 -74
  23. package/docs/architecture/meter.md +37 -47
  24. package/docs/architecture/saturation.md +75 -101
  25. package/docs/architecture/store.md +118 -99
  26. package/docs/architecture/thresholds.md +66 -73
  27. package/docs/failures/tempting-but-wrong.md +139 -165
  28. package/docs/harness/gates.md +27 -32
  29. package/docs/mechanisms/alu.md +22 -69
  30. package/docs/mechanisms/cast.md +76 -71
  31. package/docs/mechanisms/confluence.md +22 -29
  32. package/docs/mechanisms/cover.md +58 -66
  33. package/docs/mechanisms/extraction.md +33 -37
  34. package/docs/mechanisms/prefix-completion.md +36 -39
  35. package/docs/mechanisms/recall.md +60 -53
  36. package/docs/mechanisms/reference.md +63 -49
  37. package/jsr.json +1 -1
  38. package/package.json +1 -1
  39. package/src/alu/README.md +90 -298
  40. package/src/derive/README.md +94 -256
  41. package/src/mind/learning.ts +11 -12
  42. package/src/mind/mind.ts +4 -4
  43. package/src/mind/types.ts +10 -15
  44. package/src/rabitq-ivf/README.md +11 -8
  45. package/src/store.ts +5 -5
package/src/alu/README.md CHANGED
@@ -1,304 +1,106 @@
1
1
  # alu
2
2
 
3
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)` every mechanism may implement. The
12
- mind knows nothing about what the ALU computes; it only knows that `parse`
13
- returns `ComputedSpan[]`, which enter the one lightest-derivation search as
14
- authoritative axioms (at `STEP`, 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-ivf/`.
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:
4
+ arithmetic, logic and numerical computation are all _derived_. The operations a
5
+ mind should not have to learn one number at a time are declared here once: how
6
+ to add 2 and 2, how to negate a truth value. It imports nothing from the rest of
7
+ the codebase except the pure byte helpers in `../bytes.ts`, and its tests run
8
+ with no Sema dependency.
9
+
10
+ ## One tiny kernel; everything else is a rewrite
11
+
12
+ Each layer declares only its irreducible primitives and derives everything else
13
+ from them.
14
+
15
+ | Layer | Primitives | Derived |
16
+ | ----------------------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
17
+ | **Logic** (`kernel-logic.ts`) | `nand`, which is functionally complete on its own | `not`, `and`, `or`, `nor`, `xor`, `xnor`, `implies`, `iff`, and `mux(s, a, b)`, the bridge to control flow |
18
+ | **Arithmetic** (`kernel-arith.ts`) | `0`, `1`, `add`, `negate`, `multiply`, `reciprocal`, `sign` (+ optional `floor`, `mod`) | `subtract`, `divide`, every comparison (`sign ∘ subtract`), `abs`, `min`, `max`, `power`, `gcd`, `polyEval`, `dot`, `matMul`, `linsolve` |
19
+ | **Numerical** (`kernel-numeric.ts`) | `converge(step, tol)`: iterate until successive results agree within ε | `diff`, `integrate`, `solve`, `exp`, `log`, `sin`, `cos`, `sqrt`, `optimize`, `odeSolve`, `regress`, `interpolate`, `powerEig`, `topSingular` |
20
+ | **N-dimensional** (`kernel-nd.ts`) | `nd(a, b, …)`, `length(xs)`, `at(xs, i)` | `map`, `filter`, `reduce`, `find`, `concat`, `reverse`, `flatten`, `zip`, `range`, `rank`, `shape` |
21
+
22
+ - **`converge` is what makes the engine numerical** rather than a classical,
23
+ exact and finite ALU.
24
+ - **The bit-vector bootstrap is exact and exercised.** `kernel-bits.ts` builds
25
+ `full_adder` from the logic layer. From it come ripple `add`, two's-complement
26
+ `negate`, shift-add `multiply`, `sign` and `compare`, all on `bigint`, and
27
+ they are cross-checked against native `bigint`. It lives under a `bits.`
28
+ namespace, as a separately tested exhibit, never as the silent substrate of a
29
+ real-number computation.
30
+ - **Arithmetic is polymorphic over domains.** Exact operands (`bit`, `int`) run
31
+ on `bigint`. Once a `real` appears, the expression lifts to IEEE doubles.
32
+ - **The higher-order list operations take an operation as an argument.** It is
33
+ resolved by the same machinery as any operator: a surface form, or else its
34
+ resonant meaning (`OpContext.resolveOp`). For example, `reduce(xs, +)` is a
35
+ sum, and `reduce(rows, +)` is a column sum.
36
+
37
+ ## Values — byte-native, any modality, n-dimensional (`value.ts`)
120
38
 
121
39
  ```ts
122
40
  type Value =
123
41
  | { domain: "bit"; b: 0 | 1 }
124
42
  | { domain: "int"; n: bigint }
125
43
  | { domain: "real"; x: number }
126
- | { domain: "symbol"; bytes: Uint8Array }
44
+ | { domain: "symbol"; bytes: Uint8Array } // an opaque byte span of any modality
127
45
  | { domain: "nd"; items: Value[] }; // recursive: a list of any-domain values
128
46
  ```
129
47
 
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.
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, worthRunning): 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.
48
+ **A symbol carries the polymorphic inverse.** The inverse of a number is its
49
+ negation. The inverse of a symbol is its resonant opposite, found in the
50
+ resonance space rather than by arithmetic. One `inverse` operation dispatches on
51
+ the operand's domain.
226
52
 
227
- ### Pre-resolution — async to sync
53
+ **An `nd` is the only container.** A matrix is an `nd` of `nd`s, and a ragged or
54
+ heterogeneous table needs no new type. Its literal is `[e0,e1,…]`, which
55
+ round-trips through `parseValue`.
228
56
 
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:
57
+ **Broadcast is defined once** (`OperationRegistry.context`). A scalar operation
58
+ applied to a list lifts element-wise and recurses into nesting:
59
+ `add([1,2,3], 10) = [11,12,13]`, and
60
+ `inverse([large,3,tall]) =
61
+ [small,-3,short]`. Structural operations, marked with
62
+ the trailing `structural = true` flag, are exempt, because they consume a list
63
+ whole.
233
64
 
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. A named operation applied to the query's operand stream resolves
242
- opposites ON DEMAND (`withOppositesOnDemand`). The kernel runs against a
243
- snapshot of the opposites resolved so far. When it asked for one of its symbol
244
- operands that is not resolved yet, that one is resolved through the host and the
245
- pure kernel runs again. The result is the eager prefetch's, but only the
246
- polymorphic inverse reads opposites. Before this, every symbol operand of ANY
247
- operation paid one host call, and on Sema each is a halo-index query (30–200 ms
248
- of a plain dialogue turn's parse that computed nothing). The public
249
- `Mind.compute(name, operands)` path pre-resolves every symbol span before the
250
- synchronous kernel runs, using the same discipline.
251
-
252
- ### The mind loop
65
+ ## How it joins a host
253
66
 
254
- `think()` collects every mechanism's `parse` result before the grounding loop
255
- runs:
67
+ The ALU is a plain class (`alu.ts`) that exposes
68
+ `parse(query) →
69
+ ComputedSpan[]`. A `ComputedSpan` is `{ i, j, bytes }`: a
70
+ half-open byte range and the authoritative result computed for it. In Sema,
71
+ `aluToMechanism` wraps it as an ordinary pipeline mechanism. Computed spans mask
72
+ the recognised sites they overlap, which is how computation always wins
73
+ (`docs/mechanisms/alu.md`).
256
74
 
257
- ```ts
258
- for (const m of mechanisms) {
259
- if (m.parse) out.push(...await m.parse(query));
260
- }
261
- ```
75
+ **The host port.** At construction the ALU receives an `ExtensionHost`, four
76
+ neutral capabilities that know nothing about the ALU:
77
+ `meaningOf(bytes, anchors)`, `continuation(bytes)`, `segment(bytes)` and
78
+ `reach`. The ALU adapts them into its own `AluResonance` (`resonance.ts`):
262
79
 
263
- Each result is grounded into an `Out` item with `rec = true` (authoritative,
264
- like a learned edge) at `STEP` cost. Then — crucially — any recognised site
265
- whose span overlaps a computed span is **masked** before the search. This is the
266
- "computation always wins" policy: a deliberately-trained `2+2 → 5` is masked;
267
- the computed `4` is the cover's sole completion there. The search itself stays a
268
- neutral cost engine (a computed `Out` and a learned edge both cost `STEP`);
269
- precedence lives entirely in the masking step, which is in
270
- `src/mind/mechanisms/cover.ts`, not in the search and not in the ALU.
80
+ - `meaningOf` becomes `recogniseOp`: which operation does this span mean?
81
+ - `continuation` becomes `opposite`: a symbol's inverse.
271
82
 
272
- A computation and an _unrelated_ rewrite still compose in one answer
273
- (`"ice 2+2"` → `"cold 4"`) because the masking is scoped to the colliding span
274
- only.
83
+ Without a host (`STRUCTURAL_HOST`), the parser still reads literal notation, and
84
+ only the paths that depend on meaning stay silent.
275
85
 
276
- ### The complete decoupling
86
+ **The parser** (`parser.ts`, with its grammar in `expr.ts` and byte classes in
87
+ `text.ts`) finds two kinds of computation:
277
88
 
278
- ```
279
- src/mind/mind.ts alu/
280
- └── mechanisms: PipelineMechanism[]
281
- └── parse(query) ← the part the ALU uses
282
- ↑ aluToMechanism(alu) wraps
283
- Alu ← plain class, no mechanism shape
284
- ↑ receives at construction
285
- ExtensionHost port ← 4 neutral capabilities
286
- ↑ mind.extensionHost()
287
- AluResonance adapter ← specialised reading
288
- ↑ parser.ts QueryParser
289
- ```
89
+ - **Infix arithmetic** (`2+3*4`), read with precedence climbing and independent
90
+ of any chunking, so a multi-digit number is always read whole.
91
+ - **Operations named by meaning,** where a term's gist lands on a learnt anchor
92
+ registered as an operation's meaning.
290
93
 
291
- The ALU imports nothing from the mind except `../../bytes.js`. The mind imports
292
- nothing from the ALU beyond its `Alu` class and the `PipelineMechanism`
293
- contract. Each remains independently testable (the ALU test suite runs with zero
294
- Sema dependency) and replaceable. A user-supplied extension — a CAS, a type
295
- checker, a domain-specific solver — joins through the same `mechanismFactories`
296
- hook (`MindOptions.mechanismFactories`), receives the same host port, and its
297
- computed spans mask recall with the same precedence.
94
+ **Asynchronous reads are resolved before the synchronous kernel runs.**
95
+ `prefetchResonance` resolves operations by meaning. Opposites are resolved on
96
+ demand (`withOppositesOnDemand`): the kernel runs against the opposites resolved
97
+ so far, and is re-run only when it asked for a missing one. Before this, every
98
+ symbol operand of every operation paid one halo query, 30–200 ms of a plain
99
+ dialogue turn that computed nothing.
298
100
 
299
101
  ## Adding an operation
300
102
 
301
- One declarative call, in the relevant kernel file or by the host:
103
+ Add one declarative call:
302
104
 
303
105
  ```ts
304
106
  registry.derive("hypot", 2, ["hypot"], (args, ctx) =>
@@ -310,30 +112,20 @@ registry.derive("hypot", 2, ["hypot"], (args, ctx) =>
310
112
  ]));
311
113
  ```
312
114
 
313
- No kernel, graph-search or resonance edit — name it, list its surface forms,
314
- write the body from existing ops. A scalar op broadcasts over `nd`
315
- automatically; pass `structural = true` (the trailing flag on `prim`/`derive`)
316
- only for an op that consumes a list _whole_, like the `nd` kernel's own.
115
+ Give it a name, its surface forms, and a body made of existing operations. No
116
+ kernel, search or resonance edit is needed. A scalar operation broadcasts over
117
+ `nd` automatically.
317
118
 
318
119
  ## Layout
319
120
 
320
121
  ```
321
- alu/
322
- ├── README.md this file
323
- ├── src/
324
- │ ├── value.ts the Value union, parse, the byte⇄value codec
325
- │ ├── operation.ts the Operation record + registry (derivations compose by name)
326
- │ ├── parser.ts QueryParser: lexer, infix arithmetic, operation-by-meaning
327
- │ ├── expr.ts expression grammar (precedence climbing), tokenizer
328
- │ ├── text.ts byte-class constants (digit, whitespace, bracket, etc.)
329
- │ ├── resonance.ts AluResonance (host-injected) + the async→sync prefetch
330
- │ ├── kernel-logic.ts nand → not/and/or/nor/xor/xnor/implies/iff/mux
331
- │ ├── kernel-bits.ts the exact full_adder→add→multiply bootstrap (bigint)
332
- │ ├── kernel-arith.ts identities + add/negate/multiply/reciprocal/sign + derived
333
- │ ├── kernel-numeric.ts converge → diff/integrate/solve → exp/log/sin/cos/sqrt/…
334
- │ ├── kernel-nd.ts nd/length/at → map/reduce/filter/find/concat/zip/rank/shape
335
- │ ├── alu.ts the assembled Alu: exposes parse(), owns the parser
336
- │ └── index.ts public surface
337
- └── test/
338
- └── alu.test.ts self-contained tests (no Sema dependency)
122
+ src/value.ts the Value union and the byte ⇄ value codec
123
+ src/operation.ts Operation records and the registry; derivations compose by name
124
+ src/parser.ts QueryParser: infix arithmetic and operations by meaning
125
+ src/expr.ts, text.ts the expression grammar and the byte classes
126
+ src/resonance.ts AluResonance and the async → sync pre-resolution
127
+ src/kernel-*.ts logic, bits, arith, numeric, nd
128
+ src/alu.ts the assembled Alu
129
+ src/index.ts public surface
130
+ test/alu.test.ts self-contained tests
339
131
  ```