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
//! **Retarget** — the change of config lineage, and of the role an agent
//! resolves as (ARCH §2.2, §4.3, §3.4).
//!
//! Fork chooses the lineage, and resolution follows its current tip at
//! every step boundary (§2.2, bl-403b) — an operator who fixes an
//! expired model id sees every conversation on the lineage pick it up
//! at its next step, no retarget needed. What remains this landing's to
//! do is the *lineage* itself: moving an agent onto a different
//! `config/*` line, or settling one held on its fork commit because
//! diverged lineages both reach it.
//!
//! **Retarget is a re-fork, and it is the compaction landing's own two
//! moves** (§2.6) — no merge appears anywhere, because §2.3's invariant is
//! unconditional and §2.6 left no merge in the system to imitate:
//!
//! 1. **The base** ([`base`]) — a *newly minted* dispatch commit on top of
//! the target config commit, derived through the fork's own machinery
//! rather than rebased. Everything config-shaped is re-derived there:
//! the descriptor cut, the control-file removal, the pinned soul.
//! 2. **The replay** ([`crate::prompt::rebase_forward`]) — the agent's own
//! post-dispatch commits land on the new base, and the branch moves to
//! the replayed tip. Transcript entries are one immutable file each
//! with monotonic names (§2.3), so this is conflict-free by the same
//! construction compaction relies on, and the same stage-reading
//! decline applies where it is violated.
//!
//! After it, `governing_config` — unchanged, still a pure ancestry query —
//! answers the target commit. No new stored fact anywhere.
//!
//! **The user act is a ref mark, so the single-writer rule is untouched.**
//! `litany retarget` writes `refs/litany/retarget/<agent-id>`
//! ([`crate::workspace::retarget`]); the agent's **own executor** consumes
//! it at the next `advance` step boundary, exactly where the compaction
//! landing runs. §2.3 holds verbatim: the branch still advances by one
//! writer, and that writer is still its executor.
//!
//! **Why this rewrite is legitimate** is §2.6's own argument, applied to
//! the other axis. A compactor's payload is the dispatching branch's own
//! *context*, rewritten on purpose — its payload, not its contamination.
//! A retarget's payload is the branch's own *policy*, re-forked on
//! purpose. Same polarity, same landing, same writer.
//!
//! **Timing is semantics, not compromise.** The mark takes effect at the
//! agent's next step, never mid-step: a config governs steps, and a
//! retarget is in practice followed by a message, which *is* that next
//! step.
//!
//! **The role rides the same landing** (bl-946c). An agent's role lives
//! in its dispatch commit subject ([`role`]), and this landing mints a
//! fresh dispatch commit — so *changing the role is changing what that
//! commit says*, which is one field of the mint rather than a second
//! mechanism. `litany retarget --role planner` writes the role mark
//! beside the config one ([`workspace::retarget`]); either mark alone is
//! a legal act, and an absent one reads as *unchanged*, so a role-only
//! retarget re-forks the branch onto the config commit it already
//! resolves and settles it as a planner. That is plan mode for a whole
//! running conversation with no `litany config` pass (§6 *Plan mode is a
//! lineage*), and accepting the plan is `--role worker` back.
pub use preflight;
use ;
use crate;
use crateGitRunner;
use crateworkspace;
use Path;
/// What consuming a retarget mark did to the branch.
/// The commit the agent already resolves — the followed answer (§2.2
/// *Fork chooses the lineage*, bl-403b): a target the agent's next step
/// would read anyway is a clean no-op, so under follow-the-tip a
/// retarget onto the agent's own advanced lineage head no-ops, and what
/// retargets is a change of *lineage* (or the healing of a diverged
/// one).
/// The role the branch has committed — its own fact (§6), read from the
/// dispatch commit subject reachable from `start` ([`role::derive`]). A
/// root founded before bl-946c carries no role there, which is
/// [`WORKER_ROLE`], exactly as step resolution reads it.
/// Consume `agent_id`'s retarget marks, if it has either, against its
/// branch checked out at `worktree` (ARCH §2.2). `Ok(None)` — neither
/// mark — is every agent's ordinary state at every boundary, so the whole
/// feature costs an unmarked branch two ref reads.
///
/// **An absent mark means unchanged, never nothing.** A config mark alone
/// re-forks onto another lineage under the role the branch already
/// carries; a role mark alone re-forks onto the commit it already
/// resolves under a new role (bl-946c); both move both. There is no
/// third case, because [`consume`] fills each absence from the branch's
/// own committed fact.
///
/// **Both marks are consumed in every outcome.** Landed, declined or
/// no-op alike, the question has been answered; a surviving mark would
/// re-ask it at the next boundary, and a declined landing would
/// re-attempt a rebase that has already been recorded as refused.
/// The landing proper, split from [`land`] so the mark is consumed on
/// every path out of it — including a failure, which has still answered
/// the mark and must not be re-attempted at every subsequent boundary.
pub