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
121
122
123
124
125
126
127
128
129
130
131
//! RFC 116 stage 2 (design-v1.md N1, N2, N4; `stage-2-negotiation-artifacts-handoff-v1.md`) — the
//! negotiation artifacts and the delta computation. **Nothing here touches the network.**
//! `prikk-store` stays bytes-in, bytes-out (RFC 116 ruling 2); every function in this module and
//! its submodules is a pure read or a pure computation over already-decoded bytes.
//!
//! **Two artifacts, one computation, one sender:**
//! - [`build_sync_summary`]/[`decode_sync_summary`] (`summary.rs`): `PSYNCSU1`, one message
//! covering every local `heads/*` ref -- name, [`patch_set_digest::PatchSetDigest`], patch count.
//! 32 bytes plus a name per ref (design §1.1): cheap enough that two repositories already in sync
//! can find out for a few hundred bytes, never a patch-id list.
//! - [`build_have_list`]/[`decode_have_list`] (`have_list.rs`): `PSYNCHV1`, one ref's own full
//! patch-id list plus a digest the receiver of the message recomputes and checks (§1.3) --
//! self-consistent by construction, never trusted from the wire.
//! - [`compute_sync_delta`] (N4): `reachable(sender's own ref) ∖ have_list.patch_ids`, sorted.
//! - [`build_sync_artifact`] (stage 3, `sender.rs`): given a ref and a have-list, produces the
//! `PEXCH001` that closes the gap -- see `sender.rs`'s own module doc for why this is the one
//! and only place in the crate that ever constructs a `RecognitionClaimPayload`.
//!
//! **Representational, not frozen** (RFC 114 §3, restated per artifact): both formats carry objects
//! whose identity is already frozen (`ObjectId`, [`patch_set_digest::PatchSetDigest`]) and carry no
//! identity of their own.
//!
//! **Unsigned by design (N2).** A lying negotiation message can only cause a wrong delta -- more
//! patches sent than needed (wasteful, harmless: the receiver deduplicates by content address) or
//! fewer (the receiver's next summary comparison says so). Every byte that finally arrives is still
//! verified by Stage 3's accept path against material it carries, and Stage 4 seals only under the
//! receiver's own key. Signing these would imply the negotiation itself is trust-bearing; it is
//! not, and implying otherwise is worse than leaving it plain. **Negotiation does disclose
//! metadata** -- a have-list reveals which patch ids a repository holds, never their content; this
//! is the one property to document, not defend against (N2).
//!
//! **Branches only (§2 ruling).** `remotes/*` never appears: those pointers live in
//! [`crate::received`]'s own index, not the ordinary ref-pointer index [`crate::refs::RefStore`]
//! enumerates, so there is nothing to filter there. `tags/*` **is** enumerable through the ordinary
//! index and is excluded deliberately, not by oversight: [`crate::seal_from_accepted_claim`]
//! requires [`crate::refs::validate_local_branch_ref`] -- a tag cannot be sealed onto -- so
//! including tags here would report differences nothing downstream can act on. Tag sync is its own
//! question, not answered here.
//!
//! **This top-level module, `summary.rs`, and `have_list.rs` construct no
//! [`prikk_object::RecognitionClaimPayload`].** `sender.rs` is the sole exception, deliberately:
//! it is stage 3's sender side, the first claim producer in the project's history, and closes the
//! free-schema-amendment window D6 and N3 both used (RFC 114).
use BTreeSet;
use ;
use ;
use crateRepositoryLayout;
use crate;
use cratepatch_ids_reachable_from_block;
use crate;
pub use ;
pub use ;
pub use ;
/// N4 (design-v1.md §4): the delta for the one ref `have_list` names -- every patch id reachable
/// from this repository's own tip for that ref, minus what `have_list` says the other side already
/// has. **Returned sorted** (§3's own instruction), following naturally from
/// [`patch_ids_reachable_from_block`]'s own `BTreeSet`-derived order. Does not build a `PEXCH001`
/// artifact -- see [`build_sync_artifact`] for that -- and constructs no `RecognitionClaimPayload`,
/// only a `Vec<ObjectId>`.
///
/// **A ref this repository does not hold produces the full reachable set as the delta, not a
/// refusal** (design §5 item 6 / N5 item 6): an absent local ref behaves as an empty local reach
/// set, so the delta is simply everything the other side is missing -- the correct outcome when the
/// other side has never seen this ref at all, not a special case.
/// Resolve `ref_name` (already validated as a local branch ref shape) to its target Block id, or
/// `None` if this repository does not hold the ref at all. No tag hop -- branches only, per this
/// module's own scope (§2).