provident-storeroom 1.2.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.
- package/README.guide.md +212 -5
- package/README.md +36 -11
- package/RELEASE-NOTES.md +610 -0
- package/index.d.ts +77 -6
- package/index.mjs +120 -34
- package/package.json +7 -6
- package/src/entry/constraints.mjs +662 -73
- package/src/entry/delivery.mjs +19 -5
- package/src/entry/kernel-attempt.mjs +181 -23
- package/src/entry/kernel-commit.mjs +191 -2
- package/src/entry/kernel-foundations.mjs +266 -24
- package/src/entry/kernel-registration.mjs +81 -27
- package/src/entry/kernel-terminal.mjs +18 -5
- package/src/entry/state.mjs +47 -4
|
@@ -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
|
|
@@ -72,11 +80,16 @@ export function constraintsKernel() {
|
|
|
72
80
|
return KERNEL;
|
|
73
81
|
}
|
|
74
82
|
|
|
75
|
-
/// `fail-surface.md §2` / `kernel-surface.md §2.2`'s `KC-1`…`KC-
|
|
83
|
+
/// `fail-surface.md §2` / `kernel-surface.md §2.2`'s `KC-1`…`KC-9`, read HERE for their ONE use: to tell a
|
|
76
84
|
/// refusal the KERNEL raised from one a STORE VERB raised, so that `A120` (2) can be applied to the first
|
|
77
85
|
/// and not to the second. **NO `KC` SPELLING CROSSES THIS SURFACE** (`docs/specs/storeroom-js/surface.md §2.12` item 1's read-through clause:
|
|
78
86
|
/// printed here it would be a second, unowned home for the kernel's own vocabulary).
|
|
79
|
-
|
|
87
|
+
///
|
|
88
|
+
/// **⟶ AND THE LIST MOVES `8 → 9` WITH THE SET ITSELF, 2026-10-28 (`D-53`: *"Open the token set"*).** The ninth
|
|
89
|
+
/// member is the SAVE ARM's (`KC-9`, `kernel-foundations.mjs`'s `KC.saveFailed`); **this list must carry it or a
|
|
90
|
+
/// kernel refusal carrying `KC-9` in `state` would be read here as a STORE code** and cross converted, which is the
|
|
91
|
+
/// one thing this predicate exists to prevent.
|
|
92
|
+
const KC_TOKENS = ['KC-1', 'KC-2', 'KC-3', 'KC-4', 'KC-5', 'KC-6', 'KC-7', 'KC-8', 'KC-9'];
|
|
80
93
|
|
|
81
94
|
/// **⟶ THE PAIR'S OWN KEY IS `(id, address-set)` — `U-STOREROOM-HELD-LISTENER-IDENTITY` (`D-GP-SHLI`).**
|
|
82
95
|
/// **ONE PAIR OVER N ADDRESSES IS ONE PAIR: ONE `id`, N ADDRESSES, ONE row of `constraints()`** (`P:
|
|
@@ -484,7 +497,11 @@ export function registrationCrossing(refusal) {
|
|
|
484
497
|
// is the caller's own value and is answered as it was thrown.
|
|
485
498
|
const carried = bodyThrowCarried(refusal);
|
|
486
499
|
if (carried !== null) {
|
|
487
|
-
|
|
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);
|
|
488
505
|
if (converted !== null) throw converted;
|
|
489
506
|
}
|
|
490
507
|
if (isKernelBuiltRefusal(refusal) === false) throw refusal;
|
|
@@ -505,11 +522,11 @@ export function registrationCrossing(refusal) {
|
|
|
505
522
|
// keeps its own trigger and its own sentence) — the `message` the STORE'S OWN GENERATED SENTENCE, and the
|
|
506
523
|
// `log` the synthetic attempt's log where a repair was attempted and `[]` where none was. **NO `KC` TOKEN CROSSES** (`A120` (2); `docs/specs/storeroom-js/surface.md §2.12` item 3 item 2): the synthetic attempt's
|
|
507
524
|
// terminal token stays in the kernel and reaches no caller.
|
|
508
|
-
throw {
|
|
525
|
+
throw packageRefusal({
|
|
509
526
|
status: refusal.status,
|
|
510
527
|
message: generated,
|
|
511
528
|
log: refusalLog(refusal.log),
|
|
512
|
-
};
|
|
529
|
+
});
|
|
513
530
|
}
|
|
514
531
|
|
|
515
532
|
/// **THE DISABLED PAIR'S STANDING ELEMENT** — a function that PASSES (`kernel-surface.md §2.3` item 1:
|
|
@@ -824,6 +841,140 @@ export function constraintWrite(state, instance, address, tier, value) {
|
|
|
824
841
|
};
|
|
825
842
|
}
|
|
826
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
|
+
|
|
827
978
|
/// **THE FAIL ARM'S CROSSING — `A120` (2): THE ENTRY CARRIES THE KERNEL'S TOKEN, THE THROW KEEPS THE
|
|
828
979
|
/// STORE'S — AND THE FORM CROSSES AT THREE MEMBERS FROM 2026-10-16** (`surface.md §2.5`'s clause of that
|
|
829
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).
|
|
@@ -1013,6 +1164,91 @@ function bodyThrowCarried(value) {
|
|
|
1013
1164
|
return carried;
|
|
1014
1165
|
}
|
|
1015
1166
|
|
|
1167
|
+
/// **⟶ ADDED 2026-10-28 — `DEF-AK`: THE INNER REFUSAL A CONSTRAINT BODY SWALLOWED AND THE CARRIER THAT PUTS
|
|
1168
|
+
/// IT BESIDE THE CROSSED ONE.**
|
|
1169
|
+
///
|
|
1170
|
+
/// **THE MEASUREMENT, STATED AS MEASURED.** A LISTENER body propagates an inner refusal VERBATIM — same
|
|
1171
|
+
/// `status`, same `message`, same two-entry `log`, same op — because no kernel frame catches a listener's body
|
|
1172
|
+
/// and nothing marks it. **A CONSTRAINT body making the IDENTICAL write had it REPLACED by the generated
|
|
1173
|
+
/// `ConstraintBodyThrew` form** (the set's rank `18`), whose single log entry was the OUTER attempt's and in
|
|
1174
|
+
/// which **the inner refusal's distinctive literal occurred ZERO TIMES**. **So the host you were inside decided
|
|
1175
|
+
/// what you were told**, and the crossed sentence's own *"a constraint body's throwable crosses as this
|
|
1176
|
+
/// refusal"* promised a carriage the crossing did not make.
|
|
1177
|
+
///
|
|
1178
|
+
/// **WHAT MOVES, AND WHAT DOES NOT.** `ConstraintBodyThrew` STAYS THE STATUS THAT CROSSES (the body did
|
|
1179
|
+
/// throw, and `DEF-S`'s ruling is unmoved); **the inner refusal — its `status`, its `message` and its own `log`
|
|
1180
|
+
/// — is carried BESIDE the crossed one** under this `Symbol.for` key, which both sides can spell and which
|
|
1181
|
+
/// `Object.keys` and `Object.getOwnPropertyNames` do not see. **The crossed `message` names the inner status,
|
|
1182
|
+
/// quotes the inner message and says in its own words that the value the body threw does NOT cross as the
|
|
1183
|
+
/// crossed refusal** — so the crossed sentence no longer claims more than it delivers, and the literal is in
|
|
1184
|
+
/// the text a consumer reads first. **NO MEMBER OF THE CROSSED FORM MOVES** (`{status, message, log}`, three
|
|
1185
|
+
/// own enumerable members), **the rank-`18` member is not renamed, no status is minted** (`DD-40`) and **an
|
|
1186
|
+
/// UNMARKED value still crosses as itself** (`DEF-A`'s protection, unmoved).
|
|
1187
|
+
const INNER_REFUSAL = Symbol.for('provident-storeroom.inner-refusal');
|
|
1188
|
+
|
|
1189
|
+
/// **⟶ AND THE PROVENANCE MARK THAT MAKES AN INNER REFUSAL AN INNER REFUSAL, 2026-10-28 — `DEF-AK`, AND IT IS
|
|
1190
|
+
/// THE WHOLE REASON A SHAPE TEST CANNOT DO.**
|
|
1191
|
+
///
|
|
1192
|
+
/// **A CALLER'S BODY IS THE CALLER'S CODE, so a value it throws may carry `{status, message, log}` and be a
|
|
1193
|
+
/// FORGERY.** `DEF-A`'s protection — a forged refusal must never be answered as the package's own — has a
|
|
1194
|
+
/// second consequence here: **a forged shape must not have its text quoted back inside the package's crossed
|
|
1195
|
+
/// sentence either.** Measured on this pass's first cut: a constraint body throwing
|
|
1196
|
+
/// `{status: 'ValueNotAdmitted', message: 'the caller forged this refusal', log: []}` had the forged text
|
|
1197
|
+
/// printed in the crossed message as though the package had found a refusal there, which is the same
|
|
1198
|
+
/// laundering `DEF-A` closed one layer out.
|
|
1199
|
+
///
|
|
1200
|
+
/// **SO AN INNER REFUSAL IS IDENTIFIED BY A MARK THIS PACKAGE SETS ON THE FORMS IT BUILDS**, spelled here
|
|
1201
|
+
/// under a `Symbol.for` key exactly as `KERNEL_REFUSAL` and `CONSTRAINT_BODY_THREW_ENTRY` are, and never by a
|
|
1202
|
+
/// member a caller can spell. The kernel's own refusals (`isKernelBuiltRefusal`) count too: both are the
|
|
1203
|
+
/// store's forms, and a caller's value is neither.
|
|
1204
|
+
const PACKAGE_REFUSAL = Symbol.for('provident-storeroom.package-refusal');
|
|
1205
|
+
|
|
1206
|
+
/// **THE ONE PLACE THIS FILE'S OWN REFUSAL FORMS ARE MARKED** — the three crossing arms and the judgement's
|
|
1207
|
+
/// own form reach it, so a refusal built here and then caught from a body is recognisable as the store's and
|
|
1208
|
+
/// never as a caller's. **NO MEMBER MOVES**: the mark is a symbol-keyed, non-enumerable own data member, so
|
|
1209
|
+
/// `Object.keys` still reads `["log","message","status"]` and no census of the three sees it.
|
|
1210
|
+
function packageRefusal(form) {
|
|
1211
|
+
Object.defineProperty(form, PACKAGE_REFUSAL, {
|
|
1212
|
+
value: true,
|
|
1213
|
+
writable: false,
|
|
1214
|
+
enumerable: false,
|
|
1215
|
+
configurable: true,
|
|
1216
|
+
});
|
|
1217
|
+
return form;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
/// **THE INNER REFUSAL A BODY'S THROWABLE CARRIES, OR `null`** — asked of the value the frame that CAUGHT it
|
|
1221
|
+
/// from the body has in hand, so the identity question is already answered: this reads the value's OWN data
|
|
1222
|
+
/// members (`D-35`'s read half) and answers the value only where it carries the surface's own refusal form —
|
|
1223
|
+
/// a non-empty `status` string, a `message` string and a `log` array. **A BODY THAT THREW SOMETHING ELSE IS
|
|
1224
|
+
/// `null`** (a `TypeError`, a string, a bare object with no `log`), and the crossed sentence then stands as
|
|
1225
|
+
/// the generated one: the throwable is not a refusal, there is no inner refusal to carry beside the crossed
|
|
1226
|
+
/// one, and nothing is invented for it.
|
|
1227
|
+
function innerRefusalThrown(thrown) {
|
|
1228
|
+
if (thrown === null || typeof thrown !== 'object') return null;
|
|
1229
|
+
// **THE PROVENANCE TEST COMES FIRST AND IS THE MARK, NOT THE SHAPE** (`PACKAGE_REFUSAL` above): a refusal
|
|
1230
|
+
// this package built, or one the kernel built, is the store's; anything else — including a caller's forged
|
|
1231
|
+
// three-member object — is not, and the crossed sentence never quotes a value it cannot attribute.
|
|
1232
|
+
if (thrown[PACKAGE_REFUSAL] !== true && isKernelBuiltRefusal(thrown) === false) return null;
|
|
1233
|
+
const status = ownDataMember(thrown, 'status');
|
|
1234
|
+
const message = ownDataMember(thrown, 'message');
|
|
1235
|
+
const log = ownDataMember(thrown, 'log');
|
|
1236
|
+
if (typeof status !== 'string' || status.length === 0) return null;
|
|
1237
|
+
if (typeof message !== 'string' || message.length === 0) return null;
|
|
1238
|
+
if (Array.isArray(log) === false) return null;
|
|
1239
|
+
return thrown;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
/// **THE INNER REFUSAL A CROSSED REFUSAL CARRIES BESIDE IT, OR `null`** — the mark's read half, taken off
|
|
1243
|
+
/// the value this package BUILT and never off a caller's shape: the fact travels under the `Symbol.for` key
|
|
1244
|
+
/// above, so no member a caller can spell decides it.
|
|
1245
|
+
function innerRefusalCarried(value) {
|
|
1246
|
+
if (value === null || typeof value !== 'object') return null;
|
|
1247
|
+
const carried = value[INNER_REFUSAL];
|
|
1248
|
+
if (carried === null || typeof carried !== 'object') return null;
|
|
1249
|
+
return carried;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1016
1252
|
/// **THE ONE FAILURE FORM FOR A BODY'S THROW** — `{status, message, log}`, `§2.5` items 3–4's form at this arm
|
|
1017
1253
|
/// too: the `status` the set's rank-`18` member, the `message` the STORE'S OWN GENERATED sentence (reached
|
|
1018
1254
|
/// through the generator this package already holds, `addon_.errorMessage` — `DD-52` forbids a second source),
|
|
@@ -1021,17 +1257,59 @@ function bodyThrowCarried(value) {
|
|
|
1021
1257
|
/// **A TREE THAT CARRIES NO USABLE GENERATOR ANSWERS `null`**, and both crossings then re-throw the marked
|
|
1022
1258
|
/// value AS ITSELF — the same safe direction `registrationCrossing` takes for a kernel refusal, and no
|
|
1023
1259
|
/// sentence is authored here.
|
|
1024
|
-
function bodyThrowRefusal(carried) {
|
|
1260
|
+
function bodyThrowRefusal(carried, thrown, recorded) {
|
|
1025
1261
|
const addon_ = withAddon();
|
|
1026
1262
|
if (typeof addon_.errorMessage !== 'function') return null;
|
|
1027
1263
|
const subject = typeof carried.address === 'string' ? carried.address : '';
|
|
1028
|
-
|
|
1264
|
+
let generated = addon_.errorMessage(BODY_THREW_STATUS, subject);
|
|
1029
1265
|
if (typeof generated !== 'string' || generated.length === 0) return null;
|
|
1030
|
-
|
|
1266
|
+
// **⟶ `DEF-AK`, 2026-10-28: THE INNER REFUSAL IS CARRIED BESIDE THE CROSSED ONE AND THE SENTENCE SAYS SO.**
|
|
1267
|
+
// The value this frame was handed is the very value the body threw (the frame above caught it and marked it),
|
|
1268
|
+
// so the inner refusal is in hand: where it carries the surface's own form, the generated sentence — whose
|
|
1269
|
+
// own words are *"a constraint body's throwable crosses as this refusal"* — is followed by the clause that
|
|
1270
|
+
// stops it claiming more than the crossing delivers, and the value itself travels under `INNER_REFUSAL`.
|
|
1271
|
+
const inner = innerRefusalThrown(thrown);
|
|
1272
|
+
if (inner !== null) {
|
|
1273
|
+
const innerStatus = ownDataMember(inner, 'status');
|
|
1274
|
+
const innerSaid = ownDataMember(inner, 'message');
|
|
1275
|
+
generated = `${generated} — the value the constraint body threw does NOT cross as this refusal: it was `
|
|
1276
|
+
+ `ITSELF a refusal, ${JSON.stringify(innerStatus)} with the message ${JSON.stringify(innerSaid)}, and it `
|
|
1277
|
+
+ `crosses BESIDE this one under Symbol.for('provident-storeroom.inner-refusal') with its own log — the `
|
|
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}`;
|
|
1295
|
+
}
|
|
1296
|
+
const crossed = {
|
|
1031
1297
|
status: BODY_THREW_STATUS,
|
|
1032
1298
|
message: generated,
|
|
1033
1299
|
log: refusalLog(carried.log),
|
|
1034
1300
|
};
|
|
1301
|
+
packageRefusal(crossed);
|
|
1302
|
+
if (inner !== null) {
|
|
1303
|
+
// A SYMBOL-KEYED, NON-ENUMERABLE OWN MEMBER: `Object.keys` and `Object.getOwnPropertyNames` read the
|
|
1304
|
+
// crossed form's three members exactly as they did, and the inner refusal is reachable by its name.
|
|
1305
|
+
Object.defineProperty(crossed, INNER_REFUSAL, {
|
|
1306
|
+
value: inner,
|
|
1307
|
+
writable: false,
|
|
1308
|
+
enumerable: false,
|
|
1309
|
+
configurable: true,
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
return crossed;
|
|
1035
1313
|
}
|
|
1036
1314
|
|
|
1037
1315
|
function constraintCrossing(refusal) {
|
|
@@ -1043,7 +1321,10 @@ function constraintCrossing(refusal) {
|
|
|
1043
1321
|
// `{status, message}` AND NO MARK STILL CROSSES AS ITSELF, BELOW.**
|
|
1044
1322
|
const carried = bodyThrowCarried(refusal);
|
|
1045
1323
|
if (carried !== null) {
|
|
1046
|
-
|
|
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);
|
|
1047
1328
|
if (converted !== null) throw converted;
|
|
1048
1329
|
}
|
|
1049
1330
|
const isObject = refusal !== null && typeof refusal === 'object';
|
|
@@ -1076,11 +1357,11 @@ function constraintCrossing(refusal) {
|
|
|
1076
1357
|
}
|
|
1077
1358
|
}
|
|
1078
1359
|
if (typeof status !== 'string' || kernelToken === false) {
|
|
1079
|
-
throw {
|
|
1360
|
+
throw packageRefusal({
|
|
1080
1361
|
status: refusal.status,
|
|
1081
1362
|
message: refusal.message,
|
|
1082
1363
|
log: refusalLog(log),
|
|
1083
|
-
};
|
|
1364
|
+
});
|
|
1084
1365
|
}
|
|
1085
1366
|
// **THE KERNEL'S OWN `KC` REFUSAL.** Its `{status, message, log}` is the KERNEL'S OWN three-member form
|
|
1086
1367
|
// (`docs/specs/storeroom-constraints/fail-surface.md §1.1`), and **⟶ FROM 2026-10-26 IT CROSSES WITH THE
|
|
@@ -1089,13 +1370,13 @@ function constraintCrossing(refusal) {
|
|
|
1089
1370
|
// **THE TOKEN STILL DOES NOT ENTER `status`** — it is on the attempt's own `outcome` entry's `state` in the
|
|
1090
1371
|
// `log`, which is `D-38`'s reading — **AND `FileCommitFailed` IS NOW THE SAVE'S CODE ALONE, minted by save
|
|
1091
1372
|
// failures only.** The message is the kernel's own, UNMOVED; the `log` is the attempt's, VERBATIM.
|
|
1092
|
-
throw {
|
|
1373
|
+
throw packageRefusal({
|
|
1093
1374
|
status: CONSTRAINT_PASS_REFUSED,
|
|
1094
1375
|
message: typeof refusal.message === 'string'
|
|
1095
1376
|
? refusal.message
|
|
1096
1377
|
: 'the write was refused by a constraint of this attempt',
|
|
1097
1378
|
log: refusalLog(log),
|
|
1098
|
-
};
|
|
1379
|
+
});
|
|
1099
1380
|
}
|
|
1100
1381
|
|
|
1101
1382
|
|
|
@@ -1336,10 +1617,16 @@ function reversalAtRest(instance) {
|
|
|
1336
1617
|
/// the store object, so a second store is a second record, the record dies with its store, and **NO MEMBER IS
|
|
1337
1618
|
/// ADDED TO THE PRODUCT, TO A RECORD OR TO THE KERNEL** (`A117` (D6)'s four-member guardrail is untouched).
|
|
1338
1619
|
///
|
|
1339
|
-
/// **`pending` IS THE REQUEST** — `{ watched, reversalId, window }`:
|
|
1620
|
+
/// **`pending` IS THE REQUEST** — `{ watched, reversalId, window, asked }`:
|
|
1340
1621
|
/// * `watched` the check's own beginning captured BEFORE the action ran (`reversalWatch`);
|
|
1341
1622
|
/// * `reversalId` the store's own echo of the id the reversal named (attached by `judgeReversal` in the same
|
|
1342
1623
|
/// frame, one line after the action);
|
|
1624
|
+
/// * **⟶ `asked` THE PAIR THAT WAS BEING ASKED WHEN THE ACTION WAS RAISED, OR `null`, ADDED 2026-10-28 —
|
|
1625
|
+
/// `DEF-AL`, THE MISATTRIBUTION.** The budget's refusal used to name `watched[0]` — the FIRST WATCHED
|
|
1626
|
+
/// ADDRESS — so **registration order decided the accusation**: measured, the pair it named had answered
|
|
1627
|
+
/// `true` on every ask it received. **The ask in flight is known at the instant the request is raised**
|
|
1628
|
+
/// (`ASKING` below, set by `judgeReversal` around the one body invocation and read here), so the request
|
|
1629
|
+
/// records the pair and the address the check was actually at, and the arm past the budget names THOSE.
|
|
1343
1630
|
/// * **⟶ `window` the IDENTITY OF THE COMMIT THE ACTION WAS TAKEN IN** (`state.mjs`'s `currentWindow`, minted
|
|
1344
1631
|
/// with the opening and answered by every joining call), **ADDED 2026-10-27 — AND IT IS WHAT RETIRES THE
|
|
1345
1632
|
/// COUNTING FRAME.** `D-42`'s own sentence is *"a request belongs to the act that raised it"*; while the
|
|
@@ -1352,6 +1639,43 @@ function reversalAtRest(instance) {
|
|
|
1352
1639
|
/// by the enclosing pass's) still belongs to that window and is still consumed.
|
|
1353
1640
|
const RESTARTS = new WeakMap();
|
|
1354
1641
|
|
|
1642
|
+
/// **⟶ `D-54` (b)'s ONE FLAG, SPELLED HERE AND IN `kernel-attempt.mjs`** — the `Symbol.for` key the kernel's
|
|
1643
|
+
/// terminal act stands on its own record while its compensating composition runs, so `reversalWatch` can tell
|
|
1644
|
+
/// the package's own undo from a consumer's `rollback` member call (`D-42`: *"a restart is only ever raised by a
|
|
1645
|
+
/// consumer's own `rollback` member call"*). **A SYMBOL ON THE KERNEL RECORD AND NOT A MEMBER OF THE PRODUCT OR
|
|
1646
|
+
/// OF ANY RECORD** (`A117` (D6)), no kernel item is minted (`kernel-surface.md §1` item 2), and the flag stands
|
|
1647
|
+
/// only for the duration of that one call.
|
|
1648
|
+
const COMPENSATING = Symbol.for('provident-storeroom.compensating-rollback');
|
|
1649
|
+
|
|
1650
|
+
/// **⟶ THE ASK IN FLIGHT, 2026-10-28 — `DEF-AL`'s ONE NEW READ, AND IT IS A `WeakMap` FOR THE SAME REASONS
|
|
1651
|
+
/// THE RESTART RECORD IS ONE** (`D-30`; `D-46`): keyed by the store, so a second store is a second record, the
|
|
1652
|
+
/// record dies with its store, and no member is added to the product, to a record or to the kernel.
|
|
1653
|
+
///
|
|
1654
|
+
/// **WHAT IT CARRIES, AND WHY IT CANNOT LIVE ON THE REQUEST ALONE.** `{ entry, address }` — the pair
|
|
1655
|
+
/// `judgeReversal` is asking and the address it is asking at — set immediately BEFORE the one body invocation
|
|
1656
|
+
/// and cleared immediately after it, on every arm including the throwing one. **A body that raises a reversal
|
|
1657
|
+
/// does it INSIDE that invocation**, so `reversalWatch`'s in-flight arm reads the entry standing here and
|
|
1658
|
+
/// stamps it on the request it raises. Without it the arm past the budget has nothing to name but the watch's
|
|
1659
|
+
/// first address, which is a fact about registration order and not about the check.
|
|
1660
|
+
const ASKING = new WeakMap();
|
|
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
|
+
|
|
1355
1679
|
/// **HOW MANY RESTARTS ONE PASS'S COMMIT SCOPE MAY TAKE** — the bound `drainRestartRequests` spends. Three is
|
|
1356
1680
|
/// the declared figure: two fewer than any arm of this package's own batteries drives, and enough that a lawful
|
|
1357
1681
|
/// in-commit action's single restart never meets it.
|
|
@@ -1428,29 +1752,38 @@ export function drainRestartRequests(instance, report) {
|
|
|
1428
1752
|
for (;;) {
|
|
1429
1753
|
const request = record.pending;
|
|
1430
1754
|
if (request === null) return report;
|
|
1431
|
-
// **A
|
|
1432
|
-
//
|
|
1433
|
-
//
|
|
1434
|
-
//
|
|
1435
|
-
//
|
|
1436
|
-
//
|
|
1437
|
-
//
|
|
1438
|
-
//
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1755
|
+
// **A PASS DOES NOT CONSUME A REQUEST IT DID NOT RAISE — `D-54`, 2026-10-28, MEASURED.**
|
|
1756
|
+
// `RCA-8(g)` ANNOTATE-BESIDE: the bytes that stood here read *"a request standing from a window this pass
|
|
1757
|
+
// did not open has no consumer HERE, and it is dropped"*, and **the drop was a CONSUMPTION**: a nested
|
|
1758
|
+
// pass — a listener body's own write, a reentrant write inside an open commit — cleared a request the
|
|
1759
|
+
// ENCLOSING window had raised, so the enclosing pass's own drain found nothing to judge and the reversal's
|
|
1760
|
+
// effect stood. **THE REQUEST IS THEREFORE LEFT WHERE IT STANDS**: this pass asks nothing at it and takes
|
|
1761
|
+
// nothing from it, and the consumer that matches its window is still free to reach it. **A REQUEST NOBODY
|
|
1762
|
+
// CONSUMES STILL DIES WITH ITS WINDOW** (`D-42` item `3`; `D-43` item `2`): windows are never reused, so a
|
|
1763
|
+
// stale stamp can be consumed by no later pass, it is overwritten by the next action's own request, and the
|
|
1764
|
+
// two declared passless windows have their own answers — the `delete`'s witness reports (and clears) its
|
|
1765
|
+
// own, the registration's is read by no surface. **A MISMATCHED REQUEST IS NOT CONSUMED, AND THAT IS THE
|
|
1766
|
+
// WHOLE OF HALF (a).**
|
|
1767
|
+
if (request.window !== window) return report;
|
|
1443
1768
|
record.pending = null;
|
|
1444
1769
|
if (request.watched.length === 0) continue;
|
|
1445
1770
|
rounds += 1;
|
|
1446
1771
|
if (rounds > RESTART_LIMIT) {
|
|
1447
1772
|
// THE CHECK DID NOT SETTLE: THE SAME FORM, THE SAME STATUS, THE SAME COMPENSATION (`D-41` item `4`'s
|
|
1448
1773
|
// direction), and the log entry says the budget was spent rather than that a pair refused.
|
|
1449
|
-
|
|
1774
|
+
//
|
|
1775
|
+
// **⟶ AND IT NAMES THE ADDRESS THE BUDGET WAS SPENT AT AND THE PAIR THAT WAS BEING ASKED, 2026-10-28 —
|
|
1776
|
+
// `DEF-AL`, MEASURED.** This arm named `request.watched[0]` — the FIRST WATCHED ADDRESS — so
|
|
1777
|
+
// REGISTRATION ORDER DECIDED THE ACCUSATION, and the pair it named had answered `true` on every ask it
|
|
1778
|
+
// received: `log[0]` named the true cause while naming a passing pair by id. **THE REQUEST'S OWN
|
|
1779
|
+
// `asked` IS THAT PAIR** (`reversalWatch`'s clause above), and it is the one the check was at when it
|
|
1780
|
+
// ran out. Where no ask stood, the entry says so and names no pair it cannot know.
|
|
1781
|
+
const asked = request.asked !== null && request.asked !== undefined ? request.asked : null;
|
|
1782
|
+
const one = asked === null ? request.watched[0] : { entry: asked.entry, address: asked.address };
|
|
1450
1783
|
const after = standingAt(instance, one.address);
|
|
1451
1784
|
const undo = restoreReversal(instance, request.watched);
|
|
1452
1785
|
return carryRestartRefusal(report,
|
|
1453
|
-
reversalRefusal(one, after, null, request.reversalId, undo, null, true));
|
|
1786
|
+
reversalRefusal(one, after, null, request.reversalId, undo, null, true, asked !== null));
|
|
1454
1787
|
}
|
|
1455
1788
|
try {
|
|
1456
1789
|
judgeReversal(instance, request.watched, request.reversalId);
|
|
@@ -1476,11 +1809,13 @@ export function drainRestartRequests(instance, report) {
|
|
|
1476
1809
|
/// **WHAT THIS FUNCTION IS, AND WHAT IT IS NOT.**
|
|
1477
1810
|
/// * **IT RUNS NO PASS, NO BODY AND NO JUDGEMENT.** It reads the instance's own restart record — the record
|
|
1478
1811
|
/// `reversalWatch` raised the request in — and answers a fresh copy of the two facts a consumer needs: the
|
|
1479
|
-
/// id the reversal named (`reversalId`, the store's own echo) and the addresses the
|
|
1480
|
-
///
|
|
1481
|
-
/// **THE
|
|
1482
|
-
///
|
|
1483
|
-
///
|
|
1812
|
+
/// id the reversal named (`reversalId`, the store's own echo) and **the addresses the refused act MOVED**
|
|
1813
|
+
/// (`request.moved`, measured by `judgeReversal` at the reversal's own instant and deduplicated by spelling,
|
|
1814
|
+
/// segment for segment). **THE WATCH'S FULL ADDRESS LIST IS THE DEBT RECORD AND IS NOT THE WITNESS**: naming
|
|
1815
|
+
/// every watched address would say nothing about what the act did (`DEF-AM`, 2026-10-28). **THE STORE IS NOT
|
|
1816
|
+
/// TOUCHED, NO CODE IS MINTED, NO LOG ENTRY IS APPENDED AND NO MEMBER OF ANY RECORD IS MOVED** — the `D-49`
|
|
1817
|
+
/// bar: *"a witness is not a refusal: the act still answers what it answered, the discard is reported beside
|
|
1818
|
+
/// it, and nothing new is minted in the closed status set."*
|
|
1484
1819
|
/// * **IT CONSUMES THE REQUEST IT REPORTS.** A request whose window is the caller's has no consumer that could
|
|
1485
1820
|
/// ever run it (the window's act ran no pass, and a later pass compares the identity and drops it — the
|
|
1486
1821
|
/// drain's own arm), so clearing the slot here moves no behaviour: it is the same clearing the drain would
|
|
@@ -1507,10 +1842,16 @@ export function witnessDiscardedReversal(instance, window) {
|
|
|
1507
1842
|
// 2026-10-27): a request standing from another window is that window's and is left where it stands.
|
|
1508
1843
|
if (request.window !== window) return null;
|
|
1509
1844
|
record.pending = null;
|
|
1845
|
+
// **⟶ AND THE ADDRESSES ARE THE ONES THE REFUSED ACT MOVED, NOT THE WHOLE WATCHED REGISTRY — `DEF-AM`,
|
|
1846
|
+
// 2026-10-28.** The request's `watched` is the DEBT record and names every enabled pair's every address;
|
|
1847
|
+
// `moved` is what `judgeReversal` measured at the reversal's own instant (`movedStanding`) and is the only
|
|
1848
|
+
// answer a witness owes. **A WITNESS THAT NAMES EVERY ADDRESS THE REGISTRY WATCHES NAME NOTHING**: the
|
|
1849
|
+
// discarded check's subject is the state the reversal changed.
|
|
1850
|
+
const subject = Array.isArray(request.moved) ? request.moved : [];
|
|
1510
1851
|
const addresses = [];
|
|
1511
1852
|
const spellings = [];
|
|
1512
|
-
for (let index = 0; index <
|
|
1513
|
-
const address =
|
|
1853
|
+
for (let index = 0; index < subject.length; index += 1) {
|
|
1854
|
+
const address = subject[index].address;
|
|
1514
1855
|
const spelling = homeAddressKey(address);
|
|
1515
1856
|
let seen = false;
|
|
1516
1857
|
for (let known = 0; known < spellings.length; known += 1) {
|
|
@@ -1531,6 +1872,17 @@ export function witnessDiscardedReversal(instance, window) {
|
|
|
1531
1872
|
}
|
|
1532
1873
|
// THE STORE'S OWN ECHO OF THE ID THE REVERSAL NAMED — `null` where the reversal's call answered no id (the
|
|
1533
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;
|
|
1534
1886
|
return {
|
|
1535
1887
|
opId: typeof request.reversalId === 'string' ? request.reversalId : null,
|
|
1536
1888
|
addresses,
|
|
@@ -1574,7 +1926,14 @@ function carryRestartRefusal(report, refusal) {
|
|
|
1574
1926
|
const log = { log: report.log };
|
|
1575
1927
|
for (let index = 0; index < carried.length; index += 1) {
|
|
1576
1928
|
const entry = carried[index];
|
|
1577
|
-
|
|
1929
|
+
// **⟶ AND THE REPLAY NAMES THE ITERATION AS THE ENTRY IT IS CARRYING NAMES IT — `D-53`'s first ruling.** This is
|
|
1930
|
+
// the ONE `append` site whose two identities come from a CARRIED ENTRY and not from an acted-upon pair and op
|
|
1931
|
+
// (`D-52` counted it as rule 1's fourth kind), so the iteration is rebuilt from the two identities the entry
|
|
1932
|
+
// itself carries: **the pair stands by its `id`, and the op by the `opId` the judgement's reversal answered —
|
|
1933
|
+
// and the pair's own row is not in hand here, which is why the identity alone is spelled.** Nothing is
|
|
1934
|
+
// renumbered and nothing is re-authored: the entry minted here is the report's own, by the report's own
|
|
1935
|
+
// ordinal, and its two identity columns read exactly what the entry it carries read.
|
|
1936
|
+
append(log, entry.kind, { pair: { id: entry.id }, op: { opId: entry.opId } }, entry.message, entry.state);
|
|
1578
1937
|
}
|
|
1579
1938
|
Object.defineProperty(report, RESTART_REFUSAL, {
|
|
1580
1939
|
value: refusal,
|
|
@@ -1639,10 +1998,74 @@ export function reversalWatch(state, instance) {
|
|
|
1639
1998
|
// runs in, so *"a request belongs to the act that raised it"* (`D-42` item `3`) is MEASURED at this line and
|
|
1640
1999
|
// checked at that one, and the `CHECK_DEPTH` frame that once approximated it is deleted with its clears.
|
|
1641
2000
|
if (reversalAtRest(instance) === false) {
|
|
1642
|
-
|
|
1643
|
-
|
|
2001
|
+
// **⟶ AND THE KERNEL'S OWN COMPENSATING ROLLBACK IS NOT A CONSUMER'S ACTION — `D-54`, 2026-10-28,
|
|
2002
|
+
// MEASURED.** `D-42` declares it: *"A RESTART IS ONLY EVER RAISED BY A CONSUMER'S OWN `rollback` MEMBER
|
|
2003
|
+
// CALL."* **THE KERNEL'S TERMINAL COMPOSITION REACHES THAT MEMBER** (`kernel-terminal.mjs`'s
|
|
2004
|
+
// `composeRollback` calls `attempt.store.rollback`, the app's published member), so with the failing pass's
|
|
2005
|
+
// drain now reached (`D-54` (b)) the composition's own reversal was raising a request in the pass's window
|
|
2006
|
+
// — **A PHANTOM THE DRAIN THEN JUDGED**, asking a pair at the state the compensation had restored to and
|
|
2007
|
+
// re-shaping a refusal no consumer wrote. **THE FLAG IS THE KERNEL'S, TAKEN AROUND ITS OWN TERMINAL ACT**
|
|
2008
|
+
// (`kernel-attempt.mjs`'s `terminalComposed`), **and it is a `Symbol.for` key on the kernel record that both
|
|
2009
|
+
// modules spell** — no member of any record and none of the product moves (`A117` (D6)). With it, the
|
|
2010
|
+
// composition takes no watch, raises no request and judges no step: the request the pass's own bodies
|
|
2011
|
+
// raised is the one the drain carries to the terminal judgement, and no other.
|
|
2012
|
+
if (kernelFor(instance)[COMPENSATING] === true) return watched;
|
|
2013
|
+
// **⟶ AND THE REQUEST NAMES THE ASK IT WAS RAISED UNDER, 2026-10-28 (`DEF-AL`).** A body acts INSIDE the
|
|
2014
|
+
// one invocation `judgeReversal` wrapped in `ASKING`, so the pair and the address the check was actually
|
|
2015
|
+
// asking are in hand at this instant. `null` where no ask stands (an action raised by a body outside a
|
|
2016
|
+
// judgement — a listener's own window is the measured arm), and the arm past the budget then says so
|
|
2017
|
+
// rather than naming a pair it cannot know.
|
|
2018
|
+
const asking = ASKING.get(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,
|
|
2063
|
+
// **AND THE MOVED SET IS MEASURED BY THE JUDGEMENT, NOT BY THE WATCH** (`judgeReversal`'s in-flight arm;
|
|
2064
|
+
// `DEF-AM`): the watch is taken BEFORE the reversal runs, so what moved is not knowable here.
|
|
2065
|
+
moved: null,
|
|
1644
2066
|
reversalId: null,
|
|
1645
|
-
window
|
|
2067
|
+
window,
|
|
2068
|
+
asked: asking === undefined ? null : asking,
|
|
1646
2069
|
};
|
|
1647
2070
|
return watched;
|
|
1648
2071
|
}
|
|
@@ -1722,6 +2145,30 @@ function captureStanding(instance, address) {
|
|
|
1722
2145
|
};
|
|
1723
2146
|
}
|
|
1724
2147
|
|
|
2148
|
+
/// **THE ADDRESSES THE REVERSAL ACTUALLY MOVED, MEASURED ONCE** — the watch's capture against the standing the
|
|
2149
|
+
/// store holds now, with each entry's `after` beside its `before`. **A STANDING THIS REVERSAL DID NOT MOVE IS NOT
|
|
2150
|
+
/// A STANDING IT LEFT**, so the pair is not asked at it and cannot refuse the reversal for a state the reversal
|
|
2151
|
+
/// found. **IT IS THE JUDGEMENT'S SUBJECT AND THE RESTORE'S DEBT** (`judgeReversal`), and from 2026-10-28 it is
|
|
2152
|
+
/// also **THE WITNESS'S SUBJECT** (`DEF-AM`: the discarded request reports the addresses that MOVED, not every
|
|
2153
|
+
/// address the registry watches).
|
|
2154
|
+
function movedStanding(instance, watched) {
|
|
2155
|
+
const moved = [];
|
|
2156
|
+
for (let index = 0; index < watched.length; index += 1) {
|
|
2157
|
+
const one = watched[index];
|
|
2158
|
+
const after = standingAt(instance, one.address);
|
|
2159
|
+
if (sameStanding(one.before, after) === true) continue;
|
|
2160
|
+
appendOwn(moved, {
|
|
2161
|
+
entry: one.entry,
|
|
2162
|
+
address: one.address,
|
|
2163
|
+
before: one.before,
|
|
2164
|
+
beforeTier: one.beforeTier,
|
|
2165
|
+
beforeTiers: one.beforeTiers,
|
|
2166
|
+
after,
|
|
2167
|
+
});
|
|
2168
|
+
}
|
|
2169
|
+
return moved;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
1725
2172
|
/// **THE JUDGEMENT — THE TERMINAL STATE, ASKED OF EVERY PAIR THE REVERSAL TOUCHED, ONCE.** It answers
|
|
1726
2173
|
/// `undefined` on the lawful arm (**and the caller's record then crosses unchanged**) and THROWS the surface's
|
|
1727
2174
|
/// one plain form on the refusing arm. `reversalId` is the store's own echo of the id the reversal named
|
|
@@ -1750,6 +2197,10 @@ function captureStanding(instance, address) {
|
|
|
1750
2197
|
/// actually happened: a body threw), while the treatment — restore, one log entry naming the pair, one plain
|
|
1751
2198
|
/// form — is the violation's.
|
|
1752
2199
|
export function judgeReversal(instance, watched, reversalId) {
|
|
2200
|
+
// **A COMPENSATING ROLLBACK IS NOT JUDGED AS A STEP EITHER — `D-54` (b)**: the member is reached by the
|
|
2201
|
+
// kernel's own terminal act with the flag standing, and this act must not touch a pending request or ask a
|
|
2202
|
+
// pair. The consumer's own judgement is the drain's, at the pass's terminal state.
|
|
2203
|
+
if (kernelFor(instance)[COMPENSATING] === true) return undefined;
|
|
1753
2204
|
// **⟶ AND THE IN-FLIGHT ARM IS THE REQUEST'S OTHER HALF, `D-42` (2026-10-27).** `reversalWatch` answers
|
|
1754
2205
|
// `[]` for an action taken inside an open window — no body is invoked at the reversal's instant and the step
|
|
1755
2206
|
// is still not judged as a step — **and this frame is where the store's own echo of the id the reversal
|
|
@@ -1761,6 +2212,13 @@ export function judgeReversal(instance, watched, reversalId) {
|
|
|
1761
2212
|
const record = RESTARTS.get(instance);
|
|
1762
2213
|
if (record !== undefined && record.pending !== null && record.pending.reversalId === null) {
|
|
1763
2214
|
record.pending.reversalId = typeof reversalId === 'string' ? reversalId : null;
|
|
2215
|
+
// **⟶ AND THE WITNESS NAMES WHAT MOVED, NOT THE WHOLE WATCHED REGISTRY — `DEF-AM`, 2026-10-28.** The
|
|
2216
|
+
// request the watch raised carries every enabled pair's every address as the DEBT record, which is what
|
|
2217
|
+
// the restarted check must ask; the WITNESS is a different question — *"what did the refused act move?"* —
|
|
2218
|
+
// and the moved set is measured here, at the reversal's own instant, by the same `before`/`after`
|
|
2219
|
+
// comparison the at-rest judgement takes. **THE STORE IS READ ONCE PER WATCHED ADDRESS AND NOTHING IS
|
|
2220
|
+
// INVOKED**: this is the same walk `movedStanding` performs for the at-rest arm.
|
|
2221
|
+
record.pending.moved = movedStanding(instance, record.pending.watched);
|
|
1764
2222
|
}
|
|
1765
2223
|
return undefined;
|
|
1766
2224
|
}
|
|
@@ -1781,34 +2239,25 @@ export function judgeReversal(instance, watched, reversalId) {
|
|
|
1781
2239
|
// THE MOVED SET IS TAKEN FIRST, ONCE: the judgement's subject is the CHANGE the reversal made and nothing
|
|
1782
2240
|
// wider, and the same list is what a refusal has to put back — with the tier capture the watch took, so a
|
|
1783
2241
|
// restore knows WHERE each value stood and not merely what it was.
|
|
1784
|
-
const moved =
|
|
1785
|
-
for (let index = 0; index < watched.length; index += 1) {
|
|
1786
|
-
const one = watched[index];
|
|
1787
|
-
// THE ADDRESS IS READ AGAIN, AT THE STATE THE REVERSAL LEFT. **A STANDING THIS REVERSAL DID NOT MOVE IS
|
|
1788
|
-
// NOT A STANDING IT LEFT**, so the pair is not asked and cannot refuse the reversal for a state the
|
|
1789
|
-
// reversal found.
|
|
1790
|
-
const after = standingAt(instance, one.address);
|
|
1791
|
-
if (sameStanding(one.before, after) === true) continue;
|
|
1792
|
-
appendOwn(moved, {
|
|
1793
|
-
entry: one.entry,
|
|
1794
|
-
address: one.address,
|
|
1795
|
-
before: one.before,
|
|
1796
|
-
beforeTier: one.beforeTier,
|
|
1797
|
-
beforeTiers: one.beforeTiers,
|
|
1798
|
-
after,
|
|
1799
|
-
});
|
|
1800
|
-
}
|
|
2242
|
+
const moved = movedStanding(instance, watched);
|
|
1801
2243
|
for (let index = 0; index < moved.length; index += 1) {
|
|
1802
2244
|
const one = moved[index];
|
|
1803
2245
|
// **THE BODY'S THROW IS THE JUDGEMENT'S OWN CATCH AND NOT A PROPAGATING VALUE** — `reversalOutcome` converts
|
|
1804
2246
|
// a body's throwable to the surface's rank-`18` form and re-throws anything unmarked as itself, and BOTH
|
|
1805
2247
|
// arrive here: the reversal has run, so a judgement that cannot complete restores and refuses (below).
|
|
1806
2248
|
let outcome;
|
|
2249
|
+
// **⟶ AND THE ASK IS NAMED BEFORE THE BODY RUNS, 2026-10-28 (`DEF-AL`).** A body that acts does it
|
|
2250
|
+
// inside this one invocation, and the request it raises must name the pair the check was ASKING — not
|
|
2251
|
+
// the watch's first address. The mark is cleared on every arm, the throwing one included, so no later
|
|
2252
|
+
// act inherits an ask that has ended.
|
|
2253
|
+
ASKING.set(instance, { entry: one.entry, address: one.address });
|
|
1807
2254
|
try {
|
|
1808
2255
|
outcome = reversalOutcome(instance, one.entry, one.address, one.after);
|
|
1809
2256
|
} catch (thrown) {
|
|
1810
2257
|
const undo = restoreReversal(instance, moved);
|
|
1811
2258
|
throw reversalRefusal(one, one.after, null, reversalId, undo, thrown);
|
|
2259
|
+
} finally {
|
|
2260
|
+
ASKING.delete(instance);
|
|
1812
2261
|
}
|
|
1813
2262
|
if (outcome === true) continue;
|
|
1814
2263
|
// **THE FIRST VIOLATING PAIR DECIDES AND THE SECOND IS NOT EVALUATED** (`attempt-lifecycle.md §2.4` item 5
|
|
@@ -1883,6 +2332,20 @@ export function judgeReversal(instance, watched, reversalId) {
|
|
|
1883
2332
|
/// honesty `D-41` item `2` measured at `200` of `200`. **NO WRITE AND NO DELETE IS ISSUED BY THIS FUNCTION ON
|
|
1884
2333
|
/// ANY ARM**; the store's own verb is the whole act.
|
|
1885
2334
|
///
|
|
2335
|
+
/// **⟶ AND FROM 2026-10-28 THE BASELINE THE VERDICT MEASURES IS NAMED, AND THE TWO SUCCESSES ARE TOLD APART —
|
|
2336
|
+
/// `DEF-AJ`, MEASURED.** **A restore that fully succeeded was reported as one that failed**: the store's act
|
|
2337
|
+
/// returns the store to the journal mark its commit cached at its OPENING (the 2026-10-27 ruling above), and in
|
|
2338
|
+
/// the restart arm the commit has already landed writes when the reversal is asked for, so **the mark's state is
|
|
2339
|
+
/// not the pre-reversal standing the watch captured** — every moved address then failed an `exact` test the act
|
|
2340
|
+
/// had already satisfied, and the sentence said *"0 of the 1 address it moved stand again"* beside a store that
|
|
2341
|
+
/// stood exactly where the whole commit had opened. **SO THE SENTENCE HAS TWO SUCCESS ARMS AND ONE FAILURE ARM,
|
|
2342
|
+
/// AND THE BASELINE OF EACH IS SAID IN IT:** a successful act with every address equal to the pre-reversal
|
|
2343
|
+
/// capture is *"UNDONE … (the baseline this verdict measured is the pre-reversal standing, which is the state the
|
|
2344
|
+
/// journal mark the commit cached at its opening holds)"*; a successful act with any address PAST the capture is
|
|
2345
|
+
/// *"UNDONE — as a WHOLE-COMMIT UNDO"*, and each such address is named with what stands there and what stood
|
|
2346
|
+
/// there immediately before the reversal; and a REFUSED mark, a CACHELESS window and a store that did not
|
|
2347
|
+
/// restore are *"NOT undone"*, naming every address that does not stand again (the arm unchanged).
|
|
2348
|
+
///
|
|
1886
2349
|
/// **AND WHY IT CANNOT RECURSE INTO THE MEMBER.** `judgeReversal` is reached from `index.mjs`'s `rollback`
|
|
1887
2350
|
/// member; the restore never calls that member, the addon's `rollback`, or any package member — only the store's
|
|
1888
2351
|
/// `restoreMark` at its entry — so the judgement's ONE pass over the pairs stays one pass and `D-40`'s floor law
|
|
@@ -1936,6 +2399,16 @@ function restoreReversal(instance, moved) {
|
|
|
1936
2399
|
const stateRestored = cacheless === false && (refused === null || unsaved !== null);
|
|
1937
2400
|
let restored = 0;
|
|
1938
2401
|
const failed = [];
|
|
2402
|
+
// **⟶ AND THE VERDICT'S BASELINE IS NAMED FROM 2026-10-28 — `DEF-AJ`, MEASURED.** A restore that SUCCEEDED
|
|
2403
|
+
// (`stateRestored`) has returned the store to the journal mark the commit cached at its OPENING, and that is a
|
|
2404
|
+
// WHOLE-COMMIT undo: where the commit had already moved an address before the reversal was asked for, the
|
|
2405
|
+
// address stands at the mark's state and NOT at the pre-reversal standing the watch captured. The old count
|
|
2406
|
+
// read every such address as a FAILED restore — a restore that fully succeeded reported as one that did not —
|
|
2407
|
+
// because the baseline it compared against was the pre-reversal capture and never the mark. **SO THE TWO ARE
|
|
2408
|
+
// TOLD APART HERE**: `failed` is the list an UNRESTORED store is reported by (the refused mark, the cacheless
|
|
2409
|
+
// window), and `wholeCommit` is the list of addresses the store's successful act returned PAST the pre-reversal
|
|
2410
|
+
// standing — each named with what stands there now and what stood there immediately before the reversal.
|
|
2411
|
+
const wholeCommit = [];
|
|
1939
2412
|
// ONE VERIFICATION PER ADDRESS: two pairs over one address (or one pair naming it twice) must not be counted
|
|
1940
2413
|
// twice, so the addresses already measured are remembered — by a local loop, never by `Array.prototype.includes`
|
|
1941
2414
|
// on a refusal path (`contract.md §2.1`'s clause on `F8-2` and item `(2b)`'s row `54`).
|
|
@@ -1946,9 +2419,27 @@ function restoreReversal(instance, moved) {
|
|
|
1946
2419
|
if (hasOwnSpelling(measured, key) === true) continue;
|
|
1947
2420
|
appendOwn(measured, key);
|
|
1948
2421
|
// **THE ADDRESS IS READ AGAIN, AGAINST THE CAPTURE** — the cross-tier standing and every tier with its own
|
|
1949
|
-
// value — and
|
|
2422
|
+
// value — and `exact` says whether it equals what the watch took before the reversal.
|
|
1950
2423
|
const verdict = standingVerdict(instance, one);
|
|
1951
|
-
if (stateRestored
|
|
2424
|
+
if (stateRestored) {
|
|
2425
|
+
// THE STORE'S ACT SUCCEEDED, so every measured address was returned to the mark — that is the claim the
|
|
2426
|
+
// store's own answer supports, and it is counted as restored. Where the mark's state is not the
|
|
2427
|
+
// pre-reversal standing, the address belongs to `wholeCommit`, which the sentence reports as the commit's
|
|
2428
|
+
// own earlier work undone with the reversal rather than as a failed restore.
|
|
2429
|
+
restored += 1;
|
|
2430
|
+
if (verdict.exact !== true) {
|
|
2431
|
+
appendOwn(wholeCommit, {
|
|
2432
|
+
address: one.address,
|
|
2433
|
+
before: one.before,
|
|
2434
|
+
beforeTier: one.beforeTier,
|
|
2435
|
+
beforeTiers: one.beforeTiers,
|
|
2436
|
+
standing: verdict.value,
|
|
2437
|
+
tiers: verdict.tiers,
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2440
|
+
continue;
|
|
2441
|
+
}
|
|
2442
|
+
if (verdict.exact === true) {
|
|
1952
2443
|
restored += 1;
|
|
1953
2444
|
continue;
|
|
1954
2445
|
}
|
|
@@ -1963,7 +2454,7 @@ function restoreReversal(instance, moved) {
|
|
|
1963
2454
|
tiers: verdict.tiers,
|
|
1964
2455
|
});
|
|
1965
2456
|
}
|
|
1966
|
-
return { restored, total: measured.length, failed, refused, unsaved, cacheless };
|
|
2457
|
+
return { restored, total: measured.length, failed, wholeCommit, refused, unsaved, cacheless };
|
|
1967
2458
|
}
|
|
1968
2459
|
|
|
1969
2460
|
/// **WHETHER A LOCAL LIST OF SPELLINGS ALREADY HOLDS ONE** — a local index loop and not `Array.prototype.includes`.
|
|
@@ -2002,10 +2493,19 @@ function standingVerdict(instance, one) {
|
|
|
2002
2493
|
}
|
|
2003
2494
|
|
|
2004
2495
|
/// **THE SENTENCE THE LOG CARRIES ABOUT THE UNDOING** — the refusal's own record of the compensating act, read
|
|
2005
|
-
/// at the ONE site that builds the log entry. **IT MAY CLAIM *"THE REVERSAL WAS UNDONE"* ONLY WHERE
|
|
2006
|
-
/// IT MOVED STANDS AGAIN
|
|
2007
|
-
/// address that could not be restored and says what stands there INSTEAD and
|
|
2008
|
-
/// *"a message must not claim a restoration that did not happen"*).
|
|
2496
|
+
/// at the ONE site that builds the log entry. **IT MAY CLAIM *"THE REVERSAL WAS UNDONE"* ONLY WHERE THE STORE'S
|
|
2497
|
+
/// OWN ACT SUCCEEDED AND EVERY ADDRESS IT MOVED STANDS AGAIN AS THE MARK SAYS** (`restoreReversal`'s verdict);
|
|
2498
|
+
/// where it cannot, **it names each address that could not be restored and says what stands there INSTEAD and
|
|
2499
|
+
/// what it was owed** (`D-41` item `2`: *"a message must not claim a restoration that did not happen"*).
|
|
2500
|
+
/// `DEF-Q`: no column prints `undefined`.
|
|
2501
|
+
///
|
|
2502
|
+
/// **⟶ AND A SUCCESSFUL RESTORE'S BASELINE IS NAMED, 2026-10-28 — `DEF-AJ`, MEASURED.** The act restores the
|
|
2503
|
+
/// journal mark the commit cached at its OPENING; where that mark stands before the reversal (the restart arm),
|
|
2504
|
+
/// the addresses the commit had already moved come back to the MET MARK and not to the watch's pre-reversal
|
|
2505
|
+
/// capture. **THE SENTENCE THEREFORE SAYS WHICH BASELINE IT MEASURED, AND A WHOLE-COMMIT UNDO IS SPOKEN AS A
|
|
2506
|
+
/// SUCCESS** — *"UNDONE — as a WHOLE-COMMIT UNDO"* — with each address that stands at the mark's state named
|
|
2507
|
+
/// beside what stood there immediately before the reversal. **ONLY THE ARMS THAT DID NOT RESTORE SAY *"NOT
|
|
2508
|
+
/// undone"*: the refused mark, the cacheless window, and any address left standing at what the reversal left.**
|
|
2009
2509
|
///
|
|
2010
2510
|
/// **⟶ AND THE TWO ARMS THE STORE CAN ANSWER WITH ARE NAMED SEPARATELY, 2026-10-27 (THE FILE-SAVE RULING).**
|
|
2011
2511
|
/// **A REFUSED MARK** means the store holds what it held, and the sentence says exactly that. **A FAILED SAVE
|
|
@@ -2046,9 +2546,30 @@ function undoSpelling(undo) {
|
|
|
2046
2546
|
refusal = `the store REFUSED the journal mark (${JSON.stringify(typeof status === 'string' ? status : 'a refusal')}`
|
|
2047
2547
|
+ `: ${typeof said === 'string' ? said : ''}) and holds the state it held; `;
|
|
2048
2548
|
}
|
|
2049
|
-
if (undo.failed.length === 0) {
|
|
2549
|
+
if (undo.failed.length === 0 && undo.wholeCommit.length === 0) {
|
|
2050
2550
|
return `${refusal}the reversal was UNDONE: every address it moved stands again exactly as it stood before `
|
|
2051
|
-
+ 'the reversal — the same value at the same tier, or absent where it was absent'
|
|
2551
|
+
+ 'the reversal — the same value at the same tier, or absent where it was absent (the baseline this '
|
|
2552
|
+
+ 'verdict measured is the pre-reversal standing, which is the state the journal mark the commit cached '
|
|
2553
|
+
+ 'at its opening holds)';
|
|
2554
|
+
}
|
|
2555
|
+
// **⟶ AND A SUCCESSFUL RESTORE WHOSE MARK STANDS BEFORE THE REVERSAL IS NAMED AS WHAT IT IS — `DEF-AJ`.**
|
|
2556
|
+
// The store's act succeeded (`failed` is empty), so nothing here is a failure; what differs from the watch's
|
|
2557
|
+
// capture is the commit's own earlier work, which the same mark undoes. **THE SENTENCE SAYS *UNDONE* AND SAYS
|
|
2558
|
+
// ITS BASELINE**, because a restore that succeeded must say so.
|
|
2559
|
+
if (undo.failed.length === 0) {
|
|
2560
|
+
let named = '';
|
|
2561
|
+
for (let index = 0; index < undo.wholeCommit.length; index += 1) {
|
|
2562
|
+
const one = undo.wholeCommit[index];
|
|
2563
|
+
named += index === 0 ? '' : '; ';
|
|
2564
|
+
named += `${addressSpelling(one.address)} stands ${standingDescription(one.standing, one.tiers)} where it `
|
|
2565
|
+
+ `stood ${capturedDescription(one)} immediately before the reversal`;
|
|
2566
|
+
}
|
|
2567
|
+
const movedCount = undo.total === 1 ? 'address' : 'addresses';
|
|
2568
|
+
const stands = undo.restored === 1 ? 'stands' : 'stand';
|
|
2569
|
+
return `${refusal}the store was restored to the journal mark its commit cached at its opening, so the `
|
|
2570
|
+
+ `reversal was UNDONE — as a WHOLE-COMMIT UNDO (the baseline this verdict measured is the pre-reversal `
|
|
2571
|
+
+ `standing): all ${undo.total} ${movedCount} it moved ${stands} where that mark leaves them, and the `
|
|
2572
|
+
+ `difference from the pre-reversal standing is the commit's own earlier work, undone with it — ${named}`;
|
|
2052
2573
|
}
|
|
2053
2574
|
let named = '';
|
|
2054
2575
|
for (let index = 0; index < undo.failed.length; index += 1) {
|
|
@@ -2209,7 +2730,21 @@ function reversalOutcome(instance, entry, address, value) {
|
|
|
2209
2730
|
// attempt stands at a reversal's judgement.
|
|
2210
2731
|
carried.address = addressSpelling(address);
|
|
2211
2732
|
carried.log = [];
|
|
2212
|
-
|
|
2733
|
+
// **⟶ AND THE BODY'S OWN VALUE IS HANDED IN, 2026-10-28 (`DEF-AK`)**: `bodyThrowRefusal` carries an inner
|
|
2734
|
+
// refusal beside the crossed one and names it in the crossed sentence, and the value the body threw is
|
|
2735
|
+
// the only place that refusal stands.
|
|
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);
|
|
2213
2748
|
throw converted === null ? body : converted;
|
|
2214
2749
|
}
|
|
2215
2750
|
}
|
|
@@ -2254,7 +2789,7 @@ function reversalSaid(outcome) {
|
|
|
2254
2789
|
/// **WHERE THE THROWN VALUE IS NOT THE KERNEL'S MARKED FORM** (a body's raw throwable on a tree with no usable
|
|
2255
2790
|
/// generator), the same rank-`18` refusal is built here — the restoration and the pair's name cross regardless
|
|
2256
2791
|
/// of the body's own value's class, which is the difference between a compensating act and a conversion.
|
|
2257
|
-
function reversalRefusal(one, after, said, reversalId, undo, thrown, unsettled = false) {
|
|
2792
|
+
function reversalRefusal(one, after, said, reversalId, undo, thrown, unsettled = false, spentAtAsked = true) {
|
|
2258
2793
|
const addon_ = withAddon();
|
|
2259
2794
|
// **THE `<SEGMENT>` SLOT IS THE ADDRESS SPELLING THE KERNEL'S OWN REGISTRATION REFUSAL HANDS THE SAME
|
|
2260
2795
|
// GENERATOR** (`kernel-registration.mjs`'s `registrationRefusal`: the segments joined by `/`, BARE — the
|
|
@@ -2278,23 +2813,66 @@ function reversalRefusal(one, after, said, reversalId, undo, thrown, unsettled =
|
|
|
2278
2813
|
+ 'constraints admit'
|
|
2279
2814
|
: 'the reversal was refused by a constraint body that threw, the state it would leave could not be judged';
|
|
2280
2815
|
}
|
|
2816
|
+
// **⟶ AND A SPENT BUDGET IS NOT A PAIR REFUSING, IN ITS OWN WORDS — 2026-10-28, `DEF-AL`, MEASURED.** The
|
|
2817
|
+
// budget's crossed `message` used to be BYTE-IDENTICAL to a genuine refusal's (the same rank-`20` member and
|
|
2818
|
+
// the same generated sentence at the same subject), so a consumer reading only the message could not tell a
|
|
2819
|
+
// real refusal from an exhausted budget. **The store's generated sentence still stands first (`DD-52`: one
|
|
2820
|
+
// source for the code), and this arm appends the fact the code cannot carry** — the check did not settle and
|
|
2821
|
+
// NO PAIR REFUSED ANYTHING; a pair body acted at every restart. A genuine refusal's message never carries
|
|
2822
|
+
// this clause, which is what makes the two distinguishable.
|
|
2823
|
+
if (unsettled === true) {
|
|
2824
|
+
message = `${message} — this refusal is a RESTART BUDGET EXHAUSTION and NOT a constraint pair refusing a `
|
|
2825
|
+
+ `state: no pair refused the state the check was asking it for, a pair body acted inside the check at `
|
|
2826
|
+
+ `every restart, the budget of ${RESTART_LIMIT} restarts is spent and the check could not settle`;
|
|
2827
|
+
}
|
|
2828
|
+
// **⟶ AND AN INNER REFUSAL THE BODY THREW IS CARRIED BESIDE THE CROSSED ONE, 2026-10-28 (`DEF-AK`).** The
|
|
2829
|
+
// body that threw at this judgement threw through `reversalOutcome`, whose conversion is `bodyThrowRefusal`'s
|
|
2830
|
+
// — so the converted form carries the inner refusal under the same symbol, and it travels on from here.
|
|
2831
|
+
const inner = thrown === null ? null : innerRefusalCarried(thrown);
|
|
2832
|
+
if (inner !== null) {
|
|
2833
|
+
const innerStatus = ownDataMember(inner, 'status');
|
|
2834
|
+
const innerSaid = ownDataMember(inner, 'message');
|
|
2835
|
+
message = `${message} — the value the constraint body threw does NOT cross as this refusal: it was ITSELF a `
|
|
2836
|
+
+ `refusal, ${JSON.stringify(innerStatus)} with the message ${JSON.stringify(innerSaid)}, and it crosses `
|
|
2837
|
+
+ `BESIDE this one under Symbol.for('provident-storeroom.inner-refusal') with its own log`;
|
|
2838
|
+
}
|
|
2281
2839
|
// **THE LOG ENTRY'S SENTENCE, AT ITS THREE ARMS** — a pair that refused the state the reversal (or the
|
|
2282
2840
|
// in-commit action) left, a body that threw at the judgement of it, and — from `D-42` — **the restart's own
|
|
2283
2841
|
// budget spent**. The third arm is the one the restart's exhaustion reaches and it names no refusing pair.
|
|
2284
2842
|
let spelled;
|
|
2285
2843
|
if (unsettled === true) {
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2844
|
+
// **⟶ AND THE ENTRY NAMES THE PAIR THE CHECK WAS ASKING AND THE ADDRESS IT WAS ASKING AT, 2026-10-28
|
|
2845
|
+
// (`DEF-AL`).** It used to name the FIRST WATCHED pair — a passing one, by id — because registration order
|
|
2846
|
+
// decided it. The `spentAtAsked` arm says plainly WHEN THE BUDGET RAN OUT WITH NO ASK IN FLIGHT, so the
|
|
2847
|
+
// entry never claims to name a pair it cannot know.
|
|
2848
|
+
spelled = spentAtAsked === true
|
|
2849
|
+
? `the constraint ${one.entry.id} could not be asked a state that would settle at `
|
|
2850
|
+
+ `${addressSpelling(one.address)}: the value there is ${standingSpelling(after)} — this pair was being `
|
|
2851
|
+
+ `asked when the restart budget ran out, it did not refuse anything, a pair body acted inside the `
|
|
2852
|
+
+ `check at every restart, the check was restarted ${RESTART_LIMIT} times and the budget is spent, so `
|
|
2853
|
+
+ `the check does not pass — ${undoSpelling(undo)}`
|
|
2854
|
+
: `no pair was being asked when the restart budget ran out at ${addressSpelling(one.address)}: the value `
|
|
2855
|
+
+ `there is ${standingSpelling(after)} — a pair body acted inside the check without an ask in flight, `
|
|
2856
|
+
+ `the check was restarted ${RESTART_LIMIT} times and the budget is spent, so the check does not pass `
|
|
2857
|
+
+ `— ${undoSpelling(undo)}`;
|
|
2290
2858
|
} else if (thrown === null) {
|
|
2291
2859
|
spelled = `the constraint ${one.entry.id} refused the state the reversal left at `
|
|
2292
2860
|
+ `${addressSpelling(one.address)}: the value there is ${standingSpelling(after)}`
|
|
2293
2861
|
+ (said === null ? '' : ` — ${said}`)
|
|
2294
2862
|
+ ` — ${undoSpelling(undo)}`;
|
|
2295
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);
|
|
2296
2873
|
spelled = `the constraint ${one.entry.id} THREW at the judgement of the state the reversal left at `
|
|
2297
2874
|
+ `${addressSpelling(one.address)}: the value there is ${standingSpelling(after)}`
|
|
2875
|
+
+ ` — the value it threw was ${form}`
|
|
2298
2876
|
+ ` — ${undoSpelling(undo)}`;
|
|
2299
2877
|
}
|
|
2300
2878
|
const entry = {
|
|
@@ -2331,7 +2909,18 @@ function reversalRefusal(one, after, said, reversalId, undo, thrown, unsettled =
|
|
|
2331
2909
|
// **THE CROSSED `status` IS THE ARM'S OWN AND IS NEVER MINTED** (`DD-40`): rank `20` where a pair refused the
|
|
2332
2910
|
// state the reversal left, rank `18` where a pair's body threw at the judgement of it (`D-41` item `4`). The
|
|
2333
2911
|
// sentence beside it was generated for that same code — one source for each (`DD-52`).
|
|
2334
|
-
|
|
2912
|
+
const crossed = packageRefusal({ status, message, log: refusalLog(log) });
|
|
2913
|
+
if (inner !== null) {
|
|
2914
|
+
// THE INNER REFUSAL TRAVELS ON THE REFUSAL THE CALLER CATCHES, under the same symbol and the same
|
|
2915
|
+
// non-enumerable discipline `bodyThrowRefusal` uses: the crossed form's three members are unmoved.
|
|
2916
|
+
Object.defineProperty(crossed, INNER_REFUSAL, {
|
|
2917
|
+
value: inner,
|
|
2918
|
+
writable: false,
|
|
2919
|
+
enumerable: false,
|
|
2920
|
+
configurable: true,
|
|
2921
|
+
});
|
|
2922
|
+
}
|
|
2923
|
+
return crossed;
|
|
2335
2924
|
}
|
|
2336
2925
|
|
|
2337
2926
|
/// **THE ADDRESS'S OWN `<SEGMENT>` SPELLING, JOINED BY `/` AND BARE** — the kernel's own
|