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
//! `yog tool-host` — **the client-side executor** (REMOTE §5, §9 step 7;
//! bl-024b): the far end of the routing leg, and the wire's second shipped
//! client mode.
//!
//! It is a *client*, not a server, and that is REMOTE §3's whole routing
//! ruling: the ask never inverts. This process dials the engine exactly as
//! [`seat`](super::seat) does, presents what this machine can run, and then
//! **rides a follow-class read** for its next invocation — one ordinary
//! `Query` whose answer takes as long as it takes. It runs what comes back and
//! posts each capture as an ordinary `Action`. Nothing about the framing, the
//! listener or a client's socket posture changes; the engine's work flows down
//! a stream this process asked for.
//!
//! **One loop, three gestures, all of them the boundary's** (REMOTE §3's ban on
//! wire-only verbs): `advertise` once, then `invocations` → run → `complete`,
//! forever. Every one of them is typable at any other seat.
//!
//! **It runs serially and it does not reconnect.** A host executes one
//! invocation at a time, so it is *absent* — holding no connection — for as
//! long as a tool takes, which is why nothing in the engine treats presence as
//! the routing predicate (see [`crate::registry::mailbox`]). And when the
//! channel fails it exits, saying why: a reconnect ladder is a policy about
//! *this machine's* supervision, which the operator who installed the tool host
//! already owns, and inventing one here would be yog deciding how a box it does
//! not administer restarts a program.
//!
//! **It serves every channel this box holds** (REMOTE §8.2, bl-4e31): the flat
//! root and one per [`entry`](crate::wire::entries), each on that entry's own
//! material and therefore under that entry's own client identity. Serial stays
//! serial *per channel*; [`entries`] is the resolution and the fan-out, and its
//! doc is where that seam is stated.
use Duration;
use Value;
use Seat;
use Material;
use cratecodec;
use crate;
use crate;
use crate;
use crateEnv;
/// What this machine can run, and how (REMOTE §5.2).
/// Every channel this box serves (REMOTE §8.2, bl-4e31) — the flat root beside
/// one per entry, and the fan-out that serves them at once.
pub
/// Running one invocation locally — lernie's own tool contract.
/// This mode's own word, for the usage line its refusals carry.
const VERB: &str = HOST_SUBCMD;
/// How long one tool may run before the child is terminated and the capture
/// says so. It is the host's own bound, not the caller's: the machine that
/// spawned the process is the one that can stop it, and the driver's patience
/// (`tool_host::remote::patience`) stands behind it as a second, longer bound
/// for the case where this whole process went away.
const DEADLINE: Duration = from_mins;
/// Run the tool-host mode. It does not return while the wire is up; a channel
/// that fails is an exit with the reason on stderr, and a machine with no
/// config or no wire material is the same refusal `yog seat` gives.
/// Present, then wait, run and answer — on **every** channel this box is
/// provisioned for — until each has stopped, and **it answers the sentences
/// that stopped them**.
///
/// There is no success exit, so none is spelled: a channel's only way out is a
/// gesture that failed, and a `Result` here would carry an `Ok` arm no state of
/// the world can reach. Every sentence below is a reason an operator can read.
///
/// The config is read first, because a machine with nothing to offer has
/// nothing to present and no reason to dial anything. Then §8.2's channel set:
/// a box with no channel at all refuses with what its channels said, which for
/// a box holding no entries is the flat root's own sentence and nothing else.
/// One channel, served: advertise once, then `invocations` → run → `complete`,
/// forever. Serial by construction, which is REMOTE §10's deferred-concurrency
/// row unmoved — a host executes one invocation at a time, per engine it is
/// present at.
/// The follow-class read: this machine's next work, or the empty answer of a
/// hold that ended quietly. Both are ordinary; only a channel failure is not.
/// Post one capture back. The receipt is read rather than discarded, because
/// an engine that refused the completion — an expired handle, a slot addressed
/// elsewhere — is a thing this host must stop rather than keep answering into.
/// One gesture over the wire, in the one codec, read back with the one reply
/// decoder — so this client speaks exactly what every other seat speaks and can
/// add nothing to it.