provident-storeroom 1.2.0 → 1.3.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 +122 -3
- package/README.md +24 -8
- package/RELEASE-NOTES.md +584 -0
- package/index.d.ts +38 -2
- package/index.mjs +11 -3
- package/package.json +7 -6
- package/src/entry/constraints.mjs +402 -69
- package/src/entry/delivery.mjs +8 -2
- package/src/entry/kernel-attempt.mjs +136 -19
- package/src/entry/kernel-commit.mjs +26 -2
- package/src/entry/kernel-foundations.mjs +100 -8
- package/src/entry/kernel-registration.mjs +63 -22
- package/src/entry/kernel-terminal.mjs +18 -5
- package/src/entry/state.mjs +47 -4
|
@@ -72,11 +72,16 @@ export function constraintsKernel() {
|
|
|
72
72
|
return KERNEL;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
/// `fail-surface.md §2` / `kernel-surface.md §2.2`'s `KC-1`…`KC-
|
|
75
|
+
/// `fail-surface.md §2` / `kernel-surface.md §2.2`'s `KC-1`…`KC-9`, read HERE for their ONE use: to tell a
|
|
76
76
|
/// refusal the KERNEL raised from one a STORE VERB raised, so that `A120` (2) can be applied to the first
|
|
77
77
|
/// 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
78
|
/// printed here it would be a second, unowned home for the kernel's own vocabulary).
|
|
79
|
-
|
|
79
|
+
///
|
|
80
|
+
/// **⟶ AND THE LIST MOVES `8 → 9` WITH THE SET ITSELF, 2026-10-28 (`D-53`: *"Open the token set"*).** The ninth
|
|
81
|
+
/// member is the SAVE ARM's (`KC-9`, `kernel-foundations.mjs`'s `KC.saveFailed`); **this list must carry it or a
|
|
82
|
+
/// kernel refusal carrying `KC-9` in `state` would be read here as a STORE code** and cross converted, which is the
|
|
83
|
+
/// one thing this predicate exists to prevent.
|
|
84
|
+
const KC_TOKENS = ['KC-1', 'KC-2', 'KC-3', 'KC-4', 'KC-5', 'KC-6', 'KC-7', 'KC-8', 'KC-9'];
|
|
80
85
|
|
|
81
86
|
/// **⟶ THE PAIR'S OWN KEY IS `(id, address-set)` — `U-STOREROOM-HELD-LISTENER-IDENTITY` (`D-GP-SHLI`).**
|
|
82
87
|
/// **ONE PAIR OVER N ADDRESSES IS ONE PAIR: ONE `id`, N ADDRESSES, ONE row of `constraints()`** (`P:
|
|
@@ -484,7 +489,7 @@ export function registrationCrossing(refusal) {
|
|
|
484
489
|
// is the caller's own value and is answered as it was thrown.
|
|
485
490
|
const carried = bodyThrowCarried(refusal);
|
|
486
491
|
if (carried !== null) {
|
|
487
|
-
const converted = bodyThrowRefusal(carried);
|
|
492
|
+
const converted = bodyThrowRefusal(carried, refusal);
|
|
488
493
|
if (converted !== null) throw converted;
|
|
489
494
|
}
|
|
490
495
|
if (isKernelBuiltRefusal(refusal) === false) throw refusal;
|
|
@@ -505,11 +510,11 @@ export function registrationCrossing(refusal) {
|
|
|
505
510
|
// keeps its own trigger and its own sentence) — the `message` the STORE'S OWN GENERATED SENTENCE, and the
|
|
506
511
|
// `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
512
|
// terminal token stays in the kernel and reaches no caller.
|
|
508
|
-
throw {
|
|
513
|
+
throw packageRefusal({
|
|
509
514
|
status: refusal.status,
|
|
510
515
|
message: generated,
|
|
511
516
|
log: refusalLog(refusal.log),
|
|
512
|
-
};
|
|
517
|
+
});
|
|
513
518
|
}
|
|
514
519
|
|
|
515
520
|
/// **THE DISABLED PAIR'S STANDING ELEMENT** — a function that PASSES (`kernel-surface.md §2.3` item 1:
|
|
@@ -1013,6 +1018,91 @@ function bodyThrowCarried(value) {
|
|
|
1013
1018
|
return carried;
|
|
1014
1019
|
}
|
|
1015
1020
|
|
|
1021
|
+
/// **⟶ ADDED 2026-10-28 — `DEF-AK`: THE INNER REFUSAL A CONSTRAINT BODY SWALLOWED AND THE CARRIER THAT PUTS
|
|
1022
|
+
/// IT BESIDE THE CROSSED ONE.**
|
|
1023
|
+
///
|
|
1024
|
+
/// **THE MEASUREMENT, STATED AS MEASURED.** A LISTENER body propagates an inner refusal VERBATIM — same
|
|
1025
|
+
/// `status`, same `message`, same two-entry `log`, same op — because no kernel frame catches a listener's body
|
|
1026
|
+
/// and nothing marks it. **A CONSTRAINT body making the IDENTICAL write had it REPLACED by the generated
|
|
1027
|
+
/// `ConstraintBodyThrew` form** (the set's rank `18`), whose single log entry was the OUTER attempt's and in
|
|
1028
|
+
/// which **the inner refusal's distinctive literal occurred ZERO TIMES**. **So the host you were inside decided
|
|
1029
|
+
/// what you were told**, and the crossed sentence's own *"a constraint body's throwable crosses as this
|
|
1030
|
+
/// refusal"* promised a carriage the crossing did not make.
|
|
1031
|
+
///
|
|
1032
|
+
/// **WHAT MOVES, AND WHAT DOES NOT.** `ConstraintBodyThrew` STAYS THE STATUS THAT CROSSES (the body did
|
|
1033
|
+
/// throw, and `DEF-S`'s ruling is unmoved); **the inner refusal — its `status`, its `message` and its own `log`
|
|
1034
|
+
/// — is carried BESIDE the crossed one** under this `Symbol.for` key, which both sides can spell and which
|
|
1035
|
+
/// `Object.keys` and `Object.getOwnPropertyNames` do not see. **The crossed `message` names the inner status,
|
|
1036
|
+
/// quotes the inner message and says in its own words that the value the body threw does NOT cross as the
|
|
1037
|
+
/// crossed refusal** — so the crossed sentence no longer claims more than it delivers, and the literal is in
|
|
1038
|
+
/// the text a consumer reads first. **NO MEMBER OF THE CROSSED FORM MOVES** (`{status, message, log}`, three
|
|
1039
|
+
/// own enumerable members), **the rank-`18` member is not renamed, no status is minted** (`DD-40`) and **an
|
|
1040
|
+
/// UNMARKED value still crosses as itself** (`DEF-A`'s protection, unmoved).
|
|
1041
|
+
const INNER_REFUSAL = Symbol.for('provident-storeroom.inner-refusal');
|
|
1042
|
+
|
|
1043
|
+
/// **⟶ AND THE PROVENANCE MARK THAT MAKES AN INNER REFUSAL AN INNER REFUSAL, 2026-10-28 — `DEF-AK`, AND IT IS
|
|
1044
|
+
/// THE WHOLE REASON A SHAPE TEST CANNOT DO.**
|
|
1045
|
+
///
|
|
1046
|
+
/// **A CALLER'S BODY IS THE CALLER'S CODE, so a value it throws may carry `{status, message, log}` and be a
|
|
1047
|
+
/// FORGERY.** `DEF-A`'s protection — a forged refusal must never be answered as the package's own — has a
|
|
1048
|
+
/// second consequence here: **a forged shape must not have its text quoted back inside the package's crossed
|
|
1049
|
+
/// sentence either.** Measured on this pass's first cut: a constraint body throwing
|
|
1050
|
+
/// `{status: 'ValueNotAdmitted', message: 'the caller forged this refusal', log: []}` had the forged text
|
|
1051
|
+
/// printed in the crossed message as though the package had found a refusal there, which is the same
|
|
1052
|
+
/// laundering `DEF-A` closed one layer out.
|
|
1053
|
+
///
|
|
1054
|
+
/// **SO AN INNER REFUSAL IS IDENTIFIED BY A MARK THIS PACKAGE SETS ON THE FORMS IT BUILDS**, spelled here
|
|
1055
|
+
/// under a `Symbol.for` key exactly as `KERNEL_REFUSAL` and `CONSTRAINT_BODY_THREW_ENTRY` are, and never by a
|
|
1056
|
+
/// member a caller can spell. The kernel's own refusals (`isKernelBuiltRefusal`) count too: both are the
|
|
1057
|
+
/// store's forms, and a caller's value is neither.
|
|
1058
|
+
const PACKAGE_REFUSAL = Symbol.for('provident-storeroom.package-refusal');
|
|
1059
|
+
|
|
1060
|
+
/// **THE ONE PLACE THIS FILE'S OWN REFUSAL FORMS ARE MARKED** — the three crossing arms and the judgement's
|
|
1061
|
+
/// own form reach it, so a refusal built here and then caught from a body is recognisable as the store's and
|
|
1062
|
+
/// never as a caller's. **NO MEMBER MOVES**: the mark is a symbol-keyed, non-enumerable own data member, so
|
|
1063
|
+
/// `Object.keys` still reads `["log","message","status"]` and no census of the three sees it.
|
|
1064
|
+
function packageRefusal(form) {
|
|
1065
|
+
Object.defineProperty(form, PACKAGE_REFUSAL, {
|
|
1066
|
+
value: true,
|
|
1067
|
+
writable: false,
|
|
1068
|
+
enumerable: false,
|
|
1069
|
+
configurable: true,
|
|
1070
|
+
});
|
|
1071
|
+
return form;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
/// **THE INNER REFUSAL A BODY'S THROWABLE CARRIES, OR `null`** — asked of the value the frame that CAUGHT it
|
|
1075
|
+
/// from the body has in hand, so the identity question is already answered: this reads the value's OWN data
|
|
1076
|
+
/// members (`D-35`'s read half) and answers the value only where it carries the surface's own refusal form —
|
|
1077
|
+
/// a non-empty `status` string, a `message` string and a `log` array. **A BODY THAT THREW SOMETHING ELSE IS
|
|
1078
|
+
/// `null`** (a `TypeError`, a string, a bare object with no `log`), and the crossed sentence then stands as
|
|
1079
|
+
/// the generated one: the throwable is not a refusal, there is no inner refusal to carry beside the crossed
|
|
1080
|
+
/// one, and nothing is invented for it.
|
|
1081
|
+
function innerRefusalThrown(thrown) {
|
|
1082
|
+
if (thrown === null || typeof thrown !== 'object') return null;
|
|
1083
|
+
// **THE PROVENANCE TEST COMES FIRST AND IS THE MARK, NOT THE SHAPE** (`PACKAGE_REFUSAL` above): a refusal
|
|
1084
|
+
// this package built, or one the kernel built, is the store's; anything else — including a caller's forged
|
|
1085
|
+
// three-member object — is not, and the crossed sentence never quotes a value it cannot attribute.
|
|
1086
|
+
if (thrown[PACKAGE_REFUSAL] !== true && isKernelBuiltRefusal(thrown) === false) return null;
|
|
1087
|
+
const status = ownDataMember(thrown, 'status');
|
|
1088
|
+
const message = ownDataMember(thrown, 'message');
|
|
1089
|
+
const log = ownDataMember(thrown, 'log');
|
|
1090
|
+
if (typeof status !== 'string' || status.length === 0) return null;
|
|
1091
|
+
if (typeof message !== 'string' || message.length === 0) return null;
|
|
1092
|
+
if (Array.isArray(log) === false) return null;
|
|
1093
|
+
return thrown;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
/// **THE INNER REFUSAL A CROSSED REFUSAL CARRIES BESIDE IT, OR `null`** — the mark's read half, taken off
|
|
1097
|
+
/// the value this package BUILT and never off a caller's shape: the fact travels under the `Symbol.for` key
|
|
1098
|
+
/// above, so no member a caller can spell decides it.
|
|
1099
|
+
function innerRefusalCarried(value) {
|
|
1100
|
+
if (value === null || typeof value !== 'object') return null;
|
|
1101
|
+
const carried = value[INNER_REFUSAL];
|
|
1102
|
+
if (carried === null || typeof carried !== 'object') return null;
|
|
1103
|
+
return carried;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1016
1106
|
/// **THE ONE FAILURE FORM FOR A BODY'S THROW** — `{status, message, log}`, `§2.5` items 3–4's form at this arm
|
|
1017
1107
|
/// too: the `status` the set's rank-`18` member, the `message` the STORE'S OWN GENERATED sentence (reached
|
|
1018
1108
|
/// through the generator this package already holds, `addon_.errorMessage` — `DD-52` forbids a second source),
|
|
@@ -1021,17 +1111,43 @@ function bodyThrowCarried(value) {
|
|
|
1021
1111
|
/// **A TREE THAT CARRIES NO USABLE GENERATOR ANSWERS `null`**, and both crossings then re-throw the marked
|
|
1022
1112
|
/// value AS ITSELF — the same safe direction `registrationCrossing` takes for a kernel refusal, and no
|
|
1023
1113
|
/// sentence is authored here.
|
|
1024
|
-
function bodyThrowRefusal(carried) {
|
|
1114
|
+
function bodyThrowRefusal(carried, thrown) {
|
|
1025
1115
|
const addon_ = withAddon();
|
|
1026
1116
|
if (typeof addon_.errorMessage !== 'function') return null;
|
|
1027
1117
|
const subject = typeof carried.address === 'string' ? carried.address : '';
|
|
1028
|
-
|
|
1118
|
+
let generated = addon_.errorMessage(BODY_THREW_STATUS, subject);
|
|
1029
1119
|
if (typeof generated !== 'string' || generated.length === 0) return null;
|
|
1030
|
-
|
|
1120
|
+
// **⟶ `DEF-AK`, 2026-10-28: THE INNER REFUSAL IS CARRIED BESIDE THE CROSSED ONE AND THE SENTENCE SAYS SO.**
|
|
1121
|
+
// The value this frame was handed is the very value the body threw (the frame above caught it and marked it),
|
|
1122
|
+
// so the inner refusal is in hand: where it carries the surface's own form, the generated sentence — whose
|
|
1123
|
+
// own words are *"a constraint body's throwable crosses as this refusal"* — is followed by the clause that
|
|
1124
|
+
// stops it claiming more than the crossing delivers, and the value itself travels under `INNER_REFUSAL`.
|
|
1125
|
+
const inner = innerRefusalThrown(thrown);
|
|
1126
|
+
if (inner !== null) {
|
|
1127
|
+
const innerStatus = ownDataMember(inner, 'status');
|
|
1128
|
+
const innerSaid = ownDataMember(inner, 'message');
|
|
1129
|
+
generated = `${generated} — the value the constraint body threw does NOT cross as this refusal: it was `
|
|
1130
|
+
+ `ITSELF a refusal, ${JSON.stringify(innerStatus)} with the message ${JSON.stringify(innerSaid)}, and it `
|
|
1131
|
+
+ `crosses BESIDE this one under Symbol.for('provident-storeroom.inner-refusal') with its own log — the `
|
|
1132
|
+
+ `generated sentence above names the CODE for a body that threw and not the value the body threw`;
|
|
1133
|
+
}
|
|
1134
|
+
const crossed = {
|
|
1031
1135
|
status: BODY_THREW_STATUS,
|
|
1032
1136
|
message: generated,
|
|
1033
1137
|
log: refusalLog(carried.log),
|
|
1034
1138
|
};
|
|
1139
|
+
packageRefusal(crossed);
|
|
1140
|
+
if (inner !== null) {
|
|
1141
|
+
// A SYMBOL-KEYED, NON-ENUMERABLE OWN MEMBER: `Object.keys` and `Object.getOwnPropertyNames` read the
|
|
1142
|
+
// crossed form's three members exactly as they did, and the inner refusal is reachable by its name.
|
|
1143
|
+
Object.defineProperty(crossed, INNER_REFUSAL, {
|
|
1144
|
+
value: inner,
|
|
1145
|
+
writable: false,
|
|
1146
|
+
enumerable: false,
|
|
1147
|
+
configurable: true,
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
return crossed;
|
|
1035
1151
|
}
|
|
1036
1152
|
|
|
1037
1153
|
function constraintCrossing(refusal) {
|
|
@@ -1043,7 +1159,7 @@ function constraintCrossing(refusal) {
|
|
|
1043
1159
|
// `{status, message}` AND NO MARK STILL CROSSES AS ITSELF, BELOW.**
|
|
1044
1160
|
const carried = bodyThrowCarried(refusal);
|
|
1045
1161
|
if (carried !== null) {
|
|
1046
|
-
const converted = bodyThrowRefusal(carried);
|
|
1162
|
+
const converted = bodyThrowRefusal(carried, refusal);
|
|
1047
1163
|
if (converted !== null) throw converted;
|
|
1048
1164
|
}
|
|
1049
1165
|
const isObject = refusal !== null && typeof refusal === 'object';
|
|
@@ -1076,11 +1192,11 @@ function constraintCrossing(refusal) {
|
|
|
1076
1192
|
}
|
|
1077
1193
|
}
|
|
1078
1194
|
if (typeof status !== 'string' || kernelToken === false) {
|
|
1079
|
-
throw {
|
|
1195
|
+
throw packageRefusal({
|
|
1080
1196
|
status: refusal.status,
|
|
1081
1197
|
message: refusal.message,
|
|
1082
1198
|
log: refusalLog(log),
|
|
1083
|
-
};
|
|
1199
|
+
});
|
|
1084
1200
|
}
|
|
1085
1201
|
// **THE KERNEL'S OWN `KC` REFUSAL.** Its `{status, message, log}` is the KERNEL'S OWN three-member form
|
|
1086
1202
|
// (`docs/specs/storeroom-constraints/fail-surface.md §1.1`), and **⟶ FROM 2026-10-26 IT CROSSES WITH THE
|
|
@@ -1089,13 +1205,13 @@ function constraintCrossing(refusal) {
|
|
|
1089
1205
|
// **THE TOKEN STILL DOES NOT ENTER `status`** — it is on the attempt's own `outcome` entry's `state` in the
|
|
1090
1206
|
// `log`, which is `D-38`'s reading — **AND `FileCommitFailed` IS NOW THE SAVE'S CODE ALONE, minted by save
|
|
1091
1207
|
// failures only.** The message is the kernel's own, UNMOVED; the `log` is the attempt's, VERBATIM.
|
|
1092
|
-
throw {
|
|
1208
|
+
throw packageRefusal({
|
|
1093
1209
|
status: CONSTRAINT_PASS_REFUSED,
|
|
1094
1210
|
message: typeof refusal.message === 'string'
|
|
1095
1211
|
? refusal.message
|
|
1096
1212
|
: 'the write was refused by a constraint of this attempt',
|
|
1097
1213
|
log: refusalLog(log),
|
|
1098
|
-
};
|
|
1214
|
+
});
|
|
1099
1215
|
}
|
|
1100
1216
|
|
|
1101
1217
|
|
|
@@ -1336,10 +1452,16 @@ function reversalAtRest(instance) {
|
|
|
1336
1452
|
/// the store object, so a second store is a second record, the record dies with its store, and **NO MEMBER IS
|
|
1337
1453
|
/// ADDED TO THE PRODUCT, TO A RECORD OR TO THE KERNEL** (`A117` (D6)'s four-member guardrail is untouched).
|
|
1338
1454
|
///
|
|
1339
|
-
/// **`pending` IS THE REQUEST** — `{ watched, reversalId, window }`:
|
|
1455
|
+
/// **`pending` IS THE REQUEST** — `{ watched, reversalId, window, asked }`:
|
|
1340
1456
|
/// * `watched` the check's own beginning captured BEFORE the action ran (`reversalWatch`);
|
|
1341
1457
|
/// * `reversalId` the store's own echo of the id the reversal named (attached by `judgeReversal` in the same
|
|
1342
1458
|
/// frame, one line after the action);
|
|
1459
|
+
/// * **⟶ `asked` THE PAIR THAT WAS BEING ASKED WHEN THE ACTION WAS RAISED, OR `null`, ADDED 2026-10-28 —
|
|
1460
|
+
/// `DEF-AL`, THE MISATTRIBUTION.** The budget's refusal used to name `watched[0]` — the FIRST WATCHED
|
|
1461
|
+
/// ADDRESS — so **registration order decided the accusation**: measured, the pair it named had answered
|
|
1462
|
+
/// `true` on every ask it received. **The ask in flight is known at the instant the request is raised**
|
|
1463
|
+
/// (`ASKING` below, set by `judgeReversal` around the one body invocation and read here), so the request
|
|
1464
|
+
/// records the pair and the address the check was actually at, and the arm past the budget names THOSE.
|
|
1343
1465
|
/// * **⟶ `window` the IDENTITY OF THE COMMIT THE ACTION WAS TAKEN IN** (`state.mjs`'s `currentWindow`, minted
|
|
1344
1466
|
/// with the opening and answered by every joining call), **ADDED 2026-10-27 — AND IT IS WHAT RETIRES THE
|
|
1345
1467
|
/// COUNTING FRAME.** `D-42`'s own sentence is *"a request belongs to the act that raised it"*; while the
|
|
@@ -1352,6 +1474,26 @@ function reversalAtRest(instance) {
|
|
|
1352
1474
|
/// by the enclosing pass's) still belongs to that window and is still consumed.
|
|
1353
1475
|
const RESTARTS = new WeakMap();
|
|
1354
1476
|
|
|
1477
|
+
/// **⟶ `D-54` (b)'s ONE FLAG, SPELLED HERE AND IN `kernel-attempt.mjs`** — the `Symbol.for` key the kernel's
|
|
1478
|
+
/// terminal act stands on its own record while its compensating composition runs, so `reversalWatch` can tell
|
|
1479
|
+
/// the package's own undo from a consumer's `rollback` member call (`D-42`: *"a restart is only ever raised by a
|
|
1480
|
+
/// consumer's own `rollback` member call"*). **A SYMBOL ON THE KERNEL RECORD AND NOT A MEMBER OF THE PRODUCT OR
|
|
1481
|
+
/// OF ANY RECORD** (`A117` (D6)), no kernel item is minted (`kernel-surface.md §1` item 2), and the flag stands
|
|
1482
|
+
/// only for the duration of that one call.
|
|
1483
|
+
const COMPENSATING = Symbol.for('provident-storeroom.compensating-rollback');
|
|
1484
|
+
|
|
1485
|
+
/// **⟶ THE ASK IN FLIGHT, 2026-10-28 — `DEF-AL`'s ONE NEW READ, AND IT IS A `WeakMap` FOR THE SAME REASONS
|
|
1486
|
+
/// THE RESTART RECORD IS ONE** (`D-30`; `D-46`): keyed by the store, so a second store is a second record, the
|
|
1487
|
+
/// record dies with its store, and no member is added to the product, to a record or to the kernel.
|
|
1488
|
+
///
|
|
1489
|
+
/// **WHAT IT CARRIES, AND WHY IT CANNOT LIVE ON THE REQUEST ALONE.** `{ entry, address }` — the pair
|
|
1490
|
+
/// `judgeReversal` is asking and the address it is asking at — set immediately BEFORE the one body invocation
|
|
1491
|
+
/// and cleared immediately after it, on every arm including the throwing one. **A body that raises a reversal
|
|
1492
|
+
/// does it INSIDE that invocation**, so `reversalWatch`'s in-flight arm reads the entry standing here and
|
|
1493
|
+
/// stamps it on the request it raises. Without it the arm past the budget has nothing to name but the watch's
|
|
1494
|
+
/// first address, which is a fact about registration order and not about the check.
|
|
1495
|
+
const ASKING = new WeakMap();
|
|
1496
|
+
|
|
1355
1497
|
/// **HOW MANY RESTARTS ONE PASS'S COMMIT SCOPE MAY TAKE** — the bound `drainRestartRequests` spends. Three is
|
|
1356
1498
|
/// the declared figure: two fewer than any arm of this package's own batteries drives, and enough that a lawful
|
|
1357
1499
|
/// in-commit action's single restart never meets it.
|
|
@@ -1428,29 +1570,38 @@ export function drainRestartRequests(instance, report) {
|
|
|
1428
1570
|
for (;;) {
|
|
1429
1571
|
const request = record.pending;
|
|
1430
1572
|
if (request === null) return report;
|
|
1431
|
-
// **A
|
|
1432
|
-
//
|
|
1433
|
-
//
|
|
1434
|
-
//
|
|
1435
|
-
//
|
|
1436
|
-
//
|
|
1437
|
-
//
|
|
1438
|
-
//
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1573
|
+
// **A PASS DOES NOT CONSUME A REQUEST IT DID NOT RAISE — `D-54`, 2026-10-28, MEASURED.**
|
|
1574
|
+
// `RCA-8(g)` ANNOTATE-BESIDE: the bytes that stood here read *"a request standing from a window this pass
|
|
1575
|
+
// did not open has no consumer HERE, and it is dropped"*, and **the drop was a CONSUMPTION**: a nested
|
|
1576
|
+
// pass — a listener body's own write, a reentrant write inside an open commit — cleared a request the
|
|
1577
|
+
// ENCLOSING window had raised, so the enclosing pass's own drain found nothing to judge and the reversal's
|
|
1578
|
+
// effect stood. **THE REQUEST IS THEREFORE LEFT WHERE IT STANDS**: this pass asks nothing at it and takes
|
|
1579
|
+
// nothing from it, and the consumer that matches its window is still free to reach it. **A REQUEST NOBODY
|
|
1580
|
+
// CONSUMES STILL DIES WITH ITS WINDOW** (`D-42` item `3`; `D-43` item `2`): windows are never reused, so a
|
|
1581
|
+
// stale stamp can be consumed by no later pass, it is overwritten by the next action's own request, and the
|
|
1582
|
+
// two declared passless windows have their own answers — the `delete`'s witness reports (and clears) its
|
|
1583
|
+
// own, the registration's is read by no surface. **A MISMATCHED REQUEST IS NOT CONSUMED, AND THAT IS THE
|
|
1584
|
+
// WHOLE OF HALF (a).**
|
|
1585
|
+
if (request.window !== window) return report;
|
|
1443
1586
|
record.pending = null;
|
|
1444
1587
|
if (request.watched.length === 0) continue;
|
|
1445
1588
|
rounds += 1;
|
|
1446
1589
|
if (rounds > RESTART_LIMIT) {
|
|
1447
1590
|
// THE CHECK DID NOT SETTLE: THE SAME FORM, THE SAME STATUS, THE SAME COMPENSATION (`D-41` item `4`'s
|
|
1448
1591
|
// direction), and the log entry says the budget was spent rather than that a pair refused.
|
|
1449
|
-
|
|
1592
|
+
//
|
|
1593
|
+
// **⟶ AND IT NAMES THE ADDRESS THE BUDGET WAS SPENT AT AND THE PAIR THAT WAS BEING ASKED, 2026-10-28 —
|
|
1594
|
+
// `DEF-AL`, MEASURED.** This arm named `request.watched[0]` — the FIRST WATCHED ADDRESS — so
|
|
1595
|
+
// REGISTRATION ORDER DECIDED THE ACCUSATION, and the pair it named had answered `true` on every ask it
|
|
1596
|
+
// received: `log[0]` named the true cause while naming a passing pair by id. **THE REQUEST'S OWN
|
|
1597
|
+
// `asked` IS THAT PAIR** (`reversalWatch`'s clause above), and it is the one the check was at when it
|
|
1598
|
+
// ran out. Where no ask stood, the entry says so and names no pair it cannot know.
|
|
1599
|
+
const asked = request.asked !== null && request.asked !== undefined ? request.asked : null;
|
|
1600
|
+
const one = asked === null ? request.watched[0] : { entry: asked.entry, address: asked.address };
|
|
1450
1601
|
const after = standingAt(instance, one.address);
|
|
1451
1602
|
const undo = restoreReversal(instance, request.watched);
|
|
1452
1603
|
return carryRestartRefusal(report,
|
|
1453
|
-
reversalRefusal(one, after, null, request.reversalId, undo, null, true));
|
|
1604
|
+
reversalRefusal(one, after, null, request.reversalId, undo, null, true, asked !== null));
|
|
1454
1605
|
}
|
|
1455
1606
|
try {
|
|
1456
1607
|
judgeReversal(instance, request.watched, request.reversalId);
|
|
@@ -1476,11 +1627,13 @@ export function drainRestartRequests(instance, report) {
|
|
|
1476
1627
|
/// **WHAT THIS FUNCTION IS, AND WHAT IT IS NOT.**
|
|
1477
1628
|
/// * **IT RUNS NO PASS, NO BODY AND NO JUDGEMENT.** It reads the instance's own restart record — the record
|
|
1478
1629
|
/// `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
|
-
///
|
|
1630
|
+
/// id the reversal named (`reversalId`, the store's own echo) and **the addresses the refused act MOVED**
|
|
1631
|
+
/// (`request.moved`, measured by `judgeReversal` at the reversal's own instant and deduplicated by spelling,
|
|
1632
|
+
/// segment for segment). **THE WATCH'S FULL ADDRESS LIST IS THE DEBT RECORD AND IS NOT THE WITNESS**: naming
|
|
1633
|
+
/// every watched address would say nothing about what the act did (`DEF-AM`, 2026-10-28). **THE STORE IS NOT
|
|
1634
|
+
/// TOUCHED, NO CODE IS MINTED, NO LOG ENTRY IS APPENDED AND NO MEMBER OF ANY RECORD IS MOVED** — the `D-49`
|
|
1635
|
+
/// bar: *"a witness is not a refusal: the act still answers what it answered, the discard is reported beside
|
|
1636
|
+
/// it, and nothing new is minted in the closed status set."*
|
|
1484
1637
|
/// * **IT CONSUMES THE REQUEST IT REPORTS.** A request whose window is the caller's has no consumer that could
|
|
1485
1638
|
/// ever run it (the window's act ran no pass, and a later pass compares the identity and drops it — the
|
|
1486
1639
|
/// drain's own arm), so clearing the slot here moves no behaviour: it is the same clearing the drain would
|
|
@@ -1507,10 +1660,16 @@ export function witnessDiscardedReversal(instance, window) {
|
|
|
1507
1660
|
// 2026-10-27): a request standing from another window is that window's and is left where it stands.
|
|
1508
1661
|
if (request.window !== window) return null;
|
|
1509
1662
|
record.pending = null;
|
|
1663
|
+
// **⟶ AND THE ADDRESSES ARE THE ONES THE REFUSED ACT MOVED, NOT THE WHOLE WATCHED REGISTRY — `DEF-AM`,
|
|
1664
|
+
// 2026-10-28.** The request's `watched` is the DEBT record and names every enabled pair's every address;
|
|
1665
|
+
// `moved` is what `judgeReversal` measured at the reversal's own instant (`movedStanding`) and is the only
|
|
1666
|
+
// answer a witness owes. **A WITNESS THAT NAMES EVERY ADDRESS THE REGISTRY WATCHES NAME NOTHING**: the
|
|
1667
|
+
// discarded check's subject is the state the reversal changed.
|
|
1668
|
+
const subject = Array.isArray(request.moved) ? request.moved : [];
|
|
1510
1669
|
const addresses = [];
|
|
1511
1670
|
const spellings = [];
|
|
1512
|
-
for (let index = 0; index <
|
|
1513
|
-
const address =
|
|
1671
|
+
for (let index = 0; index < subject.length; index += 1) {
|
|
1672
|
+
const address = subject[index].address;
|
|
1514
1673
|
const spelling = homeAddressKey(address);
|
|
1515
1674
|
let seen = false;
|
|
1516
1675
|
for (let known = 0; known < spellings.length; known += 1) {
|
|
@@ -1574,7 +1733,14 @@ function carryRestartRefusal(report, refusal) {
|
|
|
1574
1733
|
const log = { log: report.log };
|
|
1575
1734
|
for (let index = 0; index < carried.length; index += 1) {
|
|
1576
1735
|
const entry = carried[index];
|
|
1577
|
-
|
|
1736
|
+
// **⟶ AND THE REPLAY NAMES THE ITERATION AS THE ENTRY IT IS CARRYING NAMES IT — `D-53`'s first ruling.** This is
|
|
1737
|
+
// the ONE `append` site whose two identities come from a CARRIED ENTRY and not from an acted-upon pair and op
|
|
1738
|
+
// (`D-52` counted it as rule 1's fourth kind), so the iteration is rebuilt from the two identities the entry
|
|
1739
|
+
// itself carries: **the pair stands by its `id`, and the op by the `opId` the judgement's reversal answered —
|
|
1740
|
+
// and the pair's own row is not in hand here, which is why the identity alone is spelled.** Nothing is
|
|
1741
|
+
// renumbered and nothing is re-authored: the entry minted here is the report's own, by the report's own
|
|
1742
|
+
// ordinal, and its two identity columns read exactly what the entry it carries read.
|
|
1743
|
+
append(log, entry.kind, { pair: { id: entry.id }, op: { opId: entry.opId } }, entry.message, entry.state);
|
|
1578
1744
|
}
|
|
1579
1745
|
Object.defineProperty(report, RESTART_REFUSAL, {
|
|
1580
1746
|
value: refusal,
|
|
@@ -1639,10 +1805,32 @@ export function reversalWatch(state, instance) {
|
|
|
1639
1805
|
// runs in, so *"a request belongs to the act that raised it"* (`D-42` item `3`) is MEASURED at this line and
|
|
1640
1806
|
// checked at that one, and the `CHECK_DEPTH` frame that once approximated it is deleted with its clears.
|
|
1641
1807
|
if (reversalAtRest(instance) === false) {
|
|
1808
|
+
// **⟶ AND THE KERNEL'S OWN COMPENSATING ROLLBACK IS NOT A CONSUMER'S ACTION — `D-54`, 2026-10-28,
|
|
1809
|
+
// MEASURED.** `D-42` declares it: *"A RESTART IS ONLY EVER RAISED BY A CONSUMER'S OWN `rollback` MEMBER
|
|
1810
|
+
// CALL."* **THE KERNEL'S TERMINAL COMPOSITION REACHES THAT MEMBER** (`kernel-terminal.mjs`'s
|
|
1811
|
+
// `composeRollback` calls `attempt.store.rollback`, the app's published member), so with the failing pass's
|
|
1812
|
+
// drain now reached (`D-54` (b)) the composition's own reversal was raising a request in the pass's window
|
|
1813
|
+
// — **A PHANTOM THE DRAIN THEN JUDGED**, asking a pair at the state the compensation had restored to and
|
|
1814
|
+
// re-shaping a refusal no consumer wrote. **THE FLAG IS THE KERNEL'S, TAKEN AROUND ITS OWN TERMINAL ACT**
|
|
1815
|
+
// (`kernel-attempt.mjs`'s `terminalComposed`), **and it is a `Symbol.for` key on the kernel record that both
|
|
1816
|
+
// modules spell** — no member of any record and none of the product moves (`A117` (D6)). With it, the
|
|
1817
|
+
// composition takes no watch, raises no request and judges no step: the request the pass's own bodies
|
|
1818
|
+
// raised is the one the drain carries to the terminal judgement, and no other.
|
|
1819
|
+
if (kernelFor(instance)[COMPENSATING] === true) return watched;
|
|
1820
|
+
// **⟶ AND THE REQUEST NAMES THE ASK IT WAS RAISED UNDER, 2026-10-28 (`DEF-AL`).** A body acts INSIDE the
|
|
1821
|
+
// one invocation `judgeReversal` wrapped in `ASKING`, so the pair and the address the check was actually
|
|
1822
|
+
// asking are in hand at this instant. `null` where no ask stands (an action raised by a body outside a
|
|
1823
|
+
// judgement — a listener's own window is the measured arm), and the arm past the budget then says so
|
|
1824
|
+
// rather than naming a pair it cannot know.
|
|
1825
|
+
const asking = ASKING.get(instance);
|
|
1642
1826
|
restartRecord(instance).pending = {
|
|
1643
1827
|
watched: watchStanding(state, instance),
|
|
1828
|
+
// **AND THE MOVED SET IS MEASURED BY THE JUDGEMENT, NOT BY THE WATCH** (`judgeReversal`'s in-flight arm;
|
|
1829
|
+
// `DEF-AM`): the watch is taken BEFORE the reversal runs, so what moved is not knowable here.
|
|
1830
|
+
moved: null,
|
|
1644
1831
|
reversalId: null,
|
|
1645
1832
|
window: currentWindow(instance),
|
|
1833
|
+
asked: asking === undefined ? null : asking,
|
|
1646
1834
|
};
|
|
1647
1835
|
return watched;
|
|
1648
1836
|
}
|
|
@@ -1722,6 +1910,30 @@ function captureStanding(instance, address) {
|
|
|
1722
1910
|
};
|
|
1723
1911
|
}
|
|
1724
1912
|
|
|
1913
|
+
/// **THE ADDRESSES THE REVERSAL ACTUALLY MOVED, MEASURED ONCE** — the watch's capture against the standing the
|
|
1914
|
+
/// store holds now, with each entry's `after` beside its `before`. **A STANDING THIS REVERSAL DID NOT MOVE IS NOT
|
|
1915
|
+
/// A STANDING IT LEFT**, so the pair is not asked at it and cannot refuse the reversal for a state the reversal
|
|
1916
|
+
/// found. **IT IS THE JUDGEMENT'S SUBJECT AND THE RESTORE'S DEBT** (`judgeReversal`), and from 2026-10-28 it is
|
|
1917
|
+
/// also **THE WITNESS'S SUBJECT** (`DEF-AM`: the discarded request reports the addresses that MOVED, not every
|
|
1918
|
+
/// address the registry watches).
|
|
1919
|
+
function movedStanding(instance, watched) {
|
|
1920
|
+
const moved = [];
|
|
1921
|
+
for (let index = 0; index < watched.length; index += 1) {
|
|
1922
|
+
const one = watched[index];
|
|
1923
|
+
const after = standingAt(instance, one.address);
|
|
1924
|
+
if (sameStanding(one.before, after) === true) continue;
|
|
1925
|
+
appendOwn(moved, {
|
|
1926
|
+
entry: one.entry,
|
|
1927
|
+
address: one.address,
|
|
1928
|
+
before: one.before,
|
|
1929
|
+
beforeTier: one.beforeTier,
|
|
1930
|
+
beforeTiers: one.beforeTiers,
|
|
1931
|
+
after,
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
return moved;
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1725
1937
|
/// **THE JUDGEMENT — THE TERMINAL STATE, ASKED OF EVERY PAIR THE REVERSAL TOUCHED, ONCE.** It answers
|
|
1726
1938
|
/// `undefined` on the lawful arm (**and the caller's record then crosses unchanged**) and THROWS the surface's
|
|
1727
1939
|
/// one plain form on the refusing arm. `reversalId` is the store's own echo of the id the reversal named
|
|
@@ -1750,6 +1962,10 @@ function captureStanding(instance, address) {
|
|
|
1750
1962
|
/// actually happened: a body threw), while the treatment — restore, one log entry naming the pair, one plain
|
|
1751
1963
|
/// form — is the violation's.
|
|
1752
1964
|
export function judgeReversal(instance, watched, reversalId) {
|
|
1965
|
+
// **A COMPENSATING ROLLBACK IS NOT JUDGED AS A STEP EITHER — `D-54` (b)**: the member is reached by the
|
|
1966
|
+
// kernel's own terminal act with the flag standing, and this act must not touch a pending request or ask a
|
|
1967
|
+
// pair. The consumer's own judgement is the drain's, at the pass's terminal state.
|
|
1968
|
+
if (kernelFor(instance)[COMPENSATING] === true) return undefined;
|
|
1753
1969
|
// **⟶ AND THE IN-FLIGHT ARM IS THE REQUEST'S OTHER HALF, `D-42` (2026-10-27).** `reversalWatch` answers
|
|
1754
1970
|
// `[]` for an action taken inside an open window — no body is invoked at the reversal's instant and the step
|
|
1755
1971
|
// is still not judged as a step — **and this frame is where the store's own echo of the id the reversal
|
|
@@ -1761,6 +1977,13 @@ export function judgeReversal(instance, watched, reversalId) {
|
|
|
1761
1977
|
const record = RESTARTS.get(instance);
|
|
1762
1978
|
if (record !== undefined && record.pending !== null && record.pending.reversalId === null) {
|
|
1763
1979
|
record.pending.reversalId = typeof reversalId === 'string' ? reversalId : null;
|
|
1980
|
+
// **⟶ AND THE WITNESS NAMES WHAT MOVED, NOT THE WHOLE WATCHED REGISTRY — `DEF-AM`, 2026-10-28.** The
|
|
1981
|
+
// request the watch raised carries every enabled pair's every address as the DEBT record, which is what
|
|
1982
|
+
// the restarted check must ask; the WITNESS is a different question — *"what did the refused act move?"* —
|
|
1983
|
+
// and the moved set is measured here, at the reversal's own instant, by the same `before`/`after`
|
|
1984
|
+
// comparison the at-rest judgement takes. **THE STORE IS READ ONCE PER WATCHED ADDRESS AND NOTHING IS
|
|
1985
|
+
// INVOKED**: this is the same walk `movedStanding` performs for the at-rest arm.
|
|
1986
|
+
record.pending.moved = movedStanding(instance, record.pending.watched);
|
|
1764
1987
|
}
|
|
1765
1988
|
return undefined;
|
|
1766
1989
|
}
|
|
@@ -1781,34 +2004,25 @@ export function judgeReversal(instance, watched, reversalId) {
|
|
|
1781
2004
|
// THE MOVED SET IS TAKEN FIRST, ONCE: the judgement's subject is the CHANGE the reversal made and nothing
|
|
1782
2005
|
// wider, and the same list is what a refusal has to put back — with the tier capture the watch took, so a
|
|
1783
2006
|
// 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
|
-
}
|
|
2007
|
+
const moved = movedStanding(instance, watched);
|
|
1801
2008
|
for (let index = 0; index < moved.length; index += 1) {
|
|
1802
2009
|
const one = moved[index];
|
|
1803
2010
|
// **THE BODY'S THROW IS THE JUDGEMENT'S OWN CATCH AND NOT A PROPAGATING VALUE** — `reversalOutcome` converts
|
|
1804
2011
|
// a body's throwable to the surface's rank-`18` form and re-throws anything unmarked as itself, and BOTH
|
|
1805
2012
|
// arrive here: the reversal has run, so a judgement that cannot complete restores and refuses (below).
|
|
1806
2013
|
let outcome;
|
|
2014
|
+
// **⟶ AND THE ASK IS NAMED BEFORE THE BODY RUNS, 2026-10-28 (`DEF-AL`).** A body that acts does it
|
|
2015
|
+
// inside this one invocation, and the request it raises must name the pair the check was ASKING — not
|
|
2016
|
+
// the watch's first address. The mark is cleared on every arm, the throwing one included, so no later
|
|
2017
|
+
// act inherits an ask that has ended.
|
|
2018
|
+
ASKING.set(instance, { entry: one.entry, address: one.address });
|
|
1807
2019
|
try {
|
|
1808
2020
|
outcome = reversalOutcome(instance, one.entry, one.address, one.after);
|
|
1809
2021
|
} catch (thrown) {
|
|
1810
2022
|
const undo = restoreReversal(instance, moved);
|
|
1811
2023
|
throw reversalRefusal(one, one.after, null, reversalId, undo, thrown);
|
|
2024
|
+
} finally {
|
|
2025
|
+
ASKING.delete(instance);
|
|
1812
2026
|
}
|
|
1813
2027
|
if (outcome === true) continue;
|
|
1814
2028
|
// **THE FIRST VIOLATING PAIR DECIDES AND THE SECOND IS NOT EVALUATED** (`attempt-lifecycle.md §2.4` item 5
|
|
@@ -1883,6 +2097,20 @@ export function judgeReversal(instance, watched, reversalId) {
|
|
|
1883
2097
|
/// honesty `D-41` item `2` measured at `200` of `200`. **NO WRITE AND NO DELETE IS ISSUED BY THIS FUNCTION ON
|
|
1884
2098
|
/// ANY ARM**; the store's own verb is the whole act.
|
|
1885
2099
|
///
|
|
2100
|
+
/// **⟶ AND FROM 2026-10-28 THE BASELINE THE VERDICT MEASURES IS NAMED, AND THE TWO SUCCESSES ARE TOLD APART —
|
|
2101
|
+
/// `DEF-AJ`, MEASURED.** **A restore that fully succeeded was reported as one that failed**: the store's act
|
|
2102
|
+
/// returns the store to the journal mark its commit cached at its OPENING (the 2026-10-27 ruling above), and in
|
|
2103
|
+
/// the restart arm the commit has already landed writes when the reversal is asked for, so **the mark's state is
|
|
2104
|
+
/// not the pre-reversal standing the watch captured** — every moved address then failed an `exact` test the act
|
|
2105
|
+
/// had already satisfied, and the sentence said *"0 of the 1 address it moved stand again"* beside a store that
|
|
2106
|
+
/// stood exactly where the whole commit had opened. **SO THE SENTENCE HAS TWO SUCCESS ARMS AND ONE FAILURE ARM,
|
|
2107
|
+
/// AND THE BASELINE OF EACH IS SAID IN IT:** a successful act with every address equal to the pre-reversal
|
|
2108
|
+
/// capture is *"UNDONE … (the baseline this verdict measured is the pre-reversal standing, which is the state the
|
|
2109
|
+
/// journal mark the commit cached at its opening holds)"*; a successful act with any address PAST the capture is
|
|
2110
|
+
/// *"UNDONE — as a WHOLE-COMMIT UNDO"*, and each such address is named with what stands there and what stood
|
|
2111
|
+
/// there immediately before the reversal; and a REFUSED mark, a CACHELESS window and a store that did not
|
|
2112
|
+
/// restore are *"NOT undone"*, naming every address that does not stand again (the arm unchanged).
|
|
2113
|
+
///
|
|
1886
2114
|
/// **AND WHY IT CANNOT RECURSE INTO THE MEMBER.** `judgeReversal` is reached from `index.mjs`'s `rollback`
|
|
1887
2115
|
/// member; the restore never calls that member, the addon's `rollback`, or any package member — only the store's
|
|
1888
2116
|
/// `restoreMark` at its entry — so the judgement's ONE pass over the pairs stays one pass and `D-40`'s floor law
|
|
@@ -1936,6 +2164,16 @@ function restoreReversal(instance, moved) {
|
|
|
1936
2164
|
const stateRestored = cacheless === false && (refused === null || unsaved !== null);
|
|
1937
2165
|
let restored = 0;
|
|
1938
2166
|
const failed = [];
|
|
2167
|
+
// **⟶ AND THE VERDICT'S BASELINE IS NAMED FROM 2026-10-28 — `DEF-AJ`, MEASURED.** A restore that SUCCEEDED
|
|
2168
|
+
// (`stateRestored`) has returned the store to the journal mark the commit cached at its OPENING, and that is a
|
|
2169
|
+
// WHOLE-COMMIT undo: where the commit had already moved an address before the reversal was asked for, the
|
|
2170
|
+
// address stands at the mark's state and NOT at the pre-reversal standing the watch captured. The old count
|
|
2171
|
+
// read every such address as a FAILED restore — a restore that fully succeeded reported as one that did not —
|
|
2172
|
+
// because the baseline it compared against was the pre-reversal capture and never the mark. **SO THE TWO ARE
|
|
2173
|
+
// TOLD APART HERE**: `failed` is the list an UNRESTORED store is reported by (the refused mark, the cacheless
|
|
2174
|
+
// window), and `wholeCommit` is the list of addresses the store's successful act returned PAST the pre-reversal
|
|
2175
|
+
// standing — each named with what stands there now and what stood there immediately before the reversal.
|
|
2176
|
+
const wholeCommit = [];
|
|
1939
2177
|
// ONE VERIFICATION PER ADDRESS: two pairs over one address (or one pair naming it twice) must not be counted
|
|
1940
2178
|
// twice, so the addresses already measured are remembered — by a local loop, never by `Array.prototype.includes`
|
|
1941
2179
|
// on a refusal path (`contract.md §2.1`'s clause on `F8-2` and item `(2b)`'s row `54`).
|
|
@@ -1946,9 +2184,27 @@ function restoreReversal(instance, moved) {
|
|
|
1946
2184
|
if (hasOwnSpelling(measured, key) === true) continue;
|
|
1947
2185
|
appendOwn(measured, key);
|
|
1948
2186
|
// **THE ADDRESS IS READ AGAIN, AGAINST THE CAPTURE** — the cross-tier standing and every tier with its own
|
|
1949
|
-
// value — and
|
|
2187
|
+
// value — and `exact` says whether it equals what the watch took before the reversal.
|
|
1950
2188
|
const verdict = standingVerdict(instance, one);
|
|
1951
|
-
if (stateRestored
|
|
2189
|
+
if (stateRestored) {
|
|
2190
|
+
// THE STORE'S ACT SUCCEEDED, so every measured address was returned to the mark — that is the claim the
|
|
2191
|
+
// store's own answer supports, and it is counted as restored. Where the mark's state is not the
|
|
2192
|
+
// pre-reversal standing, the address belongs to `wholeCommit`, which the sentence reports as the commit's
|
|
2193
|
+
// own earlier work undone with the reversal rather than as a failed restore.
|
|
2194
|
+
restored += 1;
|
|
2195
|
+
if (verdict.exact !== true) {
|
|
2196
|
+
appendOwn(wholeCommit, {
|
|
2197
|
+
address: one.address,
|
|
2198
|
+
before: one.before,
|
|
2199
|
+
beforeTier: one.beforeTier,
|
|
2200
|
+
beforeTiers: one.beforeTiers,
|
|
2201
|
+
standing: verdict.value,
|
|
2202
|
+
tiers: verdict.tiers,
|
|
2203
|
+
});
|
|
2204
|
+
}
|
|
2205
|
+
continue;
|
|
2206
|
+
}
|
|
2207
|
+
if (verdict.exact === true) {
|
|
1952
2208
|
restored += 1;
|
|
1953
2209
|
continue;
|
|
1954
2210
|
}
|
|
@@ -1963,7 +2219,7 @@ function restoreReversal(instance, moved) {
|
|
|
1963
2219
|
tiers: verdict.tiers,
|
|
1964
2220
|
});
|
|
1965
2221
|
}
|
|
1966
|
-
return { restored, total: measured.length, failed, refused, unsaved, cacheless };
|
|
2222
|
+
return { restored, total: measured.length, failed, wholeCommit, refused, unsaved, cacheless };
|
|
1967
2223
|
}
|
|
1968
2224
|
|
|
1969
2225
|
/// **WHETHER A LOCAL LIST OF SPELLINGS ALREADY HOLDS ONE** — a local index loop and not `Array.prototype.includes`.
|
|
@@ -2002,10 +2258,19 @@ function standingVerdict(instance, one) {
|
|
|
2002
2258
|
}
|
|
2003
2259
|
|
|
2004
2260
|
/// **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"*).
|
|
2261
|
+
/// at the ONE site that builds the log entry. **IT MAY CLAIM *"THE REVERSAL WAS UNDONE"* ONLY WHERE THE STORE'S
|
|
2262
|
+
/// OWN ACT SUCCEEDED AND EVERY ADDRESS IT MOVED STANDS AGAIN AS THE MARK SAYS** (`restoreReversal`'s verdict);
|
|
2263
|
+
/// where it cannot, **it names each address that could not be restored and says what stands there INSTEAD and
|
|
2264
|
+
/// what it was owed** (`D-41` item `2`: *"a message must not claim a restoration that did not happen"*).
|
|
2265
|
+
/// `DEF-Q`: no column prints `undefined`.
|
|
2266
|
+
///
|
|
2267
|
+
/// **⟶ AND A SUCCESSFUL RESTORE'S BASELINE IS NAMED, 2026-10-28 — `DEF-AJ`, MEASURED.** The act restores the
|
|
2268
|
+
/// journal mark the commit cached at its OPENING; where that mark stands before the reversal (the restart arm),
|
|
2269
|
+
/// the addresses the commit had already moved come back to the MET MARK and not to the watch's pre-reversal
|
|
2270
|
+
/// capture. **THE SENTENCE THEREFORE SAYS WHICH BASELINE IT MEASURED, AND A WHOLE-COMMIT UNDO IS SPOKEN AS A
|
|
2271
|
+
/// SUCCESS** — *"UNDONE — as a WHOLE-COMMIT UNDO"* — with each address that stands at the mark's state named
|
|
2272
|
+
/// beside what stood there immediately before the reversal. **ONLY THE ARMS THAT DID NOT RESTORE SAY *"NOT
|
|
2273
|
+
/// undone"*: the refused mark, the cacheless window, and any address left standing at what the reversal left.**
|
|
2009
2274
|
///
|
|
2010
2275
|
/// **⟶ AND THE TWO ARMS THE STORE CAN ANSWER WITH ARE NAMED SEPARATELY, 2026-10-27 (THE FILE-SAVE RULING).**
|
|
2011
2276
|
/// **A REFUSED MARK** means the store holds what it held, and the sentence says exactly that. **A FAILED SAVE
|
|
@@ -2046,9 +2311,30 @@ function undoSpelling(undo) {
|
|
|
2046
2311
|
refusal = `the store REFUSED the journal mark (${JSON.stringify(typeof status === 'string' ? status : 'a refusal')}`
|
|
2047
2312
|
+ `: ${typeof said === 'string' ? said : ''}) and holds the state it held; `;
|
|
2048
2313
|
}
|
|
2049
|
-
if (undo.failed.length === 0) {
|
|
2314
|
+
if (undo.failed.length === 0 && undo.wholeCommit.length === 0) {
|
|
2050
2315
|
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'
|
|
2316
|
+
+ 'the reversal — the same value at the same tier, or absent where it was absent (the baseline this '
|
|
2317
|
+
+ 'verdict measured is the pre-reversal standing, which is the state the journal mark the commit cached '
|
|
2318
|
+
+ 'at its opening holds)';
|
|
2319
|
+
}
|
|
2320
|
+
// **⟶ AND A SUCCESSFUL RESTORE WHOSE MARK STANDS BEFORE THE REVERSAL IS NAMED AS WHAT IT IS — `DEF-AJ`.**
|
|
2321
|
+
// The store's act succeeded (`failed` is empty), so nothing here is a failure; what differs from the watch's
|
|
2322
|
+
// capture is the commit's own earlier work, which the same mark undoes. **THE SENTENCE SAYS *UNDONE* AND SAYS
|
|
2323
|
+
// ITS BASELINE**, because a restore that succeeded must say so.
|
|
2324
|
+
if (undo.failed.length === 0) {
|
|
2325
|
+
let named = '';
|
|
2326
|
+
for (let index = 0; index < undo.wholeCommit.length; index += 1) {
|
|
2327
|
+
const one = undo.wholeCommit[index];
|
|
2328
|
+
named += index === 0 ? '' : '; ';
|
|
2329
|
+
named += `${addressSpelling(one.address)} stands ${standingDescription(one.standing, one.tiers)} where it `
|
|
2330
|
+
+ `stood ${capturedDescription(one)} immediately before the reversal`;
|
|
2331
|
+
}
|
|
2332
|
+
const movedCount = undo.total === 1 ? 'address' : 'addresses';
|
|
2333
|
+
const stands = undo.restored === 1 ? 'stands' : 'stand';
|
|
2334
|
+
return `${refusal}the store was restored to the journal mark its commit cached at its opening, so the `
|
|
2335
|
+
+ `reversal was UNDONE — as a WHOLE-COMMIT UNDO (the baseline this verdict measured is the pre-reversal `
|
|
2336
|
+
+ `standing): all ${undo.total} ${movedCount} it moved ${stands} where that mark leaves them, and the `
|
|
2337
|
+
+ `difference from the pre-reversal standing is the commit's own earlier work, undone with it — ${named}`;
|
|
2052
2338
|
}
|
|
2053
2339
|
let named = '';
|
|
2054
2340
|
for (let index = 0; index < undo.failed.length; index += 1) {
|
|
@@ -2209,7 +2495,10 @@ function reversalOutcome(instance, entry, address, value) {
|
|
|
2209
2495
|
// attempt stands at a reversal's judgement.
|
|
2210
2496
|
carried.address = addressSpelling(address);
|
|
2211
2497
|
carried.log = [];
|
|
2212
|
-
|
|
2498
|
+
// **⟶ AND THE BODY'S OWN VALUE IS HANDED IN, 2026-10-28 (`DEF-AK`)**: `bodyThrowRefusal` carries an inner
|
|
2499
|
+
// refusal beside the crossed one and names it in the crossed sentence, and the value the body threw is
|
|
2500
|
+
// the only place that refusal stands.
|
|
2501
|
+
const converted = bodyThrowRefusal(carried, body);
|
|
2213
2502
|
throw converted === null ? body : converted;
|
|
2214
2503
|
}
|
|
2215
2504
|
}
|
|
@@ -2254,7 +2543,7 @@ function reversalSaid(outcome) {
|
|
|
2254
2543
|
/// **WHERE THE THROWN VALUE IS NOT THE KERNEL'S MARKED FORM** (a body's raw throwable on a tree with no usable
|
|
2255
2544
|
/// generator), the same rank-`18` refusal is built here — the restoration and the pair's name cross regardless
|
|
2256
2545
|
/// 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) {
|
|
2546
|
+
function reversalRefusal(one, after, said, reversalId, undo, thrown, unsettled = false, spentAtAsked = true) {
|
|
2258
2547
|
const addon_ = withAddon();
|
|
2259
2548
|
// **THE `<SEGMENT>` SLOT IS THE ADDRESS SPELLING THE KERNEL'S OWN REGISTRATION REFUSAL HANDS THE SAME
|
|
2260
2549
|
// GENERATOR** (`kernel-registration.mjs`'s `registrationRefusal`: the segments joined by `/`, BARE — the
|
|
@@ -2278,15 +2567,48 @@ function reversalRefusal(one, after, said, reversalId, undo, thrown, unsettled =
|
|
|
2278
2567
|
+ 'constraints admit'
|
|
2279
2568
|
: 'the reversal was refused by a constraint body that threw, the state it would leave could not be judged';
|
|
2280
2569
|
}
|
|
2570
|
+
// **⟶ AND A SPENT BUDGET IS NOT A PAIR REFUSING, IN ITS OWN WORDS — 2026-10-28, `DEF-AL`, MEASURED.** The
|
|
2571
|
+
// budget's crossed `message` used to be BYTE-IDENTICAL to a genuine refusal's (the same rank-`20` member and
|
|
2572
|
+
// the same generated sentence at the same subject), so a consumer reading only the message could not tell a
|
|
2573
|
+
// real refusal from an exhausted budget. **The store's generated sentence still stands first (`DD-52`: one
|
|
2574
|
+
// source for the code), and this arm appends the fact the code cannot carry** — the check did not settle and
|
|
2575
|
+
// NO PAIR REFUSED ANYTHING; a pair body acted at every restart. A genuine refusal's message never carries
|
|
2576
|
+
// this clause, which is what makes the two distinguishable.
|
|
2577
|
+
if (unsettled === true) {
|
|
2578
|
+
message = `${message} — this refusal is a RESTART BUDGET EXHAUSTION and NOT a constraint pair refusing a `
|
|
2579
|
+
+ `state: no pair refused the state the check was asking it for, a pair body acted inside the check at `
|
|
2580
|
+
+ `every restart, the budget of ${RESTART_LIMIT} restarts is spent and the check could not settle`;
|
|
2581
|
+
}
|
|
2582
|
+
// **⟶ AND AN INNER REFUSAL THE BODY THREW IS CARRIED BESIDE THE CROSSED ONE, 2026-10-28 (`DEF-AK`).** The
|
|
2583
|
+
// body that threw at this judgement threw through `reversalOutcome`, whose conversion is `bodyThrowRefusal`'s
|
|
2584
|
+
// — so the converted form carries the inner refusal under the same symbol, and it travels on from here.
|
|
2585
|
+
const inner = thrown === null ? null : innerRefusalCarried(thrown);
|
|
2586
|
+
if (inner !== null) {
|
|
2587
|
+
const innerStatus = ownDataMember(inner, 'status');
|
|
2588
|
+
const innerSaid = ownDataMember(inner, 'message');
|
|
2589
|
+
message = `${message} — the value the constraint body threw does NOT cross as this refusal: it was ITSELF a `
|
|
2590
|
+
+ `refusal, ${JSON.stringify(innerStatus)} with the message ${JSON.stringify(innerSaid)}, and it crosses `
|
|
2591
|
+
+ `BESIDE this one under Symbol.for('provident-storeroom.inner-refusal') with its own log`;
|
|
2592
|
+
}
|
|
2281
2593
|
// **THE LOG ENTRY'S SENTENCE, AT ITS THREE ARMS** — a pair that refused the state the reversal (or the
|
|
2282
2594
|
// in-commit action) left, a body that threw at the judgement of it, and — from `D-42` — **the restart's own
|
|
2283
2595
|
// budget spent**. The third arm is the one the restart's exhaustion reaches and it names no refusing pair.
|
|
2284
2596
|
let spelled;
|
|
2285
2597
|
if (unsettled === true) {
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2598
|
+
// **⟶ AND THE ENTRY NAMES THE PAIR THE CHECK WAS ASKING AND THE ADDRESS IT WAS ASKING AT, 2026-10-28
|
|
2599
|
+
// (`DEF-AL`).** It used to name the FIRST WATCHED pair — a passing one, by id — because registration order
|
|
2600
|
+
// decided it. The `spentAtAsked` arm says plainly WHEN THE BUDGET RAN OUT WITH NO ASK IN FLIGHT, so the
|
|
2601
|
+
// entry never claims to name a pair it cannot know.
|
|
2602
|
+
spelled = spentAtAsked === true
|
|
2603
|
+
? `the constraint ${one.entry.id} could not be asked a state that would settle at `
|
|
2604
|
+
+ `${addressSpelling(one.address)}: the value there is ${standingSpelling(after)} — this pair was being `
|
|
2605
|
+
+ `asked when the restart budget ran out, it did not refuse anything, a pair body acted inside the `
|
|
2606
|
+
+ `check at every restart, the check was restarted ${RESTART_LIMIT} times and the budget is spent, so `
|
|
2607
|
+
+ `the check does not pass — ${undoSpelling(undo)}`
|
|
2608
|
+
: `no pair was being asked when the restart budget ran out at ${addressSpelling(one.address)}: the value `
|
|
2609
|
+
+ `there is ${standingSpelling(after)} — a pair body acted inside the check without an ask in flight, `
|
|
2610
|
+
+ `the check was restarted ${RESTART_LIMIT} times and the budget is spent, so the check does not pass `
|
|
2611
|
+
+ `— ${undoSpelling(undo)}`;
|
|
2290
2612
|
} else if (thrown === null) {
|
|
2291
2613
|
spelled = `the constraint ${one.entry.id} refused the state the reversal left at `
|
|
2292
2614
|
+ `${addressSpelling(one.address)}: the value there is ${standingSpelling(after)}`
|
|
@@ -2331,7 +2653,18 @@ function reversalRefusal(one, after, said, reversalId, undo, thrown, unsettled =
|
|
|
2331
2653
|
// **THE CROSSED `status` IS THE ARM'S OWN AND IS NEVER MINTED** (`DD-40`): rank `20` where a pair refused the
|
|
2332
2654
|
// state the reversal left, rank `18` where a pair's body threw at the judgement of it (`D-41` item `4`). The
|
|
2333
2655
|
// sentence beside it was generated for that same code — one source for each (`DD-52`).
|
|
2334
|
-
|
|
2656
|
+
const crossed = packageRefusal({ status, message, log: refusalLog(log) });
|
|
2657
|
+
if (inner !== null) {
|
|
2658
|
+
// THE INNER REFUSAL TRAVELS ON THE REFUSAL THE CALLER CATCHES, under the same symbol and the same
|
|
2659
|
+
// non-enumerable discipline `bodyThrowRefusal` uses: the crossed form's three members are unmoved.
|
|
2660
|
+
Object.defineProperty(crossed, INNER_REFUSAL, {
|
|
2661
|
+
value: inner,
|
|
2662
|
+
writable: false,
|
|
2663
|
+
enumerable: false,
|
|
2664
|
+
configurable: true,
|
|
2665
|
+
});
|
|
2666
|
+
}
|
|
2667
|
+
return crossed;
|
|
2335
2668
|
}
|
|
2336
2669
|
|
|
2337
2670
|
/// **THE ADDRESS'S OWN `<SEGMENT>` SPELLING, JOINED BY `/` AND BARE** — the kernel's own
|