agent: warded director should ask once at init whether to kick off by draining the headless queue #361

Closed
opened 2026-06-26 01:18:44 +00:00 by coilysiren · 2 comments
Owner

Goal

At warded director startup, ask the human once - at the beginning of init, before the first drain tick - whether to kick off by burning down the headless queue. Do not silently auto-start the drain.

Behavior

When director starts, its startup instructions (the director seed from ward#351) should have it ask the human a single question up front, e.g. "Kick off by draining the headless backlog now?":

  • yes -> begin the autonomous drain heartbeat (dispatch engineers, poll, reconcile) per the ward#351 flow.
  • no -> skip the initial drain and go straight to the interactive surface, where the human directs; a drain can begin later once they hand it work / direction.

Asked exactly once, at init. It is not re-asked per tick, and it is not re-asked on subsequent drain cycles after a surface -> direction -> resume - only the very first kickoff is gated. After the one-time answer, the heartbeat / surface flow proceeds exactly as designed (ward#350/#351).

Why

Fits the managed / human-in-the-loop model (ward#350: director is never detached, the human is in the loop). Even the opening autonomous drain is a deliberate opt-in, not an assumption - so a freshly-launched director that you only meant to talk to does not immediately start spinning up engineers.

Where

This is a change to director's startup seed / instructions (the prompt the director session is seeded with in ward#351, cmd/ward/agent_director.go), not a new flag - the interactive director simply asks first and branches on the answer. (--dry-run stays a separate show-and-exit path.)

Acceptance

  • A fresh warded director asks once, at init, whether to drain the headless queue; "yes" starts the drain, "no" surfaces to interactive immediately.
  • The question is asked only once - not per tick, not on later resume cycles.
  • The rest of the heartbeat / surface behavior is unchanged.
  • make build, make test, make vet, make lint green.

Sequencing

Touches cmd/ward/agent_director.go (the director seed), which the in-flight ward#355 (+ward#352) run is editing - land this after that to avoid a conflict.

References

ward#350 (the unified-director design, human-in-the-loop), ward#351 (the spine + the startup seed this modifies), ward#355 / ward#352 (in-flight on the same file).

## Goal At `warded director` startup, **ask the human once** - at the beginning of init, before the first drain tick - whether to kick off by burning down the headless queue. Do not silently auto-start the drain. ## Behavior When director starts, its **startup instructions** (the director seed from ward#351) should have it ask the human a single question up front, e.g. "Kick off by draining the headless backlog now?": - **yes** -> begin the autonomous drain heartbeat (dispatch engineers, poll, reconcile) per the ward#351 flow. - **no** -> skip the initial drain and go straight to the interactive surface, where the human directs; a drain can begin later once they hand it work / direction. **Asked exactly once, at init.** It is not re-asked per tick, and it is not re-asked on subsequent drain cycles after a surface -> direction -> resume - only the very first kickoff is gated. After the one-time answer, the heartbeat / surface flow proceeds exactly as designed (ward#350/#351). ## Why Fits the managed / human-in-the-loop model (ward#350: director is never detached, the human is in the loop). Even the opening autonomous drain is a deliberate opt-in, not an assumption - so a freshly-launched director that you only meant to talk to does not immediately start spinning up engineers. ## Where This is a change to director's **startup seed / instructions** (the prompt the director session is seeded with in ward#351, `cmd/ward/agent_director.go`), not a new flag - the interactive director simply asks first and branches on the answer. (`--dry-run` stays a separate show-and-exit path.) ## Acceptance - A fresh `warded director` asks once, at init, whether to drain the headless queue; "yes" starts the drain, "no" surfaces to interactive immediately. - The question is asked only once - not per tick, not on later resume cycles. - The rest of the heartbeat / surface behavior is unchanged. - `make build`, `make test`, `make vet`, `make lint` green. ## Sequencing Touches `cmd/ward/agent_director.go` (the director seed), which the in-flight ward#355 (+ward#352) run is editing - land this **after** that to avoid a conflict. ## References ward#350 (the unified-director design, human-in-the-loop), ward#351 (the spine + the startup seed this modifies), ward#355 / ward#352 (in-flight on the same file).
Author
Owner

🔒 Reserved by ward agent --driver claude — container ward-ward-issue-361-claude-6be51b6e on host 4f2062d4fed1 is carrying this issue (reserved 2026-06-26T02:40:51Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); --force overrides.

— Claude (she/her), via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --driver claude` — container `ward-ward-issue-361-claude-6be51b6e` on host `4f2062d4fed1` is carrying this issue (reserved 2026-06-26T02:40:51Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (2h0m0s TTL); `--force` overrides. <!-- ward-agent-signature --> — Claude (she/her), via `ward agent`
Author
Owner

Landed. The interesting twist: the issue framed this as a change to the director "startup seed," but the real director isn't a seeded LLM session — it's a deterministic Go heartbeat (runDirectorLoop) that only reaches for an LLM in per-tick one-shots. So the faithful lever was a one-time gate at the top of the loop, threaded through the directorBackend seam (confirmKickoff) and reusing the ward#366 pre-launch gate's TTY probe + writers. That made it cleanly testable on both branches without a terminal, which I'm confident in.

One judgment call worth flagging: I defaulted a bare Enter (and any no-terminal run) to drain, matching the existing pre-launch gate's "Enter proceeds" convention. The "Why" section leans "deliberate opt-in," which could argue for defaulting to no instead — easy to flip if you'd rather Enter mean "just talk."

What actually fought back wasn't the code — it was the doc/comment size caps. The 2-line comment cap and the 80-line/4000-char caps on docs/agent-director.md meant a real fight to fit the new section; I had to tighten existing prose to claw back ~500 chars. The pre-commit trufflehog hook also blocked the commit because the binary ships via Brew and wasn't in this container — installing it was its own little detour. No follow-ups I'd file beyond reconsidering that default if it doesn't match your intent.

Landed. The interesting twist: the issue framed this as a change to the director "startup seed," but the real director isn't a seeded LLM session — it's a deterministic Go heartbeat (`runDirectorLoop`) that only reaches for an LLM in per-tick one-shots. So the faithful lever was a one-time gate at the top of the loop, threaded through the `directorBackend` seam (`confirmKickoff`) and reusing the ward#366 pre-launch gate's TTY probe + writers. That made it cleanly testable on both branches without a terminal, which I'm confident in. One judgment call worth flagging: I defaulted a bare Enter (and any no-terminal run) to *drain*, matching the existing pre-launch gate's "Enter proceeds" convention. The "Why" section leans "deliberate opt-in," which could argue for defaulting to *no* instead — easy to flip if you'd rather Enter mean "just talk." What actually fought back wasn't the code — it was the doc/comment size caps. The 2-line comment cap and the 80-line/4000-char caps on `docs/agent-director.md` meant a real fight to fit the new section; I had to tighten existing prose to claw back ~500 chars. The pre-commit `trufflehog` hook also blocked the commit because the binary ships via Brew and wasn't in this container — installing it was its own little detour. No follow-ups I'd file beyond reconsidering that default if it doesn't match your intent.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#361
No description provided.