pub struct CloseRule { /* private fields */ }Expand description
Constraint 4’s close rule as a pure, line-fed state machine: stdin may be
released only once a DEVFLOW_RESULT marker has appeared inside a
TOP-LEVEL result event and the background-task list has drained.
An AND of two arms, neither sufficient alone:
- Marker arm. Satisfied only by
[
crate::agent_result::event_is_top_level_result_marker] — a composition of the existingis_top_levelpredicate and the existing marker parser, never a looser text search. The CLI echoes the operator’s prompt back into the same stdout, and DevFlow’s own stage prompts discussDEVFLOW_RESULTmarkers at length, so marker text alone is not evidence (T-31-01; the same echo produced the checkpoint false positive 30-05 fixed). - Drain arm. Satisfied when no
background_tasks_changedevent has ever announced anything (vacuous — the common single-plan case) or when the most recent one carried an empty list.
The drain alone is never a stop signal. 30c/30d measured the
drain-to-final-result lag at 4.54–11.51s across 14 trials; closing at the
drain would have truncated the final orchestrator turn in all seven 30d
trials.
Never count result events. Constraint 7: the CLI coalesces
completions, so a wave whose children finish together produces one result
for several of them — a shape superficially indistinguishable from “one
child delivered, one lost”. The drained list is the only thing separating
those two. Per 30-04 the drain arm is defensive rather than load-bearing
(n=2 Mode B trials delivered everything without it); that is the recorded
reason to keep it cheaply, not a reason to drop it.
A line that does not parse as JSON is ignored by this rule — it can neither satisfy nor block either arm — but it is still teed verbatim to the capture file by the reader thread. A torn line therefore cannot silently decide anything, and cannot be silently lost either.