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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Index — where stable IDs and (later) the materialized graph live.
//!
//! An index fuses two natures (DESIGN §5): the **authoritative** id↔path
//! registry — not rebuildable from the documents — and (to come) the
//! **derived** resolution cache and adjacency index, which are. Keeping it
//! behind a trait is deliberate: a sidecar file, an in-memory map, or a
//! sync-backed store are all valid homes.
//!
//! Only the query half is here — [`IdIndex`], the lookups link resolution
//! needs. Everything that *changes* a registration (`IndexStore`, the
//! `Rebase` seam, the in-memory and registry-document stores) is
//! `prov-store`'s `index` module, for the same reason the write half of
//! [`fs`](crate::fs) is: a read-only consumer must not merely decline to write,
//! it must have nothing to write with.
//!
//! ## Tombstones — IDs are forever
//!
//! DESIGN's open question #1 ("does the registry ever need to survive without
//! its documents?") is answered **yes, minimally**: deleting a document leaves
//! a *tombstone* — the ID stops resolving but is never forgotten, so it can
//! never be reminted to mean something else. A dangling `prov:` reference
//! then stays *diagnosable* (validation can say "that document was deleted")
//! instead of becoming a silent re-resolution hazard. [`is_known`] is the
//! question that tells the two apart.
//!
//! [`is_known`]: IdIndex::is_known
use ;
use crateId;
/// A registration that would displace one the index already holds.
///
/// The index is a **bijection**: one id names one path, one path carries one id.
/// Registering across an existing entry breaks that, and in one of two
/// directions — worth telling apart, because what the user has to do about them
/// differs.
///
/// Both are ordinary under sync. `id_storage` defaults to `both`, so a document's
/// id travels *in its own frontmatter*: a transport can land a copy of a document
/// under a new name, and now two files spell one id with the registry able to
/// name only one of them. The registry cannot arbitrate that — only the author
/// can — so an operation that would resolve it silently refuses instead.
/// The query half of an ID index: the three lookups link resolution needs, and
/// no way to change what is stored.
///
/// This is the trait [`crate::graph`] is generic over, and it is the whole of
/// what the read core asks of a registry — `id:` resolution
/// ([`resolve`](IdIndex::resolve)), the reverse lookup a census entry is tagged
/// with ([`id_for_path`](IdIndex::id_for_path)), and the tombstone question that
/// distinguishes "never existed" from "retired"
/// ([`is_known`](IdIndex::is_known)).
///
/// Split out of `prov-store`'s `IndexStore` for the same reason
/// [`ReadStorage`](crate::fs::ReadStorage) is split out of that crate's
/// `Storage`: a read-only consumer must be able to depend on traversal without
/// linking the staging machinery, and `IndexStore`'s staging half is not merely
/// unused by the read core — it is *stated in write vocabulary*, down to
/// `rebase`, which only a pending mutation has anything to say to.
/// No index — identity-off workspaces. Registers nothing, resolves nothing.
;