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
//! How deep a delegation already is, and where it stops.
//!
//! mentra has a floor of its own, and it does not apply here: a disposable
//! subagent gets `task` added to its hidden set by name
//! (`DisposableSubagentTemplate::spawn`), which stops *mentra's* delegation
//! tool from nesting and says nothing about a tool basis registered. ADR-0016
//! therefore makes the guard `spawn`'s own.
//!
//! # Why a ledger rather than the agent's name
//!
//! A subagent is named `{parent}::task` by mentra, so counting `::task` in
//! `agent_name()` would give the depth for free — and would fail *open* the
//! day mentra renames its subagents, which is the wrong direction for a guard
//! to fail in. This keys on agent ids instead, which are the identity mentra
//! promises. One [`SpawnTool`](super::SpawnTool) is registered per runtime and
//! every subagent shares that runtime's registry, so one ledger sees the whole
//! tree.
//!
//! Entries live exactly as long as the delegated run: `spawn` owns the child's
//! whole lifetime — it awaits `Agent::run` — so [`Depth::entered`] hands back a
//! guard that removes the entry on drop, including on an early return or a
//! panic. A long session therefore holds one entry per delegation *in flight*,
//! not one per delegation ever made.
use ;
/// How many levels of delegation `spawn` will start.
///
/// Zero would be mentra's answer for `task` — a subagent that cannot delegate
/// at all. Two is the smallest bound that leaves delegation compositional (a
/// subagent may split its own work once) while keeping runaway recursion
/// structurally impossible rather than merely unlikely. The root run is depth
/// 0, so the deepest agent that can still delegate is depth 1.
pub const MAX_DEPTH: usize = 2;
/// The delegation depth of every agent with a delegation in flight.
///
/// Absent means depth 0: a root run has never been recorded by anything.
pub
/// Removes one agent's depth entry when the delegation that opened it ends.
pub
/// What the model reads when the guard fires.
///
/// It names the floor and says what to do instead, because a refusal that only
/// says no is one the model answers by trying again.