provident-storeroom 1.0.1 → 1.2.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 CHANGED
@@ -30,6 +30,38 @@ pins, `§8.1`'s *"an installed `0.5.0`"*, and `§11`'s manifest table.** **AND T
30
30
  IS UNMOVED: no `npm install` was run against the registry, so a registry-installed `1.0.0` is described here from
31
31
  the manifest and from measurements on this checkout, and is still not witnessed.**
32
32
 
33
+ **⟶ AND THE FIGURE THAT CORRECTION CARRIES IS ITSELF ONE RELEASE BEHIND, 2026-10-27 — THE VERSION THIS GUIDE
34
+ DESCRIBES IS `1.0.1`, AND EVERY `1.0.0` THIS GUIDE PRINTS READS `1.0.1` FROM HERE ON.** `RCA-8(g)`
35
+ ANNOTATE-BESIDE: **the paragraph above stands BYTE-FOR-BYTE and is read THROUGH this clause — so do its reading of
36
+ `0.5.0` and its reading of `1.0.0`; each was true of the tree it was read on and each is one release behind the
37
+ shipped tree from this date.** **THE MANIFEST AT ITS OWN BYTES: `bindings/js/package.json`'s `version` is
38
+ `"1.0.1"`, and all five `optionalDependencies` pins are `1.0.1` with it** — the six figures move together and never
39
+ singly (§0 item 1; `PUB-DD-10`) — **and the tags the tree carries are `v1.0.0` and `v1.0.1`, with `main` sixteen
40
+ commits past `v1.0.1` and no version bump in any of them** (`git describe` at this date reads `v1.0.1-16-gdf3ef88`;
41
+ `D-41` item `1`'s semver ruling names the next release `1.1.0`, and that release has not been cut). **SO THE SITES
42
+ ARE RE-READ, NOT RE-SPELLED:** §2.2's five exact pins, §8.1's *"an installed `0.5.0`"* — itself already corrected to
43
+ `1.0.0` — and §11's manifest table all read `1.0.1`; **every `0.5.0` this guide prints is the figure of its writing
44
+ date and reads `1.0.1` from here on.** **AND THE ONE THING NO PASS WITNESSED IS STILL UNMOVED: no `npm install` was
45
+ run against the registry, so a registry-installed `1.0.1` is described here from the manifest and from
46
+ measurements on a locally packed, installed artefact, and is still not witnessed as a registry download.**
47
+
48
+ **⟶ AND THE FIGURE THE PARAGRAPH ABOVE CARRIES IS ITSELF ONE RELEASE BEHIND THE TARBALL IT DESCRIBES, 2026-10-28 — THE VERSION THIS GUIDE DESCRIBES IS `1.1.0`, `1.1.0` HAS BEEN CUT, AND EVERY `1.0.1` THIS GUIDE PRINTS READS `1.1.0` FROM HERE ON.** `RCA-8(g)` ANNOTATE-BESIDE: **the three dated paragraphs above stand BYTE-FOR-BYTE and are read THROUGH this clause — so do their readings of `0.5.0`, of `1.0.0` and of `1.0.1`; each was true of the tree it was read on and each is one release behind the shipped tree from this date.** **THE PARAGRAPH THAT OWES THIS IS QUOTED AT ITS OWN BYTES, because a guide that denies its own tarball is the defect this clause closes — `D-48` · `DEF-AC`: *"THE VERSION THIS GUIDE DESCRIBES IS `1.0.1`, AND EVERY `1.0.0` THIS GUIDE PRINTS READS `1.0.1` FROM HERE ON … the tags the tree carries are `v1.0.0` and `v1.0.1`, with `main` sixteen commits past `v1.0.1` and no version bump in any of them (`git describe` at this date reads `v1.0.1-16-gdf3ef88`; `D-41` item `1`'s semver ruling names the next release `1.1.0`, and that release has not been cut)."*** **THE TARBALL DENIES EVERY FIGURE OF THAT SENTENCE, AND IT IS THE FILE THE GUIDE TELLS YOU TO READ: `bindings/js/package.json`'s `version` is `"1.1.0"` at its own bytes, all five `optionalDependencies` pins are `1.1.0` with it, the tags the tree carries are `v1.0.0` · `v1.0.1` and `v1.1.0`, `git describe` reads `v1.1.0-1-gcbc3f8a`, and `D-41` item `1`'s minor has been RELEASED rather than awaited.** **SO THE SITES ARE RE-READ, NOT RE-SPELLED:** §0's two paragraphs above, §2.2's five exact pins, §8.1's *"an installed `0.5.0`"* — itself already corrected to `1.0.0` and then to `1.0.1` — and §11's manifest table all read `1.1.0`; **every `0.5.0`, `1.0.0` and `1.0.1` this guide prints is the figure of its writing date and reads `1.1.0` from here on**, and the six figures — the main `version` and the five pins — move together and never singly (§0 item 1; `PUB-DD-10`). **THE ONE THING THAT IS STILL UNMOVED IS THE ONE THING NO PASS WITNESSED, AND IT IS NOT A FIGURE:** no `npm install` was run against the registry, so a registry-installed `1.1.0` is described here from the manifest and from measurements on a locally packed, installed artefact, and is still not witnessed as a registry download. **NO OTHER CLAIM OF THIS GUIDE MOVES: the `files` allowlist's six rows (§11's dated re-read clause (i)), the packed set's nineteen-bare/twenty-assembled (§11's clause (ii)), the twenty-status set (§11's clause (iv)), the fourteen own members and every API clause stand exactly as they stood.** (`strata/decisions.md` · `D-48` · `DEF-AC`; `D-41` item `1`; `D-42` item `1`; `D-38`; `docs/specs/storeroom-publish/contract.md §2.3` item `3` — the byte-for-byte guide stage this correction travels by.)
49
+
50
+ **⟶ AND THE RELEASE IN PREPARATION IS NOT THIS GUIDE'S VERSION, 2026-10-28 — THE MANIFEST IS `1.1.0`, AND THIS GUIDE CLAIMS NO `1.2.0`.** `RCA-8(g)` ANNOTATE-BESIDE: **the four dated paragraphs above stand BYTE-FOR-BYTE and are read THROUGH this clause; this clause re-reads one figure and adds one pointer, and moves no other claim of this file.** **THE FIGURE, AT ITS OWN BYTES, READ THIS DATE: `bindings/js/package.json`'s `version` is `"1.1.0"` and all five `optionalDependencies` pins are `1.1.0` with it** — the six figures move together and never singly (§0 item 1; `PUB-DD-10`) — **so `1.1.0` is the version this guide DESCRIBES, and it is the version an installed tree answers to.** **A RELEASE IS IN PREPARATION AND IT HAS NOT BEEN CUT: what it adds is listed in `RELEASE-NOTES.md` at the repository root, under a `1.2.0` heading MARKED UNRELEASED, and nothing in that section is a version this guide claims or a behaviour this guide measured as shipped.** **AND THAT FILE SHIPS NOWHERE:** it stands at the repository root and no tarball carries it (§11's `files` allowlist, six rows), so a consumer reading `node_modules/provident-storeroom` has this guide and the six figures of `1.1.0`, and the `1.2.0` list is a CHECKOUT reader's document. **The rule, in one line: this guide describes what was cut (`1.1.0`); `RELEASE-NOTES.md` describes what is being prepared (`1.2.0`, UNRELEASED); neither claims the other's figure.** (`D-41` item `1`; §11's manifest table reads the same six figures; `docs/specs/storeroom-publish/contract.md §2.3` item `3`.)
51
+
52
+ **⟶ AND THE FIGURES MOVE TO THE PREPARED RELEASE, 2026-10-28 — THE SIX FIGURES THIS GUIDE POINTS AT READ `1.2.0`, AND `1.2.0` IS PREPARED, NOT CUT.** `RCA-8(g)` ANNOTATE-BESIDE: **the five dated paragraphs above stand BYTE-FOR-BYTE and are read THROUGH this clause — so do their readings of `0.5.0`, `1.0.0`, `1.0.1` and `1.1.0`; each was true of the tree it was read on.** **THE MANIFEST AT ITS OWN BYTES THIS DATE: `bindings/js/package.json`'s `version` is `"1.2.0"` and all five `optionalDependencies` pins are `1.2.0` with it** — the six figures move together and never singly (§0 item 1; `PUB-DD-10`) — **and the five platform manifests' own `version` fields read `1.2.0` with them, which is eleven sites and one rebuild.** **SO THE SITES ARE RE-READ, NOT RE-SPELLED:** this section's version line, §2.2's five exact pins, §8.1's *"an installed `0.5.0`"* and §11's manifest table all read `1.2.0`; **every `0.5.0`, `1.0.0`, `1.0.1` and `1.1.0` this guide prints is the figure of its writing date and reads `1.2.0` from here on.** **AND WHAT THIS CLAUSE DOES NOT CLAIM, SAID FIRST BECAUSE IT IS THE EASIER THING TO GET WRONG: `1.2.0` IS PREPARED AT THOSE SIX FIGURES AND THE TAG IS NOT CUT — `git tag --list` carries `v1.0.0` · `v1.0.1` · `v1.1.0` and no `v1.2.0`, so nothing here says the release is cut, and the tag is not cut until the architect cuts it.** **THE ONE THING THAT IS STILL UNMOVED IS THE ONE THING NO PASS WITNESSED, AND IT IS NOT A FIGURE:** no `npm install` was run against the registry, so a registry-installed `1.2.0` is described here from the manifest and from measurements on a locally packed, installed artefact, and is still not witnessed as a registry download. **NO OTHER CLAIM OF THIS GUIDE MOVES: the `files` allowlist's six rows (§11's dated re-read clause (i)), the packed set's nineteen-bare/twenty-assembled (§11's clause (ii)), the twenty-status set (§11's clause (iv)), the fourteen own members and every API clause stand exactly as they stood.** (`D-41` item `1`; `D-48` · `DEF-AC`; `docs/specs/storeroom-publish/contract.md §2.3` item `3` — the byte-for-byte guide stage this correction travels by; `scripts/publish.sh`'s eleven cells, and the tag coupling `release.md §2.5` puts AFTER them.)
53
+
54
+ **AND ONE THING A READER OF THE INSTALLED PACKAGE SHOULD KNOW BEFORE THE CITATIONS: WHEN THIS DOCUMENT IS AT
55
+ `node_modules/provident-storeroom/README.guide.md`, IT IS THIS GUIDE.** **Its ONE authored home is
56
+ `docs/guides/package-use.md` in the repository, and the release's assembly stages it byte-for-byte at the packaging
57
+ root as `README.guide.md`, beside `README.md`, where the manifest's `files` row ships it** (`PUB-DD-11`;
58
+ `docs/specs/storeroom-publish/contract.md §2.3` item `3`; `scripts/publish.sh`'s guide stage). **The paths this guide
59
+ cites — `bindings/js/…`, `docs/specs/…`, `tests/…` — are the CHECKOUT's, and they do not travel in the tarball; a
60
+ consumer reading from `node_modules` has this guide's text and the package's own shipped bytes (`index.mjs`,
61
+ `index.d.ts`, `README.md`, `src/`), and every declaration a citation names is answered first by those bytes.** **So
62
+ nothing here is addressed to a checkout reader alone: the installed tree carries this text unaltered, and a clause
63
+ that names a repository path says where its authority lives, not where you must stand to use it.**
64
+
33
65
  **Every figure carries one of four marks, and the four are not the same thing:**
34
66
 
35
67
  | the mark | what it means |
@@ -156,6 +188,13 @@ range, all six figures moving together (§0 item 1; `PUB-DD-10`).** **`1.0.0` is
156
188
  §11), so the main `version` and the five pins are one figure and a consumer who reads a `0.5.0` anywhere in a
157
189
  manifest has the wrong package.**
158
190
 
191
+ **⟶ AND THE FIGURE MOVES AGAIN, 2026-10-27: each of the five is pinned to `1.0.1`, not `1.0.0`**
192
+ (`bindings/js/package.json`, read at its own bytes; §0's correction of this date; `RCA-8(g)` ANNOTATE-BESIDE — the
193
+ two clauses above stand and are read THROUGH this one). **THE READING THEY TEACH IS UNMOVED AND IS THE POINT: five
194
+ EXACT pins, no caret, no tilde and no range, all six figures moving together (§0 item 1; `PUB-DD-10`) — so `1.0.1`
195
+ is the package's own version and the five pins' one figure, and a consumer who reads anything else in a manifest
196
+ has the wrong package.**
197
+
159
198
  ### §2.3 The three rungs
160
199
 
161
200
  1. **RUNG ONE — the scoped platform package for this runtime's `process.platform` × `process.arch` key.** This is
@@ -655,6 +694,50 @@ filter nothing on one.** **There is no read-side enforcement arm, none is declar
655
694
  writes and on nothing else** — and **reads consult no constraint's verdict, filter nothing on one, and refuse
656
695
  nothing because of one.**
657
696
 
697
+ ### §7.6 ★ `context.value` is what the write verb returned — read anything else yourself
698
+
699
+ **★ THE ONE SENTENCE TO CARRY AWAY: `context.value` is the value the write verb returned; a constraint that
700
+ cares about another location reads it.** (`D-50`, the architect, verbatim: *"If a constraint needs to look for
701
+ the data at a given location, it can read()"*.)
702
+
703
+ **AND THE CASE THAT MAKES IT MATTER IS A REPAIR THAT LANDS SOMEWHERE ELSE.** A constraint that refuses `2` at
704
+ its own address `['a']` returns a repair that writes `11` at a *different* address `['b']`. **The repair's op is
705
+ the attempt's last op, so the re-run hands your body the value that op landed — `11` — while the address your
706
+ pair judges still stands at `2`.** **That is not a machinery defect: it is the value the write verb returned, and
707
+ the package cannot be wrong about a value it was told to hand over — it can only be wrong about what it stored.**
708
+ **If your constraint cares about the state at any other location — the address it judges, the address its repair
709
+ landed at, or anywhere else — IT READS THAT LOCATION.** The body is your code, it closes over the store handle
710
+ you already hold, and `store.read(address)` is a published verb. **Measured 2026-10-28**
711
+ (`tests/e2e/discard-witness.mjs`, the `W8` cell): the re-run handed the pair `11` while its own address read
712
+ `2`; **the same body with `store.read(['b'])` refused on what it read** — the write failed and the store was
713
+ restored — **and the same body without the read passed, answering its record with its own value still standing at
714
+ its address.** **The read is the whole difference.**
715
+
716
+ **★ AND THE CONSEQUENCE A READER GETS WRONG, IN `D-50`'S OWN WORDS: *"a constraint that reads inside its body is
717
+ caller code entering the surface, so by `D-45` that read opens its own commit"* — **⟶ MEASURED 2026-10-28, AND THAT CLAUSE IS WRONG: A READ BRACKETS NO COMMIT AT ALL.** `read`, `readLiteral` and `constraints` are the surface's **NON-BRACKETING** calls — the count during a constraint body's read is the attempt's own and is left undisturbed, `attempt-opened` does not fire for it, and the same `attempt` is in force. **So the accurate consequence is the shorter one: a read inside a body runs INSIDE the attempt's window, opens nothing, and disturbs nothing.** (The `D-45` quote above is kept as the reading of its own date; this sentence governs.) — AND A READ RUNS NO CHECK, SO
718
+ NOTHING IS JUDGED BY IT.** **No constraint is asked on the value it returns, no pass runs, and the value you
719
+ read back is never a verdict.** **AND THE COUNT'S OWN RULE IS WHERE THE ACT'S SHAPE IS VISIBLE — MEASURED
720
+ 2026-10-28 AT THE `W8` CELL, ON BOTH SIDES OF THE READ: `read`, `readLiteral` and `constraints` are the surface's
721
+ NON-BRACKETING calls — no commit is bracketed for them — so the count during your read is the attempt's own
722
+ (`open` `1`, `live` `1`) and it is left undisturbed (`open` `1`, the same attempt).** **THE DECLARED SENTENCE IS
723
+ THE AUTHORSHIP — the read is not the write's act — and the count shows what that authorship costs: nothing is
724
+ opened and nothing is judged for it.** **So the load-bearing half for you is the authorship and the absence of a
725
+ check: your read is your own act at the surface, it carries no judgement, and it neither re-asks a constraint nor
726
+ re-runs the pass. A read is data, never a verdict — if you want a state judged, read it and judge it in your
727
+ body.**
728
+
729
+ **⟶ AND THE PASS ASKS EXACTLY THE PAIRS STANDING AT THE ADDRESS IT WRITES, 2026-10-28 — `D-50`'S CONSEQUENCE, WHICH NO CLAUSE ABOVE SPELLS OUT.** `RCA-8(g)` ANNOTATE-BESIDE: **every clause of §7.6 above stands BYTE-FOR-BYTE and is read THROUGH this one; this clause adds one declaration and moves nothing it prints.** **THE RULE: A WRITE'S CONSTRAINT PASS JUDGES THE PAIRS STANDING AT THE ADDRESS IT WRITES — the kernel's own `pairsAtAddress` reads the pair record at that one address — SO A PAIR AT A DIFFERENT ADDRESS IS NOT ASKED.** **If a constraint cares about another location it READS it** (`D-50`, the architect, verbatim: *"If a constraint needs to look for the data at a given location, it can read()"*). **MEASURED 2026-10-28, on this checkout, through the published entry, in a two-address drive:** a pair `b1` registered at `['b']`; **a write at `['a']` asked `b1` `0` times**; **the same write at `['b']` asked it once**, and the value the body was handed was the one that write returned. **So an action one address away is INVISIBLE to your pair** — it was never asked at the address the action moved — **and the body's own `store.read` is the only thing that makes it visible.** **That is the whole reason this section tells you to read what you care about: the pass will not ask a pair that does not stand where you wrote.** (`held-listener/contract.md §2.8` item `1`, `HL-8`: *"the pass selects the rows whose address IS the triggering address"*, preserving the EXACT-ADDRESS rule rather than widening it; `D-50`; §7.1–§7.5's declarations; the pass's own scan at `bindings/js/src/entry/kernel-foundations.mjs:782`.)
730
+
731
+ ### §7.7 ★ The check is BOUNDED — THREE restarts per terminal act, and past the budget it fails closed
732
+
733
+ **★ THE LIMIT, DECLARED HERE BECAUSE NO CLAUSE OF THIS GUIDE SAID IT: A CONSTRAINT CHECK RESTARTS AT MOST THREE TIMES PER TERMINAL ACT.** The bound is **`RESTART_LIMIT` = `3`**, one exported constant at **`bindings/js/src/entry/constraints.mjs:1366`**. **THE BUDGET IS SPENT AND NOT RESET by an action raised inside a restart** — a body that reverses again inside a restart's own ask spends the SAME budget and not a fresh one — **AND PAST IT THE CHECK FAILS CLOSED IN THE ONE FORM:** the write throws the same plain `{status, message, log}` it throws for a refused pass (§8), with `status` **`'ConstraintPassRefused'`** and **ONE log entry** whose message says the budget was spent rather than that a pair refused a state it never judged. **The store is restored** — the request's own watch records what is owed — so the terminal act leaves no unjudged effect standing (`D-42` item `3`; `D-41` item `4`).
734
+
735
+ **MEASURED 2026-10-28, ON THIS CHECKOUT, THROUGH THE PUBLISHED ENTRY — AND THE MEASUREMENT IS THE POINT: THE RESIDUAL IS THE BUDGET, NOT THE STATE AND NOT THE JOURNAL.** A pair whose body raises ONE FRESH REVERSAL on every ask the restart makes, **with every ask passing**, was driven twice: **with `60` fresh reversals available it rests at exactly `3` restart asks** (the listener's own action plus one per ask — `4` actions in all), **and with `40` available it answers identically, `3`.** **The body had `57` and `37` reversals it never got to spend, and nothing structural stopped it: every ask it made passed.** The terminal write then refused `ConstraintPassRefused` with its log entry saying the budget was spent.
736
+
737
+ **AND WHY THE BOUND EXISTS, SAID PLAINLY: NO STRUCTURAL STATE DISTINGUISHES A BODY THAT KEEPS REVERSING FROM ONE THAT MEANS TO.** The machinery cannot tell a loop from a caller with more work to do, so the restarts are COUNTED and the check fails closed instead of spinning.
738
+
739
+ **WHAT DOES NOT SPEND THE BUDGET**, so a lawful in-commit action costs at most one round and no more: **a request whose watch shows no moved address is consumed and asks nothing** — it can neither loop nor exhaust the budget — and **the count belongs to the PASS's own scope**, so a nested pass (a listener body's own write) has a scope and a budget of its own, exactly as it has its own commit (`js/contract.md §2.6`'s clause of 2026-10-27, item `4`).
740
+
658
741
  ---
659
742
 
660
743
  ## §8 · Refusals
@@ -756,6 +839,11 @@ BYTE and is read THROUGH this clause). **(i) *"The store implements seventeen (`
756
839
  NINETEEN**: `src/error.rs`'s `CODES` is `[&str; 19]`, ranks `18` and `19` being the two this set's 2026-10-26 ruling
757
840
  appended — **so the declaration of record and the crate agree at nineteen, which is the row above.** **(ii)
758
841
  *"installed `0.5.0`"* READS `1.0.0`** (`bindings/js/package.json`, read at its own bytes; §0's correction clause).
842
+
843
+ **⟶ AND THAT CORRECTED FIGURE IS ITSELF ONE RELEASE BEHIND, 2026-10-27: *"installed `0.5.0`"* READS `1.0.1`**
844
+ (`bindings/js/package.json` at its own bytes; §0's correction of this date; `RCA-8(g)` ANNOTATE-BESIDE — the
845
+ sentence above stands and is read THROUGH this one). **THE SENTENCE'S OWN POINT IS UNMOVED: the escape arm is what
846
+ keeps a member the set has since gained typeable in an installed copy, and the set is the store's to close.**
759
847
  **(iii) THE SET HAS NOW MOVED FOUR TIMES, NOT THREE**: fourteen to fifteen, fifteen to sixteen, sixteen to
760
848
  seventeen, **and seventeen to nineteen** — **the escape arm's argument is strengthened rather than weakened by the
761
849
  fourth move, which is exactly the arm's own evidence.** **NO TABLE ROW, NO RANK AND NO TRIGGER MOVES, and the two
@@ -876,6 +964,21 @@ defect** (`DD-28`; `native/contract.md §7.2` item 6; `write-and-read.md §4.3`'
876
964
  **What this means for you, in one line: durability is a property of `file`-tier WRITES. If you delete something
877
965
  durable and the process then restarts, expect it back — and delete it again after the boot, or write over it.**
878
966
 
967
+ **⟶ AND THE SENTENCE ABOUT THE BYTES IS ONE PRODUCER SHORT, 2026-10-27 — A REFUSED REVERSAL'S RESTORE NOW WRITES
968
+ THEM WHERE IT MOVED A `file`-TIER NODE (`bd0fd8c`).** `RCA-8(g)` ANNOTATE-BESIDE: **the section above stands
969
+ BYTE-FOR-BYTE and is read THROUGH this clause; THIS clause is a PURE INSERTION and moves no verb, no tier, no status
970
+ and no record.** **WHAT MOVED: the restore a REFUSED `rollback` performs — the compensating act that puts the state
971
+ back before the reversal — takes the `file` tier's projection before it and again after it, and where a version
972
+ standing at `Tier::File` moved it SAVES the restored image with the store's one writer.** **SO THE BYTES AT
973
+ `filePath` ARE THE LAST SUCCESSFUL SAVE'S, whose producers are a `file`-tier `write`'s commit AND a restore that moved
974
+ a file-tier node** — and **`and no other state` stands whole: the boot reads the register image at the file tier and
975
+ nothing else** (`native/contract.md §6.6` item `5`'s clause of 2026-10-27, the declaration's one home; `DD-28`'s
976
+ amended cell). **WHAT DOES NOT MOVE, SAID SO THE READING IS NOT TAKEN WIDER THAN IT IS:** **a `delete` still performs
977
+ no file I/O and a SUCCESSFUL `rollback` still performs none either**, so the paragraph above holds for both — the
978
+ removed version still stands again after the re-boot; **the save is the REFUSED arm's alone, it appends no journal
979
+ entry (a save is an effect and not an op), and a save that cannot land is reported (`FileCommitFailed`, the
980
+ in-memory state restored and the bytes not updated) rather than swallowed.**
981
+
879
982
  ### §9.4 When the save itself fails
880
983
 
881
984
  **On a `file`-tier write's save that fails — the act itself failing, not a constraint — the store rolls the write
@@ -1016,6 +1119,24 @@ contract.**
1016
1119
  clause). **`name`, `type`, `license`, `engines`, `exports` and `files` are UNMOVED and were re-read at the same
1017
1120
  bytes; the five `files` rows are still a fact of this tree and not a rule (the ★ paragraph below).**
1018
1121
 
1122
+ **⟶ AND THE TWO FIGURES THAT CLAUSE CORRECTS MOVE AGAIN, 2026-10-27: `version` is `1.0.1` and each of the five
1123
+ `optionalDependencies` is pinned to `1.0.1`** (`bindings/js/package.json`, read at its own bytes; §0's correction of
1124
+ this date; `RCA-8(g)` ANNOTATE-BESIDE — the table and the correction above stand and are read THROUGH this clause).
1125
+ **AND THE `files` ROW'S OWN FIGURE IS RE-READ AT ITS OWN SITE IN THE CLAUSE BELOW: it reads SIX rows, the sixth
1126
+ being the consumer guide's landed copy, `README.guide.md`.**
1127
+
1128
+ **⟶ AND THE FIVE FIGURES THIS GUIDE PRINTS ABOUT THE SHIPPED TREE ARE RE-MEASURED AT IT ON ONE DATE, 2026-10-27, SO
1129
+ THE GUIDE IS NOT LEFT ONE TREE BEHIND ANY OF THEM.** `RCA-8(g)` ANNOTATE-BESIDE: **every table row, every ★
1130
+ paragraph and every figure above stands BYTE-FOR-BYTE and is read THROUGH this clause; THIS clause adds no rule and
1131
+ moves no figure — it records, at one date, the reading of each figure the guide states about the shipped tree, and
1132
+ each is the figure its own clause already prints.** **THE FIVE, EACH WITH ITS MEASUREMENT:**
1133
+ 1. **THE STATUS SET IS TWENTY** — `src/error.rs`'s `CODES` is `[&str; 20]`, ranks `1`…`20`, and the declaration of record (`index.d.ts`, `StoreStatus`) agrees with the crate at twenty (§8.1's heading, its table's `20` row and its dated clauses).
1134
+ 2. **THE PACKED MEMBER SET IS NINETEEN BARE AND TWENTY ASSEMBLED** — measured with `npm pack --json` at `bindings/js`: the BARE tarball carries `19` paths (`1` `package.json` + `4` root files — `README.guide.md` among them + `13` entry modules + `1` kernel: `1 + 4 + 13 + 1 = 19` ✓), and the ASSEMBLED tarball — the same stage with the release's `LICENSE` copy — carries `20`, the nineteen plus the licence (the ★ re-read clause (ii) below; the installed battery's `INSTALL-01` prints `members=20` on every run).
1135
+ 3. **THE ALLOWLIST IS SIX ROWS** — `bindings/js/package.json`'s `files` reads `index.mjs` · `README.md` · `README.guide.md` · `index.d.ts` · `src/entry/` · `src/constraint-kernel.mjs` (`6 = 4 + 2` ✓) — **and `README.guide.md` is THIS document's landed copy** (§0's clause on the landing; the ★ re-read clause (i) below).
1136
+ 4. **THE INSTANCE CARRIES FOURTEEN OWN MEMBERS** — measured on an instance built in memory from the shipped artefact: `Object.keys` and `Object.getOwnPropertyNames` are both the same fourteen-name list, and `read`'s own descriptor reads `writable: true, enumerable: true, configurable: true` (§3's table; §3.1).
1137
+ 5. **THE DEPTH CEILING IS `126`** — the crossing's guard reads `depth > 126` (`bindings/js/src/crossing.rs`), so a value of depth `126` is admitted and one of depth `127` is refused; the node ceiling stands at `1,000,000` beside it (`json-crossing/contract.md §4`'s clause; §10.4).
1138
+ **NO FIGURE MOVES BY THIS CLAUSE, AND THE ONE THING IT ADDS IS THE DATE ON WHICH ALL FIVE WERE READ AT THE SAME TREE.**
1139
+
1019
1140
  **★ THE `exports` MAP HAS ONE ARM, AND THAT IS A PROMISE ABOUT WHAT IS REACHABLE:** **the addon is NOT reachable
1020
1141
  as a subpath and neither is the constraint kernel.** **There is no wildcard export, no deep import to the addon
1021
1142
  and no CJS arm** (`bindings/js/README.md`; `docs/specs/storeroom-publish/contract.md §1.3`;
@@ -1202,6 +1323,49 @@ that a read-back's prototype is or is not a particular object.** **What IS decla
1202
1323
  tree sharing no mutable member with the store or with another crossing**, which is the guarantee worth relying on
1203
1324
  (`json-crossing/contract.md §5`, item (3)(c)).
1204
1325
 
1326
+ ### §12.6b The two known fail-states, and how you leave them
1327
+
1328
+ **⟶ ADDED `1.1.0` — THIS IS THE ONE PART OF THE PROMISE A CONSUMER READING ONLY `node_modules` HAD NOWHERE TO FIND, AND IT SHIPS HERE BECAUSE THIS DOCUMENT SHIPS.**
1329
+
1330
+ **Two windows in the constraint machinery are known and are NOT defects. Each is a state you can leave.**
1331
+
1332
+ 1. **A `delete`'s listener delivery.** A listener invoked by a delete's delivery runs **no constraint pass** — there is no attempt for a pass to run over. **A `rollback` issued from inside it is unjudged, and its effect stands.**
1333
+ 2. **A registration's own evaluation.** `addConstraint`'s and `constraintRegister`'s evaluation of a supplied body runs **no pass** for the same reason — **an action raised there is unjudged and its effect stands.**
1334
+
1335
+ **THE FIRST EXIT — RELOAD THE FILE.** Since `1.1.0`, **a restore that moved a version standing at the `file` tier SAVES the restored image**, so **the file records the state the store was restored to, and a fresh boot over that path returns to judged bytes.**
1336
+
1337
+ **THE SECOND EXIT — REGENERATE THE STORE.** Construct a new instance and replay your writes; **a judged state by construction.**
1338
+
1339
+ **Neither window is new and neither is a defect**: both are places **a pass does not begin**, not places a judgement was skipped mid-flight. **And every pass that DOES run drains its own restart request** — so the fail-state is bounded by the two acts that run none.
1340
+
1341
+ **⟶ ADDED 2026-10-28 — `D-49`: THE DISCARD IS NOW OBSERVABLE ON THE `delete`'S OWN ANSWER, AND THE OTHER
1342
+ WINDOW STILL CARRIES NOTHING. READ THIS BEFORE YOU RELY ON EITHER FAIL-STATE.**
1343
+
1344
+ **THE USE CASE THAT MADE IT A DEFECT, IN YOUR TERMS.** Your `window.tabs` is one object; **a listener you
1345
+ installed at `window.tabs` DOES fire when you delete `window.tabs.landingPage`** — the triggered set's rule is the
1346
+ address prefix, and the invocation's one argument is the deleted address. That is exactly where you would check
1347
+ your own invariant — *"exactly one tab is active"* — **and that check IS the kind of act the delete-delivery
1348
+ window throws away**: if it fails and you raise a `rollback`, **the request dies with the window** (`DEF-AH`).
1349
+
1350
+ - **WHAT YOU CAN NOW SEE.** **A `delete`'s record carries `discarded` beside its four members** — a list, `0` or
1351
+ `1` long, of `{ opId, addresses }`: **`opId` is the id the reversal you raised named**, and **`addresses` are
1352
+ the addresses the discarded check would have been asked at**. **`record.discarded.length === 0` means this
1353
+ act's delivery discarded nothing.** **This is a WITNESS, not a repair** — the delete still answers everything
1354
+ it answered, **throws nothing**, mints no new status, and the reversal's effect **still stands**; the
1355
+ fail-state, the exits below and the behaviour of both windows are unchanged.
1356
+ - **READ IT BY ITS NAME, AND EXPECT IT NOT TO BE ENUMERABLE.** `record.discarded` works; **`Object.keys(record)`
1357
+ still prints the four members you already know**, and **a spread or `Object.assign` copy of a receipt does not
1358
+ carry the witness** — read `discarded` off the record itself.
1359
+ - **WHAT IT CANNOT SHOW, SAID PLAINLY.** **A registration's answer (`addConstraint`) is an opaque identity and
1360
+ carries NO witness** — an action raised inside that evaluation is still unobservable, and no member was
1361
+ invented for it. **And the machinery holds ONE pending request per instance**: a second in-flight action
1362
+ overwrites the first, so the witness reports the **last** request a delivery raised, and earlier ones were
1363
+ never recorded. **Neither limit is a defect; both are the declared shape.**
1364
+
1365
+ **THE EXITS ARE STILL YOURS AND ARE UNCHANGED: reload the file, or regenerate the store.** What changed is that
1366
+ **the `delete` now tells you the discard happened** — *"a fail-state is honest only if the consumer learns it
1367
+ happened"* (`D-49`).
1368
+
1205
1369
  ### §12.7 A skip is not a green, and your own throws are not refusals
1206
1370
 
1207
1371
  **WHAT BREAKS:** **a `skipped` cell is a cell that DID NOT RUN** — *"a skip is not a green"*, in the authority
@@ -1249,3 +1413,5 @@ quietly.**
1249
1413
  document, not a test report:** the declared documents are the instrument for questions of semantics, and a
1250
1414
  driven run is the instrument for questions of behaviour. **This guide tries to say which is which, and it is not
1251
1415
  the instrument that decides between them.**
1416
+
1417
+ **⟶ CORRECTED 2026-10-28 — THE BULLET ABOVE'S *"the two of 2026-10-26"* NO LONGER COUNTS THIS FILE, AND THE FIGURE IS MOVED RATHER THAN THE RULE.** `RCA-8(g)` ANNOTATE-BESIDE: **the bullet above stands BYTE-FOR-BYTE and is read THROUGH this clause.** **This file now names FOUR measurements of its own — the two of 2026-10-26 the bullet carries, §7.6's two-address `b1` drive and §7.7's 60/40-reversal restart-budget drive, both taken 2026-10-28 on this checkout through the published entry — and each is named where it stands rather than gathered here.** **WHAT DOES NOT MOVE IS THE BULLET'S RULE AND THE DOCUMENT'S OWN STANDING: this guide is a consumer document and not a test report; a figure it states is either declared and cited or measured and marked; and the declared documents and the driven batteries remain the instruments for questions of semantics and of behaviour respectively.** **A reader who wants the measurements re-run finds their drives named at their sites, and no figure of this file is offered as a green.**
package/index.d.ts CHANGED
@@ -465,6 +465,61 @@ export interface DeleteRecord {
465
465
  readonly tiers: readonly Tier[];
466
466
  /** **THE TRIGGER'S PAIRS** (`contract.md §2.4` item 1; `PAR-HL-38`; `A43` — a delete fires its own set). */
467
467
  readonly triggered: readonly TriggerPair[];
468
+ /**
469
+ * **THE OP THE `delete` LANDED — THE STORE'S OWN JOURNAL RECORD, `null` WHERE THE ACT REMOVED NOTHING**
470
+ * (`strata/decisions.md` · `D-43` item 3, the architect, verbatim: *"Delete should be journaled and
471
+ * reversible"*).
472
+ *
473
+ * **IT IS THE MEMBER `WriteRecord` CARRIES, AT THE SAME NAME AND THE SAME TYPE** (`WriteRecord.op` above,
474
+ * the store's own eight-member `JournalOp`), so a caller has **one spelling for "the op this act landed"**
475
+ * and one route to reversing it: `store.rollback(record.op.opId)` restores every version the delete
476
+ * removed, **at its own tier**, exactly as a write's reversal restores what the write replaced.
477
+ *
478
+ * **THE MEASURED FACT THIS MEMBER EXISTS FOR.** The delete was already journaled — the store appended one
479
+ * entry carrying the address, the per-tier before-state and an op id, and `rollback` already accepted that
480
+ * id — but the record carried no identity, so **the act could not be NAMED, and an act that cannot be
481
+ * named cannot be reversed**: that is why the kernel's unwinding could not reach a delete's effect at all.
482
+ *
483
+ * **AND `null` IS THE `D-3` ARM, SAID PLAINLY.** A delete that removes no version is a **success** with
484
+ * `tiers: []` (`§4.4` arm `D-3`; `native contract.md §6.5` item 11 adds `triggered: []`) and appends no
485
+ * journal entry, so there is no op to carry: **nothing is named because nothing was destroyed.**
486
+ */
487
+ readonly op: JournalOp | null;
488
+ /**
489
+ * **THE DISCARD'S WITNESS — THE REVERSALS THIS ACT'S OWN DELIVERY RAISED AND THE PACKAGE THREW AWAY**
490
+ * (`strata/decisions.md` · `D-49`, the architect, verbatim: *"Make discard observable"*; `DEF-AH`).
491
+ *
492
+ * **WHY THIS MEMBER EXISTS.** A `delete`'s listener delivery **runs no constraint pass** — there is no attempt
493
+ * for one to run over — so a `rollback` a listener body issues inside it raises a **restart request with no
494
+ * consumer**, and the fail-state is honest only if the caller learns it happened (`D-43` item 2's fail-state
495
+ * and both exits stand; `D-49` owes the witness and nothing else). **A listener at `window.tabs` fires for a
496
+ * delete at `window.tabs.landingPage`** — the triggered set's membership rule is the address prefix — **and the
497
+ * check it runs there is exactly the act the window discards**; this member is where that caller reads it.
498
+ *
499
+ * **ITS SHAPE, AND IT IS A LIST SO THE MEMBER CAN CARRY ONE TODAY AND MORE WITHOUT A SECOND SPELLING.** The
500
+ * restart machinery holds **one** pending request per instance (a second in-flight action overwrites the
501
+ * first — a declared limit, not a claim of this member), so the array is **`0` or `1` long**:
502
+ * * `opId` — **the store's own echo of the id the discarded reversal named**, or `null` where the reversal's
503
+ * call answered no id;
504
+ * * `addresses` — **the addresses the discarded check would have been asked at** (the watch's own addresses,
505
+ * each a fresh segment list), so a caller can re-run its own check at exactly those addresses.
506
+ *
507
+ * **A WITNESS IS NOT A REFUSAL.** The `delete` still answers what it answered — this record's other members
508
+ * are unmoved, the act **throws nothing**, **no member of the closed status set is minted**, and the reversed
509
+ * effect **still stands** (the request is reported, not re-run). **AND THIS MEMBER IS A NON-ENUMERABLE OWN
510
+ * PROPERTY**: `Object.keys(record)` and every deep-equality over the record read the same four members they
511
+ * read before, while a caller reads the witness **by its name**. A spread or `Object.assign` copy of the record
512
+ * does not carry it — read the member off the record itself.
513
+ *
514
+ * **WHAT IT CANNOT CARRY, SAID HERE RATHER THAN LEFT TO BE DISCOVERED.** The other passless window — a
515
+ * registration's own evaluation (`addConstraint`) — answers an **opaque identity** and carries **no witness**:
516
+ * an identity is not a record and no member of it is declared, so the action raised there remains unobservable
517
+ * without a new surface (`D-49`'s own instruction: say so rather than invent a member).
518
+ */
519
+ readonly discarded: readonly {
520
+ readonly opId: string | null;
521
+ readonly addresses: readonly Address[];
522
+ }[];
468
523
  }
469
524
 
470
525
  /**
@@ -665,6 +720,16 @@ export interface StoreInstance {
665
720
  * call `a.rollback(w.op.opId)`, whose id is the string `write` returned, is a correct call.
666
721
  */
667
722
  rollback(opId: string): RollbackRecord;
723
+
724
+ /**
725
+ * **⟶ AND IT THROWS: `1.1.0`'S DECLARATION, ADDED BESIDE THE SIGNATURE RATHER THAN IN IT.** **`rollback` was
726
+ * TOTAL at `1.0.1` — it answered a `RollbackRecord` and could not fail. It is PARTIAL now**: **a reversal the
727
+ * registered constraints do not admit REFUSES**, throwing the one plain form `{status, message, log}` with
728
+ * `status: 'ConstraintPassRefused'`, **and the store is restored to the state it stood at before the reversal**
729
+ * (`D-38`, `D-40`, `D-41`). **A TypeScript signature has no `throws` clause, so this is the honest place to say
730
+ * it**: *the return type describes what a call returns when it returns, and the throw is part of the contract.*
731
+ * **A lawful reversal is unchanged** — same record, same members, no `log`. **Callers on `1.0.1` must handle it.**
732
+ */
668
733
  /**
669
734
  * Begin watching the addresses the caller names under the caller's own handle.
670
735
  *
package/index.mjs CHANGED
@@ -87,9 +87,10 @@ import { withAddon, boundaryReject, adoptModuleContext } from './src/entry/artef
87
87
  import { VALUE_ARGUMENT_POSITION, accessorOrSymbolArm, arrayClass, classSpelling, extendedPath, hasLoneSurrogate, inDomainAddress, isAdmittedArray, isLawfulListenerElement, isPlainObjectValue, protoClass, shapeArmClass, targetSpelling, valueReject, valueTargetSpelling } from './src/entry/class-decision.mjs';
88
88
  import { encodeAddress, encodeFilePath, encodeJournalLength, encodeOpId, encodeTier, encodeValue, handleWire, inDomainHandle } from './src/entry/carrier.mjs';
89
89
  import { admittedConstraintBatch, constraintAddress, decodeBaseState, decodeJournalOp, decodeSegments, decodeValue, encodeConfig, spellConstraintAddress } from './src/entry/frame.mjs';
90
- import { FORGET_PAIR, INSTANCES, STORE_INDEX, STORE_RETIREMENT, TERMINAL_ARM, carryRefusal, closeCommit, crossTriggered, entryOf, homeAddressKey, installAttemptSeam, isStoreReceiver, openCommit, writeRefusal } from './src/entry/state.mjs';
90
+ import { addressSpelling } from './src/entry/kernel-foundations.mjs';
91
+ import { FORGET_PAIR, INSTANCES, STORE_INDEX, STORE_RETIREMENT, TERMINAL_ARM, carryRefusal, closeCommit, crossTriggered, currentWindow, entryOf, homeAddressKey, installAttemptSeam, isStoreReceiver, openCommit, writeRefusal } from './src/entry/state.mjs';
91
92
  import { commitPositionRefusal, constraintOverwrittenByListen, deliver, listenerStandingAt, registerOn, terminalArm } from './src/entry/delivery.mjs';
92
- import { ARGUMENT_POSITION_FIRST, addressSetKey, carryConstraint, constraintDetached, constraintPairKey, constraintRefuse, constraintSite, constraintUncarried, constraintWrite, constraintsKernel, enumerateConstraints, judgeReversal, registrationCrossing, restoreHeldPair, reversalWatch, unionAddressSets, withEmptyLog, withdrawStanding } from './src/entry/constraints.mjs';
93
+ import { ARGUMENT_POSITION_FIRST, addressSetKey, carryConstraint, constraintDetached, constraintPairKey, constraintRefuse, constraintSite, constraintUncarried, constraintWrite, constraintsKernel, enumerateConstraints, judgeReversal, registrationCrossing, restoreHeldPair, reversalWatch, unionAddressSets, withEmptyLog, witnessDiscardedReversal, withdrawStanding } from './src/entry/constraints.mjs';
93
94
  const require_ = createRequire(import.meta.url);
94
95
  const ADDON_PATH = join(dirOf(fileURLToPath(import.meta.url)), 'build', 'Release', 'storeroom_js_binding.node');
95
96
 
@@ -312,12 +313,20 @@ export function storeCreate(cfg) {
312
313
  // the receiver is known to be one. **NO TOKEN IS MINTED AND NO SECOND FORM IS BUILT** — the entry's own
313
314
  // refusal is what answers, reached by handing the receiver on.
314
315
  if (!isStoreReceiver(this)) return decodeValue(carryRefusal(() => entryOf().write.call(this), []));
315
- // **⟶ `§4.1`: `write` OPENS ONE — AND A KERNEL-DRIVEN WRITE JOINS THE EXTANT RATHER THAN OPENING A
316
- // SECOND.** The bracket is taken at this member's OWN opening, so the kernel's four-position leg and a
317
- // listener body's nested write both find the count above zero and join it (`openCommit`). **THE
318
- // DECREMENT IS ON THE FINAL RETURN TO THE CLIENT** (`closeCommit`), taken in a `finally` so the bracket
319
- // is released on every arm — a count left standing after a return is on `§5`'s failure list.
320
- const opened = openCommit(instance);
316
+ // **⟶ `§4.1`: `write` OPENS ONE — UNLESS THE CALL NAMES A COMMIT AT THIS METHOD'S FOURTH POSITION, WHICH
317
+ // IS THE DISCRIMINATOR `D-46` SETS: A CALL THAT SUPPLIES IT JOINS THE COMMIT IT NAMES, AND A CALL THAT
318
+ // SUPPLIES NONE OPENS A NEW ONE** (`strata/decisions.md` · `D-46`). **THE POSITION IS READ HERE AND
319
+ // NOWHERE ELSE**, because this member is the one place a call's own entry names a commit: the kernel's
320
+ // store leg is a FOUR-position call (`store.write(address, tier, value, record)`, `kernel-commit.mjs`) and
321
+ // therefore JOINS the commit the caller's three-position write opened, while a caller's plain write, a
322
+ // listener body's write and a constraint body's write all supply three positions and OPEN — the listener's
323
+ // being `D-43` item `1`'s *"its own commit"*, reached by declaration rather than by an authorship the
324
+ // package used to infer. **A SUPPLIED POSITION NAMES A COMMIT WHETHER OR NOT IT IS IN THE POSITION'S CLASS
325
+ // DOMAIN**: the class test below refuses an outside value before any store act, and a refused write
326
+ // releases the bracket in the `finally` below like every other arm.
327
+ // **THE DECREMENT IS ON THE FINAL RETURN TO THE CLIENT** (`closeCommit`), taken in a `finally` so the
328
+ // bracket is released on every arm — a count left standing after a return is on `§5`'s failure list.
329
+ const opened = openCommit(instance, arguments.length >= 4 ? commit : undefined);
321
330
  try {
322
331
  // **⟶ `docs/specs/storeroom-js/surface.md §2.12` ITEM 1, STAGE 1, AMENDED 2026-10-18 — THE ENTRY→KERNEL EDGE IS UNCONDITIONAL: EVERY
323
332
  // FOUR-POSITION WRITE ENTERS THE KERNEL'S `K-2`, AND THE `carriesConstraintAt` GATE THIS VERB ONCE TOOK
@@ -457,9 +466,43 @@ export function storeCreate(cfg) {
457
466
  /// and the in-domain no-op arm a SUCCESS returning `tiers: []`. **Its declared NAME is `delete`, and it is
458
467
  /// published under that name ALONE** (`package.md §1.3` item 3): `deleteOp` is a reserved-word workaround
459
468
  /// for the declaration and never a member of the package's namespace.
469
+ ///
470
+ /// **⟶ AND IT CARRIES THE DELETE'S OWN `op` FROM 2026-10-27** (`D-43` item 3; `index.d.ts`
471
+ /// `DeleteRecord.op`): the member `write`'s record carries, at the same name, so `rollback(record.op.opId)`
472
+ /// reverses the delete. `null` is the `D-3` arm that removed nothing — it appended no entry, so it names
473
+ /// no op — and it crosses unchanged rather than folding to `undefined` (`crossing.md §1.3`).
474
+ ///
475
+ /// **⟶ AND IT CARRIES THE DISCARD'S WITNESS FROM 2026-10-28 — `D-49`, `strata/decisions.md`, THE ARCHITECT,
476
+ /// VERBATIM: *"Make discard observable"*** (`index.d.ts` `DeleteRecord.discarded`; the use case's own
477
+ /// foundation is the prefix rule the delivery already obeys: **a listener at `window.tabs` FIRES for a
478
+ /// delete at `window.tabs.landingPage`, and the check it runs there is exactly the kind of act the
479
+ /// `delete`-delivery window throws away**).
480
+ ///
481
+ /// **`delete` IS THE ONE ACT WHOSE DELIVERY RUNS NO PASS AND WHOSE ANSWER SURVIVES TO TELL** (`D-43` item
482
+ /// 2's other window is a registration, whose answer is an opaque identity and carries nothing). So the
483
+ /// request a listener body raises inside THIS window — a `rollback`, stamped with this commit's identity by
484
+ /// `reversalWatch` — is read at the end of the delivery and reported **BESIDE** the record's four members, by
485
+ /// the one rule `D-49` sets: **the act still answers what it answered, no status is minted, and the witness
486
+ /// is not a refusal.**
487
+ ///
488
+ /// **THE MEMBER IS A NON-ENUMERABLE OWN `data` PROPERTY, AND THE CHOICE IS DECLARED.** It is **visible to the
489
+ /// caller by its name** (`record.discarded`) and declared in `index.d.ts`, while the record's **enumerable
490
+ /// member set stays the four its declaration and its cells assert** — `Object.keys`, every deep-equality over
491
+ /// a receipt and every census of a record's members read exactly what they read before. **A witness added by
492
+ /// moving the record's own declared ENUMERABLE shape would make the cells that assert that set's readings
493
+ /// false to buy nothing a caller needs**; a `Symbol.for` key would be the family's other device (`A117` (D6))
494
+ /// but is not declarable as a member of `DeleteRecord`, and `D-49` asks for the member to be declared.
495
+ ///
496
+ /// **THE VALUE IS `[]` WHERE NOTHING WAS DISCARDED AND ONE `{ opId, addresses }` ENTRY WHERE A REQUEST WAS**
497
+ /// — the id the reversal named (the store's own echo) and the addresses the discarded check would have been
498
+ /// asked at. **NO PASS RUNS, NO BODY IS INVOKED, NO JUDGEMENT IS TAKEN AND THE BEHAVIOUR OF THE WINDOW IS
499
+ /// UNMOVED**: the request is consumed (reported) and its effect still stands.
460
500
  delete(address, tier) {
461
501
  // **⟶ `§4.1`: `delete` OPENS ONE.**
462
502
  const opened = openCommit(instance);
503
+ // **THE WINDOW THIS ACT OWNS, TAKEN AT ITS OPENING** — the identity `reversalWatch` stamps a request with,
504
+ // so that what the witness reads is the request THIS delivery raised and never another window's.
505
+ const window = currentWindow(instance);
463
506
  try {
464
507
  const args = arguments.length >= 1 ? [encodeAddress(address, undefined, 'first argument')] : [];
465
508
  // `delete`'s tier is read as a VALUE and not by an arity fold: an ABSENT position is the whole-target
@@ -471,9 +514,22 @@ export function storeCreate(cfg) {
471
514
  address: decodeSegments(answer.address),
472
515
  tiers: answer.tiers,
473
516
  triggered: crossTriggered(state, answer.triggered),
517
+ op: answer.op === null ? null : decodeJournalOp(answer.op),
474
518
  };
475
519
  // `A43`: a delete FIRES its own triggered set, on the same window as a write (`docs/specs/storeroom-js/surface.md §2.7` item 2).
476
520
  deliver(state, receipt.triggered, answer.triggeringAddress);
521
+ // **⟶ `D-49`: THE WITNESS, READ AFTER THE DELIVERY AND REPORTED BESIDE THE RECORD** — the delivery is
522
+ // the only body-invoking instant this act has, so a request standing after it is one this window raised.
523
+ // **ONLY A DELETE THAT OPENED ITS OWN WINDOW REPORTS**: a call that joined an enclosing commit has no
524
+ // window of its own to witness, and any request under that identity belongs to the act that opened it
525
+ // (`witnessDiscardedReversal` clears a request of the window handed in and of no other).
526
+ const discarded = opened === true ? witnessDiscardedReversal(instance, window) : null;
527
+ Object.defineProperty(receipt, 'discarded', {
528
+ value: discarded === null ? [] : [discarded],
529
+ enumerable: false,
530
+ writable: false,
531
+ configurable: true,
532
+ });
477
533
  return receipt;
478
534
  } finally {
479
535
  closeCommit(instance, opened);
@@ -617,8 +673,8 @@ export function storeCreate(cfg) {
617
673
  if (overwritten !== null) {
618
674
  boundaryReject(
619
675
  'AddressMalformed',
620
- spellConstraintAddress(overwritten.address),
621
- `the listener '${handle}' cannot be installed at ${JSON.stringify(overwritten.address)}: the constraint `
676
+ addressSpelling(overwritten.address),
677
+ `the listener '${handle}' cannot be installed at ${addressSpelling(overwritten.address)}: the constraint `
622
678
  + `'${overwritten.id}' stands there, and a listener and a constraint do not share one`,
623
679
  );
624
680
  }
@@ -807,9 +863,9 @@ export function storeCreate(cfg) {
807
863
  if (collided !== null) {
808
864
  boundaryReject(
809
865
  'AddressMalformed',
810
- spellConstraintAddress(collided.address),
866
+ addressSpelling(collided.address),
811
867
  `the listener '${site.id}' cannot share its handle with the constraint '${site.id}' at `
812
- + `${JSON.stringify(collided.address)}: a listener and a constraint do not share one`,
868
+ + `${addressSpelling(collided.address)}: a listener and a constraint do not share one`,
813
869
  );
814
870
  }
815
871
  const held = site.state.constraints.get(constraintPairKey(site.addresses, site.id));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "provident-storeroom",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "U-STOREROOM-PUBLISH: the published Node ESM binding for the native Rust store of Provident-Storeroom — the entry resolves the scoped per-target platform package first, the checkout's own module-relative addon second, and answers the store's single declared absent-addon form when neither loads",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0",
@@ -40,11 +40,11 @@
40
40
  "src/constraint-kernel.mjs"
41
41
  ],
42
42
  "optionalDependencies": {
43
- "@auspicion/provident-storeroom-js-linux-x64-gnu": "1.0.1",
44
- "@auspicion/provident-storeroom-js-linux-arm64-gnu": "1.0.1",
45
- "@auspicion/provident-storeroom-js-darwin-x64": "1.0.1",
46
- "@auspicion/provident-storeroom-js-darwin-arm64": "1.0.1",
47
- "@auspicion/provident-storeroom-js-win32-x64-msvc": "1.0.1"
43
+ "@auspicion/provident-storeroom-js-linux-x64-gnu": "1.2.0",
44
+ "@auspicion/provident-storeroom-js-linux-arm64-gnu": "1.2.0",
45
+ "@auspicion/provident-storeroom-js-darwin-x64": "1.2.0",
46
+ "@auspicion/provident-storeroom-js-darwin-arm64": "1.2.0",
47
+ "@auspicion/provident-storeroom-js-win32-x64-msvc": "1.2.0"
48
48
  },
49
49
  "publishConfig": {
50
50
  "access": "public"