Fix documentation defects found by an adversarial review

Fifteen findings, all verified before acting. The ones that mattered:

- Corrections added without updating what they corrected. §5's table still
  said a cap-less NURI is one "without :k:", two hundred lines after §4
  established the discriminant is `r:`. Same shape of defect in the P1a
  report, which kept the sentence "it is the owner's keyring, upstream the
  keyring is the wallet" — the exact sentence §4quater declares wrong, and the
  one that produced a global in-memory keyring.

- A wrong source citation: RootCapRefresh/BranchCapRefresh live in
  verifier/src/commits/mod.rs, not repo/src/commit.rs, and are no-op stubs.

- Documentation describing deleted code: isolation.ts, discovery.readIndex,
  the global index, and an acceptance test that was dropped with discovery.

- The P1a implementation report had aged into being wrong in four places
  (caps not persisted, inbox processing not started, plain string types, the
  :k: segment). It is dated, so it now carries a header saying what later lots
  overtook, rather than being rewritten.

- vision.md stated "a document's data is stored encrypted" in the present
  tense. That is the target; here the cap value is the constant OK and nothing
  is encrypted. Said plainly now.

- Prose left mangled by an earlier mechanical find-and-replace, in four places
  I had claimed were repaired.

Also: reach.ts and connect.ts had no home in the permanent docs — the boundary
and the connection sequence are now described in simulation.md, not only in a
brief.
This commit is contained in:
Sylvain Duchesne
2026-08-03 11:34:24 +02:00
parent ae9c32e271
commit 9d3e2d2bfe
13 changed files with 39 additions and 28 deletions
+3
View File
@@ -92,6 +92,9 @@ useShape<T extends BaseType>(
- `shape` — the ORM shape type (generated from a SHEX shape). Names the entity type
and the properties to materialize.
- `scope` — where to read: a `{ graphs, subjects }` scope object or a NURI string.
**Not to be confused with this library's `Scope`** (`types.ts`), which is the
literal union `public | protected | private` naming a store. Same word, two
meanings: the ORM's is a read target, ours is a placement.
`undefined` yields an empty read.
- **Returns** a `DeepSignalSet<T>` — a **live reactive set**. Iterate it like a set;
the component re-renders whenever the set changes.
+1 -1
View File
@@ -63,7 +63,7 @@ export class CapRegistry {
* whoever HOLDS the link, exactly like §5 of the brief says ("whoever has the
* URL reads the content"), and holding it means having received it. The set
* exists so the library can refuse to surface a document its holder never
* published (see `discovery.submitToIndex`).
* published. *(This fed `discovery.submitToIndex`, removed 2026-07-30; the flag is kept because publishing is still what turns a document into a shareable link.)*
*/
private published = new Set<Nuri>();
/** doc NURI → principals holding its WRITE cap. Decorative until P1b. */
+2 -2
View File
@@ -295,7 +295,7 @@ export async function read(targetInbox: Nuri): Promise<Deposit[]> {
await assertOwnInbox(targetInbox, "read");
const sid = await sessionId();
// NOTE: cold-start repo opening is done by the COLD DIRECT readers that need it
// (e.g. `discovery.readIndex` → `ensureInboxRepoOpen`), NOT here — `inbox.watch`
// (a cold reader that opens the repo before reading), NOT here — `inbox.watch`
// already holds the repo open via its own `subscribeDoc`, so opening a second
// bootstrap subscription from inside a watch's re-read would be redundant and can
// race the watch's own initial-`State` delivery. Keeping `read` a pure anchored
@@ -384,7 +384,7 @@ export const materialize = read;
* `self.repos`, so a plain anchored `read` resolves an unopened repo and silently
* returns 0 deposits — even for a deposit a remote session already synced to the
* broker. Gating on the sync barrier makes the read see the synced deposits. This
* is the SAME cold-read heal `discovery.readIndex` applies to the index inbox.
* is the same cold-read heal any cold direct reader needs.
*
* NOT for the `watch` path: {@link watch} already holds the repo open via its own
* `subscribeDoc`, so opening a second bootstrap subscription from inside a watch
@@ -14,7 +14,7 @@
* inbox files it, which fires the held-caps signal, which re-runs the read — the
* protected document appears with nothing else happening.
*
* The difference between Bob and Charlie is ONLY what what they hold holds. There is
* The difference between Bob and Charlie is ONLY each of them holds. There is
* no authorization list anywhere, and nobody was named to the registry.
*/
import { test, expect, mock, afterAll } from "bun:test";
@@ -257,7 +257,7 @@ test("Charlie: same public document, same reference — and he reads through it"
expect(await readValues([ref], SECRET)).toEqual(["the-protected-content"]);
});
test("the ONLY difference between Bob and Charlie is what what they hold holds", async () => {
test("the ONLY difference between Bob and Charlie is each of them holds", async () => {
inject();
const { protDoc, pubLink, protCap } = await aliceSetsUpHerDocuments();
const CHARLIE_INBOX = await walletInbox("charlie");