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
//! Replication — sending a repository's stored bytes out to another gunnar.
//!
//! # THIS MODULE IS DELIBERATELY EMPTY
//!
//! [`replicate_out`] is a signature, a contract and a `todo!()`. It is a
//! placeholder to be filled in **tomorrow (from 2026-08-07)** and it is not a
//! forgotten stub: the shape below is the decision that was made today, and the
//! wire is the part that was not. [`tests::replicate_out_is_deliberately_empty`]
//! asserts the emptiness, so that if someone half-implements this the test that
//! says "still empty" fails and has to be removed on purpose.
//!
//! **Nothing here opens a socket, and no protocol is designed here.** Do not add
//! one to this file as a convenience — a peer transport is its own decision.
//!
//! ## What was decided, and is therefore in the signature
//!
//! * **STORE-side.** Replication is a command on the store that holds the bytes.
//! It is not a read path and not a plugin hook; the receiving gunnar is a peer,
//! not a client of a lookup.
//! * **No index travels with it.** Not the Arrow object index, not the stree oid
//! section, not the redb tail. The receiver has its own
//! [`ObjectReadStack`](crate::read_stack::ObjectReadStack) and rebuilds its own
//! projection from what it receives — an index is a derivation, and shipping a
//! derivation is how two copies of a repository come to disagree about the
//! same bytes. This is the reason [`ReplicationReceipt`] reports objects and
//! bytes and says nothing about rows or generations of any index.
//! * **One transaction, per repository.** The unit is one repository's archive
//! between two generation marks: it either lands whole at the peer or it does
//! not land. There is no partial-repository state to reconcile, because a
//! half-replicated object set is exactly the thing whose repair costs more
//! than the resend.
//! * **Append-only makes it resumable, later.** Because the archive is
//! append-only, `from_generation` is a watermark and not a diff: everything
//! above it is new and nothing below it has changed. A resumed transaction is
//! therefore a fresh one with a higher watermark. That property is why the
//! parameter is a single `u64` and not a manifest.
use Path;
use Result;
/// Another gunnar. Deliberately just a name and an address: what an endpoint
/// string means is the transport's business, and the transport is not decided.
/// What a completed replication transaction reports.
///
/// Counts of things that actually moved — objects and bytes — and the watermark
/// the next transaction should start from. Nothing about indexes: none travelled.
/// **Send one repository's new objects to `peer`. NOT IMPLEMENTED — see the
/// module documentation.**
///
/// A store-side, all-or-nothing transaction over the bytes of `archive` above
/// `from_generation`. No index of any kind is transmitted; the peer derives its
/// own.
///
/// # Panics
///
/// Always. This is a placeholder with a settled signature and no body yet.