refactor: les commentaires disent cap-surface et cap-enforcement
Suite du balayage commencé dans la doc : 20 occurrences de P1a/P1b dans les commentaires, les titres de tests et le README. Les phrases ont été récrites, pas substituées : « the breach P1a opened » devient « the breach that cap-surface opened », et « labelled P1b's » ne survivait pas à un nom plus long. Un lecteur qui n'a jamais entendu ni l'un ni l'autre doit comprendre la phrase. L'avertissement de déploiement du README garde sa force et gagne un nom : « "anonymous" or "private" until cap-enforcement lands per-document encryption. » Reste une occurrence dans e2e/polyfill-entry.ts, qui part avec le lot e2e.
This commit is contained in:
@@ -105,7 +105,7 @@ export function holdOwnCap(id: string, scope: Scope, doc: Nuri, cap: ReadCap): v
|
||||
const caps = getCaps();
|
||||
// `learn(cap)`, not `open(doc, scope)` — the cap must be the SAME value that was
|
||||
// written to the Store branch, not a second one minted from the NURI. They agree
|
||||
// today only because the stand-in value is a constant; with a real key (P1b) a
|
||||
// today only because the stand-in value is a constant; with a real key (cap-enforcement) a
|
||||
// second mint would produce a DIFFERENT key and the document would be unreadable
|
||||
// by the very session that created it. Mint once, store it, hold that one.
|
||||
caps.learn(cap);
|
||||
|
||||
@@ -46,10 +46,11 @@
|
||||
* reference. Filed apart (`learnFromPublicStore`) because it grants reading only.
|
||||
*
|
||||
* ── What this module does NOT do ──────────────────────────────────────────
|
||||
* Enforce. The shape is right after P1a; the isolation is still fake. Per-document
|
||||
* encryption and closing the read paths that bypass the guard (an ANCHORLESS
|
||||
* `docs.sparqlQuery`, the inbox, `store-registry`, `subscribe`, `open-repo`) are P1b.
|
||||
* Nothing may be claimed "anonymous" or "private" until then.
|
||||
* Enforce. The shape is right, delivered by cap-surface; the isolation is still
|
||||
* fake. Per-document encryption and closing the read paths that bypass the guard
|
||||
* (an ANCHORLESS `docs.sparqlQuery`, the inbox, `store-registry`, `subscribe`,
|
||||
* `open-repo`) are cap-enforcement's job. Nothing may be claimed "anonymous" or
|
||||
* "private" until then.
|
||||
*
|
||||
* The write caps below (`grantWrite`, `governsWrite`, `canWrite`, `hasWritePolicy`) are
|
||||
* **inert, not partial** — a distinction the docs got wrong until 2026-08-07, when an
|
||||
@@ -57,7 +58,7 @@
|
||||
* `hasWritePolicy()` is permanently false and the `ng-proxy` guard they feed never fires
|
||||
* at all. Writing is governed instead by OWNERSHIP, at the write door (`reach.ts`
|
||||
* `assertMayWrite`) — which is what upstream's `verify_permission` actually checks. These
|
||||
* four are dead surface kept for P1b; do not read them as a working policy.
|
||||
* four are dead surface kept for cap-enforcement; do not read them as a working policy.
|
||||
*/
|
||||
|
||||
import { CAP_SEGMENT, hasReadCap, targetOf } from "../model/nuri";
|
||||
@@ -74,7 +75,7 @@ import type { Nuri, PrincipalId, ReadCap, Scope } from "../model/types";
|
||||
* own header, and put the emulation's one invented value in the file that claims to hold
|
||||
* only verified target vocabulary.
|
||||
*
|
||||
* P1b replaces this single constant with a real key; migration deletes both.
|
||||
* cap-enforcement replaces this single constant with a real key; migration deletes both.
|
||||
*/
|
||||
const STAND_IN_CAP = "OK";
|
||||
|
||||
@@ -117,7 +118,7 @@ export class CapRegistry {
|
||||
* been, the holder holds it like any other and this set records only how it got there.
|
||||
*/
|
||||
private inPublicStore = new Set<Nuri>();
|
||||
/** doc NURI → principals holding its WRITE cap. Decorative until P1b. */
|
||||
/** doc NURI → principals holding its WRITE cap. Decorative until cap-enforcement. */
|
||||
private writers = new Map<Nuri, Set<PrincipalId>>();
|
||||
/** Fired whenever a holder gains a cap — a cap delivered asynchronously must
|
||||
* re-trigger the reads that were empty for want of it. */
|
||||
@@ -246,7 +247,7 @@ export class CapRegistry {
|
||||
* It is a READ grant and nothing else. Upstream a public store makes its repos
|
||||
* world-readable, never world-writable — writing needs the write cap, and
|
||||
* `verify_permission` fires on WRITE only. Here the write guard still consults the
|
||||
* read cap (write caps are decorative until P1b, see the module header), so without
|
||||
* read cap (write caps are decorative until cap-enforcement, see the module header), so without
|
||||
* this distinction a bare reference to a public document would buy a WRITE — a
|
||||
* consumer would build on it, and have to unlearn it at migration.
|
||||
*
|
||||
@@ -308,7 +309,7 @@ export class CapRegistry {
|
||||
* and when listing the holder's own documents back, which is how a holder's caps are
|
||||
* rebuilt on a fresh session.
|
||||
*
|
||||
* Deliberately does NOT touch write caps: those are decorative until P1b, and
|
||||
* Deliberately does NOT touch write caps: those are decorative until cap-enforcement, and
|
||||
* arming their guard here would be enforcement this batch does not do.
|
||||
*/
|
||||
open(nuri: Nuri, scope: Scope): ReadCap {
|
||||
@@ -367,7 +368,7 @@ export class CapRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
// --- write caps (decorative until P1b) ----------------------------------
|
||||
// --- write caps (decorative until cap-enforcement) ----------------------------------
|
||||
|
||||
/** Grant `principal` the WRITE cap of document `doc`. */
|
||||
grantWrite(doc: Nuri, principal: PrincipalId): void {
|
||||
|
||||
@@ -106,8 +106,8 @@ export function assertMayReach(nuri: Nuri, op: string): void {
|
||||
*
|
||||
* - too lax — a cap received in an inbox passed, so an application could write into a
|
||||
* document it merely reads. Someone could ship collaborative editing on it and lose
|
||||
* it at migration. It was labelled "P1b's", but P1b is key MATERIAL and this is a
|
||||
* model relation;
|
||||
* it at migration. It was labelled cap-enforcement's responsibility, but
|
||||
* cap-enforcement is key MATERIAL and this is a model relation;
|
||||
* - too strict — the owner of her own public document was refused, whenever she opened
|
||||
* it from its reference before her store had been listed (a deep link, a fresh
|
||||
* session). The comment beside the code asserted the opposite.
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
* can answer is **do I hold this document's cap, or not** — so the key value is the
|
||||
* constant `OK`, which says exactly that and pretends nothing more. What identifies
|
||||
* the document is the NURI the key is attached to; the value carries no information.
|
||||
* Real per-document encryption is P1b's job, and it replaces this one constant.
|
||||
* Real per-document encryption is cap-enforcement's job, and it replaces this one constant.
|
||||
* Until then, possession is a SHAPE, not a protection.
|
||||
*/
|
||||
|
||||
|
||||
@@ -896,8 +896,8 @@ const inboxCache = new Map<string, Nuri>();
|
||||
* recipient's inbox. That makes the inbox the **bootstrap of the whole
|
||||
* reachability graph** rather than a side feature — and it is why an inbox has to
|
||||
* BELONG to someone. Before this existed, an inbox was any NURI a caller passed,
|
||||
* so "read the inbox" meant "read anyone's inbox", and since P1a routes caps
|
||||
* through it, reading someone else's collected the caps addressed to them.
|
||||
* so "read the inbox" meant "read anyone's inbox", and since cap-surface routes
|
||||
* caps through it, reading someone else's collected the caps addressed to them.
|
||||
*
|
||||
* Created on first sight and stable thereafter. Recorded in the doc-shim under its
|
||||
* own predicate, read by its OWN query rather than added to the account SELECT: an
|
||||
@@ -1144,7 +1144,7 @@ export async function listMyEntityDocs(id: string, scope: Scope): Promise<Nuri[]
|
||||
// Recover the caps by READING the Store branch, never by recomputing them from
|
||||
// the NURIs — that is the whole point of storing them. A fresh session gets back
|
||||
// exactly what was recorded, and the day the stand-in value becomes a real key
|
||||
// (P1b) this path needs no change at all.
|
||||
// (cap-enforcement) this path needs no change at all.
|
||||
//
|
||||
// Scoped to the current holder: another user's store caps are not ours to hold.
|
||||
const holder = getCurrentUser();
|
||||
|
||||
Reference in New Issue
Block a user