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
//! The fire (DESIGN §3.3, §8.1 step 2): mint the conversation's name and spawn
//! `lernie prompt` **detached** — the goal exactly as the operator edited it.
//!
//! Split from [`exec`](super::exec) at §12's 300-line budget, along the seam the
//! design already draws: everything else in the start flow is a piped, gated
//! substrate step, while this is the one irreversible launch — and the one place
//! the §3.3 conversation mint runs for real. The mint is re-derived *here*, not
//! carried from the composer's preview: another instance may have taken the
//! predicted name between preview and Enter, so the preview is a prediction and
//! this mint is the truth.
use mint_conversation;
use ;
use crateCli;
use crateRng;
use crate;
use io;
use Path;
const PROMPT: &str = "prompt";
const NAME_FLAG: &str = "--name";
const YOG_NAME: &str = "YOG_NAME";
/// `lernie prompt --name <minted> <workspace> <goal>` fired **detached** (§8.1):
/// own process
/// group, stdin/stdout→null, stderr→the per-spawn sink ([`opslog::detached::sink`]),
/// `YOG_NAME=<workspace name>` layered (§8, §3.2 — the harness channel the goal
/// text no longer duplicates), cwd the §3.4 driver dir. `prepared` carries all
/// three, composed once by [`goal::compose_prepared`](super::goal).
///
/// The conversation name mints first ([`mint_conversation`] over `occupied` + the
/// injected `rng`); an exhausted pool leaves a `["yog-step","mint"]` row and
/// aborts before anything spawns (§4.2). The minted name rides `--name` (§3.3 as
/// ruled by bl-50f3): lernie commits it beside `goal.md`, the one durable home
/// the display ladder reads back — and on a lost-race re-mint the re-derived
/// name is what passes, since the mint here *is* the truth. What is sent is
/// `goal` **verbatim** — the operator's edited payload, unmutated (operator
/// ruling bl-6920): identity is `--name`'s alone, and lernie states the stored
/// name fact in its assembled context (lernie bl-d55f, released 0.0.4 —
/// `compose_system`'s `Your name is <name>.` in the system slot); yog prepends
/// nothing. The *logged* argv rides
/// the full goal through [`opslog::clip_goal`], which trims it so the serialized
/// line stays ≤ CAP/PIPE_BUF (§4.2 atomicity) — the *spawned* one is full. Only
/// the spawn is logged, and which line it writes is the outcome (bl-afa9): a
/// handoff logs [`DETACHED_EXIT`] and nothing else, a fork that never landed logs
/// the §4.2 synthetic-failure line with the error in `stderr`. A child that dies
/// *after* launching speaks through the sink, folded into the `-2` row at read
/// time (§13.3 amended).
///
/// Returns the **minted conversation name** — the one thing the fire learns that
/// no caller could have known beforehand (the preview only predicted it). It is
/// the handle the §3.4 focus claim is held by: the started root has no agent id
/// until the detached driver writes its branch, so the name is what identifies
/// the conversation until then ([`AppModel::await_conversation`](crate::AppModel::await_conversation)).