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
//! The agent's **retarget mark** — `refs/litany/retarget/<agent-id>`
//! (ARCH §2.2 *Fork chooses the lineage*, §3.4 `litany retarget`).
//!
//! Fork chooses the lineage and resolution follows its tip (§2.2,
//! bl-403b), so a same-lineage config edit reaches the agent by
//! resolution alone. The **retarget mark** is the act that remains: a
//! user act naming the config commit — another lineage's head — the
//! agent should be governed by from its next step on, consumed by the
//! agent's **own executor** at the next `advance` step boundary
//! ([`crate::prompt::retarget`]).
//!
//! Writing a ref is what keeps §2.3's branch-advancement invariant intact:
//! the user marks, the executor lands. Nothing else writes the agent's
//! branch, and no second writer appears — the same shape every other
//! orthogonal, non-derivable per-agent fact takes ([`super::MARK_REF_ROOT`]
//! — `conflicted`, `budget-exhausted`, `abandoned`, `notify`, `cwd`), so
//! it is reaped with the agent by `litany delete` (§9.2 enumerates the
//! mark root) and crosses no fork and no transfer.
//!
//! **The mark names a commit, not a value.** `cwd` (§3.3) points at a
//! blob because its fact is a path; this one points at the target
//! **config commit** itself, which is exactly the fact — so the landing
//! reads a commit-ish and nothing decodes anything. `git gc` keeps the
//! commit alive for as long as the mark does, which is what makes a
//! marked-then-rewound config lineage still land.
//!
//! **The role mark is the second half of the same act** (bl-946c),
//! `refs/litany/role/<agent-id>`, written by `litany retarget --role`
//! and consumed by the same landing at the same boundary. It is a
//! *second ref* and not a field on the first because the two are
//! orthogonal facts of different shapes — which config lineage governs
//! (a commit), and which role the agent is (a name, so a blob, the
//! `cwd` shape). Either may be marked without the other, and the
//! landing takes each absent one to mean *unchanged*: the general path
//! with empty inputs. Both live here because one verb writes them and
//! one landing answers them; a role has no other mark and no other
//! reader, its permanent home being the dispatch commit subject
//! ([`crate::prompt::role`]) the landing re-mints.
use ;
use crateGitRunner;
use io;
use Path;
/// Ref-namespace prefix for the retarget mark (§2.2).
pub const RETARGET_REF_PREFIX: &str = "retarget/";
/// `refs/litany/retarget/<agent-id>` — the mark ref for one agent.
/// The config commit an agent is marked to be retargeted to, or `None`
/// when no mark is set — the ordinary state of every agent, not an error.
/// An unreadable mark reads the same way: a step never fails for want of
/// a mark it does not have.
/// Mark `agent_id` for retargeting onto `commit` — last write wins, so an
/// operator who changes their mind before the next step simply marks
/// again.
/// Ref-namespace prefix for the role mark (§4.3, bl-946c).
pub const ROLE_REF_PREFIX: &str = "role/";
/// `refs/litany/role/<agent-id>` — the role mark ref for one agent.
/// The role an agent is marked to be settled on, or `None` when no role
/// mark is set — the ordinary state of every agent, and the landing's
/// reading of *keep the role the branch already committed*. An
/// unreadable mark reads the same way, for the reason [`read`] gives.
/// Mark `agent_id` for settling onto `role` — last write wins, like
/// [`write`]. The name is stored as a blob the ref points at, the
/// value-carrying mark shape `cwd` established (§3.3); role names are
/// `providers.yaml` keys, so no round-trip guard is needed beyond the
/// trim [`read_role`] performs.
/// Consume the role mark, on every path out of the landing — the reason
/// [`clear`] gives, for the same boundary.
/// Consume the mark. Called by the executor once the landing has been
/// adjudicated — landed, declined, or a no-op alike — because in every
/// case the mark has been answered, and a surviving one would re-ask the
/// same question at every subsequent step boundary.