provident-storeroom 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "provident-storeroom",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "U-STOREROOM-PUBLISH: the published Node ESM binding for the native Rust store of Provident-Storeroom — the entry resolves the scoped per-target platform package first, the checkout's own module-relative addon second, and answers the store's single declared absent-addon form when neither loads",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0",
@@ -38,11 +38,11 @@
38
38
  "src/constraint-kernel.mjs"
39
39
  ],
40
40
  "optionalDependencies": {
41
- "@auspicion/provident-storeroom-js-linux-x64-gnu": "0.3.1",
42
- "@auspicion/provident-storeroom-js-linux-arm64-gnu": "0.3.1",
43
- "@auspicion/provident-storeroom-js-darwin-x64": "0.3.1",
44
- "@auspicion/provident-storeroom-js-darwin-arm64": "0.3.1",
45
- "@auspicion/provident-storeroom-js-win32-x64-msvc": "0.3.1"
41
+ "@auspicion/provident-storeroom-js-linux-x64-gnu": "0.5.0",
42
+ "@auspicion/provident-storeroom-js-linux-arm64-gnu": "0.5.0",
43
+ "@auspicion/provident-storeroom-js-darwin-x64": "0.5.0",
44
+ "@auspicion/provident-storeroom-js-darwin-arm64": "0.5.0",
45
+ "@auspicion/provident-storeroom-js-win32-x64-msvc": "0.5.0"
46
46
  },
47
47
  "publishConfig": {
48
48
  "access": "public"
@@ -131,8 +131,27 @@ const SETTLED_ON_THE_PASSING_ARM = Symbol.for('provident-storeroom.settled-on-th
131
131
  const SAVE_FAILED_AT_THE_TERMINAL_ARM = Symbol.for('provident-storeroom.save-failed-at-the-terminal-arm');
132
132
 
133
133
  /** `fail-surface.md §1.1` — ONE THROWN PLAIN OBJECT, EXACTLY THREE MEMBERS, NEVER AN `Error`. */
134
+ const KERNEL_REFUSAL = Symbol.for('provident-storeroom.kernel-refusal');
134
135
  function refuse(status, message, log) {
135
- throw { status, message, log: log === undefined ? [] : log };
136
+ throw {
137
+ status,
138
+ message,
139
+ log: log === undefined ? [] : log,
140
+ [KERNEL_REFUSAL]: true,
141
+ };
142
+ }
143
+
144
+ /// **WHETHER A VALUE IS A REFUSAL THIS KERNEL BUILT** — the entry's crossing and this kernel's own repair
145
+ /// arm both ask this and nothing else.
146
+ ///
147
+ /// **IT IS NOT AN EXPORT, AND THE REASON IS THE SPEC'S OWN CLOSED COUNT:** `kernel-surface.md §1` item 2
148
+ /// declares the module's export set as **EXACTLY the five `K-1`–`K-5` items** — *"the kernel exports no
149
+ /// route, no addon handle and no sixth name"* — so a predicate exported from here would be a SIXTH NAME and
150
+ /// a FINDING. **The mark is therefore read through the `Symbol.for` key itself, which both sides spell**
151
+ /// (`KERNEL_REFUSAL` above), and the fact travels on the VALUE rather than in the module's namespace —
152
+ /// exactly as `SETTLED_ON_THE_PASSING_ARM` and `SAVE_FAILED_AT_THE_TERMINAL_ARM` already travel.
153
+ function isKernelRefusal(value) {
154
+ return value !== null && typeof value === 'object' && value[KERNEL_REFUSAL] === true;
136
155
  }
137
156
 
138
157
  // ---------------------------------------------------------------------------------------------
@@ -380,9 +399,364 @@ export function register(store, address, id, constraint) {
380
399
  } else {
381
400
  standing.constraint = constraint;
382
401
  }
402
+
403
+
404
+ // ═══════════════════════════════════════════════════════════════════════════════════════════════
405
+ // THE THIRD STEP — THE REGISTRATION-TIME EVALUATION (`docs/specs/storeroom-native/contract.md §7.3`
406
+ // (b) states 1–3 and its `3-bis` clause of 2026-10-16; `kernel-surface.md §2.1` item 1's third step).
407
+ // ═══════════════════════════════════════════════════════════════════════════════════════════════
408
+ //
409
+ // **WHAT THIS STEP OWES, IN THE RULING'S OWN TERMS: after channels (i) and (ii) are passed and the pair
410
+ // stands in the registry, the kernel EVALUATES THAT ONE CONSTRAINT AGAINST THE STORE'S CURRENT STATE,
411
+ // ONCE, BEFORE THE HANDLE IS RETURNED.** The scope is THAT ONE PAIR and no other: no pass is opened over
412
+ // the registry and no other registered pair is re-evaluated.
413
+ //
414
+ // **⟶ THE THREE STATES, EACH ANSWERED HERE AND AT NO OTHER SITE:**
415
+ // (i) the state PASSES → the call returns the handle exactly as before, and nothing else happened;
416
+ // (ii) it VIOLATES and NO repair is registered → the registration is REFUSED;
417
+ // (iii) it VIOLATES and a repair IS registered → THE REPAIR IS ATTEMPTED on the synthetic attempt
418
+ // `3-bis` (a) declares, and its outcome answers the call as (i) or as (ii).
419
+ //
420
+ // **AND WHAT THE KERNEL HANDS THE SURFACE IS A CODE AND ITS SLOTS, NEVER A SENTENCE.** This module owns
421
+ // no message generator, and `kernel-surface.md §1` item 2 closes its surface at the FIVE `K-1`…`K-5`
422
+ // items with no sixth name — so it imports none, is handed none, and declares no channel to one. The
423
+ // refusal it throws carries `status` (the STORE's member, `A120` (2)) and the `§8.2` row's own slot
424
+ // VALUES, and the surface renders the text through the generator it already holds. **NO `KC` TOKEN IS
425
+ // MINTED:** the synthetic attempt's own terminal token stays inside this module (`registrationRefusal`).
426
+ const refused = registrationEvaluation(kernel, store, address, id, constraint);
427
+ if (refused !== null) {
428
+ // **A REFUSED REGISTRATION LEAVES THE REGISTRY EXACTLY AS IT STOOD** (`§2.1` item 1's sentence, whose
429
+ // regulatory force reaches this third refusing act — `§7.3` (b) state 2's own reading of it): the pair
430
+ // row this call wrote is withdrawn, with its handle and its place in the address's order list.
431
+ withdrawRegistration(kernel, address, id, standing === undefined, home);
432
+ throw refused;
433
+ }
434
+ return home;
435
+ }
436
+
437
+ /**
438
+ * **WITHDRAWING THE REGISTRY ROW A REFUSED REGISTRATION WROTE** — `kernel-surface.md §2.1` item 1: *"a
439
+ * refused registration leaves the registry exactly as it stood"*, read at `docs/specs/storeroom-native/
440
+ * contract.md §7.3` (b) state 2 by that item's own clause (*"the sentence's `2` counts `KC` CHANNELS and
441
+ * the registration-time refusal is a THIRD REFUSING ACT carrying no `KC` token, so the sentence's FIGURE IS
442
+ * UNMOVED while its regulatory force (no entry on a refusal) reaches this third act"*).
443
+ *
444
+ * **WHAT IT UNDOES IS THIS CALL'S OWN WRITE AND NOTHING ELSE**, which is why the prior-standing fact is
445
+ * passed in: on the FRESH arm the pair row, its handle and its address-list entry all go; on the
446
+ * REPLACEMENT arm (a second `register` under a pair that already stood) the row's own POSITION and handle
447
+ * are left exactly as they were — the pair's idempotence rule (`CC-7`) puts the replaced registration's
448
+ * position back by never moving it.
449
+ */
450
+ function withdrawRegistration(kernel, address, id, fresh, home) {
451
+ if (!fresh) return;
452
+ const key = pairKey(address, id);
453
+ kernel.pairs.delete(key);
454
+ kernel.handles.delete(key);
455
+ const token = addressToken(address);
456
+ const list = kernel.byAddress.get(token);
457
+ if (list !== undefined) {
458
+ const at = list.indexOf(key);
459
+ if (at >= 0) list.splice(at, 1);
460
+ if (list.length === 0) kernel.byAddress.delete(token);
461
+ }
462
+ // THE ADDRESS'S HOME ENTRY STANDS: it was minted by the store's own `listen`, which this act has already
463
+ // performed, and no clause of this unit declares a kernel-side withdrawal of it (`§2.1` item 1: *"nothing
464
+ // withdraws a constraint's store registration"* — `unlisten` is the app's own verb and never this one's).
383
465
  return home;
384
466
  }
385
467
 
468
+ /**
469
+ * **THE REGISTRATION-TIME EVALUATION, AT ITS ONE SITE** (`docs/specs/storeroom-native/contract.md §7.3`
470
+ * (b) and its `3-bis` clause of 2026-10-16; `kernel-surface.md §2.1` item 1's third step and `§2.3` item
471
+ * 1's clause of 2026-10-17). It answers `null` on state 1 and on state 3's passing arm, and **the refusal
472
+ * to throw** on state 2 and on state 3's failing one.
473
+ *
474
+ * **THE EVALUATION'S CONTEXT IS `§2.3` ITEM 1'S CLAUSE OF 2026-10-17, MEMBER FOR MEMBER, AND IT IS THE
475
+ * SAME FIVE MEMBERS AS AT A LANDING** — `address` the pair's own; `tier` ABSENT, spelled `null`; `value`
476
+ * THE STORE'S CURRENT VALUE AT THE PAIR'S ADDRESS, READ AND NOT LANDED; `attempt` the synthetic attempt's
477
+ * `AttemptRef` on state 3 and `null` on states 1/2; `op` ABSENT, spelled `null`. **A SIXTH MEMBER IS
478
+ * REFUSED BY NAME** (`5 + 1 = 6` is refused at that item's (6)), and both `null`s are THAT CLAUSE's own
479
+ * spellings of an absence inside a closed record, taken from the `RollbackStep.checkpoint` precedent, and
480
+ * are not tokens minted here.
481
+ *
482
+ * **THE `value` IS OBTAINED BY THE STORE'S OWN `read` AT THE PAIR'S ADDRESS WITH THE TIER ARGUMENT
483
+ * OMITTED** — the zero-tier call — **and where that read REFUSES `AddressNotFound` the member carries
484
+ * `undefined`**, which is that clause's (3) (e) arm. **NO `null` IS MINTED FOR IT** (`DD-12` forbids a
485
+ * READ answering one) and no `AddressNotFound` code is put in a `Value` slot: the fresh-pair outcome is
486
+ * the CALLER'S OWN BODY's answer to absence, and no clause decides which a given body is.
487
+ *
488
+ * **⟶ AND THE BODY'S OWN THROW IS NOT CONVERTED HERE.** A throw out of the constraint body at this instant
489
+ * SURFACES AS ITSELF (`fail-surface.md §1.1` item 5, at `kernel-surface.md §2.3` item 1's clause of
490
+ * 2026-10-17): not re-shaped into this module's form, not wrapped, and carrying no `KC` token. So the
491
+ * invocation below is NOT wrapped — a throwing body reaches the caller as the very value it threw.
492
+ */
493
+ function registrationEvaluation(kernel, store, address, id, constraint) {
494
+ const outcome = constraint(registrationContext(store, address, null));
495
+ // THE OUTCOME IS `PAR-C-5`'S CLOSED THREE-ARM SET, read as the landing pass reads it: `true` is the pass
496
+ // arm; an object carrying `message` is the violation arm (its `repair`, where present, the repair the
497
+ // caller registered); a value outside the three arms is READ AS the `{message}` arm (`VA-11`) and never as
498
+ // an arm of its own. **A REPAIR THE OUTCOME DOES NOT CARRY IS NO REPAIR REGISTERED FOR THE PAIR.**
499
+ if (outcome === true) return null;
500
+ const repair = outcome !== null && typeof outcome === 'object' && 'message' in outcome
501
+ && 'repair' in outcome && typeof outcome.repair === 'function'
502
+ ? outcome.repair
503
+ : null;
504
+ // STATE 2 — THE STATE VIOLATES IT AND NO REPAIR IS REGISTERED. Nothing is attempted and no attempt is
505
+ // opened; the refusal carries the store's code and the row's own slots.
506
+ if (repair === null) return registrationRefusal(address, id, []);
507
+ // STATE 3 — THE REPAIR IS ATTEMPTED, on the synthetic attempt `3-bis` (a) declares.
508
+ return registrationAttempt(kernel, store, { address, id, repair });
509
+ }
510
+
511
+ /// **THE FIVE-MEMBER EVALUATION CONTEXT** (`kernel-surface.md §2.3` item 1's clause of 2026-10-17), built
512
+ /// at ONE site so states 1, 2 and 3 hand the caller's body the SAME record and only `attempt` moves:
513
+ /// `null` on states 1 and 2, the synthetic attempt's `AttemptRef` on state 3.
514
+ function registrationContext(store, address, attemptRef) {
515
+ return {
516
+ address: address.slice(),
517
+ // `tier` — ABSENT, and `op` — ABSENT: the two members carrying the landing's own absence, spelled
518
+ // `null` on that clause's (2) and (5).
519
+ tier: null,
520
+ // `value` — READ, not landed, and `undefined` at an address holding nothing (that clause's (3) (e)).
521
+ value: readCurrent(store, address),
522
+ attempt: attemptRef,
523
+ op: null,
524
+ };
525
+ }
526
+
527
+ /// The store's current value at an address, read NOT landed: the zero-tier call whose tier argument is
528
+ /// OMITTED, and `undefined` where that read refuses.
529
+ function readCurrent(store, address) {
530
+ try {
531
+ return store.read(address);
532
+ } catch (refused) {
533
+ return undefined;
534
+ }
535
+ }
536
+
537
+ /**
538
+ * **THE SIX-MEMBER `RepairContext` THE REPAIR IS HANDED AT REGISTRATION** (`kernel-surface.md §2.3` item
539
+ * 2's shape, its sixth member `pending: Handle[]` added 2026-10-15; `surface.md §2.11` clause 6, the one
540
+ * home of the architect's ruling that a repair *"IS PASSED THE COMMIT IT IS PART OF"*).
541
+ *
542
+ * **THE REPAIR'S CONTEXT IS NOT THE CONSTRAINT'S CONTEXT, AND THE TWO ARE NOT INTERCHANGEABLE**: the
543
+ * constraint receives the FIVE-member `AttemptContext` and the repair the SIX-member `RepairContext`, whose
544
+ * extra member is the commit's own `pending` — *"so that they can make their own write call use that
545
+ * commit"*. **THE SYNTHETIC ATTEMPT'S OWN `commit` MEMBER IS WHAT THIS SLOT CARRIES** (`3-bis` (a): *"the
546
+ * `CommitRecord` of the registration act"*), handed as a FRESH LIST the way the landing instant hands it, so
547
+ * the record's member is never aliased and a repair that mutated its context's list moves nothing on the
548
+ * commit.
549
+ *
550
+ * **AND THE ABSENCE AT THIS INSTANT IS SPELLED BY THE `AttemptContext`'S OWN CLAUSE, NOT MINTED HERE:** there
551
+ * is no landing, so `op` is `null` (that clause's (5)) and `tier` is `null` (its (2)) — the two absences the
552
+ * `RollbackStep.checkpoint` precedent already fixes — while `value` is the store's CURRENT value at the
553
+ * pair's address, read and not landed (its (3)). **`id` IS THE PAIR'S OWN**, which the constraint's context
554
+ * does not carry at all, the repair's shape declaring it.
555
+ */
556
+ function registrationRepairContext(store, address, id, commitRecord) {
557
+ return {
558
+ address: address.slice(),
559
+ id,
560
+ // `tier` — ABSENT, spelled `null`; `value` — READ, not landed; `op` — ABSENT, spelled `null`.
561
+ tier: null,
562
+ value: readCurrent(store, address),
563
+ op: null,
564
+ // THE COMMIT THE REPAIR IS PART OF — a FRESH LIST, never the record's own member (`§2.3` item 2).
565
+ pending: Array.isArray(commitRecord.pending) ? commitRecord.pending.slice() : [],
566
+ };
567
+ }
568
+
569
+ /**
570
+ * **STATE 3 — THE SYNTHETIC ATTEMPT AND THE REPAIR IT CARRIES** (`docs/specs/storeroom-native/contract.md
571
+ * §7.3` (b) `3-bis` (a)–(f); `attempt-lifecycle.md §2.4` items 1, 3, 4 arm (b)).
572
+ *
573
+ * **THE ATTEMPT'S RECORD IS ITEM 1's NINE MEMBERS UNCHANGED — NO TENTH MEMBER IS MINTED AND NO MEMBER'S
574
+ * DOMAIN MOVES:** `ref`, `commit`, `ops`, `log`, `ran`, `appliedRepairs`, `open`, `rollback`, `checkpoint`.
575
+ * **ITS `address` IS THE PAIR'S OWN**, **`ITS `checkpoint` BEGINS `null`*** — that member's declared `null`
576
+ * arm, because no landing at that address has yet left it valid for THIS attempt — and **its `ref` is a
577
+ * kernel-minted `AttemptRef` unique within the instance**. **Its `log` is a real `LogEntry[]` carrying this
578
+ * kernel's own `seq` ordinal**, and the `constraint-check` and `repair-run` entries arm (b) appends stand in
579
+ * it. **IT IS TERMINAL-AWARE ON BOTH ARMS**: it reaches `PASSED` or `FAILING` and closes, and no
580
+ * registration leaves an open attempt in the registry.
581
+ *
582
+ * **THE OP THE REPAIR LANDS IS HELD BY THIS ATTEMPT AND NOTHING ELSE** — `3-bis` (a)'s selection of the
583
+ * synthetic branch, so principle (1) (*"a repair's op is an attempt's op"*) still binds and no op is
584
+ * admitted outside one.
585
+ *
586
+ * **AND ITS OP LANDS DURABLY** (`3-bis` (f)): the repair's edit goes through the store's OWN verbs, its
587
+ * `op` is a real `JournalOp` in the store's own journal, readable back through every read verb at that
588
+ * address, and it stands after the registration returns. **THIS IS NOT A DRY RUN**, and no clause of that
589
+ * contract may be read as one. **ON SUCCESS NO LOG CROSSES** (`3-bis` (c), under `A135` (1)'s
590
+ * failure-only bubbling): the caller receives the identity ALONE, and the repair's outcome is carried by
591
+ * this attempt's own `log` and `ops` — the two carriers that clause fixes.
592
+ *
593
+ * **ON FAILURE THE REGISTRATION IS REFUSED** (`3-bis` (d)'s arms (d)/(e)/(f)): the store's
594
+ * `ConstraintListInvalid` is answered in the SAME form and with the SAME THREE SLOTS as state 2's. The
595
+ * synthetic attempt's `KC-4`/`KC-5`/`KC-6` **stays inside this module** and reaches no caller, because the
596
+ * caller's act is the registration and it is the registration that is refused (`§7.3` (e)'s re-reading).
597
+ */
598
+ function registrationAttempt(kernel, store, pair) {
599
+ const address = pair.address;
600
+ const key = pairKey(address, pair.id);
601
+ ATTEMPTS += 1;
602
+ const attempt = {
603
+ ref: { id: `attempt-${ATTEMPTS}` },
604
+ store,
605
+ address: address.slice(),
606
+ tier: null,
607
+ value: undefined,
608
+ // `commit` — THE REGISTRATION ACT'S OWN `CommitRecord` (`3-bis` (a)): this kernel's four members, with
609
+ // no write's op and no write's triggered set, because a registration lands no `K-2` of its own.
610
+ commit: { attempt: null, op: null, triggered: [], pending: [] },
611
+ write: null,
612
+ ops: [],
613
+ log: [],
614
+ ran: [],
615
+ appliedRepairs: [],
616
+ rollback: [],
617
+ checkpoint: null,
618
+ checkedOff: [],
619
+ status: 'open',
620
+ report: null,
621
+ };
622
+
623
+ // ARM (b) VERBATIM: the `constraint-check` entry and the `repair-run` entry are appended, the repair runs
624
+ // through the caller's own verb, and the op its `{ok: true, op}` return names is added to `ops` while its
625
+ // pair is appended to BOTH `ran` and `appliedRepairs` (`3-bis` (b): the pair JOINS both members — of the
626
+ // SYNTHETIC attempt, and of no other). **THE PAIR ENTERS `ran` BEFORE THE REPAIR RUNS**, which is that
627
+ // arm's own ordering and is what makes the repeat arms reachable at the re-run below.
628
+ append(attempt, 'constraint-check', pair.id, null, `the evaluation of ${pair.id}`);
629
+ attempt.ran.push(key);
630
+ append(attempt, 'repair-run', pair.id, null, 'the pair\'s repair was attempted at registration');
631
+
632
+ let result;
633
+ try {
634
+ result = pair.repair(registrationRepairContext(store, address, pair.id, attempt.commit));
635
+ } catch (body) {
636
+ // A REPAIR WHOSE BODY THROWS IS A FAILED REPAIR AND THE REGISTRATION IS REFUSED — the caller's act is
637
+ // the registration, so the refusal is this module's one form (`3-bis` (d); the `KC` boundary at (e)).
638
+ // **THE BODY'S THROWABLE IS NOT CONVERTED INTO A STORE FORM AND IS NOT REACHED BY THE CALLER HERE**: it
639
+ // is caught so the attempt can close and the registration can be refused in the declared form; a drive
640
+ // that expected the body's own value out of `addConstraint` has read a route no clause declares.
641
+ closeRegistrationAttempt(attempt);
642
+ return registrationRefusal(address, pair.id, attempt.log);
643
+ }
644
+
645
+ const ok = result !== null && typeof result === 'object' && result.ok === true;
646
+ const produced = ok ? landedOp(attempt, result, null) : null;
647
+ if (produced === null) {
648
+ // ARM (d) — THE REPAIR PRODUCED NO OP: `{ok: false, message}`, an outside-form return, or an
649
+ // `ok === true` return whose `op` is absent, `undefined` or not the one it landed.
650
+ closeRegistrationAttempt(attempt);
651
+ return registrationRefusal(address, pair.id, attempt.log);
652
+ }
653
+
654
+ attempt.ops.push(produced);
655
+ attempt.appliedRepairs.push(key);
656
+ const entry = attempt.log[attempt.log.length - 1];
657
+ entry.opId = produced.opId;
658
+ entry.message = `the repair ${pair.id} landed ${produced.opId}`;
659
+
660
+ // THE RE-RUN — `3-bis` (d)'s arms (e)/(f) and `3-bis` (e)'s ordinary landing rules: the repair's op
661
+ // LANDED, so the pairs registered at ITS OWN landing's address are evaluated by the ordinary pass
662
+ // (`kernel-surface.md §2.3` item 1), in first-registration order, against THAT op.
663
+ const failed = registrationRerun(kernel, attempt, produced);
664
+ if (failed !== null) {
665
+ closeRegistrationAttempt(attempt);
666
+ return registrationRefusal(address, pair.id, attempt.log);
667
+ }
668
+ // THE PASSING ARM: `PASSED` → `CLOSED` and the registration STANDS. **NO LOG CROSSES**, and the repair's
669
+ // edit STANDS in the store — the side effect the architect's trust clause licenses (`3-bis` (f)).
670
+ closeRegistrationAttempt(attempt, 'passed');
671
+ return null;
672
+ }
673
+
674
+ /// **THE SYNTHETIC ATTEMPT'S RE-RUN** — every pair standing at the attempt's own address, evaluated once
675
+ /// against the repair's own op (`attempt-lifecycle.md §2.4` item 5 (iv)'s evaluated set, which the
676
+ /// registration instant neither widens nor displaces). Answers `null` where the re-run passes and the arm's
677
+ /// token where it does not.
678
+ ///
679
+ /// **THE ARM IS READ OFF THE PAIR THAT FAILED AND OFF NOTHING ELSE** (item 4's disjointness rule): the
680
+ /// pair under repair is IN `ran` — arm (b) wrote it — and arm (b) has just put it in `appliedRepairs`, so a
681
+ /// repeat by the repair's OWN edit reaches `(e)`; a pair IN `ran` and NOT in `appliedRepairs` reaches
682
+ /// `(f)`. **`(c)` is unreachable here**, the pair's own function having already run at this instant.
683
+ function registrationRerun(kernel, attempt, produced) {
684
+ const list = kernel.byAddress.get(addressToken(attempt.address));
685
+ if (list === undefined) return null;
686
+ for (const key of list.slice()) {
687
+ const pair = kernel.pairs.get(key);
688
+ if (pair === undefined) continue;
689
+ const outcome = pair.constraint({
690
+ address: attempt.address.slice(),
691
+ tier: produced.tier === undefined ? null : produced.tier,
692
+ value: produced.after === undefined ? undefined : produced.after.value,
693
+ attempt: attempt.ref,
694
+ op: produced,
695
+ });
696
+ if (outcome === true) continue;
697
+ attempt.terminalArm = attempt.appliedRepairs.includes(key) ? 'KC-5' : 'KC-6';
698
+ return attempt.terminalArm;
699
+ }
700
+ return null;
701
+ }
702
+
703
+ /**
704
+ * **THE REFUSAL THE REGISTRATION ANSWERS — `ConstraintListInvalid` WITH ITS `§8.2`-GENERATED MESSAGE —
705
+ * COMPOSED HERE AS A CODE AND ITS SLOTS, AND RENDERED BY THE SURFACE.**
706
+ *
707
+ * **⟶ THIS IS THE ROUTE THE ARCHITECT SETTLED, AND IT IS NOT A MESSAGE FROM A SECOND SOURCE.** `DD-52`
708
+ * forbids a code's message being produced from a second source, and `§8.2`'s one row declares the slots
709
+ * this instant supplies: **`<CONTAINER>` the pair's own list name, `constraints`**; and **`<SEGMENT>` the
710
+ * ADDED PAIR's `address` spelling, joined by `/`** — the pair's OWN address and not a failing element's,
711
+ * because at this instant the entry is WELL-FORMED and the pair is SUBMITTED rather than found wrong.
712
+ * (`<KEYLIST>`, the row's third slot, is the added pair's members present; no slot of it is asserted here,
713
+ * `§8.2` clause 3 declaring that the sentence the slots make is asserted by NO clause of that contract.)
714
+ *
715
+ * **THE FIXED PHRASE *"is not a valid constraint entry in"* IS RENDERED VERBATIM AND IS NOT RE-AUTHORED** —
716
+ * `§8.2`'s clause 3 of 2026-10-16, which names the honest consequence: at this instant the sentence's SHAPE
717
+ * reports an entry that failed its own validity check while the state is a well-formed pair whose FUNCTION
718
+ * DID NOT PASS. **A HAND-AUTHORED REGISTRATION MESSAGE IS A FAIL OF `P-TP-9` AND NONE STANDS HERE**: not a
719
+ * byte of the text is written in this module, and the sentence is produced by the store's own generator at
720
+ * the surface's existing `errorMessage` path.
721
+ *
722
+ * **THE VALUE CARRIES THIS MODULE'S OWN MARK** (`KERNEL_REFUSAL`) so the surface can tell it from a
723
+ * caller's throw, and the mark is set HERE — in the frame that BUILT the value — and never by a test over
724
+ * members. **A CALLER'S OWN THROWN VALUE STILL SURFACES AS ITSELF**: the 2026-10-17 forgery fix's whole
725
+ * point, and the five shapes are re-probed with this arm in place.
726
+ */
727
+ function registrationRefusal(address, id, log) {
728
+ return {
729
+ status: 'ConstraintListInvalid',
730
+ segment: address.map((segment) => String(segment)).join('/'),
731
+ container: 'constraints',
732
+ id,
733
+ log: Array.isArray(log) ? log : [],
734
+ [KERNEL_REFUSAL]: true,
735
+ };
736
+ }
737
+
738
+ /// **THE SYNTHETIC ATTEMPT'S TERMINAL ACT — `PASSED` OR `FAILING`, AND `CLOSED` FROM THOSE TWO AND FROM
739
+ /// NOWHERE ELSE** (`attempt-lifecycle.md §2.4` item 3). It reaches neither the per-op rollback composition
740
+ /// nor the delivery seam: **the registration instant opens no `K-2`, delivers no listener and composes no
741
+ /// rollback** — the repair's edit STANDS on the passing arm (`3-bis` (f)), and a failed repair's own state
742
+ /// is left where the store's own verb left it (`3-bis` (d): the store's state is left where the composition
743
+ /// restored it, which for an attempt with no rollback composed is the state the verb produced).
744
+ function closeRegistrationAttempt(attempt, outcome = 'failed') {
745
+ attempt.status = 'closed';
746
+ const report = {
747
+ attempt: attempt.ref,
748
+ outcome,
749
+ ops: attempt.ops.slice(),
750
+ log: attempt.log,
751
+ rollback: [],
752
+ };
753
+ attempt.report = report;
754
+ CLOSED.set(attempt.ref.id, report);
755
+ LIVE.delete(attempt.ref.id);
756
+ return report;
757
+ }
758
+
759
+
386
760
  /** The store holds ONE registration per address, and its `listen` takes a function. */
387
761
  function noopListener() {}
388
762
 
@@ -908,10 +1282,24 @@ function evaluate(kernel, attempt, landing) {
908
1282
  // (the store's form is `{status, message}`, carrying no `log` member — `§1.2` item 2; the
909
1283
  // kernel's own form carries three members, and a `KC` token is never named as a store code).
910
1284
  // The entry's `state` stays `null`; the thrown form's `status` is `KC-4`.
1285
+ // **⟶ THE TEST THAT THIS THROWABLE IS *NOT* THE KERNEL'S OWN WAS `!('log' in body)`, AND THAT
1286
+ // TEST DIED ON 2026-10-16 WITH THE FLAT `log` RULING — THIS IS THE SECOND SITE THE RULING BROKE AND
1287
+ // IS REPORTED AS A FINDING, NOT SILENTLY REPAIRED.** The old test read *"the store's form carries two
1288
+ // members and the kernel's carries three, so a `log` member means the kernel built it"*. **`surface.md
1289
+ // §2.5` item 4 now puts `log` on EVERY failure the JS surface throws, so a STORE REFUSAL REACHING
1290
+ // THIS FRAME THROUGH THE PACKAGE CARRIES A `log` AND THE OLD TEST READ IT AS THE KERNEL'S OWN** —
1291
+ // measured: the two `S-JOIN` `WriteParentNotLink` cells went red with the caller's `status` reading
1292
+ // `WriteParentNotLink` instead of `KC-4`, because `storeCode` was answered `null` and the refusal fell
1293
+ // through to the unconverted `throw body` below.
1294
+ //
1295
+ // **THE REPLACEMENT IS THE SAME ONE THE ENTRY'S CROSSING TOOK — THE KERNEL'S OWN REFUSAL-CLASS MARK
1296
+ // AND NEVER A MEMBER'S PRESENCE** (`KERNEL_REFUSAL` above): a value this kernel built is marked, and
1297
+ // everything unmarked that carries a store code IS a store code, whatever members the surface has
1298
+ // attached to it on its way back. A `KC` token is still never a store code on either spelling.
911
1299
  const storeCode = body !== null && typeof body === 'object'
1300
+ && isKernelRefusal(body) === false
912
1301
  && typeof body.status === 'string'
913
1302
  && body.status.length > 0
914
- && !('log' in body)
915
1303
  && !KC_TOKENS.includes(body.status)
916
1304
  ? body.status
917
1305
  : null;
@@ -1237,13 +1625,43 @@ function composeRollback(kernel, attempt) {
1237
1625
  callList.reverse();
1238
1626
  // THE REVERSALS EARLIER RETURNED CALLS PERFORMED — the store's own reports, the only member item 5's
1239
1627
  // "still owes" predicate (and item 5 (a)'s skip) is decided by.
1628
+ //
1629
+ // ⟶ AND THE PREDICATE IS THE MEMBER ALONE, READ AGAINST THE SET IT NAMES — CORRECTED 2026-10-17, AT THE
1630
+ // TEMPORAL-STOP AMENDMENT, AND THE CORRECTION IS NAMED WITH WHAT IT WAS AND WHAT IT IS BECAUSE THIS IS
1631
+ // THE ONE KERNEL EDIT THE AMENDMENT OWES. **WHAT IT WAS:** the guard below was
1632
+ // `!performed.includes(op.opId)`, which is the same reading ONLY WHILE THE STORE'S PER-OP REACH WAS
1633
+ // TOTAL OVER THE WHOLE ADDRESSED SUBTREE — under that reach an op's ABSENCE from every earlier
1634
+ // `undoneOps` member proved a call still owed it, because a call's `undoneOps` was the whole of what lay
1635
+ // under its own op. **WHAT IT IS:** under the amended scope an entry `E` is in scope iff `op.address` is
1636
+ // a prefix of `E.address` **AND** `E.seq` >= the named op's own `seq` (`A: docs/specs/storeroom-native/
1637
+ // write-and-read.md §6.4` item 1's `M-5` amendment and item 3's `M-7` amendment, both 2026-10-16;
1638
+ // `A: docs/decisions.md` · the architect's rulings *"Add temporal stop to the rollback."* and
1639
+ // *"Overshoot is a defect."*), so the store's own walk **STOPS AT THE NAMED OP** — this composition
1640
+ // passes ops in reverse creation order, so an op it has already passed is OLDER than every op a later
1641
+ // call names, is IN THE ADDRESSED SUBTREE AND OUT OF SCOPE, and the store does NOT report it undone by
1642
+ // that later call. The skip's premise is therefore void exactly there, and a still-owed op whose `opId`
1643
+ // stands in no earlier `undoneOps` member **GETS ITS OWN CALL.**
1644
+ //
1645
+ // **THE RULE ABOVE THIS LINE IS UNCHANGED AND SO IS ITS OBSERVABLE — WHICH IS WHAT THE AMENDED CLAUSE
1646
+ // DECLARES AT ITS OWN SITE** (`composition-and-states.md §2.6` item 5 (a)'s 2026-10-16 mark: *"a call's
1647
+ // totality is TOTAL OVER THE TEMPORALLY BOUNDED SET and never over the whole addressed subtree"*, and
1648
+ // *"the kernel still reads only the returned `undoneOps` member and still reasons about no mark"*): the
1649
+ // kernel derives NOTHING from a cross-call premise below. The guard reads the step index `i` instead of
1650
+ // `op.opId` for the ONE reason the two differ and this file's own work loop needs them to: a composition
1651
+ // may in principle receive one `opId` twice (every arm this unit drives holds unique ids), and step `i`
1652
+ // is the step a call over the `i`-th member ISSUED — the op's own id is what the store was NAMED, never
1653
+ // which member it was. **NO CLAUSE MOVES WITH IT: the step count stays the calls ISSUED, `failed` stays
1654
+ // that call's own answer, no mark is consulted and the walk still stops at the failing call.**
1240
1655
  const performed = [];
1656
+ const recorded = [];
1241
1657
  let floor = null;
1242
- for (const op of callList) {
1243
- const owed = !performed.includes(op.opId);
1658
+ for (let i = 0; i < callList.length; i += 1) {
1659
+ const op = callList[i];
1244
1660
  // (2) THE SKIP: an op an earlier returned call's own `undoneOps` already reports undone is not still
1245
- // owed, so NO call is issued over it and no step stands for it (item 5 (a)).
1246
- if (!owed) continue;
1661
+ // owed, so NO call is issued over it and no step stands for it (item 5 (a)) — and under the amended
1662
+ // scope that is the WHOLE of it: absence from the member is evidence of nothing beyond the store's own
1663
+ // performed set, so an op the member does not name GETS ITS OWN CALL.
1664
+ if (recorded.includes(i)) continue;
1247
1665
  let answer = 'ok';
1248
1666
  let failed = false;
1249
1667
  let record = null;
@@ -1273,6 +1691,11 @@ function composeRollback(kernel, attempt) {
1273
1691
  });
1274
1692
  for (const undone of undoneOps) {
1275
1693
  if (!performed.includes(undone)) performed.push(undone);
1694
+ // THE STEPS THAT ARE ALREADY — RECORDED BY THE MEMBER'S OWN NAMES, WHICH IS THE PREDICATE'S ONE
1695
+ // SOURCE (`item 5 (a)`, unmoved): an op this member names is one this composition has performed.
1696
+ for (let at = i + 1; at < callList.length; at += 1) {
1697
+ if (callList[at].opId === undone && !recorded.includes(at)) recorded.push(at);
1698
+ }
1276
1699
  }
1277
1700
  // AND THE WALK STOPS AT THE FAILING CALL: a call that met either floor code is the composition's
1278
1701
  // LAST — "the walk STOPS at the failing call" (`§2.6` item 6 (a); `fail-surface.md §2`'s `KC-8`