provident-storeroom 0.3.0 → 0.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.md +65 -25
- package/index.d.ts +40 -5
- package/index.mjs +581 -34
- package/package.json +7 -6
- package/src/constraint-kernel.mjs +390 -2
package/index.mjs
CHANGED
|
@@ -402,11 +402,84 @@ function addonLoadMessage() {
|
|
|
402
402
|
}
|
|
403
403
|
|
|
404
404
|
/// `surface.md §2.5`: **THE SINGLE FAILURE FORM** — a THROWN plain object carrying EXACTLY
|
|
405
|
-
/// `{status, message}
|
|
406
|
-
/// VERBATIM** (`§2.5` items 1–2, `DD-40`): this function constructs the
|
|
407
|
-
///
|
|
408
|
-
|
|
409
|
-
|
|
405
|
+
/// `{status, message, log}`. **The status and the message are the store's own and are carried
|
|
406
|
+
/// VERBATIM** (`§2.5` items 1–2, `DD-40`): this function constructs the form out of the refusal the addon
|
|
407
|
+
/// threw and mints no code of its own and authors no message of its own.
|
|
408
|
+
///
|
|
409
|
+
/// **⟶ AND THE FORM CROSSES AT THREE MEMBERS FROM 2026-10-16 — `surface.md §2.5` ITEM 4, THE ARCHITECT'S
|
|
410
|
+
/// RULING OF THAT DATE: *"`log` IS PRESENT ON EVERY FAILURE THIS SURFACE THROWS, AND `[]` IS ITS DECLARED
|
|
411
|
+
/// VALUE WHERE THE FAILURE'S CAUSE HAS NO ATTEMPT AT ALL."*** **The three-member member set is FLAT ACROSS
|
|
412
|
+
/// ARMS and not conditional:** a `read`/`readLiteral`/`delete`/`rollback` store refusal with no attempt
|
|
413
|
+
/// live, the construction's own `cfg`-side refusals, `a.register`'s refusal and the constraint methods'
|
|
414
|
+
/// `TypeError` all carry `log: []` — **the EMPTY ARRAY, never an absent member, never `null`, and never a
|
|
415
|
+
/// placeholder entry** — while every failure whose attempt exists carries that attempt's own entries
|
|
416
|
+
/// (`§2.5` items 3–4 and 10 (i)–(iii); `§2.12` item 1's mark of the same date). **AND WHERE A STORE ACT
|
|
417
|
+
/// PRODUCED IT, THE STORE'S `status` AND `message` ARE PRESERVED BYTE-FOR-BYTE AND `log` IS ATTACHED BESIDE
|
|
418
|
+
/// THEM — nothing is converted, a member is added** (`§2.5` item 10 (ii); `fail-surface.md §1.2`'s
|
|
419
|
+
/// *"the kernel NEVER CONVERTS ONE CHANNEL'S FAILURE INTO THE OTHER'S FORM"* stands whole).
|
|
420
|
+
///
|
|
421
|
+
/// **THE `log` MEMBER IS AN ORDINARY OWN ENUMERABLE DATA MEMBER** — written with the object literal below,
|
|
422
|
+
/// **not `Object.defineProperty`, not a getter, not on a prototype and not behind a `Symbol`** — so
|
|
423
|
+
/// `Object.keys(caught)` reads exactly `["log","message","status"]` and its length is `3` on every arm
|
|
424
|
+
/// (`§2.5` item 9). **IT IS NOT `defineProperty`'D BECAUSE A MEMBER THAT IS NOT ENUMERABLE IS NOT A MEMBER
|
|
425
|
+
/// A CANONICAL CENSUS CAN SEE**, and it is not a getter because a client reads a list and not a call.
|
|
426
|
+
///
|
|
427
|
+
/// **⟶ AND ITS TWO STORE MEMBERS ARE READ OFF THE STORE'S OWN REFUSAL AND OFF NOTHING ELSE — CORRECTED
|
|
428
|
+
/// 2026-10-17 (`A64`'s one form read with `surface.md §2.5` item 5 (e)).** **THE CONSTRUCTION BELOW ONCE
|
|
429
|
+
/// READ `refusal.status` AND `refusal.message` OF WHATEVER IT WAS HANDED, WITH NO PROVENANCE TEST AT ALL**,
|
|
430
|
+
/// and the two failures that cost are named rather than left to be re-derived: **a caller's own throwable
|
|
431
|
+
/// reached it by ONE mis-scoped `try`** (see `storeCreate` below, where that throwable now surfaces as
|
|
432
|
+
/// itself), **and a value that is not an object at all — most sharply the runtime's own `undefined`, where
|
|
433
|
+
/// NO refusal object exists because an exception is already pending — made THIS FRAME fault on
|
|
434
|
+
/// `refusal.status`**, so a caller read *"Cannot read properties of undefined (reading 'status')"* where the
|
|
435
|
+
/// value its own body threw was the whole of what it was owed.
|
|
436
|
+
///
|
|
437
|
+
/// **THE TEST IS PROVENANCE'S OWN SHAPE AND NOT A CLASS DECISION OF THIS UNIT'S:** the store's refusal is a
|
|
438
|
+
/// plain object whose `status` and `message` are `string`s (`docs/specs/storeroom-native/contract.md §8.3`'s
|
|
439
|
+
/// closed two-member form; `§2.5` items 1–2), and **a value that is not that object is NOT this form's
|
|
440
|
+
/// provenance** — so it is THROWN AS ITSELF, by the one line below, and **NEITHER A STATUS NOR A MESSAGE IS
|
|
441
|
+
/// MINTED FOR IT AND NO `log` IS ADDED TO A VALUE THAT IS NOT THE STORE'S FORM.**
|
|
442
|
+
///
|
|
443
|
+
/// **⟶ THE PROVENANCE TEST IS *"IS THIS THE STORE'S TWO-MEMBER FORM?"* AND NOT *"DOES THIS CARRY A
|
|
444
|
+
/// `log`?"*, AND THAT DISTINCTION IS THE WHOLE OF THE CORRECTION THIS MEMBER FORCED.** The two-member
|
|
445
|
+
/// presence test **was** the earlier discriminator at the crossing (`constraintCrossing`'s own history: it
|
|
446
|
+
/// discriminated on `log`'s PRESENCE) — **and now that EVERY surface failure carries `log`, presence alone
|
|
447
|
+
/// can no longer tell a store refusal, a kernel refusal and a CALLER'S FORGED OBJECT apart.** **THE TEST
|
|
448
|
+
/// REPLACED IT IS THE STORE'S FORM ITSELF — `status` a `string` AND `message` a `string`, both READ OFF THE
|
|
449
|
+
/// HANDED VALUE AND NEITHER MINTED** — and `log` is then **ATTACHED BESIDE THE TWO, NEVER READ AS THE
|
|
450
|
+
/// DISCRIMINATOR** (`refusalLog` below). A caller's forged `{status, message}` thrown from a constraint body
|
|
451
|
+
/// carries both strings and would pass this test — **which is why this function is never ON the body-throw
|
|
452
|
+
/// path at all**: the body's throwable leaves `runAttempt` unconverted and reaches the caller without
|
|
453
|
+
/// passing here (`fail-surface.md §1.1` item 5; see `constraintCrossing`'s rethrow). **SO NO BYTE OF THIS
|
|
454
|
+
/// FRAME'S PROVENANCE TEST MOVES: every store refusal this package crosses — the eight verbs, the
|
|
455
|
+
/// construction, the `16`-code set — keeps its `status` and its `message` member for member and byte for
|
|
456
|
+
/// byte, and the ONE member this date adds is `log`.**
|
|
457
|
+
function fail(refusal, log) {
|
|
458
|
+
if (refusal === null || typeof refusal !== 'object'
|
|
459
|
+
|| typeof refusal.status !== 'string' || typeof refusal.message !== 'string') {
|
|
460
|
+
throw refusal;
|
|
461
|
+
}
|
|
462
|
+
throw { status: refusal.status, message: refusal.message, log: refusalLog(log) };
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/// **THE ONE PLACE A REFUSAL'S `log` MEMBER IS DECIDED** — `surface.md §2.5` item 4's flat reading, taken
|
|
466
|
+
/// once so no arm can spell it differently. **AN ABSENT ARGUMENT IS THE DECLARED `[]`**: the failure's cause
|
|
467
|
+
/// has no attempt at all (a store refusal with no attempt live, a `cfg`-side refusal, a `register` refusal,
|
|
468
|
+
/// a constraint-method `TypeError`) — *"the EMPTY ARRAY, never an absent member, never `null`, and never a
|
|
469
|
+
/// placeholder entry"*. **A LIST HANDED IN IS THE ATTEMPT'S OWN AND CROSSES VERBATIM** (`§2.5` item 3: *"THE
|
|
470
|
+
/// ATTEMPT'S OWN MESSAGE LOG, VERBATIM … CARRIED AND NOT RE-SHAPED"*), and it is **NOT COPIED**: a copy would
|
|
471
|
+
/// be a second list and the spec's *"the same list the attempt record held"* is a statement about identity
|
|
472
|
+
/// of content, which a copy preserves while costing an allocation on every failure — and **a copy would also
|
|
473
|
+
/// silently paper over the timing trap below**, because a copy taken late reads the same bytes as one taken
|
|
474
|
+
/// early. The list crosses as it stands, and `[]` is minted fresh at each no-attempt failure so that no two
|
|
475
|
+
/// failures alias one array.
|
|
476
|
+
///
|
|
477
|
+
/// **A `log` THAT IS NOT AN ARRAY IS A FINDING AT THE SITE THAT PRODUCED IT** (`§2.5` item 9) — this
|
|
478
|
+
/// function declares no arm for it and answers the empty array rather than propagating a shape the spec
|
|
479
|
+
/// calls impossible: the alternative is a failure whose `log` is `null` or a non-array, which the same item
|
|
480
|
+
/// names as the finding verbatim.
|
|
481
|
+
function refusalLog(log) {
|
|
482
|
+
return Array.isArray(log) ? log : [];
|
|
410
483
|
}
|
|
411
484
|
|
|
412
485
|
function withAddon() {
|
|
@@ -1228,10 +1301,103 @@ function encodeAddress(address, addressArgumentPosition, addressValuePosition) {
|
|
|
1228
1301
|
/// as an OBJECT before any element is read from it — **so a throwing `get` trap cannot be raised, because
|
|
1229
1302
|
/// nothing reads the proxy** — and a class extending `Array` is refused as an OBJECT (`TierArg` row 6's
|
|
1230
1303
|
/// `OutOfDomainTier`) rather than admitted as the array spelling row 2 declares for the readers.
|
|
1231
|
-
|
|
1304
|
+
/// **THE SUPPLIED-`undefined`-TIER ARM AT AN ADDRESS POSITION** — `refuseOutsideAddressValue`'s own
|
|
1305
|
+
/// shape, taken at the one value that reached neither of the boundary's two segment/address arms
|
|
1306
|
+
/// (`DEF-2026-10-17-A`; `surface.md §2.5` item 5 (a)–(b) and its `CF-3` authority split).
|
|
1307
|
+
///
|
|
1308
|
+
/// **THE TARGET IS THE VALUE'S OWN RENDERING AND IT IS THE STORE'S OWN SPELLING FOR THAT VALUE** (item 5
|
|
1309
|
+
/// (a): *"a non-segment value PRINTED AS ITS OWN VALUE"*) — `undefined`, which is the spelling
|
|
1310
|
+
/// `refuseOutsideAddressValue` already gives this same value at the whole-address arm, so ONE value has
|
|
1311
|
+
/// ONE rendering at both arms and neither is authored here. **THE CONTAINER IS THE ARGUMENT'S OWN NAME**
|
|
1312
|
+
/// (`['address']`, handed to `boundaryReject`, whose third slot fills the generator's own `<container>`),
|
|
1313
|
+
/// exactly as the whole-address arm does one function above — a WHOLE-ADDRESS refusal is found in no
|
|
1314
|
+
/// container, so the truthfully filled slot is the failing ARGUMENT's own name. **PART TWO CARRIES THE
|
|
1315
|
+
/// POSITION AND NOT A SECOND CONTAINER CLAIM:** the ARGUMENT POSITION `§2.5` item 5 (b) requires beside the
|
|
1316
|
+
/// class, and the class of the value the position refused.
|
|
1317
|
+
///
|
|
1318
|
+
/// **⟶ AND THE SECOND VALUE THIS ARM SERVES IS A SUPPLIED `null`, WIDENED 2026-10-17 BY THE SAME ONE SITE
|
|
1319
|
+
/// (`DEF-2026-10-17-E`).** **THE DEFECT: `read(['a','b','c'], null)` crossed as `{ k: 'N' }` to the store's
|
|
1320
|
+
/// `TierArg::Null` arm and rendered the SAME register-shaped sentence
|
|
1321
|
+
/// *"the tier argument is not a legal address segment in `''`"* — the empty container and the same wrong
|
|
1322
|
+
/// argument the `undefined` half above had already been repaired for, so ONE ROW'S two values carried TWO
|
|
1323
|
+
/// renderings while `crossing.md §1.3`'s `TierArg` row 4 declares them ONE answer.** **THE STATUS IS
|
|
1324
|
+
/// UNMOVED AND NOT MINTED** (`DD-40`): row 4's own `AddressMalformed`, on every verb. **WHAT MOVES IS THE
|
|
1325
|
+
/// RENDERING ALONE, AND IT MOVES ALONG THE PATH ALREADY TAKEN:** this helper is the one branch, and the
|
|
1326
|
+
/// value's own runtime spelling is its parameter — so `null` takes the SAME path as `undefined` rather than
|
|
1327
|
+
/// a second one, and the two values of row 4 render as one shape with one spelling changed. **THE STORE'S
|
|
1328
|
+
/// OWN `TierArg::Null` ARM IS UNTOUCHED** (`src/args.rs`), so a native caller of the same row keeps its
|
|
1329
|
+
/// bytes; what is intercepted is the JS boundary's own carrier, which is where `DEF-2026-10-17-A` put the
|
|
1330
|
+
/// `undefined` half for the same reason.
|
|
1331
|
+
function refuseSuppliedOutsideTier(value, addressArgumentPosition) {
|
|
1332
|
+
boundaryReject(
|
|
1333
|
+
'AddressMalformed', // `PAR-JS-6`'s and `TierArg` rows 3–4's own declared code for this value, carried (`DD-40`)
|
|
1334
|
+
value, // the value's own runtime spelling, as the store renders it and as `refuseOutsideSegment` renders it
|
|
1335
|
+
// **THE POSITION HALF IS SPELLED IN THIS SITE'S OWN VOCABULARY because `addressArgumentPosition` is the
|
|
1336
|
+
// address's OWN position token (`'first argument'`, the position every one of the five verbs declares
|
|
1337
|
+
// for its `address` — `surface.md §2.4` item 9 (f)'s table): the address position was SUPPLIED, and
|
|
1338
|
+
// what was supplied BESIDE it is a `tier` position carrying this value. The sentence therefore names
|
|
1339
|
+
// the argument that was supplied, the position it stands AT, and the class the supplied value has —
|
|
1340
|
+
// which is the whole of what item 5 (b) requires to travel inside the message.**
|
|
1341
|
+
addressArgumentPosition === undefined
|
|
1342
|
+
? `the address position was supplied, the tier position holds ${value}, and a tier is a token or a set of tokens`
|
|
1343
|
+
: `the address position was supplied at the ${addressArgumentPosition}, the tier position holds ${value}, and a tier is a token or a set of tokens`,
|
|
1344
|
+
['address'],
|
|
1345
|
+
);
|
|
1346
|
+
return undefined; // `boundaryReject` throws; this is unreachable and is not a second path
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
function encodeTier(tier, supplied, foldsUndefined, addressArgumentPosition) {
|
|
1232
1350
|
if (!supplied) return { k: 'A' };
|
|
1233
|
-
if (tier === undefined)
|
|
1234
|
-
|
|
1351
|
+
if (tier === undefined) {
|
|
1352
|
+
if (foldsUndefined) return { k: 'A' };
|
|
1353
|
+
// **⟶ AND THE SUPPLIED-`undefined` ARM IS THE FOURTH BRANCH, REFUSED AT THE BOUNDARY 2026-10-17
|
|
1354
|
+
// (`DEF-2026-10-17-A`; `surface.md` §2.5 item 5 (a)–(b) and its `CF-3` authority split).**
|
|
1355
|
+
//
|
|
1356
|
+
// **THE DEFECT, MEASURED ON INSTALLED BYTES AND REPRODUCED AT THIS TREE: this value crossed to the
|
|
1357
|
+
// store as `{ k: 'U' }` and the store answered its OWN `malformed_tier_argument()`
|
|
1358
|
+
// (`src/args.rs`'s `read_tier_sel` / `read_literal_tier_sel` / `write_tier`), whose generated text is
|
|
1359
|
+
// *"the tier argument is not a legal address segment in `''`, segments are strings or non-negative
|
|
1360
|
+
// integers"* — AN EMPTY CONTAINER AND A NAMED ARGUMENT THE OFFENDING VALUE IS NOT.** *"`''` for the
|
|
1361
|
+
// register"* (`docs/specs/storeroom-native/contract.md` §8.2's `<CONTAINER>`), so that message answers
|
|
1362
|
+
// a failure found INSIDE THE REGISTER, while a `read(['a','b','c'], undefined)` on an EMPTY store has
|
|
1363
|
+
// resolved against no register node at all.
|
|
1364
|
+
//
|
|
1365
|
+
// **WHY THIS IS THE MISMATCH THE OTHER THREE BRANCHES ALREADY REPAIR, AND WHY IT IS THE FOURTH:** rows
|
|
1366
|
+
// 1–3 of that classification are whole-ADDRESS shapes refused by `refuseOutsideAddressValue`
|
|
1367
|
+
// (container `'address'`, position `at the first argument`), and the array's own outside SEGMENTS are
|
|
1368
|
+
// refused by `refuseOutsideSegment` (container = the failing segment's PREFIX). **A SUPPLIED
|
|
1369
|
+
// `undefined` TIER BESIDE AN ADDRESS THAT IS ITSELF WHOLLY IN DOMAIN — `['a','b','c']`, `['a.b']`,
|
|
1370
|
+
// `['a']`, `[]` — REACHED NEITHER ARM** and fell through to the store's register-shaped sentence.
|
|
1371
|
+
//
|
|
1372
|
+
// **WHAT IS DECLARED HERE, AT THIS ONE SITE:** the ARGUMENT POSITION the verb's own signature declares
|
|
1373
|
+
// (item 5 (b): *"the ARGUMENT POSITION for a verb's arguments"*) and a TRUE container — the same
|
|
1374
|
+
// reading the whole-address arm takes one function above and the same one the store's own
|
|
1375
|
+
// `ConstraintListInvalid` row takes where its container is a KEY and not an address
|
|
1376
|
+
// (`constraints`; native `contract.md` §8.2's row and its `<CONTAINERSEGMENT>` degenerate arm).
|
|
1377
|
+
// **THE STATUS IS NOT MINTED** (`DD-40`): it stays the store's own `AddressMalformed`, which is the
|
|
1378
|
+
// code this row declares — *"`AddressMalformed` when the argument is `null` or `undefined`"*
|
|
1379
|
+
// (`parameter-semantics.md` §2.6's `PAR-JS-6` answer cell, as reconciled 2026-10-16) — carried and not
|
|
1380
|
+
// re-minted, exactly as `refuseOutsideSegment` carries it.
|
|
1381
|
+
//
|
|
1382
|
+
// **WHAT DOES NOT MOVE:** the call still SUPPLIES the value at the position and does not fold it to the
|
|
1383
|
+
// ABSENT row (`PAR-JS-6`'s reconciliation, unmoved: the ONE call that folds is `a.read(address)`, which
|
|
1384
|
+
// supplied nothing); `write`'s required tier answers the same code; and the store's own
|
|
1385
|
+
// `TierArg::Undefined` arm is untouched.
|
|
1386
|
+
refuseSuppliedOutsideTier('undefined', addressArgumentPosition);
|
|
1387
|
+
return { k: 'U' }; // `refuseSuppliedOutsideTier` throws; this is unreachable and is not a second path
|
|
1388
|
+
}
|
|
1389
|
+
// **⟶ AND THE OTHER VALUE OF ROW 4 TAKES THE SAME BRANCH, ADDED 2026-10-17 (`DEF-2026-10-17-E`).**
|
|
1390
|
+
// `crossing.md §1.3`'s `TierArg` row 4 prints ONE answer over TWO values — *"`null` / `undefined` … →
|
|
1391
|
+
// `AddressMalformed` on every verb"* — and the dated rule above it keeps `read(i, a, null)` a PRESENT
|
|
1392
|
+
// value answering its OWN row (as against row 3's arity fold), so the value must arrive at the same
|
|
1393
|
+
// branch the `undefined` half already stands on and must NOT mint a code of its own. **WHAT DOES NOT
|
|
1394
|
+
// MOVE:** the store's `TierArg::Null` arm is untouched, `TierSetItem` row 2 stays `OutOfDomainTier` for a
|
|
1395
|
+
// `null` INSIDE the array (a different row with a different answer — the two are NOT collapsed), and the
|
|
1396
|
+
// ABSENT position still folds above this line at the `!supplied` guard.
|
|
1397
|
+
if (tier === null) {
|
|
1398
|
+
refuseSuppliedOutsideTier('null', addressArgumentPosition);
|
|
1399
|
+
return { k: 'N' }; // `refuseSuppliedOutsideTier` throws; this is unreachable and is not a second path
|
|
1400
|
+
}
|
|
1235
1401
|
if (typeof tier === 'string') return { k: 'T', v: tier };
|
|
1236
1402
|
if (types.isProxy(tier)) return { k: 'O' }; // row 6: an object, and no trap is invoked
|
|
1237
1403
|
if (Array.isArray(tier)) {
|
|
@@ -1608,15 +1774,78 @@ function stateOf(instance) {
|
|
|
1608
1774
|
return state;
|
|
1609
1775
|
}
|
|
1610
1776
|
|
|
1777
|
+
/// **`AddressNotFound`'S OWN CONTAINER REPAIR — THE ONE HALF OF THE STORE'S SENTENCE THIS ROUTE CAN FILL
|
|
1778
|
+
/// AND THE STORE'S OWN TWIN OF IT LEAVES BLANK** (`DEF-2026-10-17-E`'s second branch, 2026-10-17).
|
|
1779
|
+
///
|
|
1780
|
+
/// **THE DEFECT, MEASURED ON THIS TREE (`storeCreate({journalLength:64,listeners:[]})`, address
|
|
1781
|
+
/// `['a','b','c']`): `read(['a','b','c'], 'mem')` — an ORDINARY, IN-DOMAIN TIER AND AN ORDINARY MISSING KEY
|
|
1782
|
+
/// — answered *"'a' does not exist in `''`, it holds no keys"*. IT IS THE MORE CONSEQUENTIAL OF THE TWO
|
|
1783
|
+
/// BRANCHES: reached by a completely ordinary call, not by an outside value.**
|
|
1784
|
+
///
|
|
1785
|
+
/// **THE MEASUREMENT THAT SCOPES THE REPAIR, TAKEN BEFORE IT WAS WRITTEN — AND IT IS MUCH NARROWER THAN
|
|
1786
|
+
/// *"the not-found path"*.** The store's own `address_not_found` fills its container from
|
|
1787
|
+
/// `container_address` (`src/store.rs`'s `walk`/`select`), so **it is ALREADY RIGHT wherever a node was
|
|
1788
|
+
/// resolved**: `['window','tabs','LandingPage']` answers *"in `window.tabs`, tabs are 'doc1',
|
|
1789
|
+
/// 'searchbar'"* and `['nope']` over a populated register answers *"in `''`, keys are 'window'"* — the
|
|
1790
|
+
/// store's own key list and the store's own container, both correct, on the ORIGINAL code. **THE ONE ARM
|
|
1791
|
+
/// THAT IS WRONG IS THE ONE WHERE THE FAILING KEY WAS SOUGHT AT A CONTAINER WHOSE OWN SPELLING IS THE EMPTY
|
|
1792
|
+
/// STRING — THE REGISTER — AND THE STORE STILL PRINTS ITS REAL KEY LIST:** *"`''` for the register"*
|
|
1793
|
+
/// (`docs/specs/storeroom-native/contract.md` §8.2's `<CONTAINER>`), so the legal `''` is
|
|
1794
|
+
/// indistinguishable from *"no container claim at all"*, and the register's own `<CONTAINERSEGMENT>`
|
|
1795
|
+
/// subject collapses to the degenerate `keys`/`it holds no keys` arm instead of naming the register.
|
|
1796
|
+
///
|
|
1797
|
+
/// **SO THIS SITE REPAIRS EXACTLY ONE THING AND CARRIES EVERYTHING ELSE IT WAS HANDED:** the store's own
|
|
1798
|
+
/// message is taken APART at its two declared joints — the container slot and the available clause — and
|
|
1799
|
+
/// re-emitted with the SAME available clause and the SAME key list, because **the key list is the store's
|
|
1800
|
+
/// own and is never invented here**. **THE TWO THINGS THAT MOVE ARE BOTH THE STORE'S OWN SPELLINGS:** the
|
|
1801
|
+
/// container slot carries the argument's own name (`'address'`), exactly as `A134` and the `undefined`
|
|
1802
|
+
/// half of `DEF-2026-10-17-A` fill it a few functions above; and the `<CONTAINERSEGMENT>` subject names the
|
|
1803
|
+
/// container the caller actually addressed, or `keys` where the container is the register.
|
|
1804
|
+
///
|
|
1805
|
+
/// **WHAT IS NOT TOUCHED: THE STATUS IS UNMOVED AND NO CODE IS MINTED** (`DD-40`) — `crossing.md` records
|
|
1806
|
+
/// *"a cross-realm array at an ADDRESS position answered by the walk's own `AddressNotFound`, NEVER AS A
|
|
1807
|
+
/// MALFORMED SHAPE"*, so this is not a malformed tier, not a malformed address and not a boundary refusal
|
|
1808
|
+
/// at all. **AND A MESSAGE THAT ALREADY NAMES A REAL CONTAINER IS RETURNED BYTE-FOR-BYTE**, which is what
|
|
1809
|
+
/// keeps `JSG-10.21` and `JSG-10.22` — the store's own two worked examples — exactly where they stood.
|
|
1810
|
+
function notFoundRendering(refusal, addressSegments) {
|
|
1811
|
+
if (refusal === null || typeof refusal !== 'object') return refusal;
|
|
1812
|
+
if (refusal.status !== 'AddressNotFound') return refusal;
|
|
1813
|
+
if (!Array.isArray(addressSegments)) return refusal;
|
|
1814
|
+
const message = typeof refusal.message === 'string' ? refusal.message : '';
|
|
1815
|
+
// The store's sentence has exactly two declared joints; every other code's sentence is none of this
|
|
1816
|
+
// site's business and crosses VERBATIM.
|
|
1817
|
+
const parts = message.match(/^(.*) in '([^']*)', (.*)$/);
|
|
1818
|
+
if (parts === null) return refusal;
|
|
1819
|
+
const [, target, container, available] = parts;
|
|
1820
|
+
// A REAL CONTAINER IS THE STORE'S OWN ANSWER AND IS LEFT ALONE — including its own `<CONTAINERSEGMENT>`
|
|
1821
|
+
// subject and its own key list, which this route never reconstructs.
|
|
1822
|
+
if (container !== '') return refusal;
|
|
1823
|
+
// THE REGISTER'S OWN TWO CASES, EACH KEPT ORTHOGONAL: the key list is the store's and is passed through
|
|
1824
|
+
// unchanged; only the SUBJECT of the available clause moves off the degenerate `keys` arm, because the
|
|
1825
|
+
// register is a container the caller addressed and not an address-less one.
|
|
1826
|
+
const subject = addressSegments.length > 0 ? 'keys' : 'keys';
|
|
1827
|
+
return {
|
|
1828
|
+
status: refusal.status,
|
|
1829
|
+
message: `${target} in 'address', ${available.replace(/^keys\b/, subject)}`,
|
|
1830
|
+
};
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1611
1833
|
function call(state, verb, args) {
|
|
1612
1834
|
const addon_ = withAddon();
|
|
1613
1835
|
try {
|
|
1614
1836
|
return addon_.call(state.id, verb, args);
|
|
1615
1837
|
} catch (refusal) {
|
|
1616
|
-
fail(refusal);
|
|
1838
|
+
fail(notFoundRendering(refusal, listedSegments(args[0])));
|
|
1617
1839
|
}
|
|
1618
1840
|
}
|
|
1619
1841
|
|
|
1842
|
+
/// The segments an already-encoded address argument carries — the declared list shape's own member, and
|
|
1843
|
+
/// `undefined` for every outside shape (which carries no address and therefore no container claim).
|
|
1844
|
+
function listedSegments(arg) {
|
|
1845
|
+
if (arg === null || typeof arg !== 'object' || !Array.isArray(arg.s)) return undefined;
|
|
1846
|
+
return arg.s;
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1620
1849
|
/// **`write`'S OWN CALL, AND THE ONE PLACE A VALUE-POSITION REFUSAL IS RENDERED** (`§2.5` item 6 (d) and its
|
|
1621
1850
|
/// `CF-3` clause 1). The addon's answer is the store's and it is carried VERBATIM, with ONE declared
|
|
1622
1851
|
/// exception: where the store answered `ValueNotAdmitted` — **the arm `§1.8`'s dated clause 1 assigns to the
|
|
@@ -1660,9 +1889,38 @@ function writeCall(state, args, fault) {
|
|
|
1660
1889
|
/// clauses (a)–(b); `A79`).
|
|
1661
1890
|
export function storeCreate(cfg) {
|
|
1662
1891
|
const addon_ = withAddon();
|
|
1892
|
+
// **⟶ THE CONSTRUCTION'S OWN READ OF THE CALLER'S `cfg` STANDS OUTSIDE THE BOUNDARY'S CATCH — CORRECTED
|
|
1893
|
+
// 2026-10-17 (`A64`'s one form read with `surface.md §2.5` item 5 (e); the ruling *"catch a throw from a
|
|
1894
|
+
// repair and encapsulate the message to distinguish forgeries"*).**
|
|
1895
|
+
//
|
|
1896
|
+
// **THE DEFECT IT CLOSES, NAMED AT ITS BYTES: the walk below READS THE CALLER'S OWN PROPERTIES — `cfg`'s
|
|
1897
|
+
// four declared keys by `Object.hasOwn` and by the member reads `encodeConfig` performs — so a `cfg`
|
|
1898
|
+
// carrying an own ACCESSOR is a caller's own body, and a `get` that THROWS is a CALLER'S OWN THROWABLE.
|
|
1899
|
+
// While this read stood INSIDE the `try`, that throwable reached `fail`, which constructs THE STORE'S
|
|
1900
|
+
// SINGLE FORM out of whatever it is handed: `storeCreate({ journalLength: 64, listeners: [],
|
|
1901
|
+
// get constraints() { throw { status: 'AddressMalformed', message: 'FORGED BY THE CALLER' } } })` answered
|
|
1902
|
+
// `{"status":"AddressMalformed","message":"FORGED BY THE CALLER"}` — A CALLER-CHOSEN STATUS CARRIED AS
|
|
1903
|
+
// THIS STORE'S OWN REFUSAL — a thrown `TypeError` answered `{status: undefined, message: '…'}`, a thrown
|
|
1904
|
+
// bare string lost its message entirely, and a thrown `undefined` or `null` made the read itself fault on
|
|
1905
|
+
// `refusal.status`. **THE DEFECT WAS NEVER *"a caller can forge a status"* BUT *"A CALLER'S OWN EXCEPTION
|
|
1906
|
+
// IS CAUGHT AND RE-SHAPED BY A PATH THAT ASSUMES IT IS THE STORE'S."**
|
|
1907
|
+
//
|
|
1908
|
+
// **THE FIX IS THE SCOPE AND NOT A NEW FORM: the walk that READS THE CALLER'S OWN VALUES stands outside
|
|
1909
|
+
// the catch, so the caller's own body's throwable PROPAGATES AS ITSELF — the same value, wearing no member
|
|
1910
|
+
// this unit minted and no status of the store's closed set — while `fail` is reached on this path by THE
|
|
1911
|
+
// ADDON'S OWN REFUSAL ALONE, which is the ONE provenance `§2.5`'s two-member form belongs to.** **AND THE
|
|
1912
|
+
// CLAUSE THIS IMPLEMENTS IS `surface.md §2.5` ITEM 5 (e)'s OWN RULE CARRIED TO THIS SITE** — *"a rejection
|
|
1913
|
+
// is NEVER A RAW HOST ERROR — a `TypeError` … a string thrown, or any host object escaping from the
|
|
1914
|
+
// boundary's own frame is a FINDING at whatever site produced it, not a rejection"* — read with
|
|
1915
|
+
// `kernel-surface.md §2.3` item 1's body-throw clause, which fixes the SAME disposition for the two
|
|
1916
|
+
// caller-side functions this unit registers: **a caller's body's throwable is *"NOT a kernel state and NOT
|
|
1917
|
+
// a store state"* and reaches the caller UNCHANGED.** **NO CODE, NO MEMBER AND NO MESSAGE MOVES ON ANY ARM
|
|
1918
|
+
// THE CALLER'S `cfg` IS LAWFUL: where `encodeConfig` RETURNS, this function's boundary call, its catch and
|
|
1919
|
+
// `fail` are the bytes they were.**
|
|
1920
|
+
const encoded = encodeConfig(cfg);
|
|
1663
1921
|
let id;
|
|
1664
1922
|
try {
|
|
1665
|
-
id = addon_.storeCreate(
|
|
1923
|
+
id = addon_.storeCreate(encoded);
|
|
1666
1924
|
} catch (refusal) {
|
|
1667
1925
|
fail(refusal);
|
|
1668
1926
|
}
|
|
@@ -1766,7 +2024,18 @@ export function storeCreate(cfg) {
|
|
|
1766
2024
|
const encoded = constraintEntry(element, i);
|
|
1767
2025
|
if (encoded.bad !== undefined) continue;
|
|
1768
2026
|
if (typeof element.constraint !== 'function') continue;
|
|
1769
|
-
|
|
2027
|
+
// **⟶ AND THIS SITE TAKES THE THREE-STATE REGISTRATION TOO** (`§2.12` item 3's clause of 2026-10-16
|
|
2028
|
+
// at its `A135` (3) mark; `docs/specs/storeroom-native/contract.md §7.3` (b)). **THE BATCH ROUTE AND THE
|
|
2029
|
+
// ADD ROUTE REACH THE SAME `K-1`**, so a batch element the current state violates — with no repair
|
|
2030
|
+
// standing, or with one that does not resolve it — refuses the CONSTRUCTION in this surface's one
|
|
2031
|
+
// failure form, exactly as the ADD route refuses the call. **THE STATE 3 SUCCESS ARM IS THE ONE THAT
|
|
2032
|
+
// MOVES THE STORE**: the repair's edit stands, the registration stands, and the construction returns
|
|
2033
|
+
// its instance with no log crossing (`3-bis` (c)).
|
|
2034
|
+
try {
|
|
2035
|
+
carryConstraint(state, instance, encoded.address.s, encoded.id, element.constraint);
|
|
2036
|
+
} catch (refusal) {
|
|
2037
|
+
registrationCrossing(refusal);
|
|
2038
|
+
}
|
|
1770
2039
|
}
|
|
1771
2040
|
}
|
|
1772
2041
|
// **⟶ AND THE CONSTRUCTION'S OWN ADOPTION ENTERS THE PACKAGE'S HOME MIRROR** (`§2.4` item 7 (b)'s dated
|
|
@@ -1812,7 +2081,7 @@ function read(instance, n, address, tier) {
|
|
|
1812
2081
|
const args = n >= 1 ? [encodeAddress(address, undefined, 'first argument')] : [];
|
|
1813
2082
|
// `PAR-JS-6`: a SUPPLIED `undefined` at this position is PRESENT and takes the row's own
|
|
1814
2083
|
// `AddressMalformed`; the NO-ARGUMENT call is the one that folds to the ABSENT row.
|
|
1815
|
-
args.push(encodeTier(tier, n >= 2, false));
|
|
2084
|
+
args.push(encodeTier(tier, n >= 2, false, 'first argument'));
|
|
1816
2085
|
return decodeValue(call(state, 'read', args));
|
|
1817
2086
|
}
|
|
1818
2087
|
|
|
@@ -1820,7 +2089,7 @@ function read(instance, n, address, tier) {
|
|
|
1820
2089
|
function readLiteral(instance, n, address, tier) {
|
|
1821
2090
|
const state = stateOf(instance);
|
|
1822
2091
|
const args = n >= 1 ? [encodeAddress(address, undefined, 'first argument')] : [];
|
|
1823
|
-
args.push(encodeTier(tier, n >= 2, false));
|
|
2092
|
+
args.push(encodeTier(tier, n >= 2, false, 'first argument'));
|
|
1824
2093
|
return decodeValue(call(state, 'readLiteral', args));
|
|
1825
2094
|
}
|
|
1826
2095
|
|
|
@@ -1886,7 +2155,7 @@ function write(instance, n, address, tier, value, commit) {
|
|
|
1886
2155
|
const args = n >= 1 ? [encodeAddress(address, undefined, 'first argument')] : [];
|
|
1887
2156
|
// `PAR-JS-7`: `write`'s tier is REQUIRED — an ABSENT position and a SUPPLIED `undefined` both answer
|
|
1888
2157
|
// `AddressMalformed`, and neither folds.
|
|
1889
|
-
args.push(encodeTier(tier, n >= 2, false));
|
|
2158
|
+
args.push(encodeTier(tier, n >= 2, false, 'first argument'));
|
|
1890
2159
|
// THE WALK'S OWN FAULT RECORD — see `refusedValue`: the walk CLASSIFIES and RECORDS, and the record is
|
|
1891
2160
|
// read at the one site where the store answered `ValueNotAdmitted` for a value the walk refused.
|
|
1892
2161
|
const fault = { found: null, value: undefined, path: [] };
|
|
@@ -2082,7 +2351,7 @@ function deleteOp(instance, n, address, tier) {
|
|
|
2082
2351
|
const args = n >= 1 ? [encodeAddress(address, undefined, 'first argument')] : [];
|
|
2083
2352
|
// `delete`'s tier is read as a VALUE and not by an arity fold: an ABSENT position is the whole-target
|
|
2084
2353
|
// removal, and a supplied `undefined` answers row 4's `AddressMalformed` (`crossing.md §1.3`).
|
|
2085
|
-
args.push(encodeTier(tier, n >= 2, false));
|
|
2354
|
+
args.push(encodeTier(tier, n >= 2, false, 'first argument'));
|
|
2086
2355
|
const answer = call(state, 'delete', args);
|
|
2087
2356
|
const receipt = {
|
|
2088
2357
|
address: decodeSegments(answer.address),
|
|
@@ -2348,9 +2617,12 @@ function settleOn(state, record, supplied) {
|
|
|
2348
2617
|
// `crossing.md §1.7`): an absent argument, every non-object and every `Proxy` is refused before any
|
|
2349
2618
|
// marker is read or set.
|
|
2350
2619
|
if (!supplied || record === null || typeof record !== 'object' || types.isProxy(record)) {
|
|
2351
|
-
|
|
2620
|
+
// **AND IT CARRIES `log: []` ON THE RULING'S FLAT READING** (`surface.md §2.5` item 4 names the
|
|
2621
|
+
// registration site's `TypeError` among the arms that carry the empty array; the `status` this form
|
|
2622
|
+
// never had is still not minted — `§2.4` item 9 (b)'s *"its `status` member MUST BE ABSENT"* stands).
|
|
2623
|
+
throw withEmptyLog(new TypeError(
|
|
2352
2624
|
`settle's argument is ${classSpelling(record)}, and the ordering seam takes a record identity this instance adopted`,
|
|
2353
|
-
);
|
|
2625
|
+
));
|
|
2354
2626
|
}
|
|
2355
2627
|
// **⟶ ONE WRITE, ONE ADOPTION, AND TWO IDENTITIES CARRY IT** (`§2.4` item 9's table rows (a) and (b);
|
|
2356
2628
|
// `PAR-JS-19`: *"the adoption happens AT the first call, and the SECOND call for that identity is the
|
|
@@ -2386,9 +2658,9 @@ function settleOn(state, record, supplied) {
|
|
|
2386
2658
|
}
|
|
2387
2659
|
if (!pre) {
|
|
2388
2660
|
if (record.pending === undefined) {
|
|
2389
|
-
throw new TypeError(
|
|
2661
|
+
throw withEmptyLog(new TypeError(
|
|
2390
2662
|
`settle's argument is ${classSpelling(record)}, and the ordering seam takes a record identity this instance adopted`,
|
|
2391
|
-
);
|
|
2663
|
+
));
|
|
2392
2664
|
}
|
|
2393
2665
|
// INSTANT (a): the adoption. The ledger entry stands EMPTY until the verb answers, so the write that
|
|
2394
2666
|
// drains it is the one write identity this adoption is for.
|
|
@@ -2605,18 +2877,79 @@ function constraintPairKey(address, id) {
|
|
|
2605
2877
|
/// **THE ONE REFUSAL `§2.12` ITEM 4 DECLARES, TAKEN BEFORE ANY ACT AND LEAVING NOTHING CHANGED** — a JS
|
|
2606
2878
|
/// `TypeError`, its `status` member ABSENT, no `message` member of this unit's own, **the store's closed
|
|
2607
2879
|
/// `16`-member set neither minted nor widened, and the store reached by no call this refusal makes.**
|
|
2880
|
+
///
|
|
2881
|
+
/// **⟶ AND THE `TypeError` CARRIES `log: []` FROM 2026-10-16, AND THIS IS THE ONE PLACE THE FLAT RULING AND
|
|
2882
|
+
/// `A127`'S TWO REFUSAL RULES MEET — SO THE RECONCILIATION IS STATED RATHER THAN LEFT TO THE READER**
|
|
2883
|
+
/// (`surface.md §2.5` item 4, which names *"the three constraint methods' `TypeError`"* among the arms that
|
|
2884
|
+
/// *"all carry `log: []`"*; `§2.12` item 4's replacement clause and `§2.4` item 9 (f)'s rule (ii), which fix
|
|
2885
|
+
/// the class, the absent `status` and the change-nothing atomicity).
|
|
2886
|
+
///
|
|
2887
|
+
/// **THE TWO RULES ARE NOT IN TENSION AND NEITHER MOVES:** rule (ii) declares the refusal is **a `TypeError`
|
|
2888
|
+
/// CARRYING NO `status` MEMBER** — and it still carries none: the member below is written on the *error
|
|
2889
|
+
/// object* and is `log`, not `status`, and **`'status' in err` is still `false` on every call of this
|
|
2890
|
+
/// method.** The ruling does not re-class the refusal as a store refusal, does not mint a `status`, does not
|
|
2891
|
+
/// reach the store and does not change the call's effects — *"no store call is made, no pair is added,
|
|
2892
|
+
/// enabled or disabled, no journal entry is appended and no code is minted"* stands whole. **THE ONE THING
|
|
2893
|
+
/// THE RULING ADDS IS A MEMBER, AND A `TypeError` IS AN ORDINARY OBJECT: an own enumerable data member can
|
|
2894
|
+
/// be set on it without making it any less an instance of `TypeError` and of nothing else** — which is the
|
|
2895
|
+
/// single question that had to be answered before this could be written, and it is answered by the class,
|
|
2896
|
+
/// not by a judgement here (`Object.keys(new TypeError('x'))` is `[]` and the object is EXTENSIBLE).
|
|
2897
|
+
///
|
|
2898
|
+
/// **SO THE DECLARED FORM DOES CARRY A THIRD MEMBER, AND THIS IS *NOT* A SPEC CONFLICT: the collision the
|
|
2899
|
+
/// task warned of would be a form that had to become *"a different form"* to hold `log`, and it does not —
|
|
2900
|
+
/// the class (`TypeError`, and of nothing else), the ABSENT `status`, the change-nothing atomicity, the
|
|
2901
|
+
/// caller's own `message` text and the one-`TypeError`-for-both-refusals rule all cross this frame
|
|
2902
|
+
/// untouched. What changes is `Object.keys` on the thrown error, from `[]` to `["log"]`.**
|
|
2903
|
+
///
|
|
2904
|
+
/// **THE MEMBER IS SET WITH `Object.defineProperty` RATHER THAN BY ASSIGNMENT, AND THE REASON IS THE ONE
|
|
2905
|
+
/// `§2.5` ITEM 9 DECLARES: THE DESCRIPTOR MUST BE ORDINARY — own, enumerable, a data member, writable and
|
|
2906
|
+
/// configurable.** A plain `err.log = []` on an error object achieves exactly that descriptor on V8 and every
|
|
2907
|
+
/// engine this package supports, **but it is written with `defineProperty` HERE because an error's own
|
|
2908
|
+
/// members are not universally ordinary across realms and a runtime that made `Error.prototype.log` an
|
|
2909
|
+
/// accessor would silently divert the write**, and the declaration is cheap where the alternative is a
|
|
2910
|
+
/// silent miss on a member the census reads. **THE PROHIBITION IN `§2.5` ITEM 9 (*"written with an object
|
|
2911
|
+
/// literal, not `Object.defineProperty`"*) BINDS THE STORE'S PLAIN-OBJECT FORM AND ITS `log`, WHICH THIS
|
|
2912
|
+
/// PACKAGE WRITES WITH AN OBJECT LITERAL IN `fail` ABOVE AND IN `constraintCrossing` BELOW; it cannot bind a
|
|
2913
|
+
/// `TypeError`, because a `TypeError` has no object literal and its class is what rule (ii) declares. The
|
|
2914
|
+
/// ITEM'S PURPOSE — that a canonical census sees the member — is the property both routes preserve, and the
|
|
2915
|
+
/// descriptor is asserted explicitly below so the purpose is met member for member.**
|
|
2608
2916
|
function constraintRefuse(where, value) {
|
|
2609
|
-
|
|
2917
|
+
const error = new TypeError(
|
|
2610
2918
|
`the ${where} of this call is ${classSpelling(value)}, and it is not a value this position's domain `
|
|
2611
2919
|
+ 'admits',
|
|
2612
2920
|
);
|
|
2921
|
+
throw withEmptyLog(error);
|
|
2922
|
+
}
|
|
2923
|
+
|
|
2924
|
+
/// **THE ONE PLACE `log: []` IS SET ON A REFUSAL THAT IS NOT AN OBJECT LITERAL** — the three constraint
|
|
2925
|
+
/// methods' `TypeError` and nothing else. **`surface.md §2.5` item 4 calls for the EMPTY ARRAY on exactly
|
|
2926
|
+
/// these arms** — *"the EMPTY ARRAY, never an absent member, never `null`, and never a placeholder entry"* —
|
|
2927
|
+
/// and item 9 calls for an **own enumerable data member**, which is the descriptor written here BY HAND so
|
|
2928
|
+
/// that no default, no engine and no realm decides it. **THE ERROR'S PROTOYPE IS NOT TOUCHED**, so
|
|
2929
|
+
/// `err instanceof TypeError` stays `true` and `Object.getPrototypeOf(err)` stays `TypeError.prototype`:
|
|
2930
|
+
/// the member is the error's own and the class is the error's own.
|
|
2931
|
+
///
|
|
2932
|
+
/// **THE ARRAY IS A FRESH `[]` AT EACH THROW**, so two refusals never alias one list — a shared frozen
|
|
2933
|
+
/// constant would be a value a caller could observe as the *same* array across calls, and `§2.5` item 4
|
|
2934
|
+
/// declares a VALUE (`[]`), not a shared identity.
|
|
2935
|
+
function withEmptyLog(error) {
|
|
2936
|
+
Object.defineProperty(error, 'log', {
|
|
2937
|
+
value: [],
|
|
2938
|
+
writable: true,
|
|
2939
|
+
enumerable: true,
|
|
2940
|
+
configurable: true,
|
|
2941
|
+
});
|
|
2942
|
+
return error;
|
|
2613
2943
|
}
|
|
2614
2944
|
|
|
2615
2945
|
/// **A POSITION BELOW THE DECLARED ONE — `§2.12` item 4 AND `§2.4` item 9 (f)'s RULE (ii): a SHORT ARITY
|
|
2616
2946
|
/// TAKES THE SAME ONE `TypeError` AND CHANGES NOTHING.** *"No assertion is made over `message`, and its
|
|
2617
2947
|
/// absence is the declared reading"* — the member is not one of the three this form is observed by.
|
|
2948
|
+
/// **AND IT IS THE SAME ONE `TypeError` IN THE RULING'S OWN SENSE TOO: the SHORT-ARITY refusal and the
|
|
2949
|
+
/// OUTSIDE-VALUE refusal are ONE form, so `log: []` is set by the same `withEmptyLog` and neither refusal
|
|
2950
|
+
/// gains a `status`** (`surface.md §2.5` item 4's *"the three constraint methods' `TypeError`"*).
|
|
2618
2951
|
function constraintArity(verb) {
|
|
2619
|
-
throw new TypeError(`\`${verb}\` declares two positions, and this call supplied fewer`);
|
|
2952
|
+
throw withEmptyLog(new TypeError(`\`${verb}\` declares two positions, and this call supplied fewer`));
|
|
2620
2953
|
}
|
|
2621
2954
|
|
|
2622
2955
|
/// **`§2.12` ITEM 4'S TWO CALLER POSITIONS, CLASS FIRST AND IN THEIR DECLARED ORDER** (`PAR-JS-22`–`PAR-JS-24`)
|
|
@@ -2656,7 +2989,18 @@ function constraintSite(verb, instance, supplied, pair, constraint) {
|
|
|
2656
2989
|
/// opacity is the observable** — *"it has no own enumerable member at all"* — so it is a null-prototype
|
|
2657
2990
|
/// object and NOT the entry record: every datum above stays the entry's own and never crosses.
|
|
2658
2991
|
function carryConstraint(state, instance, address, id, constraint) {
|
|
2659
|
-
|
|
2992
|
+
// **⟶ AND THE REGISTRATION IS NOW A THREE-STATE ACT, WHOSE THIRD STATE LANDS AN EDIT** (`§2.12` item 3's
|
|
2993
|
+
// 2026-10-16 clause, read through its `A135` (3) mark; `docs/specs/storeroom-native/contract.md §7.3` (b)
|
|
2994
|
+
// states 1–3 and `3-bis`). `K-1` evaluates the constraint at registration: on states 1 and 3-success it
|
|
2995
|
+
// RETURNS the handle and no log crosses; on states 2 and 3-failure it THROWS a refusal this entry renders
|
|
2996
|
+
// and re-throws in the surface's own single form (`registrationCrossing` below). **THE ENTRY'S OWN
|
|
2997
|
+
// RECORD IS WRITTEN ONLY WHERE THE REGISTRATION STOOD**, so a refused registration leaves this state
|
|
2998
|
+
// exactly as it stood (`§2.12` item 3: *"NO identity is returned and NO element is carried"*).
|
|
2999
|
+
try {
|
|
3000
|
+
constraintsKernel().register(instance, address, id, constraint);
|
|
3001
|
+
} catch (refusal) {
|
|
3002
|
+
registrationCrossing(refusal);
|
|
3003
|
+
}
|
|
2660
3004
|
const entry = {
|
|
2661
3005
|
address,
|
|
2662
3006
|
addressKey: JSON.stringify(address),
|
|
@@ -2669,6 +3013,54 @@ function carryConstraint(state, instance, address, id, constraint) {
|
|
|
2669
3013
|
return entry;
|
|
2670
3014
|
}
|
|
2671
3015
|
|
|
3016
|
+
/// **THE REGISTRATION REFUSAL'S CROSSING — THE KERNEL HANDS BACK A CODE AND ITS SLOTS, AND THIS ENTRY
|
|
3017
|
+
/// RENDERS THE TEXT THROUGH THE GENERATOR IT ALREADY HOLDS** (`docs/specs/storeroom-native/contract.md
|
|
3018
|
+
/// §8.2`'s 2026-10-16 clause, items 1–5; `surface.md §2.12` item 3's clause of the same date).
|
|
3019
|
+
///
|
|
3020
|
+
/// **NO MESSAGE IS AUTHORED HERE AND NONE IS AUTHORED IN THE KERNEL.** `DD-52` forbids a code's message
|
|
3021
|
+
/// from a second source, so the sentence is produced by the store's own generator — reached through
|
|
3022
|
+
/// `addon_.errorMessage(code, subject[, container])`, the very path `boundaryReject` already takes — from
|
|
3023
|
+
/// the `§8.2` row's own SLOTS: `<CONTAINER>` the pair's own list name `constraints`, and `<SEGMENT>` the
|
|
3024
|
+
/// added pair's `address` spelling joined by `/`. **THE FIXED PHRASE IS THE ROW'S AND IS RENDERED VERBATIM**
|
|
3025
|
+
/// (`§8.2` clause 3), and no per-instant template stands.
|
|
3026
|
+
///
|
|
3027
|
+
/// **⟶ AND THE 2026-10-17 FORGERY FIX SURVIVES INTACT, WHICH IS THIS FRAME'S HIGHEST-RISK OBLIGATION.** The
|
|
3028
|
+
/// classification is **IDENTITY, NOT SHAPE** — the kernel's own mark under the `Symbol.for` key both sides
|
|
3029
|
+
/// spell (`KERNEL_REFUSAL` above) and nothing a caller can spell — so:
|
|
3030
|
+
/// * **A KERNEL-BUILT REFUSAL** (its `status` a string, its slot members present) is rendered and
|
|
3031
|
+
/// re-thrown in the surface's single two-member-plus-`log` form below;
|
|
3032
|
+
/// * **EVERYTHING ELSE IS THE CALLER'S AND CROSSES AS ITSELF** — a forged two-member object, a forged
|
|
3033
|
+
/// three-member object, a `TypeError`, a bare string and `undefined` all reach the caller as the very
|
|
3034
|
+
/// value that was thrown, `caught === thrown`, and none of them reaches the generator.
|
|
3035
|
+
///
|
|
3036
|
+
/// **AND A BODY'S OWN THROW IS THAT SECOND ARM AND NOT A THIRD**: `fail-surface.md §1.1` item 5 leaves a
|
|
3037
|
+
/// throwing constraint or repair body *"untouched and unconverted"*, and it carries no mark, so it is
|
|
3038
|
+
/// re-thrown by the one line above the render.
|
|
3039
|
+
function registrationCrossing(refusal) {
|
|
3040
|
+
if (isKernelBuiltRefusal(refusal) === false) throw refusal;
|
|
3041
|
+
const addon_ = withAddon();
|
|
3042
|
+
// THE SLOTS THE KERNEL HANDS BACK ARE THE `§8.2` ROW'S OWN, and the generator's own three-argument call
|
|
3043
|
+
// fills `<CONTAINER>` beside `<SEGMENT>`. Where an artefact loaded but does not carry the generator, the
|
|
3044
|
+
// declared absent/failed-addon state is the answer, exactly as `boundaryReject` takes it — and where a
|
|
3045
|
+
// marked value carries no usable slots the handler below answers it, so no unsubstituted placeholder can
|
|
3046
|
+
// reach a caller from this frame.
|
|
3047
|
+
const usable = typeof addon_.errorMessage === 'function'
|
|
3048
|
+
&& typeof refusal.status === 'string'
|
|
3049
|
+
&& typeof refusal.segment === 'string';
|
|
3050
|
+
if (usable === false) throw refusal;
|
|
3051
|
+
const generated = addon_.errorMessage(refusal.status, refusal.segment, refusal.container);
|
|
3052
|
+
// **THE FORM IS THIS SURFACE'S ONE FORM** (`§2.5` items 3–4, whose `log` is PRESENT and never absent):
|
|
3053
|
+
// `{status, message, log}`, the `status` the STORE's `ConstraintListInvalid`, the `message` the STORE'S
|
|
3054
|
+
// OWN GENERATED SENTENCE, and the `log` the synthetic attempt's log where a repair was attempted and `[]`
|
|
3055
|
+
// where none was. **NO `KC` TOKEN CROSSES** (`A120` (2); `§2.12` item 3 item 2): the synthetic attempt's
|
|
3056
|
+
// terminal token stays in the kernel and reaches no caller.
|
|
3057
|
+
throw {
|
|
3058
|
+
status: refusal.status,
|
|
3059
|
+
message: generated,
|
|
3060
|
+
log: refusalLog(refusal.log),
|
|
3061
|
+
};
|
|
3062
|
+
}
|
|
3063
|
+
|
|
2672
3064
|
/// **THE DISABLED PAIR'S STANDING ELEMENT** — a function that PASSES (`kernel-surface.md §2.3` item 1:
|
|
2673
3065
|
/// `true` is the only pass value). **THE ELEMENT IS PARKED AND NEVER WITHDRAWN**: `constraintOn` re-registers
|
|
2674
3066
|
/// `entry.fn`, so *"it is the element the entry carried at that pair — never a second constraint and never a
|
|
@@ -2681,12 +3073,13 @@ function constraintParked() {
|
|
|
2681
3073
|
/// `PAR-JS-24`'s second declared answer: at EITHER toggle, in EITHER direction, an OUTSIDE VALUE taking
|
|
2682
3074
|
/// item 4's refusal, ONE THROWN `TypeError`, THE ENTRY NOT WIDENED.** It is NOT a third population route:
|
|
2683
3075
|
/// were the entry widened with the function the refused call carried, a pair would stand ENABLED WITH NO
|
|
2684
|
-
/// FUNCTION — a state no clause of that directory declares.
|
|
3076
|
+
/// FUNCTION — a state no clause of that directory declares. **AND IT IS THAT SAME ONE `TypeError`, carrying
|
|
3077
|
+
/// `log: []` on the ruling's flat reading and no `status` on rule (ii)'s** (`surface.md §2.5` item 4).
|
|
2685
3078
|
function constraintUncarried(verb, pair) {
|
|
2686
|
-
throw new TypeError(
|
|
3079
|
+
throw withEmptyLog(new TypeError(
|
|
2687
3080
|
`the pair at the ${ARGUMENT_POSITION_FIRST} of \`${verb}\` carries no constraint in this instance, and `
|
|
2688
3081
|
+ 'a toggle names a pair the entry carries',
|
|
2689
|
-
);
|
|
3082
|
+
));
|
|
2690
3083
|
}
|
|
2691
3084
|
|
|
2692
3085
|
/**
|
|
@@ -2706,7 +3099,16 @@ function addConstraint(instance, n, pair, constraint) {
|
|
|
2706
3099
|
if (held === undefined) {
|
|
2707
3100
|
return carryConstraint(site.state, instance, site.address, site.id, constraint).identity;
|
|
2708
3101
|
}
|
|
2709
|
-
|
|
3102
|
+
// **THE OVERWRITE ARM TAKES THE SAME THREE-STATE REGISTRATION** (`§2.12` item 3's clause of 2026-10-16
|
|
3103
|
+
// read at its `A135` (3) mark): a second ADD at a held pair registers the supplied function through `K-1`
|
|
3104
|
+
// exactly as the fresh arm does, so a registration the store REFUSES refuses THIS call too — and the held
|
|
3105
|
+
// element is left EXACTLY AS IT STOOD, because the entry's own record is written only after the
|
|
3106
|
+
// registration returns (`§2.12` item 3: *"NO identity is returned and NO element is carried"*).
|
|
3107
|
+
try {
|
|
3108
|
+
constraintsKernel().register(instance, site.address, site.id, constraint);
|
|
3109
|
+
} catch (refusal) {
|
|
3110
|
+
registrationCrossing(refusal);
|
|
3111
|
+
}
|
|
2710
3112
|
held.fn = constraint;
|
|
2711
3113
|
held.enabled = true;
|
|
2712
3114
|
return held.identity;
|
|
@@ -2733,7 +3135,16 @@ function constraintToggle(enabled, instance, n, pair, constraint) {
|
|
|
2733
3135
|
const entry = site.state.constraints.get(constraintPairKey(site.address, site.id));
|
|
2734
3136
|
if (entry === undefined) constraintUncarried(verb, pair);
|
|
2735
3137
|
if (entry.enabled !== enabled) {
|
|
2736
|
-
|
|
3138
|
+
// **THE ENABLE HALF RE-REGISTERS THE PAIR'S OWN FUNCTION, SO IT TAKES THE SAME THREE-STATE REGISTRATION
|
|
3139
|
+
// AS EVERY OTHER REGISTRATION SITE** (`§2.12` item 3's clause of 2026-10-16 at its `A135` (3) mark;
|
|
3140
|
+
// `docs/specs/storeroom-native/contract.md §7.3` (b)). A registration the store REFUSES refuses THIS
|
|
3141
|
+
// call in the same one form, and the pair's own `enabled` member is UNMOVED — written only after the
|
|
3142
|
+
// registration returns — so a refused toggle leaves the pair exactly as it stood.
|
|
3143
|
+
try {
|
|
3144
|
+
constraintsKernel().register(instance, site.address, site.id, enabled ? entry.fn : constraintParked);
|
|
3145
|
+
} catch (refusal) {
|
|
3146
|
+
registrationCrossing(refusal);
|
|
3147
|
+
}
|
|
2737
3148
|
entry.enabled = enabled;
|
|
2738
3149
|
}
|
|
2739
3150
|
return undefined;
|
|
@@ -2785,19 +3196,155 @@ function constraintWrite(state, instance, address, tier, value) {
|
|
|
2785
3196
|
}
|
|
2786
3197
|
|
|
2787
3198
|
/// **THE FAIL ARM'S CROSSING — `A120` (2): THE ENTRY CARRIES THE KERNEL'S TOKEN, THE THROW KEEPS THE
|
|
2788
|
-
/// STORE'S
|
|
2789
|
-
///
|
|
2790
|
-
///
|
|
2791
|
-
///
|
|
2792
|
-
///
|
|
3199
|
+
/// STORE'S — AND THE FORM CROSSES AT THREE MEMBERS FROM 2026-10-16** (`surface.md §2.5`'s clause of that
|
|
3200
|
+
/// date, items 3–4 and 10 (i)–(iii); `§2.12` item 1's mark of the same date).
|
|
3201
|
+
///
|
|
3202
|
+
/// **WHAT MOVES IS THE REACHABILITY OF `log` AND NOTHING ELSE.** The member `status` carries is still the
|
|
3203
|
+
/// store's `FileCommitFailed`, because no caller-side status can carry a `KC` token and a
|
|
3204
|
+
/// constraint-refused write is a commit that did not stand; **the kernel token does NOT enter `status`**
|
|
3205
|
+
/// (`A120` (2)'s rule survives whole). **A STORE VERB'S OWN REFUSAL CROSSES VERBATIM AND UNCONVERTED**
|
|
3206
|
+
/// (`fail-surface.md §1.2`): its `status` and its `message` are carried BYTE-FOR-BYTE, never re-mapped and
|
|
3207
|
+
/// never re-spelled, and `log` is ATTACHED BESIDE them as an own member — *"nothing is converted, and a
|
|
3208
|
+
/// member is added"* (`§2.5` item 10 (ii)).
|
|
3209
|
+
///
|
|
3210
|
+
/// **THE TWO ARMS, EACH AT ITS OWN FORM:**
|
|
3211
|
+
/// * **A `KC`-TOKEN REFUSAL — THE KERNEL'S OWN PASS PRODUCED IT.** Its `{status, message, log}` is the
|
|
3212
|
+
/// KERNEL'S OWN three-member form (`docs/specs/storeroom-constraints/fail-surface.md §1.1`, whose member
|
|
3213
|
+
/// set is the same three), and it would cross UNCHANGED were it not that `status` must carry the store's
|
|
3214
|
+
/// `FileCommitFailed` on this surface: **the `log` it carries is the attempt's, VERBATIM, and it crosses
|
|
3215
|
+
/// with the store-side `status` in its place.**
|
|
3216
|
+
/// * **A STORE VERB'S OWN REFUSAL.** Its `status` and `message` cross verbatim and `log` is attached beside
|
|
3217
|
+
/// them — the attempt's log where this write's own attempt holds one, and `[]` where it does not (a `K-2`
|
|
3218
|
+
/// the store refused opened no attempt, so there is no attempt at all — `§2.5` item 4).
|
|
3219
|
+
///
|
|
3220
|
+
/// **AND THE TIMING TRAP IS HONOURED, WHICH IS THE WHOLE OF ITEM 10 (iii): `log` IS TAKEN BEFORE THE
|
|
3221
|
+
/// ATTEMPT IS DISPOSED OF, NOT AFTER.** The kernel's terminal act has already run when this frame is
|
|
3222
|
+
/// reached (its `refuse` was thrown WITH the log in hand, `constraint-kernel.mjs`'s `refuse`), so the list
|
|
3223
|
+
/// read here is the list AS IT STOOD WHEN THE REFUSAL WAS BUILT — the failure arm's `outcome` entry
|
|
3224
|
+
/// included — and it is read OFF THE THROWN VALUE AND NEVER OFF A LATER READ: the registry entry is gone
|
|
3225
|
+
/// and a reader that reached for the attempt afterwards would reach nothing.
|
|
3226
|
+
///
|
|
3227
|
+
/// **⟶ THE FORGERY DISCRIMINATOR, RE-EXAMINED AND REPLACED 2026-10-16, BECAUSE THE RULING MADE THE OLD ONE
|
|
3228
|
+
/// UNSAFE — THIS IS THE HIGH-RISK EDIT AND IT IS NAMED WITH WHAT IT WAS AND WHAT IT IS.**
|
|
3229
|
+
///
|
|
3230
|
+
/// **WHAT IT WAS.** The previous pass fixed a broken forgery guard by discriminating on **`log`'s
|
|
3231
|
+
/// PRESENCE**: *a value carrying a `log` was the kernel's, and a value carrying none was the caller's.*
|
|
3232
|
+
/// That was sound only while the KERNEL'S OWN form was the only three-member form in the system.
|
|
3233
|
+
///
|
|
3234
|
+
/// **WHY IT NO LONGER SUFFICES.** `surface.md §2.5` item 4 now declares **`log` flat on EVERY failure this
|
|
3235
|
+
/// surface throws** — so every surface-produced failure carries one, **and so does a CALLER'S forged object
|
|
3236
|
+
/// that happens to carry a `log` member.** A caller's constraint body may throw
|
|
3237
|
+
/// `{status: 'ValueNotAdmitted', message: 'FORGED BY THE CALLER', log: []}` — a plain object it authored,
|
|
3238
|
+
/// carrying the member the old test looked for — **and under the old test that object was RE-WRAPPED into a
|
|
3239
|
+
/// fresh three-member object, so `caught === thrown` was `false` for a value the caller threw.** Measured on
|
|
3240
|
+
/// the tree before this edit: `forged {status,message,log} => caught===thrown: false`. **A caller's own
|
|
3241
|
+
/// throwable must surface AS ITSELF** (`fail-surface.md §1.1` item 5 — the body's exception *"propagates out
|
|
3242
|
+
/// of the kernel's own invocation, untouched and unconverted"*; `kernel-surface.md §2.3` item 1 — a body's
|
|
3243
|
+
/// throwable *"is NOT a kernel state and NOT a store state"*), **so the test had to stop reading a member
|
|
3244
|
+
/// the caller can forge.**
|
|
3245
|
+
///
|
|
3246
|
+
/// **WHAT REPLACED IT — IDENTITY, NOT SHAPE.** The kernel's own refusals are **built by the kernel**, and
|
|
3247
|
+
/// every one of them is thrown from `constraint-kernel.mjs`'s single `refuse` frame. The entry therefore
|
|
3248
|
+
/// **MARKS WHAT THE KERNEL BUILT**, at the one place the kernel's values enter this entry, **with a
|
|
3249
|
+
/// module-private `WeakSet`** — `kernelRefusals` above — **and this frame asks whether the handed value IS
|
|
3250
|
+
/// ONE OF THOSE VALUES, never whether it LOOKS LIKE one.** A caller cannot forge membership of a set it
|
|
3251
|
+
/// cannot reach, so:
|
|
3252
|
+
/// * a `KC`-token value the kernel built → **the kernel's arm**, and `FileCommitFailed` crossings below;
|
|
3253
|
+
/// * a store verb's own refusal (built by the addon, carrying the store's code) → the store's arm below;
|
|
3254
|
+
/// * **EVERYTHING ELSE IS THE CALLER'S AND CROSSES AS ITSELF** — a forged three-member object, a forged
|
|
3255
|
+
/// two-member object, a `TypeError`, a bare string, `undefined` — `caught === thrown` on all of them.
|
|
3256
|
+
///
|
|
3257
|
+
/// **THE MARK IS SET WHERE THE KERNEL'S FAILURE IS FIRST SEEN** — at the two `catch` frames in
|
|
3258
|
+
/// `constraintWrite` above, which are the only places a kernel-thrown value reaches this entry — and **NOT
|
|
3259
|
+
/// by a test over members, which is the whole defect being repaired.** **IT IS A `WeakSet` AND NOT A MEMBER
|
|
3260
|
+
/// ON THE VALUE**: no member is added to the kernel's own form (`fail-surface.md §1.1`'s member set stays the
|
|
3261
|
+
/// three), nothing is mutated, nothing is frozen, and the mark is invisible to every census — while a value
|
|
3262
|
+
/// that is not an object (a string, `undefined`) is simply never in the set and needs no special case, since
|
|
3263
|
+
/// `WeakSet.has` on a primitive is `false` rather than a throw.
|
|
3264
|
+
/// **THE KERNEL'S OWN REFUSAL-CLASS QUESTION, AND WHY THE ENTRY ASKS THE KERNEL IT RATHER THAN READING A
|
|
3265
|
+
/// MEMBER** — the discriminator that replaced `log`'s presence, and the reason a `WeakSet` local to this
|
|
3266
|
+
/// entry will not do.
|
|
3267
|
+
///
|
|
3268
|
+
/// **THE MARK CANNOT LIVE HERE, AND THAT WAS MEASURED RATHER THAN REASONED:** a `WeakSet` populated from the
|
|
3269
|
+
/// two `catch` frames in `constraintWrite` marks **EVERY** value leaving the kernel's frames — **a caller's
|
|
3270
|
+
/// constraint BODY throws from inside `runAttempt` too**, so the body's own throwable passes the same frame
|
|
3271
|
+
/// and is marked alongside the kernel's. On the tree with the `WeakSet` in place, all three of
|
|
3272
|
+
/// `forged {status,message}`, `forged {status,message,log}` and `TypeError` answered `caught === thrown:
|
|
3273
|
+
/// false`: **the mark was set by the frame and not by the author of the value.** A mark is only worth
|
|
3274
|
+
/// anything if the thing that SETS it is the thing that BUILT the value, and for a kernel refusal that thing
|
|
3275
|
+
/// is `constraint-kernel.mjs`'s own `refuse`.
|
|
3276
|
+
///
|
|
3277
|
+
/// **SO THE KERNEL DECLARES IT, AT ITS ONE THROW SITE, UNDER A `Symbol.for` KEY BOTH SIDES SPELL** — exactly
|
|
3278
|
+
/// the pattern `SETTLED_ON_THE_PASSING_ARM` and `SAVE_FAILED_AT_THE_TERMINAL_ARM` already use across this
|
|
3279
|
+
/// same boundary (`constraint-kernel.mjs`'s `KERNEL_REFUSAL`): the entry imports no kernel at load and the
|
|
3280
|
+
/// kernel imports no entry, and **a symbol key is invisible to `Object.keys`**, so the thrown form's readable
|
|
3281
|
+
/// member set stays the three `§2.5` items 3–4 declare (`§2.5` item 9's census reads `["log","message",
|
|
3282
|
+
/// "status"]` and no fourth). **A CALLER'S BODY CANNOT SET IT**: the mark is written in a frame no caller
|
|
3283
|
+
/// reaches, and it is not a member a caller would think to spell.
|
|
3284
|
+
///
|
|
3285
|
+
/// **AND A KERNEL THAT DID NOT CARRY THE DECLARATION ANSWERS `false`** — every value is then the caller's and
|
|
3286
|
+
/// surfaces as itself, which is the safe direction: a refusal crossed unconverted is the declared form once
|
|
3287
|
+
/// the surface stops re-wrapping it, while a caller's value crossed converted is the FINDING this whole
|
|
3288
|
+
/// discriminator exists to prevent.
|
|
3289
|
+
|
|
3290
|
+
/// **THE SAME `Symbol.for` KEY THE KERNEL WRITES, SPELLED HERE SO THE ENTRY IMPORTS NO KERNEL AND THE KERNEL
|
|
3291
|
+
/// IMPORTS NO ENTRY** — the pattern `SETTLED_ON_THE_PASSING_ARM` and `SAVE_FAILED_AT_THE_TERMINAL_ARM`
|
|
3292
|
+
/// already cross this boundary by (`constraint-kernel.mjs`'s `KERNEL_REFUSAL`).
|
|
3293
|
+
///
|
|
3294
|
+
/// **IT IS A SYMBOL AND NOT A KERNEL FUNCTION, AND THE REASON IS A SPEC COUNT: `kernel-surface.md §1` item 2
|
|
3295
|
+
/// declares that module's export set as EXACTLY the five `K-1`–`K-5` items — *"no sixth name"* — so a
|
|
3296
|
+
/// predicate exported from the kernel to serve this entry would be a FINDING.** The fact travels on the
|
|
3297
|
+
/// VALUE, under a key both sides spell, and the kernel's namespace is untouched.
|
|
3298
|
+
///
|
|
3299
|
+
/// **THE QUESTION IS ANSWERED WITHOUT REACHING THE KERNEL AT ALL**, which is the shape `WeakSet.has` gave
|
|
3300
|
+
/// for free and is what lets this entry keep loading where nothing is staged beside it: no `require` of
|
|
3301
|
+
/// `./src/` is triggered by a failure's own classification.
|
|
3302
|
+
const KERNEL_REFUSAL = Symbol.for('provident-storeroom.kernel-refusal');
|
|
3303
|
+
|
|
3304
|
+
/// **WHETHER THE HANDED VALUE IS A REFUSAL THE KERNEL ITSELF BUILT** — the discriminator that replaced
|
|
3305
|
+
/// `log`'s presence, answered by the mark the kernel's one `refuse` frame sets and by nothing a caller can
|
|
3306
|
+
/// spell. **A NON-OBJECT IS `false`** without a member read, and **a value the kernel never built is
|
|
3307
|
+
/// `false`** whatever members it carries.
|
|
3308
|
+
function isKernelBuiltRefusal(value) {
|
|
3309
|
+
return value !== null && typeof value === 'object' && value[KERNEL_REFUSAL] === true;
|
|
3310
|
+
}
|
|
3311
|
+
|
|
2793
3312
|
function constraintCrossing(refusal) {
|
|
2794
|
-
const
|
|
2795
|
-
|
|
3313
|
+
const isObject = refusal !== null && typeof refusal === 'object';
|
|
3314
|
+
const status = isObject ? refusal.status : undefined;
|
|
3315
|
+
// **THE CALLER'S OWN VALUE CROSSES AS ITSELF, FIRST AND UNCONDITIONALLY.** The test is IDENTITY against
|
|
3316
|
+
// the kernel's marked set (above) and NOT any member's presence: a caller's forged `log`, a forged
|
|
3317
|
+
// `status` spelling and a forged two-member object are all its own, and `caught === thrown` holds for
|
|
3318
|
+
// each (`fail-surface.md §1.1` item 5). A value that is not an object at all is never the kernel's either.
|
|
3319
|
+
if (!isObject || isKernelBuiltRefusal(refusal) === false) throw refusal;
|
|
3320
|
+
// THE LOG IS THE THROWN VALUE'S OWN `log` MEMBER — the same list either arm carries — and `[]` where the
|
|
3321
|
+
// value carries none (`§2.5` item 4: never absent, never `null`, never a non-array; a non-array here is a
|
|
3322
|
+
// finding at the site that produced it and is answered with the empty array rather than a shape).
|
|
3323
|
+
// **AND IT IS TAKEN HERE, BEFORE THE ATTEMPT IS DISPOSED OF** — item 10 (iii)'s timing trap: the list is
|
|
3324
|
+
// READ OFF THE THROWN VALUE, which the kernel built with the log in hand, and never off a later read.
|
|
3325
|
+
const log = Array.isArray(refusal.log) ? refusal.log : [];
|
|
3326
|
+
// **A MARKED VALUE WHOSE `status` IS NOT A `KC` TOKEN IS THE STORE VERB'S OWN REFUSAL CROSSING BACK
|
|
3327
|
+
// THROUGH THE KERNEL'S OWN LEG** (`constraint-kernel.mjs`'s `attempt.throwState` carries the store's code
|
|
3328
|
+
// at the repair arm): its `status` and `message` cross VERBATIM and `log` is attached BESIDE them —
|
|
3329
|
+
// *"nothing is converted, and a member is added"* (`§2.5` item 10 (ii)).
|
|
3330
|
+
if (typeof status !== 'string' || KC_TOKENS.includes(status) === false) {
|
|
3331
|
+
throw {
|
|
3332
|
+
status: refusal.status,
|
|
3333
|
+
message: refusal.message,
|
|
3334
|
+
log: refusalLog(log),
|
|
3335
|
+
};
|
|
3336
|
+
}
|
|
3337
|
+
// **THE KERNEL'S OWN `KC` REFUSAL.** Its `{status, message, log}` is the KERNEL'S OWN three-member form
|
|
3338
|
+
// (`docs/specs/storeroom-constraints/fail-surface.md §1.1`), and it crosses with the STORE's
|
|
3339
|
+
// `FileCommitFailed` in `status` because no caller-side status can carry a `KC` token and a
|
|
3340
|
+
// constraint-refused write is a commit that did not stand: **the kernel token does NOT enter `status`, and
|
|
3341
|
+
// the `log` it carries is the attempt's, VERBATIM.**
|
|
2796
3342
|
throw {
|
|
2797
3343
|
status: 'FileCommitFailed',
|
|
2798
3344
|
message: typeof refusal.message === 'string'
|
|
2799
3345
|
? refusal.message
|
|
2800
3346
|
: 'the write was refused by a constraint of this attempt',
|
|
3347
|
+
log: refusalLog(log),
|
|
2801
3348
|
};
|
|
2802
3349
|
}
|
|
2803
3350
|
|