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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
//! Version control and its remote host behind one host-neutral vocabulary.
//!
//! The review unit is a [`ChangeRequest`] — GitHub maps it to a pull request,
//! and a later host maps it to whatever it calls the same thing. [`Vcs`] owns the
//! repository side (identities, sessions, preserved work) and [`RemoteHost`] owns
//! the host side (opening a change, reading its checks, merging it). A
//! [`rules`] file decides, per repository, how a change is published and whether
//! it needs an approval. Everything a process does along the way is emitted as an
//! [`Envelope`].
//!
//! # The shape of one change
//!
//! ```text
//! session open → a per-run --shared clone and one worktree, occupancy-leased
//! → work happens in the worktree
//! → publish → fetch and merge the current base (bounded resolve-and-requeue)
//! → the repository's own merge path verifies it: its pre-push
//! hook, or the host's required checks on the change request
//! → local-direct squash, or a change request the host lands
//! → session close → the worktree goes; the branch is copied out and stays
//! ```
//!
//! Everything durable lives under one state root (`ONEVCS_HOME`, otherwise
//! `~/.onevcs`): the registry document, the advisory locks and merge-queue state,
//! the per-session workspaces, the event streams, and their artifacts.
//!
//! # Two surfaces over one decision
//!
//! [`run`] is the command line: it answers a process, with an exit code and a line
//! of prose. A caller embedding this crate wants the decision itself, so the same
//! operations answer values — [`publish`] hands back a [`Publication`],
//! [`close_session`] the session it released, [`session`] what the repository side
//! recorded, and [`EventStream`] the envelopes one session wrote. The command line
//! is a rendering of those rather than a second path through them.
pub use ;
pub use ;
pub use ;
pub use ;
pub use Providers;
pub use ;
pub use Identity;
pub use ;
pub use MergePolicy;
pub use ;
pub use EventStream;
pub use ;
/// A parsed absolute URL, re-exported so a caller needs no direct dependency on
/// the parser this crate validates change-request URLs with.
pub use Url;
/// Run one parsed command line, returning the process exit code.
///
/// The binary is a thin shell over this, so a journey that drives `onevcs` and a
/// caller that embeds it take the same path and cannot disagree about an exit code.
/// Run one parsed command line against supplied implementations of the two
/// interfaces, returning the process exit code.
///
/// [`run`] is this with [`Providers::real`], so nothing about the command's own
/// behaviour changes with the implementations behind it: one code path, reached
/// through [`Vcs`] and [`Hosting`] rather than through the types that satisfy them
/// by default.
/// Verify a session's work and publish it, returning what the publication did.
///
/// The library form of `onevcs publish`, and the reason it exists: a run answers
/// with an exit code and prose, and a caller that has to branch on *what happened*
/// can only parse the prose. [`Publication`] is that answer as a value — the policy
/// it was taken under, whether it merged, opened a change request, queued one, or
/// had nothing to publish, and the failure and what became of the branch when it
/// did not land.
///
/// It runs through the seam, so a session a supplied [`Vcs`] opened publishes
/// against a supplied [`Hosting`] with no git, no host, and no process.
/// Release a session's worktree and its occupancy lease, keeping its branch.
///
/// The library form of `onevcs session close`.
/// Every session recorded for one repository, live or not, in token order.
///
/// The library form of `onevcs session holders`, and the question a caller asks
/// *before* it has a token: which sessions hold this repository's workspaces, which
/// of them still have an owner, and which are the remains of a run that stopped.
/// [`SessionHolder::token`] is what the rest of this surface takes, so a holder is
/// a session to act on rather than a line to read.
///
/// It takes no [`Providers`] because there is nothing here for an implementation to
/// answer: the holders are the records under this host's state root, which is where
/// `Git` writes them and where the command reads them. A `Vcs` that keeps its
/// sessions elsewhere therefore does not appear in this list — the same limit the
/// command has, since the two are one path.
/// What the repository side recorded about a session.
///
/// The library form of the record every command that takes a token reads: which
/// repository it belongs to, whether it is still open, and whether its branch
/// carries an incomplete-step marker.
/// What one repository releases, and what it adopts.
///
/// The library form of `onevcs release targets`. `repo` is the identity key, a
/// registered alias, an origin URL, or a path, exactly as every other command takes
/// one. A repository the release-targets file names no rule for has no targets and
/// the global adoption rung, which is what a host with no such file answers for
/// every repository it knows.
///
/// It takes no [`Providers`] for the reason [`session_holders`] does not: what a
/// repository releases is this host's own configuration and its own record, and
/// there is nothing here for an implementation of either interface to answer.
/// What version of one target is released right now.
///
/// The library form of `onevcs release latest`. An **automated** target is answered
/// by running its probe; a **human-step** target executes nothing at all and is
/// answered from the newest acknowledgement across its landings, or
/// [`ReleaseAnswer::NoRelease`] where nobody has recorded one.
///
/// [`ReleaseAnswer::NotAnswered`] is never [`ReleaseAnswer::NoRelease`]: a consumer
/// holds on the first and acts on the second.
/// Whether the release that carries one landed change has happened yet.
///
/// The library form of `onevcs release status`. `reference` is the four-spelling
/// reference `onevcs status` takes: a change request's URL, a session token, a
/// branch name, or a commit.
/// Record that somebody performed a human-step release, and what they released.
///
/// The library form of `onevcs release acknowledge`. It refuses an automated target
/// — its version comes from its probe — a reference that has not landed, a version
/// that is not a semantic version, and a target the repository does not declare.
///
/// Recording the same version for the same landing again succeeds and changes
/// nothing, re-reporting the existing record with its original timestamp and actor.
/// Recording a *different* version is refused unless `supersede` is set, which
/// writes the new version and keeps the previous one in the record's own history.
/// Which rung of the adoption chain one repository resolves to.
///
/// The repository rung where a rule sets one and the global rung otherwise. It
/// never answers the node rung and never defaults to [`Adoption::Fast`] itself:
/// those two rungs belong to the consumer, and a crate that answered all four would
/// make the chain unreadable from either side.