1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! **Scoping is authorization, and it is one filter** (REMOTE §1.5, §4;
//! bl-8bbc): the published derivation narrowed to the workspaces one client is
//! registered in.
//!
//! **Everything else is ABSENT, not forbidden.** §4: *"enumeration replies
//! simply do not contain unregistered workspaces, the same shape as a workspace
//! that does not exist. Scope errors that confirm existence are a
//! disclosure."* Narrowing the snapshot is what makes that structural rather
//! than a promise kept twenty times:
//!
//! - [`ws_rows`](crate::boundary::answer::ws_rows) maps `workspaces`, so the
//! roster answers the registered set and nothing says a name was withheld.
//! - [`ws_path`](super::Snapshot::ws_path) resolves over `workspaces` too, so a
//! gesture naming an unregistered workspace earns
//! [`by_leaf`](crate::naming::by_leaf)'s own `unknown workspace` refusal —
//! the **identical bytes** a name nobody ever founded earns. There is no
//! scope error to write, because there is no scope branch.
//! - Every other read is aimed by the path that resolution produced, so none of
//! them can be reached at all.
//!
//! One filter, at one place, ahead of the dispatch table — the same shape
//! REMOTE §8's name resolution took, and for the same reason: twenty arms
//! re-deriving an authorization is twenty chances to forget one.
//!
//! **The workspace is the whole trust domain** (§1.5, and §11's standing
//! rejection of per-verb ACLs). So the narrowing is exactly the
//! workspace-keyed fields; the project set, the balls projection, the §3.5 join
//! and the `ops.jsonl` trail are world-wide facts this design does not divide,
//! and pretending otherwise here would be a policy layer §11 refuses until a
//! second human exists.
use Snapshot;
use crateleaf;
use BTreeSet;