@hviana/sema 0.8.3 → 0.8.6
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 +11 -10
- package/README.md +17 -38
- package/dist/example/demo.js +85 -34
- package/dist/src/geometry.d.ts +0 -10
- package/dist/src/geometry.js +0 -12
- package/dist/src/meter.d.ts +31 -5
- package/dist/src/meter.js +31 -5
- package/dist/src/mind/articulation.js +1 -1
- package/dist/src/mind/attention.js +2 -1
- 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 +37 -15
- package/dist/src/mind/match.d.ts +2 -0
- package/dist/src/mind/match.js +2 -0
- 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 +15 -18
- package/dist/src/mind/mechanisms/confluence.d.ts +0 -3
- package/dist/src/mind/mechanisms/confluence.js +3 -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 +8 -9
- package/dist/src/mind/mechanisms/reference.js +3 -4
- package/dist/src/mind/pipeline-mechanism.d.ts +1 -4
- package/dist/src/mind/pipeline.js +106 -41
- package/dist/src/mind/rationale.d.ts +0 -11
- package/dist/src/mind/rationale.js +6 -32
- package/dist/src/mind/reasoning.d.ts +4 -30
- package/dist/src/mind/reasoning.js +191 -151
- 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 +4 -4
- package/docs/architecture/closure.md +78 -0
- package/docs/architecture/commonality.md +27 -18
- package/docs/architecture/cost-model.md +5 -5
- package/docs/architecture/exact-vs-approximate.md +4 -4
- package/docs/architecture/factored-machinery.md +14 -14
- package/docs/architecture/mechanism-market.md +9 -9
- package/docs/architecture/meter.md +4 -5
- package/docs/architecture/store.md +2 -2
- package/docs/architecture/thresholds.md +1 -1
- package/docs/failures/tempting-but-wrong.md +11 -1
- package/docs/harness/gates.md +6 -6
- package/docs/mechanisms/cover.md +2 -2
- package/example/demo.ts +90 -37
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/geometry.ts +0 -13
- package/src/meter.ts +31 -5
- package/src/mind/articulation.ts +0 -1
- package/src/mind/attention.ts +2 -1
- package/src/mind/derivation.ts +477 -0
- package/src/mind/graph-search.ts +37 -20
- package/src/mind/match.ts +2 -0
- package/src/mind/mechanisms/alu.ts +0 -2
- package/src/mind/mechanisms/cast.ts +17 -21
- package/src/mind/mechanisms/confluence.ts +3 -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 +7 -9
- package/src/mind/mechanisms/reference.ts +2 -3
- package/src/mind/pipeline-mechanism.ts +1 -4
- package/src/mind/pipeline.ts +121 -46
- package/src/mind/rationale.ts +6 -36
- package/src/mind/reasoning.ts +220 -178
- package/src/mind/types.ts +5 -2
- package/test/121-the-extension-does-not-grow-with-the-corpus.test.mjs +3 -3
- 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/142-the-layer-offers-only-what-the-law-admits.test.mjs +93 -0
- package/test/143-cycles-terminate-and-are-not-closure.test.mjs +62 -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 +22 -2
- package/test/55-cost-meter.test.mjs +6 -3
package/docs/INVARIANTS.md
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
# INVARIANTS — Laws, Proofs, Derivations
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
|
6
|
-
|
|
|
7
|
-
|
|
|
8
|
-
|
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
-
| 13 | Saturation | `traverse.ts:edgeAncestors,types.ts:SaturationReason` `src/mind/junction.ts:junctionContainersFrom` `src/mind/resonance.ts:pivotInto` | `test/27` `test/16` | `saturation.md` |
|
|
3
|
+
| # | Law | Defined in | Pins | Doc |
|
|
4
|
+
| -- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ------------------------- |
|
|
5
|
+
| 1 | Determinism | `src/config.ts:seed` `src/alphabet.ts:Alphabet` `src/mind/traverse.ts:guidedFirst` | `test/20` `test/42` | `determinism.md` |
|
|
6
|
+
| 2 | Derived thresholds | `src/geometry.ts:mergeThreshold,identityBar,reachThreshold,significanceBar,consensusFloor,dominates` | `test/64` `test/40` | `thresholds.md` |
|
|
7
|
+
| 3 | Exact decides / approximate proposes | `src/mind/primitives.ts:resolve` `src/mind/match.ts:locate,alignGraded` `src/mind/resonance.ts:bridge` | `test/51` | `exact-vs-approximate.md` |
|
|
8
|
+
| 4 | One cost currency | `src/mind/graph-search.ts:MICRO,STEP,CONCEPT,PASS` `src/derive:lightestDerivation` (min,+) `src/mind/attention.ts:poolVotes` (+,+) | `test/55` `test/04` | `cost-model.md` |
|
|
9
|
+
| 5 | Bounded reads | `src/store.ts:AbstractStore:nextFirst,parentsFirst,containersSlice,hasNext,bytesPrefix` `src/mind/traverse.ts:hubBound,hubCap` | `test/90` `test/14` | `bounded-reads.md` |
|
|
10
|
+
| 6 | Fold contract | `src/geometry.ts:contentLevels` `src/mind/canonical.ts:canonicalWindows,chainReach` `src/canon.ts:canonicalizer` | `test/59` `test/63` | `fold-contract.md` |
|
|
11
|
+
| 7 | Mechanism market | `src/mind/pipeline-mechanism.ts:PipelineMechanism,Precomputed` `src/mind/pipeline.ts:think,worthRunning` | `test/01` `test/04` | `mechanism-market.md` |
|
|
12
|
+
| 8 | Two commonality measures | `src/mind/traverse.ts:reachOf,dominates,corpusN` (global) `cast.ts:depth[],MIN_WEAVE` (weave-local) | `test/17` `test/34` | `commonality.md` |
|
|
13
|
+
| 9 | Memoization idempotence | `src/mind/pipeline-mechanism.ts:Precomputed` `src/mind/mind.ts:beginResponse,endResponse,_resolvedSubtrees` | `test/42` | `memoization.md` |
|
|
14
|
+
| 10 | Caches as budgets | `src/store.ts:BoundedMap` `src/config.ts:StoreConfig:bytesCacheMax,recCacheBytes,haloCacheBytes` | `test/96` `test/91` | `caches.md` |
|
|
15
|
+
| 11 | Honest degradation | `src/mind/pipeline.ts:weight=moves+PASS*unaccounted` `src/store.ts:BoundedMap:miss→re-derive` | `test/28` `test/84` | `store.md`+`caches.md` |
|
|
16
|
+
| 12 | Meter contracts | `src/meter.ts:Meter,PhaseCost,time` `src/mind/pipeline-mechanism.ts:Precomputed.shared` | `test/55` | `meter.md` |
|
|
17
|
+
| 13 | Saturation | `traverse.ts:edgeAncestors,types.ts:SaturationReason` `src/mind/junction.ts:junctionContainersFrom` `src/mind/resonance.ts:pivotInto` | `test/27` `test/16` | `saturation.md` |
|
|
18
|
+
| 14 | Closure | `src/mind/derivation.ts:closed,admissible,advance` | `test/133`–`143` | `closure.md` |
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
> **Law:** the cost of one query is proportional to the query, not to how much
|
|
4
4
|
> was learned. No per-query read may grow with corpus size N.
|
|
5
5
|
|
|
6
|
-
Every fan-out, walk, and disambiguation
|
|
7
|
-
`ceil(sqrt(N))
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
Every fan-out, walk, and disambiguation reads at most the OLDEST `hubBound` —
|
|
7
|
+
`ceil(sqrt(N))`, floored at 2 for a near-empty store. A better-supported
|
|
8
|
+
candidate beyond that prefix is invisible: a trade, and there is no second
|
|
9
|
+
convention.
|
|
10
10
|
|
|
11
11
|
## Scale
|
|
12
12
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Closure — One Law, One Unit, Every Transition
|
|
2
|
+
|
|
3
|
+
> **Law:** a step is admitted only when it CLOSES the derivation, or MOVES to
|
|
4
|
+
> structure it has not consumed, or CARRIES material the asker left unaccounted.
|
|
5
|
+
|
|
6
|
+
One unit and one law, asked by every tier that decides whether to continue: the
|
|
7
|
+
chart's frontier, the market's candidates, the post-grounding walk, fusion, and
|
|
8
|
+
the mechanisms' own gates. None re-spells a condition the law owns.
|
|
9
|
+
|
|
10
|
+
## The unit — `src/mind/derivation.ts`
|
|
11
|
+
|
|
12
|
+
| Field | What it is |
|
|
13
|
+
| ----------- | ----------------------------------------------------- |
|
|
14
|
+
| `product` | the answer bytes so far |
|
|
15
|
+
| `accounted` | the spans of the asker's bytes it explains |
|
|
16
|
+
| `remainder` | what the asker still owes, per span, at the `W` floor |
|
|
17
|
+
| `cost` | the currency's total for the steps taken |
|
|
18
|
+
| `fixed` | a declared fixpoint: no transition is offered |
|
|
19
|
+
| `used` | the anchors the producer speaks for |
|
|
20
|
+
|
|
21
|
+
No identity field (`resolve(product)` is one), no structure field, no frontier
|
|
22
|
+
field, no producer field, and no count of any kind. The witnesses `contains` and
|
|
23
|
+
`moves` are the LAYER's: it holds the structure and hands them in, so the law
|
|
24
|
+
never probes the store.
|
|
25
|
+
|
|
26
|
+
## The boundary
|
|
27
|
+
|
|
28
|
+
`product` (what it stands on, its identity being `resolve(product)`),
|
|
29
|
+
`accounted` (the price its steps summed) and `remainder` (the question's debt,
|
|
30
|
+
at one quantum) are the derivation's own. What it REACHED and what it SPENT are
|
|
31
|
+
the layer's (`reaches`, `consumed`), never a field here: the law decides
|
|
32
|
+
admission and consumption, the layer decides frontier and termination.
|
|
33
|
+
|
|
34
|
+
## The transition
|
|
35
|
+
|
|
36
|
+
`admissible(state, continuation, query, W)` returns the witnesses the step pays
|
|
37
|
+
in, or `null`; `advance(state, continuation, witnesses)` is the only transition.
|
|
38
|
+
The remainder is consumed only by a declared move, and only by the material that
|
|
39
|
+
move CARRIES: `carries` admits by ENGAGEMENT and consumes nothing, a move
|
|
40
|
+
consumes what its window proves. Whole-span draining was refuted by `test/110`,
|
|
41
|
+
the window alone by `test/138`. The state is BORN owing what its product does
|
|
42
|
+
not carry.
|
|
43
|
+
|
|
44
|
+
The walk ends when the layer stops offering or the law refuses; owning no
|
|
45
|
+
search, the law cannot prevent a cycle — that is the layer's, over the structure
|
|
46
|
+
it holds.
|
|
47
|
+
|
|
48
|
+
## One cost home
|
|
49
|
+
|
|
50
|
+
`moves + PASS · unaccountedBytes` is computed in ONE place (`pipeline.ts`,
|
|
51
|
+
`weigh`). A mechanism reports `moves` and `accounted` — what it did — and never
|
|
52
|
+
a price; `cover` reports its chart derivation's work.
|
|
53
|
+
|
|
54
|
+
## Two limits, proved and left out
|
|
55
|
+
|
|
56
|
+
1. **The chart cannot evaluate accounting** — its interface has no parameter for
|
|
57
|
+
it, and carrying it per item was measured and rejected. The chart reads the
|
|
58
|
+
same law off an item: identity is its `key`, continuation the rule's
|
|
59
|
+
existence, progress the frontier advancing, closure the goal test, `fix` is
|
|
60
|
+
`fixed`.
|
|
61
|
+
2. **Closure by the query's position in the graph is not a term of the unit** —
|
|
62
|
+
`reason`'s echo guards stop with the remainder non-empty, and recall's
|
|
63
|
+
reverse tiers close with an empty accounting. That is a fact about the
|
|
64
|
+
asker's material in the store, available only to the layer holding it.
|
|
65
|
+
|
|
66
|
+
## Layering
|
|
67
|
+
|
|
68
|
+
Imports `../bytes.js` only, and sits below `graph-search.ts`, `match.ts`,
|
|
69
|
+
`rationale.ts` and `pipeline.ts`. The span algebra lives here too — the law's
|
|
70
|
+
vocabulary, not the tracer's.
|
|
71
|
+
|
|
72
|
+
## Pins
|
|
73
|
+
|
|
74
|
+
- `test/133`–`137` — the law's home, readings, refusal, limits.
|
|
75
|
+
- `test/138` — a cycle cannot close it, a carried move can.
|
|
76
|
+
- `test/139` — carrying is ENGAGEMENT, not explanation.
|
|
77
|
+
- `test/140` — irrelevant supply changes nothing.
|
|
78
|
+
- `test/142`, `test/143` — the offer's contract, and the cycles.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Three Measures of Commonality
|
|
2
2
|
|
|
3
|
-
Sema needs "what is shared" in
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Sema needs "what is shared" in three populations: corpus-global (how widely a
|
|
4
|
+
structure is reused), weave-local (what a local cohort of overlapping forms
|
|
5
|
+
agrees on), and container-local (how many containers hold a byte window).
|
|
6
|
+
Different data, different formulas, never conflated.
|
|
7
7
|
|
|
8
8
|
## Corpus-global — `reachOf` + `dominates`
|
|
9
9
|
|
|
@@ -11,11 +11,11 @@ _Defined in `src/mind/traverse.ts` + `src/geometry.ts`; used by climb,
|
|
|
11
11
|
containment, IDF pooling._
|
|
12
12
|
|
|
13
13
|
For a node id, `reachOf(id, N)` counts how many learnt contexts contain it
|
|
14
|
-
(
|
|
15
|
-
`
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
(capped graph walks, memoised per response in `sharedReachMemo`).
|
|
15
|
+
`dominates(reach, N)` asks whether that reach is above the corpus-determined
|
|
16
|
+
majority threshold (`geometry.ts`, over `N`). Minority reach discriminates (a
|
|
17
|
+
filler), majority reach is scaffolding. Powers the climb, edge following and
|
|
18
|
+
vote pooling.
|
|
19
19
|
|
|
20
20
|
## Weave-local — `depth[]` + `MIN_WEAVE` + `dominates`
|
|
21
21
|
|
|
@@ -23,20 +23,29 @@ _Defined and gated in `src/mind/mechanisms/cast.ts` (`depth[]` from the shared
|
|
|
23
23
|
weave, `MIN_WEAVE`); used by CAST._
|
|
24
24
|
|
|
25
25
|
For an alignment weave, `depth[i]` counts how many aligned structures cover byte
|
|
26
|
-
`i` of the query
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
`i` of the query; `MIN_WEAVE = 2` requires agreement beyond a pair (pairs are
|
|
27
|
+
ambiguous with insertions), and `dominates(depth[i], aligned)` a majority of the
|
|
28
|
+
cohort:
|
|
29
29
|
|
|
30
30
|
```
|
|
31
31
|
frame(i) ⇔ depth[i] > MIN_WEAVE ∧ dominates(depth[i], aligned)
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
This powers CAST's frame gate
|
|
35
|
-
|
|
34
|
+
This powers CAST's frame gate — what the cohort shares vs what differentiates
|
|
35
|
+
one member — and never consults corpus reach.
|
|
36
36
|
|
|
37
|
-
The
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
The three answer different questions over different populations; CAST's frame
|
|
38
|
+
must not be replaced by a reach check, and the climb must not be driven by weave
|
|
39
|
+
depth.
|
|
40
|
+
|
|
41
|
+
## Container-local — the window's rarity
|
|
42
|
+
|
|
43
|
+
_Defined in `src/mind/bridge.ts` (`containersSlice(id, 0, bound + 1).length`);
|
|
44
|
+
used by the bridge, and by attention's anchoring._
|
|
45
|
+
|
|
46
|
+
`rarity` counts how many containers hold a byte window: zero anchors nothing,
|
|
47
|
+
two or more marks it REUSED (`winReused`), and the bridge sorts its anchors by
|
|
48
|
+
it, so the rarest leads. Purpose: choosing what to anchor on.
|
|
40
49
|
|
|
41
50
|
## Pins
|
|
42
51
|
|
|
@@ -19,17 +19,17 @@ with that order give the same derivations.
|
|
|
19
19
|
|
|
20
20
|
## Pipeline weighing (`src/mind/pipeline.ts:think`)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Candidates are weighed in ONE place — a mechanism reports `moves` and
|
|
23
|
+
`accounted`, never a price:
|
|
23
24
|
|
|
24
25
|
```
|
|
25
26
|
weight = moves + PASS * unaccounted_bytes
|
|
26
27
|
grade = floor(weight / STEP)
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
`unaccounted` is
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
then does mechanism list order decide.
|
|
30
|
+
`unaccounted` is what no `accounted` span covers. Comparison is at `STEP`
|
|
31
|
+
resolution: lowest `grade` wins; at equal grade fewer `scaffolding` bytes
|
|
32
|
+
(answer bytes lifted from unrecognised spans) wins; then list order.
|
|
33
33
|
|
|
34
34
|
## Two semirings
|
|
35
35
|
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Vector scores (`resonate` / `resonateHalo`) are RaBitQ **estimates**. They rank
|
|
4
4
|
candidates and gate broad regions; they never decide identity. Identity is
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
content-addressed lookup — `resolve` / `findLeaf` / `findBranch` /
|
|
6
|
+
`canonResolve` — with ONE exception: the store's near-merge (`store.ts`).
|
|
7
7
|
|
|
8
8
|
## The law
|
|
9
9
|
|
|
10
10
|
> Scores propose, bytes dispose.
|
|
11
11
|
|
|
12
12
|
Even recall's echo decision re-folds the top hit's bytes rather than trusting
|
|
13
|
-
the estimate
|
|
14
|
-
|
|
13
|
+
the estimate. No OTHER `score >= threshold` path may mint an identity;
|
|
14
|
+
thresholds gate breadth, not truth.
|
|
15
15
|
|
|
16
16
|
## Graded evidence ladders
|
|
17
17
|
|
|
@@ -3,23 +3,23 @@
|
|
|
3
3
|
Every shared operation is defined once and imported many times. Duplicating it
|
|
4
4
|
forks the corpus contract; moving it hides who owns the gate.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
commonality measures see `commonality.md`; for work accounting see `meter.md`.
|
|
6
|
+
Siblings: `match-project.md`, `commonality.md`, `meter.md`.
|
|
8
7
|
|
|
9
8
|
## Single-definition contracts
|
|
10
9
|
|
|
11
|
-
| Symbol | Defined in
|
|
12
|
-
| ------------------------------------------------------------- |
|
|
13
|
-
| `contentLevels` | `src/geometry.ts`
|
|
14
|
-
| `canonicalWindows` / `chainReach` / `leafIdRun` / `windowIds` | `src/mind/canonical.ts`
|
|
15
|
-
| `junction.ts` + `WalkCache` | `src/mind/junction.ts`
|
|
16
|
-
| `joinWithBridge` | `src/mind/resonance.ts`
|
|
17
|
-
| `dismissedKnownContent` | `src/mind/bridge.ts`
|
|
18
|
-
| `sharedReachMemo` | `src/mind/traverse.ts`
|
|
19
|
-
| `guidedFirst` | `src/mind/traverse.ts`
|
|
20
|
-
| `leadsSomewhere` | `src/mind/traverse.ts`
|
|
21
|
-
| `isChunk` | `src/sema.ts`
|
|
22
|
-
| `twoEndedSeat` | `src/sema.ts`
|
|
10
|
+
| Symbol | Defined in | One fact |
|
|
11
|
+
| ------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
12
|
+
| `contentLevels` | `src/geometry.ts` | Single boundary rule: cuts + levels from one rolling hash pass; every segmentation reads it. |
|
|
13
|
+
| `canonicalWindows` / `chainReach` / `leafIdRun` / `windowIds` | `src/mind/canonical.ts` | Write/read contract: training interns `W-1,W` windows, reading chains to `W²` and probes `W`-windows — drift silences recognition. |
|
|
14
|
+
| `junction.ts` + `WalkCache` | `src/mind/junction.ts` | Shared junction ascent (parents + containers) with bounded `√N·W` walk; `WalkCache` memoizes capped reads/parents/containers per response; bridge and attention share it. |
|
|
15
|
+
| `joinWithBridge` | `src/mind/resonance.ts` | One out-of-search assembly: `bridge(left,right)` or bare concat with `bridgeMiss` trace. |
|
|
16
|
+
| `dismissedKnownContent` | `src/mind/bridge.ts` | Pure attestation: any unaccounted `W`-window that resolves as known content — shared gap guard for substitution and CAST. |
|
|
17
|
+
| `sharedReachMemo` | `src/mind/traverse.ts` | One response-scoped `AncestorReach` memo (cleared on write and for traces); every `reachOf`/`edgeAncestors` consumer shares it. |
|
|
18
|
+
| `guidedFirst` | `src/mind/traverse.ts` | Guided-or-first answer bytes: `guidedNext` else first-inserted edge (`LIMIT 1`). |
|
|
19
|
+
| `leadsSomewhere` | `src/mind/traverse.ts` | Admission predicate: `hasNext` (cached) or `hasHalo`; sites that lead nowhere contribute no derivation. |
|
|
20
|
+
| `isChunk` | `src/sema.ts` | `kids !== null && kids.every(k=>k.kids===null)` — smallest grouped unit; governs regions, seams, indexing. |
|
|
21
|
+
| `twoEndedSeat` | `src/sema.ts` | One seat algebra: first half low seats, second half high seats; shared by perception, `fold`, and canonical folds. |
|
|
22
|
+
| `closed`/`admissible`/`advance` | `src/mind/derivation.ts` | One admission for every derivation step and the readings every tier asks. |
|
|
23
23
|
|
|
24
24
|
## Pins
|
|
25
25
|
|
|
@@ -14,12 +14,12 @@ interface PipelineMechanism {
|
|
|
14
14
|
}
|
|
15
15
|
interface MechanismResult {
|
|
16
16
|
bytes: Uint8Array;
|
|
17
|
-
accounted: [number, number]
|
|
17
|
+
accounted: Array<[number, number]>;
|
|
18
18
|
moves: number;
|
|
19
|
-
|
|
19
|
+
used?: ReadonlySet<number>;
|
|
20
20
|
scaffolding?: number;
|
|
21
|
+
provenance?: string;
|
|
21
22
|
complete?: boolean;
|
|
22
|
-
used?: ReadonlySet<number>;
|
|
23
23
|
}
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -53,11 +53,11 @@ Weight is one currency: `weight = moves + PASS · unaccountedBytes` where
|
|
|
53
53
|
`√N` via `hubBound`/`hubCap` and `k = 2·recallQueryK` (`Precomputed.k`).
|
|
54
54
|
Enforced at the store.
|
|
55
55
|
4. **Evidence travels** — every candidate carries `accounted` (query spans
|
|
56
|
-
explained)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
explained) and `moves` (priced on `MICRO/STEP/CONCEPT/PASS`); optionally
|
|
57
|
+
`scaffolding` (answer bytes from unrecognised spans — equal-grade tie-break),
|
|
58
|
+
`complete` (trained-form continuation reached via identity; post-grounding
|
|
59
|
+
must not extend) and `provenance`. The decider honours them without knowing
|
|
60
|
+
who set them.
|
|
61
61
|
|
|
62
62
|
## Two disciplines
|
|
63
63
|
|
|
@@ -86,7 +86,7 @@ Weight is one currency: `weight = moves + PASS · unaccountedBytes` where
|
|
|
86
86
|
same act is charged twice (`PASS`/byte dominates).
|
|
87
87
|
|
|
88
88
|
`accounted` is a cost-ladder quantity; `cover.ts` leaves masked computed spans
|
|
89
|
-
out so `PASS`-bridged bytes are still charged. `
|
|
89
|
+
out so `PASS`-bridged bytes are still charged. `narrowDecision` and
|
|
90
90
|
`thinGrounding` are observational only.
|
|
91
91
|
|
|
92
92
|
## Pins
|
|
@@ -11,11 +11,10 @@ it. Harness: `bench/profile-inference.mjs`.
|
|
|
11
11
|
an ordering. Determinism survives only because the meter is observed, never
|
|
12
12
|
consulted. Every call site is `meter?.x++` on a nullable field.
|
|
13
13
|
|
|
14
|
-
2. **Counters vs hints.** Counters are
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
behaviour.
|
|
14
|
+
2. **Counters vs hints.** Counters are exact and diffable: a regression shows in
|
|
15
|
+
a diff of two COLD runs; a repeated query meters less, as memos warm.
|
|
16
|
+
Millisecond fields (`elapsedMs`, per-phase `ms`) are non-deterministic hints
|
|
17
|
+
reported separately — never use them to gate behaviour.
|
|
19
18
|
|
|
20
19
|
3. **Phases nest, they do not partition.** Each phase is charged by the layer
|
|
21
20
|
doing the work (`recognise`, the climb's two, the bridge), and a mechanism's
|
|
@@ -37,8 +37,8 @@ root never costs a full walk.
|
|
|
37
37
|
## Gist, halo, dedup
|
|
38
38
|
|
|
39
39
|
On `put*`, content dedup (`hashOf`→probe→mint) gates first. Short keys are
|
|
40
|
-
cached (`DEDUP_KEY_MAX` bypass). Near-dedup
|
|
41
|
-
|
|
40
|
+
cached (`DEDUP_KEY_MAX` bypass). Near-dedup: `identityBar(D, W, len)`, one
|
|
41
|
+
window apart. Gists sit in `_pendingGist` (byte-budgeted `BoundedMap`);
|
|
42
42
|
`indexSubtree` & `pourHalo` promote via `_vecContentUpsert`/`_vecHaloUpsert` in
|
|
43
43
|
`batchSize` batches. Buffers flush on cadence, `commit()`, and close. Halo mass
|
|
44
44
|
re-indexes geometrically (`mass<=4 || powerOfTwo`) and encodes 2-bit quantized.
|
|
@@ -17,7 +17,7 @@ perception window), or `N` (corpus size). No threshold is tuned or added to
|
|
|
17
17
|
|
|
18
18
|
| Symbol | Definition | Formula |
|
|
19
19
|
| ----------------------- | ---------------------------------------------------------------------------- | ----------------------------------- |
|
|
20
|
-
| `mergeThreshold(D)` |
|
|
20
|
+
| `mergeThreshold(D)` | Cosine below which two gists are near enough to consider merging | `1 - 1/√D` |
|
|
21
21
|
| `identityBar(D,W,len)` | Scale-aware whole-span identity claim | `max(mergeThreshold(D), 1 - W/len)` |
|
|
22
22
|
| `reachThreshold(W)` | Recall confidence floor — half a river quantum | `1 - 1/(2·W)` |
|
|
23
23
|
| `estimatorNoise(D)` | RaBitQ noise floor — 1σ of random cosine | `1/√D` |
|
|
@@ -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
|
|
package/docs/harness/gates.md
CHANGED
|
@@ -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`–`143`). §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/cover.md
CHANGED
|
@@ -33,8 +33,8 @@ and are filtered during recognition.
|
|
|
33
33
|
| `PASS` | 1000 / byte | each unaccounted byte |
|
|
34
34
|
| `MICRO` | 1e-3 | per-byte A* heuristic (`h = (len-right)*MICRO`) |
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
The cover reports `moves` (its derivation's discrete work) and `accounted`; the
|
|
37
|
+
ladder prices both.
|
|
38
38
|
|
|
39
39
|
## Pre-resolution (`src/mind/mechanisms/cover.ts`)
|
|
40
40
|
|
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