provident-storeroom 1.3.0 → 1.4.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.
@@ -19,7 +19,15 @@ import { currentWindow, homeAddressKey, installRestartConsumer, isStoreReceiver,
19
19
  // function the pass appends with — rather than pushed here with a member set of its own; the REFUSAL's own
20
20
  // list keeps its five members and no `seq`, because no attempt stands at the judgement that built it
21
21
  // (`D-41` item 4). Two records, two honest forms, one append.
22
- import { append, externalCall, kernelFor } from './kernel-foundations.mjs';
22
+ import { append, externalCall, kernelFor, throwableForm } from './kernel-foundations.mjs';
23
+ // **⟶ AND THE TWO KERNEL ACTS THE DELETE'S PATH OWES — `D-55` ITEM 3, 2026-10-29.** The kernel's public
24
+ // barrel (`src/constraint-kernel.mjs`) is untouched and keeps its five names; **these are two PART modules' own
25
+ // acts, reached here the way `append` and `kernelFor` above are** (`kernel-surface.md §1` item 1's empty import
26
+ // footprint is the kernel's side of this edge and it is unmoved: neither module imports this file or any entry
27
+ // module). `commitRemoval` is the commit part's remove-shaped act — a delete-shaped attempt that lands no write
28
+ // — and `runAttempt` is the ONE pass, taken verbatim so no second pass loop is minted for a delete.
29
+ import { commitRemoval } from './kernel-commit.mjs';
30
+ import { runAttempt } from './kernel-attempt.mjs';
23
31
  // **⟶ AND THE CARRIERS, ADDED 2026-10-26 FOR THE REFUSAL'S OWN UNDOING (`DEF-W`'s `(a)`).** The
24
32
  // compensating act below reaches the store's own verb at its entry, with the SAME carrier forms every member
25
33
  // hands it (`carrier.mjs` is the boundary's one encoder for the three positions and imports nothing of this
@@ -489,7 +497,11 @@ export function registrationCrossing(refusal) {
489
497
  // is the caller's own value and is answered as it was thrown.
490
498
  const carried = bodyThrowCarried(refusal);
491
499
  if (carried !== null) {
492
- const converted = bodyThrowRefusal(carried, refusal);
500
+ // **`false` — THE REGISTRATION INSTANT RECORDS NOTHING, AND THE CLAUSE SAYS SO.** No attempt stands at
501
+ // this evaluation, so the crossing's `log` is `surface.md §2.5` item 4's declared `[]` (`DEF-S`'s own cell
502
+ // reads it) and no terminal entry exists to carry the throwable's form: the crossed sentence must not
503
+ // point at a log that does not hold it (`DEF-AK`, 2026-10-28).
504
+ const converted = bodyThrowRefusal(carried, refusal, false);
493
505
  if (converted !== null) throw converted;
494
506
  }
495
507
  if (isKernelBuiltRefusal(refusal) === false) throw refusal;
@@ -829,6 +841,140 @@ export function constraintWrite(state, instance, address, tier, value) {
829
841
  };
830
842
  }
831
843
 
844
+ /**
845
+ * **⟶ ADDED 2026-10-29 — THE DELETE'S OWN KERNEL-DRIVEN PATH: A DELETE-SHAPED ATTEMPT, A PASS, AND THE
846
+ * TERMINAL ENTRY. `D-55` ITEM 3, `DEF-X`, THE ARCHITECT, VERBATIM: *"A delete is an editing verb and must pass
847
+ * constraints. This includes all of the relevant commit and message logic."***
848
+ *
849
+ * **WHAT WAS MEASURED AT `1.3.0`, AND IT IS WHY THIS FUNCTION EXISTS.** `delete` opened its own commit window
850
+ * and called the addon's `delete` directly: **no `K-2`, no `K-3`, no log, no terminal entry** — so a delete
851
+ * consulted no constraint at all, and **the only pass shape the artefact had LANDS A WRITE FIRST** (`K-2`'s
852
+ * store leg called `write`, so the pass it ran judged a state the delete was not in; measured `storeAfter =
853
+ * {"c":2}`). **A delete therefore needed an attempt of its OWN KIND rather than a re-used `K-2`.**
854
+ *
855
+ * **THE THREE STAGES, IN THE ONE ORDER `constraintWrite` TAKES ITS OWN** (`surface.md §2.12` item 1):
856
+ * ```
857
+ * 1. the delete-shaped attempt `kernel.commitRemoval` — the hold, the commit's log, the delete's op
858
+ * named as the attempt's landing; NO WRITE IS LANDED
859
+ * 2. the store's own leg the thunk the entry hands: the addon's `delete`, crossed by `index.mjs`
860
+ * 3. the pass `kernel.runAttempt` — every pair standing at THE DELETE'S OWN ADDRESS is
861
+ * asked against THE STATE THE DELETE LEFT (its after-state is absence)
862
+ * 4. the terminal act the attempt's ONE `outcome` entry on the refusing arm, its `commit` entry
863
+ * on the passing arm, and on a refusal the composition that undoes the
864
+ * delete (`D-55` item 5's safe state)
865
+ * ```
866
+ * **THE PASS IS THE WRITE'S PASS, MEMBER FOR MEMBER** — `runAttempt`, the same evaluated set, the same `D-39`
867
+ * registration order, the same repair and re-run arms, the same restart drain — and **the ONLY difference is the
868
+ * landing it judges**: a delete's journal op, whose `after` is absence, instead of a write's op whose `after` is
869
+ * the value it landed. **NO SECOND PASS LOOP IS MINTED**, and a repair landed under a delete's pass re-runs the
870
+ * same evaluation against ITS op (`D-53`: repairs use the same commit).
871
+ *
872
+ * **⟶ AND "THE SAME EVALUATED SET" IS NOW A PREFIX SET, 2026-10-29 — `D-56`, WHICH SUPERSEDES THE CLAUSE THIS
873
+ * PARAGRAPH PRINTED.** `RCA-8(g)` ANNOTATE-BESIDE: **the bytes that stood here read** *"the same evaluated set
874
+ * (the pairs whose own address IS the attempt's, `pairsAtAddress`'s exact-address rule and never the trigger set's
875
+ * prefix widening)"*, **and they are read THROUGH the architect's sentence**: *"A listener/constraint should fire
876
+ * when the descendants of its targeted address node change, because the descendants become part of the object
877
+ * that is read from that address"*. **SO THE DELETE'S PASS ASKS THE PAIRS AT OR ABOVE THE DELETE'S ADDRESS** —
878
+ * the pairs whose own address is a PREFIX of it — **and a pair at `['tabs']` is asked for a delete at
879
+ * `['tabs','landingPage']`** (`strata/decisions.md` · `D-56`). **THE SET IS STILL `pairsAtAddress`'s ONE
880
+ * FUNCTION AND STILL ONE SNAPSHOT** (`CX-12`): `D-56` moves WHICH rows are members and nothing about WHEN the
881
+ * list is materialised, HOW it is ordered (`HL-8` item 6: first-registration order, ancestors interleaved into
882
+ * that one order) or how many times a row is asked.
883
+ *
884
+ * **A REFUSAL IS THE ORDINARY REFUSAL** (`constraintCrossing` below): the surface's one plain form
885
+ * `{status, message, log}`, its `status` the set's rank-`20` member `ConstraintPassRefused`, and its `log` the
886
+ * COMMIT'S OWN LIST — `constraint-check` for the pair that refused, then the terminal `outcome` entry whose
887
+ * `state` is the kernel's token — each with its `seq`. **AND THE SAFE STATE IS `D-55` ITEM 5's**: the
888
+ * composition the terminal act runs (`composeRollback`, one floor call per address at that address's first owed
889
+ * op) undoes **the delete and every edit the commit made under it**, so the caller meets a store back at the
890
+ * state the commit opened at. Where the refusal is a RESTARTED check's (`D-42`, a reversal raised by a body
891
+ * inside this pass), the compensation is the reversal's own and it restores the journal mark the commit cached
892
+ * at ITS OPENING (`state.mjs`'s `windowMark`) — the same safe state by the other route.
893
+ *
894
+ * **`D-3`'S NO-OP ARM IS NOT AN EDIT**: where the delete removed nothing there is no journal op, so
895
+ * `commitRemoval` answers `null`, **no attempt is opened, no pass runs and no entry is appended** — there is no
896
+ * state for a pair to refuse and nothing for the safe-state rule to undo. The record crosses as it always did.
897
+ *
898
+ * **THE DELIVERY IS THE TERMINAL ARM'S FROM 2026-10-29, AND IT IS WHY THE PASS IS HANDED THE `CommitRecord`
899
+ * (`D-55` item 3's third demand: a listener fired by a delete sees the JUDGED state, and a refused delete
900
+ * delivers nothing, its commit having been undone).** `commitRemoval` now mints the record the pass's terminal
901
+ * arm is keyed by, and `runAttempt` reaches that arm with it (`settleArm` → the entry's `TERMINAL_ARM`), so the
902
+ * residue `record.pending` — the delete's returned set MINUS the handles its own pass checked off — is
903
+ * delivered at the arm, after the judgement, exactly as a write's is. **A REFUSED DELETE STILL DELIVERS
904
+ * NOTHING**: the failing arm reaches the same seam with the residue the discard emptied (`terminal`).
905
+ *
906
+ * **AND THE RECORD IS HANDED TO THE CONSUMER ON THE RECEIPT, UNDER THE `D-49` DEVICE.** `DeleteRecord` keeps
907
+ * its enumerable members; `commit` is a NON-ENUMERABLE own `data` property, visible by its name and declared in
908
+ * `index.d.ts`, exactly as `discarded` is — so the record a delete minted can be held (`receipt.commit`) and
909
+ * handed back (`K-4`/`K-5` take its `attempt`; a nested `write` takes the record itself at its fourth
910
+ * position). **`null` IS THE `D-3` ARM'S VALUE**: no attempt was opened there, so there is no record to carry.
911
+ */
912
+ export function constraintDelete(instance, address, tier, remove) {
913
+ // THE DELETE-SHAPED ATTEMPT, OPENED AROUND THE STORE'S OWN LEG: `remove` is the addon's `delete`, already
914
+ // crossed by the entry, and it is invoked with the hold taken and the commit's list in hand. `null` is the
915
+ // `D-3` arm (nothing removed) — the receipt the thunk answered stands and nothing is judged.
916
+ let receipt = null;
917
+ let attempt;
918
+ try {
919
+ attempt = commitRemoval(instance, address, tier, () => {
920
+ receipt = remove();
921
+ return receipt;
922
+ });
923
+ } catch (refusal) {
924
+ // THE KERNEL'S OWN `KC-7` (a held address, before the store is reached) or the store's own refusal: the
925
+ // ONE crossing every kernel-driven path takes, so a nested delete at a live attempt's address answers the
926
+ // same rank-`20` form a write does and a store refusal crosses verbatim (`§2.5` item 10 (ii)).
927
+ constraintCrossing(refusal);
928
+ }
929
+ // **THE `D-3` ARM CARRIES ITS `null`** — no attempt, so no record, and the member is present rather than
930
+ // absent (`D-21`: a member whose act did not run says so).
931
+ if (attempt === null) {
932
+ exposeCommit(receipt, null);
933
+ return receipt;
934
+ }
935
+ // THE PASS, INSIDE THE COMMIT THE MEMBER OPENED (`D-44`): `runAttempt` names THE RECORD `commitRemoval`
936
+ // minted (`attempt.record` — the same object `K-2` hands `K-3`), so its scope JOINS — the delete's window is
937
+ // the pass's window, and the pairs standing at THIS address are asked against the delete's own op. **THE
938
+ // TERMINAL ARM IS REACHED WITH THAT RECORD AND NOTHING ELSE** (`settleArm`), so the delivery and the
939
+ // `file`-tier save are the record's own facts. A failing pass throws the kernel's own refusal with its log
940
+ // and its compensating act already taken.
941
+ let report;
942
+ try {
943
+ report = runAttempt(instance, attempt.record);
944
+ } catch (refusal) {
945
+ constraintCrossing(refusal);
946
+ }
947
+ // **AND THE RESTART'S REFUSAL, WHERE THE PASS ITSELF PASSED** (`D-42`; `D-54` (b)): a reversal raised by a
948
+ // body inside this pass is drained at the pass's terminal state, and where the restarted check refused, the
949
+ // refusal the report carries is the one that crosses — the delete is refused with the store already restored
950
+ // to the mark the commit cached at its opening. THE PASSING DELETE FINDS NO CARRIED REFUSAL AND RETURNS ITS
951
+ // RECEIPT UNCHANGED.
952
+ const restarted = report !== null && typeof report === 'object' ? report[RESTART_REFUSAL] : undefined;
953
+ if (restarted !== undefined) {
954
+ constraintCrossing(restarted);
955
+ }
956
+ exposeCommit(receipt, attempt.record);
957
+ return receipt;
958
+ }
959
+
960
+ /// **THE RECORD ON THE RECEIPT — A NON-ENUMERABLE OWN `data` PROPERTY, THE DEVICE `D-49` DECLARED.**
961
+ ///
962
+ /// `Object.keys(receipt)`, every deep-equality over a receipt and every census of its ENUMERABLE members read
963
+ /// exactly what they read before, while a caller reads the commit **by its name** (`receipt.commit`) and
964
+ /// `index.d.ts` declares it. **IT IS A `data` PROPERTY AND NOT AN ACCESSOR**: a getter would run caller-side
965
+ /// code on a read, which is the read half `D-35` closes everywhere else. **A RECEIPT THAT ALREADY CARRIES ONE**
966
+ /// — the thunk answers the store's own object and this entry owns it — takes the value it was handed, and the
967
+ /// member is defined on every arm so its presence never depends on the arm.
968
+ function exposeCommit(receipt, record) {
969
+ if (receipt === null || typeof receipt !== 'object') return;
970
+ Object.defineProperty(receipt, 'commit', {
971
+ value: record === undefined ? null : record,
972
+ enumerable: false,
973
+ writable: false,
974
+ configurable: true,
975
+ });
976
+ }
977
+
832
978
  /// **THE FAIL ARM'S CROSSING — `A120` (2): THE ENTRY CARRIES THE KERNEL'S TOKEN, THE THROW KEEPS THE
833
979
  /// STORE'S — AND THE FORM CROSSES AT THREE MEMBERS FROM 2026-10-16** (`surface.md §2.5`'s clause of that
834
980
  /// date, items 3–4 and 10 (i)–(iii); `docs/specs/storeroom-js/surface.md §2.12` item 1's mark of the same date).
@@ -1111,7 +1257,7 @@ function innerRefusalCarried(value) {
1111
1257
  /// **A TREE THAT CARRIES NO USABLE GENERATOR ANSWERS `null`**, and both crossings then re-throw the marked
1112
1258
  /// value AS ITSELF — the same safe direction `registrationCrossing` takes for a kernel refusal, and no
1113
1259
  /// sentence is authored here.
1114
- function bodyThrowRefusal(carried, thrown) {
1260
+ function bodyThrowRefusal(carried, thrown, recorded) {
1115
1261
  const addon_ = withAddon();
1116
1262
  if (typeof addon_.errorMessage !== 'function') return null;
1117
1263
  const subject = typeof carried.address === 'string' ? carried.address : '';
@@ -1130,6 +1276,22 @@ function bodyThrowRefusal(carried, thrown) {
1130
1276
  + `ITSELF a refusal, ${JSON.stringify(innerStatus)} with the message ${JSON.stringify(innerSaid)}, and it `
1131
1277
  + `crosses BESIDE this one under Symbol.for('provident-storeroom.inner-refusal') with its own log — the `
1132
1278
  + `generated sentence above names the CODE for a body that threw and not the value the body threw`;
1279
+ } else {
1280
+ // **⟶ AND THE PLAIN THROWABLE'S SENTENCE STOPS CLAIMING A CROSSING IT DOES NOT MAKE — `D-55` ITEM 1,
1281
+ // `DEF-AK`, 2026-10-28.** The generated sentence's own bytes are *"a constraint body's throwable crosses
1282
+ // as this refusal"*, and the throwable DOES NOT: it is not carried, its members are not merged and its
1283
+ // identity is not handed on. **WHAT DOES CROSS IS ITS MESSAGE, IN THE COMMIT'S LOG** — the terminal arm of
1284
+ // the attempt that caught it put the form the value took (the string's own text, the object's own
1285
+ // `message` member, or the kind of value it was) in the ONE entry the arm appends. **`recorded` IS THAT
1286
+ // FACT, SAID BY THE CROSSING THAT CALLED THIS FRAME** (`constraintCrossing` reads the arm that records it;
1287
+ // `registrationCrossing` and the judgement do not), **so no arm points at a `log` that does not carry it**:
1288
+ // where the arm records nothing the clause says so and names the declared `[]` (`surface.md §2.5` item 4).
1289
+ const where = recorded === true
1290
+ ? `the form the throwable took stands in the \`outcome\` entry of this refusal's \`log\`, which is where `
1291
+ + `a throwable's own message crosses`
1292
+ : `no entry of this failure's \`log\` records it — \`log\` is the declared empty list where no attempt `
1293
+ + `stands (surface.md §2.5 item 4) — so nothing of the value crosses`;
1294
+ generated = `${generated} — the value the constraint body threw does NOT cross as this refusal: ${where}`;
1133
1295
  }
1134
1296
  const crossed = {
1135
1297
  status: BODY_THREW_STATUS,
@@ -1159,7 +1321,10 @@ function constraintCrossing(refusal) {
1159
1321
  // `{status, message}` AND NO MARK STILL CROSSES AS ITSELF, BELOW.**
1160
1322
  const carried = bodyThrowCarried(refusal);
1161
1323
  if (carried !== null) {
1162
- const converted = bodyThrowRefusal(carried, refusal);
1324
+ // **`true` — THIS IS THE LANDING'S OWN CROSSING, AND ITS TERMINAL ARM RECORDS THE THROWABLE'S FORM**
1325
+ // (`kernel-attempt.mjs`'s `evaluate`: the attempt closes with ONE `outcome` entry whose sentence carries
1326
+ // `throwableForm(body)`), so the crossed sentence may point at it and `DEF-AK`'s log entry exists.
1327
+ const converted = bodyThrowRefusal(carried, refusal, true);
1163
1328
  if (converted !== null) throw converted;
1164
1329
  }
1165
1330
  const isObject = refusal !== null && typeof refusal === 'object';
@@ -1494,6 +1659,23 @@ const COMPENSATING = Symbol.for('provident-storeroom.compensating-rollback');
1494
1659
  /// first address, which is a fact about registration order and not about the check.
1495
1660
  const ASKING = new WeakMap();
1496
1661
 
1662
+ /// **⟶ THE VALUE A BODY THREW, CARRIED FROM THE FRAME THAT CAUGHT IT TO THE ENTRY THAT MUST PRINT IT, ADDED
1663
+ /// 2026-10-28 — `D-55` ITEM 1, `DEF-AK`, MEASURED.**
1664
+ ///
1665
+ /// **THE WINDOW IT CLOSES.** A pair body that throws at a reversal's judgement is caught by `reversalOutcome`,
1666
+ /// which converts it to the surface's rank-`18` form; `judgeReversal` then catches that and builds the refusal
1667
+ /// whose ONE log entry names the throwing pair. **NOTHING OF THE THROWABLE REACHED ANY RECORD**: the crossed
1668
+ /// sentence said *"a constraint body's throwable crosses as this refusal"* and the log carried only the pair's
1669
+ /// name. **D-55's clarification (the architect, verbatim: *"Include a thrown message in the message log.
1670
+ /// Obviously."*) makes the message a log entry's own business**, and no attempt log stands at this judgement —
1671
+ /// so the form travels here, from the catch frame to `reversalRefusal`'s entry sentence.
1672
+ ///
1673
+ /// **A `WeakMap` KEYED BY THE CONVERTED FORM AND NOTHING ELSE** (`D-30`'s device, `D-46`): the form's three
1674
+ /// declared members are unmoved, no symbol is spelled on a value a caller holds, and the record dies with the
1675
+ /// value. **A TREE WITH NO USABLE GENERATOR IS NOT CONVERTED**, so its raw value reaches `reversalRefusal` and
1676
+ /// that frame spells the form itself (`throwableForm`) — the map answers nothing and nothing is invented.
1677
+ const THROWN_FORM = new WeakMap();
1678
+
1497
1679
  /// **HOW MANY RESTARTS ONE PASS'S COMMIT SCOPE MAY TAKE** — the bound `drainRestartRequests` spends. Three is
1498
1680
  /// the declared figure: two fewer than any arm of this package's own batteries drives, and enough that a lawful
1499
1681
  /// in-commit action's single restart never meets it.
@@ -1690,6 +1872,17 @@ export function witnessDiscardedReversal(instance, window) {
1690
1872
  }
1691
1873
  // THE STORE'S OWN ECHO OF THE ID THE REVERSAL NAMED — `null` where the reversal's call answered no id (the
1692
1874
  // request stands and the act's answer did not reach the echo, which is a real arm a caller can see).
1875
+ //
1876
+ // **⟶ AND AN ENTRY IS NEVER SHIPPED WITH AN EMPTY ADDRESS LIST — `D-55` ITEM 2, `DEF-AH`, 2026-10-28.**
1877
+ // The architect, verbatim: *"A witness address of [] corresponds to the register itself. This is not a legal
1878
+ // response for any other watched address."* **SO `[]` IS THE REGISTER (THE ROOT) AND IS AN ADDRESS, NEVER A
1879
+ // LIST**: a request whose reversal moved NOTHING has no discard to report — there is no legal response to
1880
+ // give it — so **the entry is ABSENT (`null`) rather than empty**, and the caller reads `discarded: []`
1881
+ // because nothing was discarded *observably*. **AND THE ROOT STAYS DISTINGUISHABLE**: an address that IS
1882
+ // `[]` is one element of `addresses` — `[[]]` — which is length `1` and therefore survives this test; the
1883
+ // distinction the ruling draws is between an ADDRESS of `[]` and a LIST of `[]`, and this is the one line
1884
+ // where it is measured.
1885
+ if (addresses.length === 0) return null;
1693
1886
  return {
1694
1887
  opId: typeof request.reversalId === 'string' ? request.reversalId : null,
1695
1888
  addresses,
@@ -1823,13 +2016,55 @@ export function reversalWatch(state, instance) {
1823
2016
  // judgement — a listener's own window is the measured arm), and the arm past the budget then says so
1824
2017
  // rather than naming a pair it cannot know.
1825
2018
  const asking = ASKING.get(instance);
1826
- restartRecord(instance).pending = {
1827
- watched: watchStanding(state, instance),
2019
+ const window = currentWindow(instance);
2020
+ // **⟶ AND A SECOND RAISE IN THE SAME COMMIT MERGES INTO THE REQUEST RATHER THAN REPLACING IT — `D-55`
2021
+ // ITEM 6's SECOND HALF, `DEF-AP`, 2026-10-28, MEASURED.** **WHAT WAS MEASURED:** two listeners each
2022
+ // reversing inside ONE commit — two raises in one window — left only the LAST raise judged; the earlier
2023
+ // listener's own violation was asked **zero** times, registration order decided which raise was lost, and
2024
+ // when the survivor's judgement passed the write returned normally **with the violation standing**. **THE
2025
+ // ROW'S OWN ESCAPE — declare that an overwritten raise may leave a violation unjudged — IS UNAVAILABLE**,
2026
+ // because `DEF-AN`'s safe-state rule is the promise: a refused edit undoes the WHOLE commit.
2027
+ // **SO THE DRAIN JUDGES THE STATE THE COMMIT STANDS AT, NOT THE REQUEST THAT HAPPENED TO SURVIVE**: the
2028
+ // request's captures are merged to the EARLIEST reading of each address — the state the commit opened at —
2029
+ // so `movedStanding` at the drain sees every address the WHOLE commit moved, whichever raise named it.
2030
+ // **THE WALK'S ORDER AND MEMBERSHIP STAY THE REGISTRY'S** (`watchStanding`'s `D-39` order, re-read now):
2031
+ // an address this raise's walk carries takes the earlier capture where one exists, and an address the
2032
+ // earlier watch carried but the registry no longer does leaves the debt record (it is not the check's
2033
+ // subject now). **THE LATEST RAISE KEEPS ITS OWN ASK AND ITS `moved` IS RE-MEASURED**; the `reversalId`
2034
+ // stays the first echo it recorded (`judgeReversal`'s in-flight arm sets it once), so the entry a refusal
2035
+ // names is never re-spelled.
2036
+ const next = watchStanding(state, instance);
2037
+ const record = restartRecord(instance);
2038
+ const prior = record.pending;
2039
+ if (prior !== null && prior.window === window) {
2040
+ const merged = [];
2041
+ for (let index = 0; index < next.length; index += 1) {
2042
+ const one = next[index];
2043
+ const spelling = homeAddressKey(one.address);
2044
+ let earlier = null;
2045
+ for (let known = 0; known < prior.watched.length; known += 1) {
2046
+ if (homeAddressKey(prior.watched[known].address) === spelling) {
2047
+ earlier = prior.watched[known];
2048
+ break;
2049
+ }
2050
+ }
2051
+ appendOwn(merged, earlier === null ? one : earlier);
2052
+ }
2053
+ prior.watched = merged;
2054
+ // THE MOVED SET IS RE-MEASURED AGAINST THE MERGED CAPTURES (`judgeReversal`'s in-flight arm does it at
2055
+ // the reversal's own instant, one frame below this call) — a set measured against the later watch would
2056
+ // hide the earlier raise's movement, which is the defect this merge closes.
2057
+ prior.moved = null;
2058
+ prior.asked = asking === undefined ? prior.asked : asking;
2059
+ return watched;
2060
+ }
2061
+ record.pending = {
2062
+ watched: next,
1828
2063
  // **AND THE MOVED SET IS MEASURED BY THE JUDGEMENT, NOT BY THE WATCH** (`judgeReversal`'s in-flight arm;
1829
2064
  // `DEF-AM`): the watch is taken BEFORE the reversal runs, so what moved is not knowable here.
1830
2065
  moved: null,
1831
2066
  reversalId: null,
1832
- window: currentWindow(instance),
2067
+ window,
1833
2068
  asked: asking === undefined ? null : asking,
1834
2069
  };
1835
2070
  return watched;
@@ -2498,7 +2733,18 @@ function reversalOutcome(instance, entry, address, value) {
2498
2733
  // **⟶ AND THE BODY'S OWN VALUE IS HANDED IN, 2026-10-28 (`DEF-AK`)**: `bodyThrowRefusal` carries an inner
2499
2734
  // refusal beside the crossed one and names it in the crossed sentence, and the value the body threw is
2500
2735
  // the only place that refusal stands.
2501
- const converted = bodyThrowRefusal(carried, body);
2736
+ //
2737
+ // **⟶ AND ITS FORM IS TAKEN HERE, 2026-10-28 — `D-55` ITEM 1, `DEF-AK`.** No attempt stands at a reversal's
2738
+ // judgement, so there is no terminal entry for the kernel to record it in: **the judgement's own refusal
2739
+ // list is the log this failure crosses with**, and its ONE entry carries the form the body threw
2740
+ // (`reversalRefusal` reads it off this `WeakMap`). **A `WeakMap` AND NOT A MEMBER**: the converted form's
2741
+ // three members are unmoved and nothing is added to any record (`A117` (D6)).
2742
+ const form = throwableForm(body);
2743
+ // **`false` — NO ATTEMPT LOG STANDS AT A JUDGEMENT, AND THIS FRAME'S OWN LIST KEEPS ITS ONE ENTRY**: the
2744
+ // form the body threw is carried through `THROWN_FORM` and printed in that entry's sentence by
2745
+ // `reversalRefusal`, so the crossed sentence points at the `log` it actually carries (`DEF-AK`).
2746
+ const converted = bodyThrowRefusal(carried, body, false);
2747
+ if (converted !== null && typeof converted === 'object') THROWN_FORM.set(converted, form);
2502
2748
  throw converted === null ? body : converted;
2503
2749
  }
2504
2750
  }
@@ -2615,8 +2861,18 @@ function reversalRefusal(one, after, said, reversalId, undo, thrown, unsettled =
2615
2861
  + (said === null ? '' : ` — ${said}`)
2616
2862
  + ` — ${undoSpelling(undo)}`;
2617
2863
  } else {
2864
+ // **⟶ AND THE THROWABLE'S OWN FORM IS PRINTED IN THIS ENTRY — `D-55` ITEM 1, `DEF-AK`, 2026-10-28.** No
2865
+ // attempt stands at a reversal's judgement, so no commit log exists for the kernel to append to: **this
2866
+ // refusal's ONE entry is the log the failure crosses with**, so the value the body threw is named HERE —
2867
+ // the form the catch frame took (`THROWN_FORM`) where the value was converted, and the value's own form
2868
+ // where the tree carried no generator to convert it. **THE ENTRY'S SHAPE, KIND, `seq` AND MEMBER COUNT DO
2869
+ // NOT MOVE**: the form is in the sentence, not in a seventh member and not in a second entry (`D-41` item
2870
+ // `4`'s one-entry arm, which the restoration's cell asserts).
2871
+ const took = THROWN_FORM.get(thrown);
2872
+ const form = typeof took === 'string' ? took : throwableForm(thrown);
2618
2873
  spelled = `the constraint ${one.entry.id} THREW at the judgement of the state the reversal left at `
2619
2874
  + `${addressSpelling(one.address)}: the value there is ${standingSpelling(after)}`
2875
+ + ` — the value it threw was ${form}`
2620
2876
  + ` — ${undoSpelling(undo)}`;
2621
2877
  }
2622
2878
  const entry = {
@@ -600,9 +600,17 @@ export function terminalArm(state, record) {
600
600
  const triggeringAddress = answer === null || answer === undefined || answer.op === null || answer.op === undefined
601
601
  ? undefined
602
602
  : answer.op.address;
603
- // `deliver` is THE SAME loop the post-verb window uses (`docs/specs/storeroom-js/surface.md §2.4` rules 1–3 read once, at both instants): ONE
604
- // invocation per DISTINCT handle, and a handle with no registered function fires nothing silently.
605
- deliver(state, triggered, triggeringAddress);
603
+ // **⟶ AND THE ARM PERFORMS THE DELIVERY FOR A KERNEL-DRIVEN WRITE AND FOR NO OTHER ACT — 2026-10-29.** A
604
+ // `delete`'s delivery is its OWN MEMBER's (`D-49` declares that window the one whose check never ran, and a
605
+ // request raised there is the witness's and not a pass's); the record is the delete's, so this arm is
606
+ // reached for it — the `file`-tier save above is the arm's act on BOTH — and the residue's delivery is the
607
+ // member's. **THE FACT IS THE PACKAGE'S OWN STATE AND NEVER A MEMBER OF ANY RECORD**, and it is `'arm'` on
608
+ // every path that does not name another, so a write's delivery is exactly where it was.
609
+ if (state.legDelivery !== 'member') {
610
+ // `deliver` is THE SAME loop the post-verb window uses (`docs/specs/storeroom-js/surface.md §2.4` rules 1–3 read once, at both instants): ONE
611
+ // invocation per DISTINCT handle, and a handle with no registered function fires nothing silently.
612
+ deliver(state, triggered, triggeringAddress);
613
+ }
606
614
  return undefined;
607
615
  }
608
616
 
@@ -1,5 +1,5 @@
1
1
  // `D-13` (`docs/L1/kernel-subdivision.md` §1 part `9d`) — the pass: bytes moved from `bindings/js/src/constraint-kernel.mjs`; no logic changed.
2
- import { KC, KC_TOKENS, SETTLED_ON_THE_PASSING_ARM, SAVE_FAILED_AT_THE_TERMINAL_ARM, TERMINAL_ARM, markBodyThrow, refuse, isKernelRefusal, pairSpelling, addressSpelling, sameAddress, kernelFor, append, appendOwn, ownMember, withdraw, landedOp, landedOpDefect, pairsAtAddress, enterCommitFrame, leaveCommitFrame } from './kernel-foundations.mjs';
2
+ import { KC, KC_TOKENS, SETTLED_ON_THE_PASSING_ARM, SAVE_FAILED_AT_THE_TERMINAL_ARM, TERMINAL_ARM, markBodyThrow, throwableForm, refuse, isKernelRefusal, pairSpelling, addressSpelling, sameAddress, kernelFor, append, appendOwn, ownMember, withdraw, landedOp, landedOpDefect, pairsAtAddress, enterCommitFrame, leaveCommitFrame, commitLogInFlight, sealHandoff } from './kernel-foundations.mjs';
3
3
  import { commitAttemptIdOf, terminal, close } from './kernel-terminal.mjs';
4
4
  // ---------------------------------------------------------------------------------------------
5
5
  // `K-3` `runAttempt(store, commit) -> AttemptReport`
@@ -160,7 +160,12 @@ export function runAttempt(store, commitRecord) {
160
160
  } catch (thrown) {
161
161
  return drainFailingPass(store, commitRecord, thrown);
162
162
  }
163
- return drainRestart(store, report);
163
+ // **⟶ AND THE RECORD IS SEALED AT THE HANDOFF — `D-55` item 6, `DEF-AO`, 2026-10-28.** The drain above is
164
+ // the LAST act of closing out (it amends the report's own `outcome` and appends the refusal's entry to the
165
+ // report's list BEFORE this line), so what the seal freezes is the record the driver receives and no record
166
+ // in flight: `report.log` and the report are `Object.freeze`d, and a later act can neither append to the
167
+ // commit's list nor re-member the report. **A PASSING ARM IS SEALED TOO** — its list is handed off once.
168
+ return sealHandoff(drainRestart(store, report), commitLogInFlight(kernelFor(store)) !== null);
164
169
  }, commitRecord);
165
170
  }
166
171
 
@@ -182,6 +187,11 @@ function drainFailingPass(store, commitRecord, thrown) {
182
187
  const closed = kernelFor(store).closed.get(commitAttemptIdOf(commitRecord));
183
188
  if (closed === undefined) throw thrown;
184
189
  const answered = drainRestart(store, closed);
190
+ // **⟶ THE FAILING ARM'S RECORD IS SEALED AT ITS OWN HANDOFF — `DEF-AO`.** The drain has already amended the
191
+ // closed report if the restarted check refused, so the seal stands before this arm picks which value crosses:
192
+ // the restarted refusal and the pass's own throwable both carry the SAME frozen list (`D-53`), and neither
193
+ // can be appended to after this line.
194
+ sealHandoff(answered, commitLogInFlight(kernelFor(store)) !== null);
185
195
  const restarted = answered !== null && typeof answered === 'object' ? answered[RESTART_REFUSAL] : undefined;
186
196
  if (restarted !== undefined && isKernelRefusal(thrown) === true) throw restarted;
187
197
  throw thrown;
@@ -445,14 +455,35 @@ function evaluate(kernel, attempt, landing) {
445
455
  // alike — and NOT the union of the store's prefix-selected addresses"), WHILE THE OP EVERY EVALUATION
446
456
  // CARRIES IS THE LANDING'S OWN — the repair's op where a repair's edit landed, and the attempt's first
447
457
  // write where the pass is the commit's own landing.
448
- // THE PASS'S OWN EVALUATED SET IS FIXED WHEN THE PASS BEGINS — a SNAPSHOT of the registry's rows for
458
+ // **⟶ AND THE SET THAT ADDRESS MATERIALISES IS NOW A PREFIX SET, 2026-10-29 (`D-56`).** `RCA-8(g)`
459
+ // ANNOTATE-BESIDE: **the quotation above stands BYTE-FOR-BYTE as `attempt-lifecycle.md §2.4` item 5 (iv)'s
460
+ // EXACT-ADDRESS rule — the clause `D-56` names by number and SUPERSEDES**; the architect's own sentence is
461
+ // *"A listener/constraint should fire when the descendants of its targeted address node change, because the
462
+ // descendants become part of the object that is read from that address"*, and what it changes here is the
463
+ // PREDICATE `pairsAtAddress` applies — **the pairs whose own address is a PREFIX of the attempt's, equality
464
+ // included.** **NO OTHER LINE OF THIS FRAME MOVES**: the address is still the attempt's, the landing's op is
465
+ // still what every evaluation carries, and the set is still ONE SNAPSHOT taken at this instant.
466
+ // THE PASS'S OWN EVALUATED SET IS FIXED WHEN THE PASS BEGINS — a SNAPSHOT of the registry's rows AT OR ABOVE
449
467
  // the attempt's address AT THAT INSTANT, and never a live view of the registry this pass reads again:
450
468
  // "a PASS's evaluated set is FIXED WHEN THE PASS BEGINS — it is every pair registered at the attempt's
451
469
  // address AT THAT INSTANT, each evaluated once in clause (ii)'s order", so "A `K-1` THAT RETURNS
452
470
  // DURING A PASS APPENDS A PAIR TO THE REGISTRY WITHOUT APPENDING ANY ENTRY TO THAT PASS AND WITHOUT
453
471
  // BEING EVALUATED BY IT: the new pair enters the NEXT pass's set" (`attempt-lifecycle.md §2.4` item 5
454
- // (iv); `CX-12`). The snapshot is ALSO the set the layer (a) delivery of this run is read over.
472
+ // (iv); `CX-12`, which `D-56` defers to and does NOT move). **THE SNAPSHOT IS MATERIALISED ONCE PER RUN AND
473
+ // READ BY THE WHOLE RUN** — the loop below, the repair arm's `list` and `releasePending`'s check-off all read
474
+ // THIS ONE array — **and it is ALSO the set the layer (a) delivery of this run is read over.**
455
475
  const list = pairsAtAddress(kernel, attempt.address);
476
+ // **⟶ AND THE COMMIT THE INVOCATIONS OF THIS RUN NAME — `D-55` ITEM 3's DELETE-SHAPED ATTEMPT, 2026-10-29.**
477
+ // **A WRITE'S ATTEMPT NAMES ITS `CommitRecord`** (`attempt.record`, the object `K-2` built and adopted), and
478
+ // every verb a body calls under it JOINS that commit (`D-46`). **A DELETE'S ATTEMPT HAS NO `CommitRecord`** —
479
+ // it lands no write, so there is no adoption, no residue and no save — **and it still owes the same
480
+ // invariant**: `D-53`'s *"Constraints/Repairs should always use the same commit"* is not a rule about records
481
+ // but about the COMMIT, and a body's write under a delete's pass that named nothing would OPEN a second commit
482
+ // and start a second list. **SO THE ATTEMPT CARRIES ITS COMMIT'S NAME** (`kernel-commit.mjs`'s
483
+ // `commitRemoval` sets `attempt.name` to the one member `commitAttemptIdOf` reads) **and this frame hands THE
484
+ // NAME where a record exists and THE RECORD where it does** — one expression, and on the write path it is the
485
+ // very object it always was, so no byte of the write's own invocation moves.
486
+ const commitName = attempt.record === undefined ? attempt.name : attempt.record;
456
487
  // THE ATOMIC LANDING EVALUATION'S OWN ARM-TAKING IS `attempt-lifecycle.md §2.4` item 4's arms, read
457
488
  // over THE PAIR THAT FAILED AT THAT OP (`kernel-surface.md §2.3` item 1; `§2.4`: `KC-3` where that pair
458
489
  // is NOT in `ran` before this run and no repair is registered for it; `KC-6` where it IS in `ran` and
@@ -503,12 +534,22 @@ function evaluate(kernel, attempt, landing) {
503
534
  // does.** The name is an INVOCATION's and nothing else's: it is set before the call and restored after it,
504
535
  // on the throwing arm too, so an ordinary write still opens ONE commit and a callback's verb is still an
505
536
  // act of its own.
506
- outcome = constraintInCommit(attempt.store, attempt.record, () => pair.constraint(context));
537
+ outcome = constraintInCommit(attempt.store, commitName, () => pair.constraint(context));
507
538
  } catch (body) {
508
539
  // A body that threw returned nothing, so no `constraint-check` entry stands and the attempt is
509
540
  // closed (`PAR-C-6`; `NX-2`; `composition-and-states.md §2.7` item 13).
510
541
  withdraw(attempt, check);
511
- terminalComposed(kernel, attempt, null, `the constraint ${pair.id} threw; the attempt is closed`);
542
+ // **⟶ AND THE THROWABLE'S OWN FORM ENTERS THE COMMIT'S LOG — `D-55` ITEM 1, `DEF-AK`, 2026-10-28.**
543
+ // The architect, verbatim: *"Include a thrown message in the message log. Obviously."* **THE ENTRY IS
544
+ // THE ONE THE TERMINAL ACT ALREADY APPENDS**: this arm closes the attempt with its ONE `outcome` entry
545
+ // (`composition-and-states.md §2.7` item 13), and NO second entry and NO fifth `kind` is minted —
546
+ // `constraint-check` was WITHDRAWN above and must not come back (`fail-surface.md §1.1` item 1 (b),
547
+ // which the kernel-level cells assert as *"NO entry stands for the pair whose body returned nothing"*).
548
+ // **SO THE TERMINAL ENTRY'S SENTENCE CARRIES THE FORM** (`throwableForm`: the string's own text, the
549
+ // object's own `message` member, or the kind of value it was, read off own members only), and the
550
+ // closed report's list — the list the crossing hands the caller — holds it at that entry's `seq`.
551
+ terminalComposed(kernel, attempt, null, `the constraint ${pair.id} threw; the attempt is closed — the `
552
+ + `value it threw was ${throwableForm(body)}`);
512
553
  // **⟶ AND THE VALUE IS MARKED HERE, BY THE FRAME THAT CAUGHT IT FROM THE BODY — `DEF-S`, 2026-10-26,
513
554
  // on the architect's ruling *"Expand the returned error set for both S/N"*.** The mark is what the
514
555
  // entry's `constraintCrossing` converts on, and an UNMARKED value still crosses as itself
@@ -644,7 +685,7 @@ function evaluate(kernel, attempt, landing) {
644
685
  // **⟶ AND THE FRAME STANDS FOR THIS INVOCATION TOO (`D-53`'s first invariant): the repair's own verbs
645
686
  // append to the attempt's list, and the frame is what makes `K-2` join rather than open.**
646
687
  enterCommitFrame(kernel, attempt.log);
647
- result = repairInCommit(attempt.store, attempt.record, () => repair(repairContext));
688
+ result = repairInCommit(attempt.store, commitName, () => repair(repairContext));
648
689
  } catch (body) {
649
690
  // THE REPAIR-RUN ENTRY IS APPENDED BEFORE THE THROW, and the attempt's outcome entry carries
650
691
  // `KC-4` (`ck_states_a_repair_body_that_throws_reaches_the_caller_unconverted`).