@hviana/sema 0.8.3 → 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.
Files changed (85) hide show
  1. package/AGENTS.md +11 -10
  2. package/README.md +17 -38
  3. package/dist/example/demo.js +85 -34
  4. package/dist/src/geometry.d.ts +0 -10
  5. package/dist/src/geometry.js +0 -12
  6. package/dist/src/meter.d.ts +11 -0
  7. package/dist/src/meter.js +11 -0
  8. package/dist/src/mind/articulation.js +1 -1
  9. package/dist/src/mind/attention.js +2 -1
  10. package/dist/src/mind/derivation.d.ts +201 -0
  11. package/dist/src/mind/derivation.js +327 -0
  12. package/dist/src/mind/graph-search.d.ts +2 -1
  13. package/dist/src/mind/graph-search.js +37 -15
  14. package/dist/src/mind/match.d.ts +2 -0
  15. package/dist/src/mind/match.js +2 -0
  16. package/dist/src/mind/mechanisms/alu.js +0 -2
  17. package/dist/src/mind/mechanisms/cast.d.ts +1 -5
  18. package/dist/src/mind/mechanisms/cast.js +15 -18
  19. package/dist/src/mind/mechanisms/confluence.d.ts +0 -3
  20. package/dist/src/mind/mechanisms/confluence.js +3 -9
  21. package/dist/src/mind/mechanisms/cover.js +17 -20
  22. package/dist/src/mind/mechanisms/extraction.d.ts +0 -1
  23. package/dist/src/mind/mechanisms/extraction.js +13 -8
  24. package/dist/src/mind/mechanisms/prefix-completion.js +0 -1
  25. package/dist/src/mind/mechanisms/recall.d.ts +0 -1
  26. package/dist/src/mind/mechanisms/recall.js +8 -9
  27. package/dist/src/mind/mechanisms/reference.js +3 -4
  28. package/dist/src/mind/pipeline-mechanism.d.ts +1 -4
  29. package/dist/src/mind/pipeline.js +106 -41
  30. package/dist/src/mind/rationale.d.ts +0 -11
  31. package/dist/src/mind/rationale.js +6 -32
  32. package/dist/src/mind/reasoning.d.ts +4 -30
  33. package/dist/src/mind/reasoning.js +183 -151
  34. package/dist/src/mind/types.js +6 -3
  35. package/docs/INDEX.md +23 -24
  36. package/docs/INVARIANTS.md +16 -17
  37. package/docs/architecture/bounded-reads.md +4 -4
  38. package/docs/architecture/closure.md +65 -0
  39. package/docs/architecture/commonality.md +27 -18
  40. package/docs/architecture/cost-model.md +5 -5
  41. package/docs/architecture/exact-vs-approximate.md +4 -4
  42. package/docs/architecture/factored-machinery.md +14 -14
  43. package/docs/architecture/mechanism-market.md +9 -9
  44. package/docs/architecture/meter.md +4 -5
  45. package/docs/architecture/store.md +2 -2
  46. package/docs/architecture/thresholds.md +1 -1
  47. package/docs/failures/tempting-but-wrong.md +11 -1
  48. package/docs/harness/gates.md +6 -6
  49. package/docs/mechanisms/cover.md +2 -2
  50. package/example/demo.ts +90 -37
  51. package/jsr.json +1 -1
  52. package/package.json +1 -1
  53. package/src/geometry.ts +0 -13
  54. package/src/meter.ts +11 -0
  55. package/src/mind/articulation.ts +0 -1
  56. package/src/mind/attention.ts +2 -1
  57. package/src/mind/derivation.ts +473 -0
  58. package/src/mind/graph-search.ts +37 -20
  59. package/src/mind/match.ts +2 -0
  60. package/src/mind/mechanisms/alu.ts +0 -2
  61. package/src/mind/mechanisms/cast.ts +17 -21
  62. package/src/mind/mechanisms/confluence.ts +3 -13
  63. package/src/mind/mechanisms/cover.ts +17 -20
  64. package/src/mind/mechanisms/extraction.ts +13 -9
  65. package/src/mind/mechanisms/prefix-completion.ts +0 -1
  66. package/src/mind/mechanisms/recall.ts +7 -9
  67. package/src/mind/mechanisms/reference.ts +2 -3
  68. package/src/mind/pipeline-mechanism.ts +1 -4
  69. package/src/mind/pipeline.ts +121 -46
  70. package/src/mind/rationale.ts +6 -36
  71. package/src/mind/reasoning.ts +208 -178
  72. package/src/mind/types.ts +5 -2
  73. package/test/133-the-decision-point-renders-the-state.test.mjs +204 -0
  74. package/test/134-the-law-explains-the-engines-own-refusal.test.mjs +237 -0
  75. package/test/135-one-law-any-producer.test.mjs +289 -0
  76. package/test/136-the-two-named-limits.test.mjs +205 -0
  77. package/test/137-the-law-lives-once-and-below.test.mjs +400 -0
  78. package/test/138-the-remainder-drains-only-what-a-move-declares.test.mjs +62 -0
  79. package/test/139-the-witness-is-engagement-not-explanation.test.mjs +51 -0
  80. package/test/140-irrelevant-supply-does-not-change-an-answer.test.mjs +48 -0
  81. package/test/141-the-question-is-paid-at-construction.test.mjs +98 -0
  82. package/test/36-already-answered-fusion.test.mjs +20 -2
  83. package/test/37-cluster-dispersion-fusion.test.mjs +30 -3
  84. package/test/38-reason-restate-guard.test.mjs +22 -2
  85. package/test/55-cost-meter.test.mjs +4 -1
@@ -0,0 +1,204 @@
1
+ // 133-the-decision-point-renders-the-state.test.mjs — FAIL BEFORE, recorded first.
2
+ //
3
+ // THE CLAIM the extraction has to earn, from the acceptance file written and
4
+ // MEASURED BEFORE any line of the law existed (3 failures on a clean tree, each
5
+ // for its own reason). The two assertions that are now green live here; the
6
+ // third — "the coverage scan exists exactly once in src/mind" — stays out of the
7
+ // tree until `reasoning.ts`'s brake is migrated onto the law, because until then
8
+ // it would be a red pin rather than a proof.
9
+ //
10
+ // 133.1 the state the pipeline decides on is RENDERED where it is decided —
11
+ // remainder spans, their bytes, and the supplied fixed point — through
12
+ // the official surface (inspectRationale's post-grounding step). It
13
+ // must fail today on the ASSERTION, not at import: the payload exists,
14
+ // it simply does not carry the state.
15
+ // 133.2 the closure law is PRODUCER-FREE as an invariant: two states equal in
16
+ // every field the law reads, differing only in a provenance label, get
17
+ // identical verdicts for every continuation. Fails today at import —
18
+ // the law has no home yet.
19
+ //
20
+ // Nor does any accept `answer === expected` as proof: the first reads the
21
+ // official instrumentation and its agreement with the meter's own reading of the
22
+ // same remainder; the second is an invariant over states; the third reads the
23
+ // source. The existing suites remain the GUARDS that the extractions change no
24
+ // answer — measured, before and after each step: answers, transition sequences
25
+ // and every meter counter identical.
26
+
27
+ import { test } from "node:test";
28
+ import assert from "node:assert/strict";
29
+ import { readdir, readFile } from "node:fs/promises";
30
+ import { dirname, join } from "node:path";
31
+ import { fileURLToPath } from "node:url";
32
+
33
+ const here = dirname(fileURLToPath(import.meta.url));
34
+ const { Mind, SQliteStore } = await import("../dist/src/index.js");
35
+
36
+ const CHAIN = [
37
+ ["What is the capital of France", "The capital of France is Paris"],
38
+ ["Paris", "Paris is famous for the Eiffel Tower"],
39
+ ["the Eiffel Tower", "the Eiffel Tower is in Paris"],
40
+ ];
41
+ const CARRIED = [
42
+ ["How do I compile hello.c?", "Run gcc hello.c"],
43
+ ["How do I compile server.c?", "Run gcc server.c"],
44
+ ["How do I compile parser.c?", "Run gcc parser.c"],
45
+ ];
46
+
47
+ async function profile(facts, query) {
48
+ const store = new SQliteStore({ path: ":memory:" });
49
+ const mind = new Mind({ seed: 7, store, profile: true });
50
+ await mind.ingest(facts);
51
+ const steps = [];
52
+ await mind.respondText(query, (s) => steps.push(s));
53
+ const out = { steps, counters: mind.lastCost?.counters ?? {} };
54
+ await store.close();
55
+ return out;
56
+ }
57
+
58
+ test("133.1 the decision point renders the state it decides on", async () => {
59
+ const { steps, counters } = await profile(
60
+ CHAIN,
61
+ "What is the capital of France famous for",
62
+ );
63
+ const pg = steps.filter((s) => s.data && s.data.preConsumed !== undefined);
64
+ assert.ok(pg.length >= 1, "the post-grounding step must exist");
65
+ const d = pg[pg.length - 1].data;
66
+ assert.equal(
67
+ typeof d.remainderSpans,
68
+ "number",
69
+ "the state's remainder must be rendered where it is decided — it is " +
70
+ "today computed, used, and published only as an aggregate counter",
71
+ );
72
+ assert.equal(typeof d.remainderBytes, "number");
73
+ assert.equal(typeof d.fixed, "boolean");
74
+ assert.equal(
75
+ d.remainderSpans,
76
+ counters.postGroundingRemainderSpans,
77
+ "the rendered state must agree with the meter's own reading of the same " +
78
+ "remainder — one measure, rendered twice, never two measures",
79
+ );
80
+ });
81
+
82
+ test("133.2 the law reads no producer, as an invariant over states", async () => {
83
+ let law;
84
+ try {
85
+ law = await import("../dist/src/mind/derivation.js");
86
+ } catch {
87
+ assert.fail(
88
+ "the closure law has no home yet: `admissible`/`advance`/`closed` must " +
89
+ "live in one lowest-layer module so every tier can ask it",
90
+ );
91
+ }
92
+ const query = new TextEncoder().encode(
93
+ "What is the capital of France famous for",
94
+ );
95
+ const W = 4;
96
+ const product = new TextEncoder().encode("qqqqqqqqqqqq");
97
+ const open = {
98
+ product,
99
+ accounted: [],
100
+ remainder: law.remainderOf(query.length, [], W),
101
+ cost: 0,
102
+ };
103
+ const continuations = [
104
+ { product, contains: true, cost: 1 },
105
+ { product, contains: true, reaches: true, cost: 1 },
106
+ { product, contains: false, cost: 1 },
107
+ ];
108
+ for (const t of continuations) {
109
+ const a = law.admissible(open, t, query, W);
110
+ for (
111
+ const label of ["cast", "cover", "recall", "reference", "alu", "prefix"]
112
+ ) {
113
+ const b = law.admissible({ ...open, provenance: label }, t, query, W);
114
+ assert.deepEqual(
115
+ b,
116
+ a,
117
+ `the verdict changed when the state was labelled "${label}" — the law ` +
118
+ `must be a function of the state and the continuation alone`,
119
+ );
120
+ }
121
+ }
122
+ });
123
+
124
+ test("133.3 the law has one home and one definition", async () => {
125
+ const mind = join(here, "..", "src", "mind");
126
+ const files = await readdir(mind);
127
+ assert.ok(
128
+ files.includes("derivation.ts"),
129
+ `the law's module must exist in the lowest mind layer; src/mind holds ${files.length} file(s)`,
130
+ );
131
+ const src = await readFile(join(mind, "derivation.ts"), "utf8");
132
+ const imports = [...src.matchAll(/from\s+"([^"]+)"/g)].map((m) => m[1]);
133
+ assert.deepEqual(
134
+ imports,
135
+ ["../bytes.js"],
136
+ `the law may import byte helpers only — it imported ${
137
+ JSON.stringify(imports)
138
+ }`,
139
+ );
140
+ let scans = 0;
141
+ for (const f of files) {
142
+ if (!f.endsWith(".ts")) continue;
143
+ const text = await readFile(join(mind, f), "utf8");
144
+ scans += (text.match(/i \+ W <= b/g) ?? []).length;
145
+ }
146
+ assert.equal(
147
+ scans,
148
+ 1,
149
+ `the coverage scan (the law's own measure) must exist exactly once in ` +
150
+ `src/mind — found ${scans}`,
151
+ );
152
+ });
153
+
154
+ test("133.4 the law costs nothing the meter can see", async () => {
155
+ // THE ZERO-COST CLAIM, on one tree and through the official instrumentation.
156
+ // The formal A/B (ten diverse fixtures against the pre-extraction tree,
157
+ // comparing every answer, every move and all 480 counter values) is recorded
158
+ // in the commit that extracted the law; what lives here is the invariant that
159
+ // makes it reproducible: asking the law moves NO counter, because the law has
160
+ // nothing to read them through.
161
+ const law = await import("../dist/src/mind/derivation.js");
162
+ const store = new SQliteStore({ path: ":memory:" });
163
+ const mind = new Mind({ seed: 7, store, profile: true });
164
+ await mind.ingest(CHAIN);
165
+ await mind.respondText("What is the capital of France famous for");
166
+ const before = JSON.stringify(mind.lastCost?.counters ?? {});
167
+ const query = new TextEncoder().encode(
168
+ "What is the capital of France famous for",
169
+ );
170
+ const W = mind.space.maxGroup;
171
+ const state = {
172
+ product: new TextEncoder().encode("qqqqqqqqqqqq"),
173
+ accounted: [],
174
+ remainder: law.remainderOf(query.length, [[0, 5]], W),
175
+ cost: 0,
176
+ };
177
+ const t = { product: query.subarray(0, 3 * W), contains: true, cost: 1 };
178
+ for (let i = 0; i < 200; i++) {
179
+ const w = law.admissible(state, t, query, W);
180
+ if (w !== null) law.advance(state, t, w);
181
+ law.closed(state);
182
+ law.carries(state.remainder, t.product, query, W);
183
+ law.restates(query, state.product, 0, { proper: true });
184
+ law.insideAnsweredTurn([[0, 5]], { at: 0 }, 1, 2);
185
+ law.unexplainedSpans(query.length, [[0, 5]]);
186
+ }
187
+ assert.equal(
188
+ JSON.stringify(mind.lastCost?.counters ?? {}),
189
+ before,
190
+ "the law moved a meter counter — it must perform no work the instrumentation " +
191
+ "can see, which is what makes the extraction free",
192
+ );
193
+ // AND IT TAKES NO CONTEXT. The arity is the structural statement: there is no
194
+ // parameter through which a store, a mind or a producer could be consulted.
195
+ assert.equal(
196
+ law.admissible.length,
197
+ 4,
198
+ "admissible(state, continuation, query, W)",
199
+ );
200
+ assert.equal(law.advance.length, 3, "advance(state, continuation, witness)");
201
+ assert.equal(law.closed.length, 1, "closed(state)");
202
+ assert.equal(law.carries.length, 4, "carries(remainder, product, query, W)");
203
+ await store.close();
204
+ });
@@ -0,0 +1,237 @@
1
+ // 134-the-law-explains-the-engines-own-refusal.test.mjs — the law, coupled to the
2
+ // engine's own observed behaviour rather than to itself.
3
+ //
4
+ // WHAT THIS PINS, and why it is not a restatement of test/133:
5
+ //
6
+ // 133 says the state is rendered where it is decided, that the law reads no
7
+ // producer, and that it has one home. This file says the LAW'S OWN MEASURE
8
+ // EXPLAINS WHAT THE ENGINE DID: on a real fixture the reasoner takes one step
9
+ // and refuses the next, and the two products are in the corpus, so the law's
10
+ // `carries` can be evaluated on them and must agree with the trace — the
11
+ // admitted product carries a quantum of the remainder, the refused one carries
12
+ // none. A test that only checked the law against itself would prove nothing
13
+ // about the engine; this one couples the two through the OFFICIAL
14
+ // instrumentation (`inspectRationale` for the products and the refusal, the
15
+ // meter for the remainder's own counts).
16
+ //
17
+ // It also pins the two invariants a reader of the extraction relies on: the law
18
+ // is TOTAL over states x continuations and every clause holds, and `advance` is
19
+ // the transition it says it is — including that the remainder TRAVELS UNCHANGED,
20
+ // the reading that was implemented and refuted (draining it let test/110's chain
21
+ // drift one hop past its satisfying answer).
22
+
23
+ import { test } from "node:test";
24
+ import assert from "node:assert/strict";
25
+ import { dirname, join } from "node:path";
26
+ import { fileURLToPath } from "node:url";
27
+
28
+ const here = dirname(fileURLToPath(import.meta.url));
29
+ const law = await import("../dist/src/mind/derivation.js");
30
+ const { Mind, SQliteStore } = await import("../dist/src/index.js");
31
+
32
+ const enc = (s) => new TextEncoder().encode(s);
33
+
34
+ /** The chain of test/110 and of the report's §16 example 3. */
35
+ const LINKS = [
36
+ ["What is the capital of France", "The capital of France is Paris"],
37
+ ["Paris", "Paris is famous for the Eiffel Tower"],
38
+ ["the Eiffel Tower", "the Eiffel Tower is in Paris"],
39
+ ];
40
+ const QUERY = "What is the capital of France famous for";
41
+
42
+ async function run() {
43
+ const store = new SQliteStore({ path: ":memory:" });
44
+ const mind = new Mind({ seed: 7, store, profile: true });
45
+ await mind.ingest(LINKS);
46
+ const steps = [];
47
+ const answer = String(await mind.respondText(QUERY, (s) => steps.push(s)))
48
+ .trim();
49
+ const out = {
50
+ mind,
51
+ store,
52
+ steps,
53
+ answer,
54
+ counters: mind.lastCost?.counters ?? {},
55
+ };
56
+ return out;
57
+ }
58
+
59
+ test("134.1 the law is total, and every clause holds over the matrix", async () => {
60
+ const query = enc(QUERY);
61
+ const W = 4;
62
+ const none = enc("qqqqqqqqqqqqqqqq");
63
+ const owed = law.remainderOf(query.length, [], W);
64
+ assert.ok(
65
+ owed.length > 0,
66
+ "the fixture must owe material, else this pins nothing",
67
+ );
68
+ const states = {
69
+ open: { product: query, accounted: [], remainder: owed, cost: 0 },
70
+ closed: {
71
+ product: none,
72
+ accounted: [[0, query.length]],
73
+ remainder: [],
74
+ cost: 3,
75
+ },
76
+ fixed: {
77
+ product: query,
78
+ accounted: [],
79
+ remainder: owed,
80
+ cost: 0,
81
+ fixed: true,
82
+ },
83
+ };
84
+ const conts = {
85
+ carries: { product: query.subarray(0, 3 * W), contains: true, cost: 1 },
86
+ moves: { product: none, contains: true, reaches: true, cost: 1 },
87
+ plain: { product: none, contains: true, cost: 1 },
88
+ alien: { product: none, contains: false, cost: 1 },
89
+ };
90
+ for (const sn of Object.keys(states)) {
91
+ for (const cn of Object.keys(conts)) {
92
+ const v = law.admissible(states[sn], conts[cn], query, W);
93
+ assert.ok(
94
+ v === null || Array.isArray(v),
95
+ `${sn} x ${cn} produced ${String(v)}, neither a witness nor a refusal`,
96
+ );
97
+ }
98
+ }
99
+ for (const cn of Object.keys(conts)) {
100
+ assert.equal(
101
+ law.admissible(states.fixed, conts[cn], query, W),
102
+ null,
103
+ `a supplied fixed point stops every continuation (${cn})`,
104
+ );
105
+ }
106
+ for (const sn of Object.keys(states)) {
107
+ assert.equal(
108
+ law.admissible(states[sn], conts.alien, query, W),
109
+ null,
110
+ `identity comes before progress: an alien structure (state ${sn})`,
111
+ );
112
+ }
113
+ for (const cn of ["carries", "moves", "plain"]) {
114
+ assert.notEqual(
115
+ law.admissible(states.closed, conts[cn], query, W),
116
+ null,
117
+ `a closed derivation admits every contained continuation (${cn})`,
118
+ );
119
+ }
120
+ assert.equal(law.closed(states.closed), true);
121
+ assert.equal(law.closed(states.open), false);
122
+ // progress is EITHER the material carried OR the structure moved to
123
+ assert.notEqual(law.admissible(states.open, conts.carries, query, W), null);
124
+ assert.notEqual(law.admissible(states.open, conts.moves, query, W), null);
125
+ assert.equal(
126
+ law.admissible(states.open, conts.plain, query, W),
127
+ null,
128
+ "a step that neither carries the remainder nor moves is refused",
129
+ );
130
+ });
131
+
132
+ test("134.2 advance is the transition it says it is", async () => {
133
+ const query = enc(QUERY);
134
+ const W = 4;
135
+ const before = {
136
+ product: query,
137
+ accounted: [],
138
+ remainder: law.remainderOf(query.length, [], W),
139
+ cost: 2,
140
+ used: new Set([1, 2]),
141
+ };
142
+ const t = { product: query.subarray(0, 3 * W), contains: true, cost: 1 };
143
+ const witness = law.admissible(before, t, query, W);
144
+ assert.ok(witness !== null);
145
+ const after = law.advance(before, t, witness);
146
+ assert.equal(after.product, t.product, "the product moves");
147
+ assert.equal(after.cost, before.cost + t.cost, "the cost accumulates");
148
+ assert.deepEqual(
149
+ after.remainder,
150
+ before.remainder,
151
+ "CARRIES ENGAGES: a step that carries question material consumes none of it",
152
+ );
153
+ assert.equal(
154
+ after.fixed,
155
+ undefined,
156
+ "the result is no longer a supplied fixed point",
157
+ );
158
+ assert.equal(after.used, before.used, "the declaration travels");
159
+ assert.deepEqual(
160
+ after.accounted,
161
+ [...before.accounted, ...witness.map((w) => w.span)],
162
+ "the accounting accumulates what the step accounted for",
163
+ );
164
+ // A DECLARED MOVE CONSUMES WHAT IT CARRIES, and only that (test/138): the same
165
+ // product, offered this time by a step that moves and accounts for the span it
166
+ // holds. This is the one thing the remainder responds to.
167
+ const movedT = {
168
+ product: t.product,
169
+ contains: true,
170
+ reaches: true,
171
+ explains: [[0, 3 * W]],
172
+ cost: 1,
173
+ };
174
+ const movedWitness = law.admissible(before, movedT, query, W);
175
+ assert.ok(movedWitness !== null);
176
+ const drained = law.advance(before, movedT, movedWitness);
177
+ assert.notDeepEqual(
178
+ drained.remainder,
179
+ before.remainder,
180
+ "a declared move consumes the question material it carries",
181
+ );
182
+ // and the state it came from is untouched (the law is pure)
183
+ assert.deepEqual(before.accounted, []);
184
+ assert.equal(before.product, query);
185
+ });
186
+
187
+ test("134.3 the engine's own refusal is the law's refusal", async () => {
188
+ const { mind, store, steps, answer, counters } = await run();
189
+ const W = mind.space.maxGroup;
190
+ const query = enc(QUERY);
191
+
192
+ // THE TRACE'S OWN PRODUCTS: what the walk produced and what it declined.
193
+ const pivots = steps.filter((s) => s.mechanism.at(-1) === "pivotStep");
194
+ const refusals = steps.filter((s) => s.mechanism.at(-1) === "pivotRefused");
195
+ assert.equal(
196
+ pivots.length,
197
+ 1,
198
+ `the fixture takes exactly one extension step (got ${pivots.length}; answer "${answer}")`,
199
+ );
200
+ assert.equal(refusals.length, 1, "and declines the next one");
201
+ assert.equal(
202
+ counters.pivotSteps,
203
+ pivots.length,
204
+ "the meter agrees with the trace",
205
+ );
206
+ const admitted = pivots[0].outputs[0].bytes;
207
+ assert.ok(
208
+ admitted && admitted.length > 0,
209
+ "the admitted step reports its product",
210
+ );
211
+
212
+ // THE REMAINDER, from the meter's own counts and the fixture's structure: the
213
+ // grounding accounts for "What is the capital of France" and owes the rest.
214
+ assert.equal(counters.postGroundingRemainderSpans, 1);
215
+ const owedSpan = [
216
+ QUERY.length - counters.postGroundingRemainderBytes,
217
+ QUERY.length,
218
+ ];
219
+ const remainder = [owedSpan];
220
+
221
+ // THE LAW ON THE ENGINE'S OWN TWO PRODUCTS.
222
+ assert.notEqual(
223
+ law.carries(remainder, admitted, query, W),
224
+ null,
225
+ "the step the engine TOOK is one the law admits: its product carries a " +
226
+ "quantum of what the grounding left unaccounted",
227
+ );
228
+ // The step it declined is the corpus's own next link — the drift test/110 pins.
229
+ const drift = enc(LINKS[2][1]);
230
+ assert.equal(
231
+ law.carries(remainder, drift, query, W),
232
+ null,
233
+ "the step the engine DECLINED carries none of that material — which is " +
234
+ "exactly the law's refusal the trace reports",
235
+ );
236
+ await store.close();
237
+ });