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
//! Result-message deposit at a terminal event (ARCH §2.6, §2.3 step 5).
//!
//! Every terminal event of a step loop deposits a **result message** —
//! "Return is not a verb" (`docs/PRINCIPLES.md`): the deposit is
//! executor-side, never a model `message` tool call. This module is the
//! executor's side of that return: it derives the recipient
//! ([`recipient`]), reads the branch tip as the terminal ref (§2.6), and
//! deposits with the matching epitaph.
//!
//! **Who the result is addressed to is decided by the epitaph's value**
//! (§2.6 — code branches on the value, never on the message's shape):
//! a **reply** (`final-response`) answers whoever last prompted this
//! agent; an **obituary** (`stopped`, `budget-exhausted`, `died`) reports
//! to the dispatcher, whose address is the agent's own id minus its last
//! descent segment ([`inbox::parent_of`], §2.11). Both can be absent —
//! a reply to the user and a root's obituary alike deposit nothing — and
//! the absent arm is one structural no-op, not two special cases (§2.4:
//! the terminal response answers the user, who reads this agent's own
//! conversation).
//!
//! **The deposit does not launch.** Waking the recipient this deposit
//! revives (§2.11 revival-on-deposit) is the exit protocol's closing
//! act, not the deposit's return value: it happens once, after the
//! depositing executor releases its own lock, and by epitaph value —
//! [`super::terminal::exit_launch`] / `revive_recipient`, which addresses
//! the same [`recipient`] the deposit did. Keeping it there keeps this a
//! pure return and keeps the launch decision in one place.
use ;
use ;
use read_branch_tip;
use terminal_ref_of;
use Content;
use Path;
/// The terminal response body iff the agent spoke: the concatenated
/// [`Content::Text`] blocks of the final assistant content, or `None`
/// when it produced none (§2.6 — the body is present exactly when the
/// agent spoke). Thinking blocks are not speech and are excluded.
pub
/// The inbox this terminal event's result message is addressed to (§2.6
/// *A reply answers the last prompter; an obituary reports to the
/// dispatcher*), or `None` when no agent is addressed.
///
/// An **obituary** — every epitaph but `final-response` — is a
/// structural fact about the tree rather than an answer to anyone: it
/// says *this agent is gone*, and the one party that has a standing
/// interest in that is the agent that dispatched it. Its address is the
/// id's ([`inbox::parent_of`]), which no rewrite of the transcript can
/// move, so the dispatcher hears about a stop, an exhausted ceiling or a
/// death even when the branch was mid-conversation with somebody else.
///
/// A **reply** — `final-response` — answers whoever last prompted this
/// agent ([`last_prompter`]), **if it owes one at all** ([`debt`]). For
/// the dispatch step the last prompter *is* the dispatcher (the goal
/// arrives as its message, §2.5), so the old parent-addressed rule is
/// this rule's first case rather than a rule of its own; `user` is
/// nobody's inbox, so an operator-prompted reply deposits nothing and is
/// read in this agent's own conversation.
///
/// **A reply is owed once, to a question** (§2.6, bl-82d8). Nothing
/// bounded the answer before, so two agents that spoke to each other
/// answered each other's answers forever. The debt is derived from this
/// branch's own transcript — has anything been delivered since the
/// previous terminal response that *asks* this agent for something —
/// and a terminal event that owes nothing addresses nobody, which is the
/// same structural no-op an operator-prompted reply already takes.
pub
/// The **last prompter**: the sender of the newest delivered message in
/// this branch's transcript that is a prompt from somebody else (§2.3 —
/// order lives in the filename, so the newest is max-`NNN`; the origin
/// token names the sender). Derived, never stored: a stored "who spoke
/// last" would be a second copy of what `messages/` already says
/// (`docs/PRINCIPLES.md` Single source of truth).
///
/// Two entries are skipped, each because it is not a prompt:
///
/// - **A returning child's result message** — a delivered entry carrying
/// `terminal_ref:` frontmatter (§2.6). It is the answer to a dispatch
/// this agent already made, not a question put to it; without the skip
/// every parent would address its own answer to the last child that
/// returned.
/// - **This agent's own note to itself** (§2.11 *Self-messages*). Its
/// answer is the agent's own next step, which has already happened;
/// addressing a reply to one's own inbox would deposit into the very
/// inbox whose delivery produced it and never terminate.
/// Deposit this branch's result message on its own behalf at a terminal
/// event (§2.3 step 5): derive the recipient ([`recipient`]), read the
/// branch tip as the terminal ref, then deposit with `epitaph` and the
/// `response` body. Addressed to nobody — an operator-prompted reply, a
/// root's obituary — it is one structural no-op; wired at the call site
/// so a step loop returns without new plumbing.
pub