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
//! **Accepted, rejected, reworked** — the projection's outcome, derived from
//! git and nothing else (VISION §4.10 items 5–7; §3.9, bl-40ab).
//!
//! Nothing is stored, no verb writes any of these, and there is no winner field
//! to read: *"the accepted candidate is the attempt whose delivery the target's
//! history records; … provenance is ancestry; rejection is the absence of a
//! delivery"* (§4.10 item 6). Three facts answer the whole enumeration:
//!
//! - **the derived acceptance mark** — the `[<id>]` tag-scan
//! ([`crate::fan::delivered_commit`]) the work-diff row already wears;
//! - **whether the source ref still resolves** — the diff row's own
//! [`Change::Absent`] naming it, which is what a discarded attempt reads as;
//! - **ancestry** — whether the source already contains the target
//! ([`crate::git_tree::is_ancestor`], the §9.3 fold's own read spent one repo
//! over: a second spelling of `merge-base --is-ancestor` would be two places
//! for one git command to drift).
//!
//! **The rework test is the delivery law's own precondition, read backwards —
//! and that is a reframe of the ball's wording** (bl-40ab said *"the source
//! advanced after a refusal or verdict"*). A clock-based reading needs two
//! clocks yog does not share: the §4.2 trail counts unix seconds, a `messages/`
//! entry orders by a filename counter, and the source's own advance is a commit
//! date in a third repo. What that reading is *for* is knowing whether a
//! superseded attempt can deliver again — and §4.10 item 5 already says exactly
//! what that means: *"every sibling is stale by construction and must rework
//! (incorporate the new target in its own worktree) before it can deliver"*. So
//! reworked **is** "the target is an ancestor of the source", which is the very
//! test balls' delivery makes before it merges anything. One git question,
//! exact, no clock — and it stays true of a rework the operator did by hand,
//! which a trail-ordering test would have missed.
//!
//! **A refusal is the occasion for a rework, never its evidence.** Only the
//! incorporation is evidence, and only the incorporation is derivable.
//!
//! **The base commit lives here too, and it is not an outcome.** §4.10 item 7
//! names three OIDs beside the delivered one, and the third — the commit the two
//! ends departed from — is [`base`]. It sits beside [`reworked`] because it is
//! the same question in the same shape: one ancestry read over this row's own
//! two ends, degrading the same way (no resolved pair, or no locatable repo, is
//! no claim). Item 6 calls balls the authority for it, and balls' authority is a
//! *formula* — *"merge-base(target, source), derived, never stored"* — which yog
//! spells itself, because the only way to ask balls is to resume the attempt and
//! that re-materializes a worktree. A read must not write. The git call is
//! [`crate::git_tree::merge_base`], the same one the config fold spends.
use Path;
use crate;
/// What became of one attempt (§4.10 items 5–7).
/// The outcome of `attempt`, given every attempt this workspace holds and the
/// project repo to ask ancestry of. `siblings` is the whole row set — cohort
/// membership is derived from it below rather than being a set anything keeps
/// (§4.10 item 6: *"cohort = attempts sharing (target, base)"*).
pub
/// The handle of a sibling whose delivery this attempt's target records.
///
/// **Siblings share the target, not just the ball.** A fan's candidates and the
/// claim they were fanned off all wear the obligation's ball id, and they are
/// not one cohort: the candidates target `work/<id>` and the claim targets the
/// branch that ball closes into, so *"attempts sharing (target, base)"* is a
/// comparison of targets and a ball-only test would call the claim's own close
/// a sibling's win.
/// This attempt's own **source ref is gone** — the retirement that discarded it
/// ([`crate::fan::discard`]). The diff row already says so by naming the source
/// among the refs that did not resolve, so this is a read of that answer and not
/// a second probe of the repo.
/// Whether the source has incorporated the target — the delivery law's own
/// staleness test. `false` for a row with no resolved pair to compare, for a
/// project that cannot be located, and for a repo that will not answer: none of
/// the three is a claim that a rework happened.
/// The commit this attempt's two ends departed from — half of item 6's cohort
/// key, and the frozen starting point of the experiment. `None` for a row with
/// no resolved pair, for a project that cannot be located, and for two ends with
/// no shared ancestor: all three are "there is no commit to name", never a guess
/// at one.
pub
/// The target ref this row was read at, when it has one.