@hviana/sema 0.8.2 → 0.8.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.
- package/AGENTS.md +38 -37
- package/README.md +17 -38
- package/TRADEMARKS.md +0 -1
- package/dist/example/demo.js +85 -34
- package/dist/src/config.d.ts +11 -0
- package/dist/src/config.js +2 -0
- package/dist/src/geometry.d.ts +21 -10
- package/dist/src/geometry.js +21 -12
- package/dist/src/meter.d.ts +62 -0
- package/dist/src/meter.js +62 -0
- package/dist/src/mind/articulation.js +1 -1
- package/dist/src/mind/attention.d.ts +4 -0
- package/dist/src/mind/attention.js +167 -17
- package/dist/src/mind/canonical.d.ts +16 -0
- package/dist/src/mind/canonical.js +41 -0
- package/dist/src/mind/derivation.d.ts +201 -0
- package/dist/src/mind/derivation.js +327 -0
- package/dist/src/mind/graph-search.d.ts +2 -1
- package/dist/src/mind/graph-search.js +70 -29
- package/dist/src/mind/match.d.ts +3 -1
- package/dist/src/mind/match.js +7 -3
- package/dist/src/mind/mechanisms/alu.js +0 -2
- package/dist/src/mind/mechanisms/cast.d.ts +1 -5
- package/dist/src/mind/mechanisms/cast.js +16 -19
- package/dist/src/mind/mechanisms/confluence.d.ts +0 -3
- package/dist/src/mind/mechanisms/confluence.js +27 -9
- package/dist/src/mind/mechanisms/cover.js +17 -20
- package/dist/src/mind/mechanisms/extraction.d.ts +0 -1
- package/dist/src/mind/mechanisms/extraction.js +13 -8
- package/dist/src/mind/mechanisms/prefix-completion.js +0 -1
- package/dist/src/mind/mechanisms/recall.d.ts +0 -1
- package/dist/src/mind/mechanisms/recall.js +40 -13
- package/dist/src/mind/mechanisms/reference.js +3 -4
- package/dist/src/mind/mind.d.ts +4 -2
- package/dist/src/mind/mind.js +5 -4
- package/dist/src/mind/pipeline-mechanism.d.ts +7 -3
- package/dist/src/mind/pipeline.js +136 -44
- package/dist/src/mind/primitives.js +9 -1
- package/dist/src/mind/rationale.d.ts +21 -5
- package/dist/src/mind/rationale.js +16 -21
- package/dist/src/mind/reasoning.d.ts +12 -20
- package/dist/src/mind/reasoning.js +190 -106
- package/dist/src/mind/recognition.js +4 -8
- package/dist/src/mind/resonance.js +20 -1
- package/dist/src/mind/trace.js +1 -0
- package/dist/src/mind/traverse.js +6 -2
- package/dist/src/mind/types.d.ts +36 -13
- package/dist/src/mind/types.js +6 -3
- package/docs/INDEX.md +23 -24
- package/docs/INVARIANTS.md +16 -17
- package/docs/architecture/bounded-reads.md +5 -5
- package/docs/architecture/closure.md +65 -0
- package/docs/architecture/commonality.md +29 -20
- package/docs/architecture/cost-model.md +7 -7
- package/docs/architecture/determinism.md +7 -7
- package/docs/architecture/exact-vs-approximate.md +4 -4
- package/docs/architecture/factored-machinery.md +14 -14
- package/docs/architecture/match-project.md +2 -3
- package/docs/architecture/mechanism-market.md +16 -16
- package/docs/architecture/meter.md +10 -11
- package/docs/architecture/store.md +4 -4
- package/docs/architecture/thresholds.md +1 -1
- package/docs/failures/tempting-but-wrong.md +14 -5
- package/docs/harness/gates.md +7 -7
- package/docs/mechanisms/cast.md +2 -2
- package/docs/mechanisms/cover.md +4 -5
- package/docs/mechanisms/extraction.md +7 -7
- package/docs/mechanisms/recall.md +8 -9
- package/example/demo.ts +90 -37
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/alu/README.md +11 -12
- package/src/config.ts +13 -0
- package/src/geometry.ts +21 -13
- package/src/meter.ts +62 -0
- package/src/mind/articulation.ts +0 -1
- package/src/mind/attention.ts +169 -17
- package/src/mind/canonical.ts +43 -0
- package/src/mind/derivation.ts +473 -0
- package/src/mind/graph-search.ts +76 -34
- package/src/mind/match.ts +7 -3
- package/src/mind/mechanisms/alu.ts +0 -2
- package/src/mind/mechanisms/cast.ts +20 -22
- package/src/mind/mechanisms/confluence.ts +27 -13
- package/src/mind/mechanisms/cover.ts +17 -20
- package/src/mind/mechanisms/extraction.ts +13 -9
- package/src/mind/mechanisms/prefix-completion.ts +0 -1
- package/src/mind/mechanisms/recall.ts +39 -13
- package/src/mind/mechanisms/reference.ts +2 -3
- package/src/mind/mind.ts +6 -4
- package/src/mind/pipeline-mechanism.ts +7 -3
- package/src/mind/pipeline.ts +160 -52
- package/src/mind/primitives.ts +9 -1
- package/src/mind/rationale.ts +27 -23
- package/src/mind/reasoning.ts +227 -120
- package/src/mind/recognition.ts +4 -8
- package/src/mind/resonance.ts +19 -1
- package/src/mind/trace.ts +1 -0
- package/src/mind/traverse.ts +7 -5
- package/src/mind/types.ts +41 -15
- package/test/105-derive-through-reports-its-refusal.test.mjs +24 -0
- package/test/118-the-join-reaches-a-key-off-the-cut.test.mjs +74 -0
- package/test/119-the-work-does-not-grow-with-the-corpus.test.mjs +122 -0
- package/test/120-composition-is-consequence.test.mjs +132 -0
- package/test/121-the-extension-does-not-grow-with-the-corpus.test.mjs +128 -0
- package/test/122-the-climb-search-does-not-grow-with-the-corpus.test.mjs +117 -0
- package/test/123-the-paired-formulas-agree.test.mjs +90 -0
- package/test/125-the-post-grounding-branch-publishes-its-operand.test.mjs +51 -0
- package/test/126-the-pipeline-does-not-name-mechanisms.test.mjs +42 -0
- package/test/128-the-leads-somewhere-pair-agrees.test.mjs +83 -0
- package/test/129-the-trace-payload-shape.test.mjs +164 -0
- package/test/133-the-decision-point-renders-the-state.test.mjs +204 -0
- package/test/134-the-law-explains-the-engines-own-refusal.test.mjs +237 -0
- package/test/135-one-law-any-producer.test.mjs +289 -0
- package/test/136-the-two-named-limits.test.mjs +205 -0
- package/test/137-the-law-lives-once-and-below.test.mjs +400 -0
- package/test/138-the-remainder-drains-only-what-a-move-declares.test.mjs +62 -0
- package/test/139-the-witness-is-engagement-not-explanation.test.mjs +51 -0
- package/test/140-irrelevant-supply-does-not-change-an-answer.test.mjs +48 -0
- package/test/141-the-question-is-paid-at-construction.test.mjs +98 -0
- package/test/32-confluence.test.mjs +68 -0
- package/test/36-already-answered-fusion.test.mjs +20 -2
- package/test/37-cluster-dispersion-fusion.test.mjs +30 -3
- package/test/38-reason-restate-guard.test.mjs +28 -2
- package/test/43-cast-analog-seat.test.mjs +10 -0
- package/test/55-cost-meter.test.mjs +862 -0
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
# Tempting but Wrong — 13 Traps
|
|
2
2
|
|
|
3
3
|
Thirteen shortcuts that look plausible and break an invariant. Each states what
|
|
4
|
-
not to do, why it fails, and what to do instead.
|
|
4
|
+
not to do, why it fails, and what to do instead. **Some things are universal:
|
|
5
|
+
discovering bugs:**
|
|
6
|
+
|
|
7
|
+
- A bug must be pinned by a test that shows it.
|
|
8
|
+
- This test cannot be accidental; it is subtle and requires deep analysis. That
|
|
9
|
+
is, it is not the test itself that reveals the bug, but rather the class of
|
|
10
|
+
errors to which the bug belongs.
|
|
11
|
+
- This is difficult to do because the suite's small synthetic corpus easily
|
|
12
|
+
leads to accidental bugs, and real-world corpus must not be compromised.
|
|
13
|
+
- Something that happens due to deduplication, a tie-breaking rule, etc., isn't
|
|
14
|
+
a bug—and that’s a subtle point.
|
|
5
15
|
|
|
6
16
|
### 1. `score >= threshold` decides identity
|
|
7
17
|
|
|
@@ -30,8 +40,7 @@ not to do, why it fails, and what to do instead.
|
|
|
30
40
|
- **WRONG:** Break equal-rank ties by picking the most recently inserted
|
|
31
41
|
edge/node.
|
|
32
42
|
- **WHY:** Tie-breaks must be corpus-determined and stable; last-inserted is
|
|
33
|
-
recency-dependent
|
|
34
|
-
first-inserted fallback).
|
|
43
|
+
recency-dependent (`AGENTS §2` Invariant 1 — first-inserted fallback).
|
|
35
44
|
- **CORRECT:** `guidedFirst`/`chooseNext`/`chooseAmong`: rank then
|
|
36
45
|
first-inserted (lowest node id / `LIMIT 1` insertion order). Pinned by
|
|
37
46
|
`test/03-recall.test.mjs` determinism suites.
|
|
@@ -55,8 +64,8 @@ not to do, why it fails, and what to do instead.
|
|
|
55
64
|
policy is enforced by masking, not pricing (`AGENTS §2` Invariant 4 — One cost
|
|
56
65
|
currency; `docs/architecture/cost-model.md` § Policy is not cost).
|
|
57
66
|
- **CORRECT:** Keep `PASS` dominating; enforce precedence in the caller (e.g.
|
|
58
|
-
`
|
|
59
|
-
|
|
67
|
+
`cover.ts` masks recognised sites overlapped by `ComputedResult`). Pinned by
|
|
68
|
+
`test/04-think.test.mjs` and `test/55-cost-meter.test.mjs`.
|
|
60
69
|
|
|
61
70
|
### 6. Reimplementing `locate`/`align` inside a mechanism
|
|
62
71
|
|
package/docs/harness/gates.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Four executable gates. Each: run the command, check what it guards, follow its
|
|
4
4
|
§.
|
|
5
5
|
|
|
6
|
-
## 1 — Correctness (all
|
|
6
|
+
## 1 — Correctness (all suites)
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
npm test
|
|
@@ -12,9 +12,9 @@ npm test
|
|
|
12
12
|
Guards honest silence, determinism, and every pinned contract. Silence:
|
|
13
13
|
unrelated queries ground to nothing (`test/28`, `50`, `56`, `67`, `76`, `84`).
|
|
14
14
|
Determinism: same seed + deposit order + query gives byte-identical answer
|
|
15
|
-
(`test/20`). Every invariant is pinned
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
(`test/20`). Every invariant is pinned, the closure law included
|
|
16
|
+
(`test/133`–`140`). §14–25 (pipeline), §64 (derived thresholds), AGENTS.md §2
|
|
17
|
+
invariants 1–5.
|
|
18
18
|
|
|
19
19
|
## 2 — Work accounting (profiler)
|
|
20
20
|
|
|
@@ -23,9 +23,9 @@ node bench/profile-inference.mjs # add [n] to limit probes
|
|
|
23
23
|
node bench/profile-inference.mjs --trace # trace is a debugging aid, not product
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Guards without trace: counters
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
Guards without trace: counters exact and diffable between COLD runs; phases nest
|
|
27
|
+
(not disjoint — each phase is charged by its own layer); shared analyses charged
|
|
28
|
+
to themselves, not to the first toucher; millisecond fields are
|
|
29
29
|
non-deterministic hints only. With `--trace`, recognition idempotence still
|
|
30
30
|
holds (`test/42`). `src/meter.ts`, `docs/architecture/meter.md`, §55,
|
|
31
31
|
`AGENTS.md` §6.
|
package/docs/mechanisms/cast.md
CHANGED
|
@@ -12,7 +12,7 @@ schema yields its own candidate and `think`'s single weight comparison picks.
|
|
|
12
12
|
halo-matched `pre.rec.sites`. The product is `pre.weave()` — `points[]` (each
|
|
13
13
|
with graded `runs[]`) and a per-query-byte `depth[]` (how many structures cover
|
|
14
14
|
that byte). CAST's single-vs-multi test is measured from those runs: a second
|
|
15
|
-
point must add ≥ one perception quantum of coverage the widest
|
|
15
|
+
point must add ≥ one perception quantum of coverage the widest does not.
|
|
16
16
|
|
|
17
17
|
## Gate — weave-local discriminative frame
|
|
18
18
|
|
|
@@ -76,5 +76,5 @@ redirection, or analogical comparison), not from a literal continuation.
|
|
|
76
76
|
## Source
|
|
77
77
|
|
|
78
78
|
`src/mind/mechanisms/cast.ts` (`counterfactualTransfer`, `seatOfNode`,
|
|
79
|
-
`MIN_WEAVE`), `src/mind/match.ts` (`alignGraded`, `project
|
|
79
|
+
`MIN_WEAVE`, `weave.depth`), `src/mind/match.ts` (`alignGraded`, `project`),
|
|
80
80
|
`src/geometry.ts` (`dominates`), `src/mind/graph-search.ts` (`STEP`).
|
package/docs/mechanisms/cover.md
CHANGED
|
@@ -15,9 +15,8 @@ consumes them directly; any site whose bytes overlap a computed span is masked
|
|
|
15
15
|
- `formRules` follow continuation edges (`GraphSearch.formRules`): each hop
|
|
16
16
|
costs `STEP` (1). Forks across all continuations up to the hub bound;
|
|
17
17
|
disambiguation is distributional, not heuristic.
|
|
18
|
-
- Edge-less forms may hop via a halo sibling (`conceptHop` / `resolveConcepts`
|
|
19
|
-
|
|
20
|
-
continuation.
|
|
18
|
+
- Edge-less forms may hop via a halo sibling (`conceptHop` / `resolveConcepts`)
|
|
19
|
+
at `CONCEPT` (10), borrowing a synonym's continuation.
|
|
21
20
|
|
|
22
21
|
## Gate — `leadsSomewhere` (`src/mind/traverse.ts`)
|
|
23
22
|
|
|
@@ -34,8 +33,8 @@ and are filtered during recognition.
|
|
|
34
33
|
| `PASS` | 1000 / byte | each unaccounted byte |
|
|
35
34
|
| `MICRO` | 1e-3 | per-byte A* heuristic (`h = (len-right)*MICRO`) |
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
The cover reports `moves` (its derivation's discrete work) and `accounted`; the
|
|
37
|
+
ladder prices both.
|
|
39
38
|
|
|
40
39
|
## Pre-resolution (`src/mind/mechanisms/cover.ts`)
|
|
41
40
|
|
|
@@ -7,13 +7,13 @@ what sits between them.
|
|
|
7
7
|
|
|
8
8
|
## Matcher — `skillExemplar` / `isSpanShaped` / `containsSpan` (`src/mind/match.ts`)
|
|
9
9
|
|
|
10
|
-
An exemplar is span-shaped when its answer
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
are ranked anchors from `climbAttentionAll`
|
|
15
|
-
|
|
16
|
-
skipped.
|
|
10
|
+
An exemplar is span-shaped when its answer embeds in order. `isSpanShaped` is
|
|
11
|
+
the open reading (sparse subsequence, any gaps) for acceptance; `containsSpan`
|
|
12
|
+
is the strict reading (contiguous run, or a resolved node) that fusion gates on,
|
|
13
|
+
extraction decomposes with `answerRunsInContext` (greedy longest runs).
|
|
14
|
+
Candidates are ranked anchors from `climbAttentionAll`
|
|
15
|
+
(`Precomputed.spanShapedOf`), tried up to `pre.k`; sub-quantum (`< W`) or
|
|
16
|
+
unanchored results are skipped.
|
|
17
17
|
|
|
18
18
|
## Projection — read between located frames (`src/mind/mechanisms/extraction.ts`)
|
|
19
19
|
|
|
@@ -24,16 +24,15 @@ W = `maxGroup` (river window); bars from `src/geometry.ts`.
|
|
|
24
24
|
## Echo — the refusing tail
|
|
25
25
|
|
|
26
26
|
If no tier grounded, the exact cosine of the top hit is re-folded (`gistOf` on
|
|
27
|
-
its bytes).
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
echo.
|
|
27
|
+
its bytes). It uses that exact value in the same chance-corrected fraction —
|
|
28
|
+
never the RaBitQ estimate. Below `reach` → silence; restating → silence;
|
|
29
|
+
otherwise the hit's own bytes are returned as an ungrounded echo.
|
|
31
30
|
|
|
32
31
|
## Provenance
|
|
33
32
|
|
|
34
33
|
Grounded answers carry `recall`; the echo carries `recall-echo` (`echoed: true`
|
|
35
|
-
on `RecallResult`)
|
|
36
|
-
from a near-identity echo.
|
|
34
|
+
on `RecallResult`); it declares `used: ∅`. Consumers distinguish a continuation
|
|
35
|
+
through learned edges from a near-identity echo.
|
|
37
36
|
|
|
38
37
|
## Substitution bridge — refusal-path only (`src/mind/bridge.ts`)
|
|
39
38
|
|
|
@@ -47,13 +46,13 @@ unanimous, and the raw gap is length-balanced. Coverage must dominate the query
|
|
|
47
46
|
and no dismissed gap may hide known content (`dismissedKnownContent` gate). Cost
|
|
48
47
|
is `CONCEPT` per substitution plus `STEP`; accounted spans include matched and
|
|
49
48
|
substituted ranges (so a 28/29-byte paraphrase is not charged `PASS` per
|
|
50
|
-
substituted byte —
|
|
49
|
+
substituted byte — the double-charge that let `cast` outbid the bridge).
|
|
51
50
|
Zero-substitution identity bridges carry `complete: true` (the whole read-out);
|
|
52
51
|
substituted bridges do not.
|
|
53
52
|
|
|
54
|
-
Scaffolding-only queries abstain: when every
|
|
53
|
+
Scaffolding-only queries abstain: when every window that could anchor is
|
|
55
54
|
saturated (corpus-global scaffolding, `allWindowsAreScaffolding`), the bridge
|
|
56
|
-
returns nothing —
|
|
55
|
+
returns nothing — one substituted word cannot carry the load.
|
|
57
56
|
|
|
58
57
|
## Cost
|
|
59
58
|
|
package/example/demo.ts
CHANGED
|
@@ -1,44 +1,97 @@
|
|
|
1
|
-
// demo.ts —
|
|
1
|
+
// demo.ts — a corpus goes in, and the memory is read back out.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// Sema is given a small corpus of plain notes, each one the shape every deposit
|
|
4
|
+
// has: a context, and what follows it. Then the memory is read two ways — what
|
|
5
|
+
// it HOLDS (`sampleCorpus`), and which of its notes a question REACHES
|
|
6
|
+
// (`searchCorpusText`). Both run through the same content-addressed machinery an
|
|
7
|
+
// answer uses (src/mind/corpus.ts); nothing is indexed and nothing is written.
|
|
8
|
+
//
|
|
9
|
+
// The search addresses content EXACTLY, not by keyword: a question reaches a
|
|
10
|
+
// note when it shares chunk-aligned content with it, so a question with no such
|
|
11
|
+
// overlap is reported as exactly that — a STATE, rendered by the text layer
|
|
12
|
+
// (`CorpusTextResult.note`), never as prose the engine invented.
|
|
13
|
+
//
|
|
14
|
+
// The last act is two ordinary answers, each with its derivation streamed as it
|
|
15
|
+
// unfolds, the PROVENANCE that names the route it grounded on, and the work it
|
|
16
|
+
// cost read off the meter: the rationale and the meter ARE the explanation
|
|
17
|
+
// surface (AGENTS.md §6).
|
|
18
|
+
|
|
19
|
+
import { decodeText, formatReport, Mind, SQliteStore } from "../src/index.js";
|
|
20
|
+
|
|
21
|
+
// One relation shown three times — a pattern taught purely by example — plus a
|
|
22
|
+
// stray fact keyed on a name none of the examples mention.
|
|
23
|
+
const CORPUS: Array<[string, string]> = [
|
|
24
|
+
["The Mona Lisa was painted by Leonardo da Vinci.", "Leonardo da Vinci"],
|
|
25
|
+
["The Starry Night was painted by Vincent van Gogh.", "Vincent van Gogh"],
|
|
26
|
+
[
|
|
27
|
+
"The Night Watch was painted by Rembrandt van Rijn.",
|
|
28
|
+
"Rembrandt van Rijn",
|
|
29
|
+
],
|
|
30
|
+
["Pablo Picasso", "Pablo Picasso co-founded the Cubist movement"],
|
|
31
|
+
["The Weeping Woman was painted by Pablo Picasso.", "Pablo Picasso"],
|
|
32
|
+
];
|
|
10
33
|
|
|
11
|
-
|
|
12
|
-
|
|
34
|
+
// Questions the corpus can address, and one it cannot — the honest miss.
|
|
35
|
+
const QUERIES = [
|
|
36
|
+
"The Mona Lisa was painted by Leonardo da Vinci.",
|
|
37
|
+
"Pablo Picasso",
|
|
38
|
+
"xylophone",
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
// One question answered by composing across the notes, and one answered by
|
|
42
|
+
// computing: the two routes the corpus search does not take.
|
|
43
|
+
const ASKS = [
|
|
44
|
+
"The Weeping Woman was painted by Pablo Picasso.",
|
|
45
|
+
"a museum charges 12*4 for a family ticket",
|
|
46
|
+
];
|
|
13
47
|
|
|
14
48
|
async function main(): Promise<void> {
|
|
15
|
-
const mind = new Mind({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
await mind.ingest(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
//
|
|
49
|
+
const mind = new Mind({
|
|
50
|
+
store: new SQliteStore({ path: ":memory:" }),
|
|
51
|
+
profile: true,
|
|
52
|
+
});
|
|
53
|
+
await mind.ingest(CORPUS);
|
|
54
|
+
|
|
55
|
+
// 1) WHAT THE MEMORY HOLDS — real pairs, browsed, no query and no random draw.
|
|
56
|
+
console.log("— the corpus, as the memory holds it —");
|
|
57
|
+
for (const p of mind.sampleCorpus(4).pairs) {
|
|
58
|
+
console.log(` ${decodeText(p.context)} → ${decodeText(p.continuation)}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 2) SEARCH — which stored notes does a question reach? A question that
|
|
62
|
+
// addresses the corpus answers with pairs; one that shares nothing with it
|
|
63
|
+
// answers with a note saying so.
|
|
64
|
+
for (const q of QUERIES) {
|
|
65
|
+
const r = mind.searchCorpusText(q, 3);
|
|
66
|
+
console.log(`\n— "${q}" — ${r.resolved} resolved / ${r.reached} reached`);
|
|
67
|
+
if (r.note !== undefined) console.log(` ${r.note}`);
|
|
68
|
+
for (const p of r.pairs) {
|
|
69
|
+
console.log(
|
|
70
|
+
` ${p.context} → ${p.continuation} (${p.matchedBytes} matched)`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 3) ANSWERS, WITH THEIR DERIVATION — the same pipeline, read as data. Steps
|
|
76
|
+
// repeat (recognise re-enters under every mechanism that needs it), so each
|
|
77
|
+
// distinct mechanism-and-note is printed once, in the order it first ran.
|
|
78
|
+
for (const q of ASKS) {
|
|
79
|
+
const seen = new Set<string>();
|
|
80
|
+
const trace: string[] = [];
|
|
81
|
+
const r = await mind.respond(q, (s) => {
|
|
82
|
+
const line = `${s.mechanism.join(" › ")}${s.note ? ` — ${s.note}` : ""}`;
|
|
83
|
+
if (seen.has(line)) return;
|
|
84
|
+
seen.add(line);
|
|
85
|
+
trace.push(`${" ".repeat(Math.max(0, s.mechanism.length - 1))}${line}`);
|
|
86
|
+
});
|
|
87
|
+
console.log(`\n— "${q}" — ${r.provenance ?? "no answer"}`);
|
|
88
|
+
console.log(` ${decodeText(r.bytes).trim()}`);
|
|
89
|
+
console.log("— how —");
|
|
90
|
+
for (const s of trace) console.log(s);
|
|
91
|
+
if (mind.lastCost !== null) {
|
|
92
|
+
console.log(`— what it cost —\n${formatReport(mind.lastCost)}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
42
95
|
|
|
43
96
|
await mind.store.close();
|
|
44
97
|
}
|
package/jsr.json
CHANGED
package/package.json
CHANGED
package/src/alu/README.md
CHANGED
|
@@ -8,10 +8,10 @@ a truth value) are declared here once.
|
|
|
8
8
|
|
|
9
9
|
It joins the mind as a `PipelineMechanism`
|
|
10
10
|
([`../mind/pipeline-mechanism.ts`](../mind/pipeline-mechanism.ts)) whose only
|
|
11
|
-
special role is the optional `parse(query)`
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
15
|
|
|
16
16
|
It has no dependency on the rest of the codebase except the pure byte helpers in
|
|
17
17
|
`../bytes.ts`, and is intended to be reused as a self-contained sublibrary in
|
|
@@ -166,7 +166,7 @@ The ALU is completely decoupled from Sema. It joins the mind through
|
|
|
166
166
|
re-exported from [`../mind/pipeline.ts`](../mind/pipeline.ts)), a thin adapter
|
|
167
167
|
that wraps the ALU's `parse` in a `PipelineMechanism` — the same uniform
|
|
168
168
|
interface every grounding mechanism (CAST, confluence, cover, extraction,
|
|
169
|
-
recall) implements, so nothing about the ALU is special-cased
|
|
169
|
+
recall) implements, so nothing about the ALU is special-cased.
|
|
170
170
|
|
|
171
171
|
### The contract
|
|
172
172
|
|
|
@@ -175,7 +175,7 @@ recall) implements, so nothing about the ALU is special-cased in the pipeline.
|
|
|
175
175
|
```ts
|
|
176
176
|
interface PipelineMechanism {
|
|
177
177
|
parse?(query: Uint8Array): Promise<ComputedSpan[]>;
|
|
178
|
-
floor(ctx, query, pre): Promise<number | null>;
|
|
178
|
+
floor(ctx, query, pre, worthRunning): Promise<number | null>;
|
|
179
179
|
run(ctx, query, pre): Promise<MechanismResult[]>;
|
|
180
180
|
}
|
|
181
181
|
```
|
|
@@ -259,7 +259,7 @@ whose span overlaps a computed span is **masked** before the search. This is the
|
|
|
259
259
|
the computed `4` is the cover's sole completion there. The search itself stays a
|
|
260
260
|
neutral cost engine (a computed `Out` and a learned edge both cost `STEP`);
|
|
261
261
|
precedence lives entirely in the masking step, which is in
|
|
262
|
-
`src/mind/
|
|
262
|
+
`src/mind/mechanisms/cover.ts`, not in the search and not in the ALU.
|
|
263
263
|
|
|
264
264
|
A computation and an _unrelated_ rewrite still compose in one answer
|
|
265
265
|
(`"ice 2+2"` → `"cold 4"`) because the masking is scoped to the colliding span
|
|
@@ -302,11 +302,10 @@ registry.derive("hypot", 2, ["hypot"], (args, ctx) =>
|
|
|
302
302
|
]));
|
|
303
303
|
```
|
|
304
304
|
|
|
305
|
-
No kernel
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
kernel's own.
|
|
305
|
+
No kernel, graph-search or resonance edit — name it, list its surface forms,
|
|
306
|
+
write the body from existing ops. A scalar op broadcasts over `nd`
|
|
307
|
+
automatically; pass `structural = true` (the trailing flag on `prim`/`derive`)
|
|
308
|
+
only for an op that consumes a list _whole_, like the `nd` kernel's own.
|
|
310
309
|
|
|
311
310
|
## Layout
|
|
312
311
|
|
package/src/config.ts
CHANGED
|
@@ -116,6 +116,17 @@ export interface MindConfig {
|
|
|
116
116
|
seed: number;
|
|
117
117
|
recallQueryK: number;
|
|
118
118
|
haloQueryK: number;
|
|
119
|
+
/** Branch nodes the pivot sweep may PROBE looking for the learnt context an
|
|
120
|
+
* answer contains — the pivot's own shortlist capacity, separate from
|
|
121
|
+
* `recallQueryK` because they are different quantities: this one bounds a
|
|
122
|
+
* MECHANICAL sweep over the answer's tree (breadth-first, largest regions
|
|
123
|
+
* first, so an exhausted allowance drops the far ones and never the near
|
|
124
|
+
* ones), while `recallQueryK` bounds the bridge's candidate reads. Sharing
|
|
125
|
+
* one number for both meant that tightening either silently starved the
|
|
126
|
+
* other — measured: at `recallQueryK: 1` the pivot cannot find a pivot at
|
|
127
|
+
* all. (`rationaleSampleK` was split out of `recallQueryK` for the same
|
|
128
|
+
* reason, found by an adversarial review.) */
|
|
129
|
+
pivotProbeK: number;
|
|
119
130
|
/** Corpus reading (see src/mind/corpus.ts): results per call, resolved
|
|
120
131
|
* nodes climbed from, contexts requested per climb, probes used to stride
|
|
121
132
|
* the id space when browsing, bytes of each side a preview keeps, and the
|
|
@@ -148,6 +159,7 @@ export const DEFAULT_CONFIG: MindConfig = {
|
|
|
148
159
|
seed: 42,
|
|
149
160
|
recallQueryK: 12,
|
|
150
161
|
haloQueryK: 12,
|
|
162
|
+
pivotProbeK: 12,
|
|
151
163
|
rationaleSampleK: 12,
|
|
152
164
|
corpusLimitMax: 24,
|
|
153
165
|
corpusClimbs: 24,
|
|
@@ -196,6 +208,7 @@ export function resolveConfig(opts: Partial<MindConfig> = {}): MindConfig {
|
|
|
196
208
|
seed: opts.seed ?? DEFAULT_CONFIG.seed,
|
|
197
209
|
recallQueryK: opts.recallQueryK ?? DEFAULT_CONFIG.recallQueryK,
|
|
198
210
|
haloQueryK: opts.haloQueryK ?? DEFAULT_CONFIG.haloQueryK,
|
|
211
|
+
pivotProbeK: opts.pivotProbeK ?? DEFAULT_CONFIG.pivotProbeK,
|
|
199
212
|
rationaleSampleK: opts.rationaleSampleK ?? DEFAULT_CONFIG.rationaleSampleK,
|
|
200
213
|
corpusLimitMax: opts.corpusLimitMax ?? DEFAULT_CONFIG.corpusLimitMax,
|
|
201
214
|
corpusClimbs: opts.corpusClimbs ?? DEFAULT_CONFIG.corpusClimbs,
|
package/src/geometry.ts
CHANGED
|
@@ -155,23 +155,31 @@ export function profileCapacity(D: number): number {
|
|
|
155
155
|
return Math.max(1, Math.floor(Math.sqrt(D)));
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
/**
|
|
159
|
+
* The POOLED-vote significance floor, and the derivation lives here because
|
|
160
|
+
* its PREMISE is a property of the caller's weighting.
|
|
161
|
+
*
|
|
162
|
+
* DERIVATION (docs/architecture/thresholds.md §2): a maximally-specific region
|
|
163
|
+
* contributes at most `ln N` to a pooled vote, so `ln(N) + 1/2` sits half a
|
|
164
|
+
* unit above ONE region's ceiling — it demands corroboration BEYOND a single
|
|
165
|
+
* region, which is what makes it a consensus bar rather than a resonance bar.
|
|
166
|
+
*
|
|
167
|
+
* PREMISE: that per-region ceiling is an IDF, `ln(N/c)` — attention.ts's
|
|
168
|
+
* `inverse` mode, the mode every non-test caller runs. The other two modes
|
|
169
|
+
* weight a region by `ln(1+c)` (`direct`) or `ln(N/c) + ln(1+c)` (`combined`),
|
|
170
|
+
* i.e. `ln N + ln(1 + 1/c)`, so they exceed the premise's ceiling by at most
|
|
171
|
+
* `ln 2` — a DERIVED bound, not a hole: the floor stays within `ln 2` of its
|
|
172
|
+
* own premise in every mode, and exactly on it in `inverse`.
|
|
173
|
+
*
|
|
174
|
+
* MEASURED: the floor is read on the pooled vote (`commitVotes`, `recall`,
|
|
175
|
+
* `cast`). Across 27 anchors on 6 queries, 11 cleared it by the sum and NONE
|
|
176
|
+
* by a single region's peak — gating on one region would refuse every elected
|
|
177
|
+
* root.
|
|
178
|
+
*/
|
|
158
179
|
export function consensusFloor(N: number): number {
|
|
159
180
|
return Math.log(N) + 1 / 2;
|
|
160
181
|
}
|
|
161
182
|
|
|
162
|
-
/** The coverage bar for the reach (interior) index, when vector-similarity
|
|
163
|
-
* gating is used. Returns the concept threshold — the structural midpoint
|
|
164
|
-
* (~0.5 at D=1024) where two forms are "more similar than not."
|
|
165
|
-
*
|
|
166
|
-
* Currently UNUSED in the hot training path: interior nodes are indexed
|
|
167
|
-
* unconditionally (hash-cons dedup bounds the index naturally).
|
|
168
|
-
* Post-hoc structural compaction ({@link Store.compactContentIndex})
|
|
169
|
-
* replaces runtime coverage gating with a batch pass that removes
|
|
170
|
-
* structurally-isolated entries. Derived, never tuned. */
|
|
171
|
-
export function coverageBar(_maxGroup: number, D: number): number {
|
|
172
|
-
return conceptThreshold(D);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
183
|
// ---- types ----
|
|
176
184
|
|
|
177
185
|
export interface Folded {
|
package/src/meter.ts
CHANGED
|
@@ -223,6 +223,12 @@ export class Meter {
|
|
|
223
223
|
joinNoKey = 0;
|
|
224
224
|
/** Refused: the fact contains no entity that leads anywhere. */
|
|
225
225
|
joinNoEntity = 0;
|
|
226
|
+
/** `recompleteNode` re-covered a produced form — the descent that decomposes
|
|
227
|
+
* a completion by ITS OWN kids. Without this the descent is invisible: a
|
|
228
|
+
* caller could see the chain's result but not whether the recomposition
|
|
229
|
+
* happened, so "the recursion stopped" and "the recursion never ran" were
|
|
230
|
+
* indistinguishable from the counters alone. */
|
|
231
|
+
recompletes = 0;
|
|
226
232
|
|
|
227
233
|
// ── Mind: the multi-hop pivot (EXTENSION) ───────────────────────────────
|
|
228
234
|
//
|
|
@@ -233,6 +239,62 @@ export class Meter {
|
|
|
233
239
|
/** Times the reasoner pivoted on a span its answer contains and stepped
|
|
234
240
|
* across that fact. */
|
|
235
241
|
pivotSteps = 0;
|
|
242
|
+
/** Canon probes REFUSED because the canon budget ran out — the one thing the
|
|
243
|
+
* budget does that nothing could see. The budget itself is derived
|
|
244
|
+
* (`bytes.length · chainReach(W)²`, recognition.ts), and the cheap exact route
|
|
245
|
+
* is deliberately unbudgeted, so this counter says exactly when the expensive
|
|
246
|
+
* route was priced out. Counted where the fact happens (the `!canonBudget`
|
|
247
|
+
* refusal), not where the probe is called. */
|
|
248
|
+
canonProbesDenied = 0;
|
|
249
|
+
/** The pipeline's remainder AT THE DECISION POINT, in bytes: what the grounded
|
|
250
|
+
* answer plus the pre-computed spans left unexplained, after the same W floor
|
|
251
|
+
* the fuse gate uses. This is the quantity that licenses (or refuses) the
|
|
252
|
+
* post-grounding extension and the fusion — it was computed, used, and never
|
|
253
|
+
* published, so nothing could measure what a search had LEFT when it decided.
|
|
254
|
+
* Read with {@link postGroundingRemainderSpans}. */
|
|
255
|
+
postGroundingRemainderBytes = 0;
|
|
256
|
+
/** How many spans that remainder consists of (each at least one W window). */
|
|
257
|
+
postGroundingRemainderSpans = 0;
|
|
258
|
+
/** Times `fuseAttention` produced a FUSED answer — not times it was called.
|
|
259
|
+
* It is entered whenever the query has a remainder ≥ W and returns early when
|
|
260
|
+
* there is nothing to bridge (`containsSpan`, a lone root, an empty pass), so
|
|
261
|
+
* the call and the fact are different things and only the fact is counted.
|
|
262
|
+
* Its own rationale step reports the fusion; this is the untraced view, and
|
|
263
|
+
* its cost is one bridging edge: `fuseRuns · STEP`. */
|
|
264
|
+
fuseRuns = 0;
|
|
265
|
+
/** Steps the post-grounding EXTENSION took — pivots plus forward-absorbs.
|
|
266
|
+
* `pivotSteps` counts only the former, so before this the extension's COST was
|
|
267
|
+
* not computable at all. With it, the price of extending the answer is
|
|
268
|
+
* `reasonSteps · STEP`, the ladder's own value for following an edge. */
|
|
269
|
+
reasonSteps = 0;
|
|
270
|
+
/** Bytes of the grounding's UNCOVERED material the extension was justified by
|
|
271
|
+
* — the union of the spans each step carried a `W`-window of. The gate
|
|
272
|
+
* already computed WHICH span carried it per step and kept only a boolean;
|
|
273
|
+
* this is that fact, accumulated. Read with {@link reasonSteps}: one is the
|
|
274
|
+
* price, the other the explanation. */
|
|
275
|
+
reasonCarriedBytes = 0;
|
|
276
|
+
/** Bytes of the question's REMAINDER a step CONSUMED — the drop the law's own
|
|
277
|
+
* `advance` makes when a declared move carries the material it accounts for.
|
|
278
|
+
* Read with {@link reasonSteps} and {@link reasonCarriedBytes}: carrying is
|
|
279
|
+
* the engagement, this is the consumption, and before it the second was
|
|
280
|
+
* invisible. */
|
|
281
|
+
closureDrainedBytes = 0;
|
|
282
|
+
/** Bytes of the question the grounding PRICED but whose material its answer does
|
|
283
|
+
* NOT carry, at or above one quantum — the debt the construction leaves for the
|
|
284
|
+
* walk to pay by carrying it. Zero means the grounding's coverage is honest:
|
|
285
|
+
* everything it priced is either held by the answer or under the W floor. */
|
|
286
|
+
groundingWithheldBytes = 0;
|
|
287
|
+
/** Branch-node probes the pivot sweep actually spent looking for the learnt
|
|
288
|
+
* context an answer contains (one `resonate` per probe). The untraced view
|
|
289
|
+
* of what the multi-hop's shortlist costs. */
|
|
290
|
+
pivotProbes = 0;
|
|
291
|
+
/** Branch nodes the pivot's probe cap withheld (`branchCount − probeCap`, over
|
|
292
|
+
* every call). A capacity fact, not a verdict: the sweep is breadth-first,
|
|
293
|
+
* so the probes it DOES spend are the largest regions, and recognition still
|
|
294
|
+
* contributes every exact containment candidate regardless of the budget.
|
|
295
|
+
* Read it with {@link pivotProbes} — one says the work, the other the
|
|
296
|
+
* shortfall. */
|
|
297
|
+
pivotBranchesUnprobed = 0;
|
|
236
298
|
|
|
237
299
|
// ── Mind: the cover's connector assembly (LIMIT) ────────────────────────
|
|
238
300
|
//
|