ward agent: deliver mid-run comments to the running agent (design; the pessimistic complement to the #494 optimistic lock) #601

Open
opened 2026-07-04 08:37:52 +00:00 by coilysiren · 0 comments
Owner

Ask (Kai)

The harness driver should let the running agent know when a comment arrives mid-run. Kai is not certain of the mechanism - this issue is to design it (advisor pass first, then an engineer implements from the recommendation).

Why

Today the engineer seeds the issue body once at launch and never re-reads it, so a comment posted mid-run reaches only human readers, never the running agent - the reservation comment states this, and the only correction channel is "a new issue, dispatched fresh." That workaround is heavy for a small mid-course correction ("actually the param is X", "skip file Y", "reuse the existing SSM key"). A lightweight in-run steering channel would catch these without a full re-dispatch. (This very director session hit the pattern several times - every correction to a reserved run had to become a fresh issue.)

Design surface to resolve

  • Detection. The driver (ward agent, per --driver claude/codex/goose/opencode) polls the issue comments on an interval, diffing against the set present at launch to spot new ones.
  • Filtering / trust. Surface only genuine human comments - skip bot / reservation / CI / self comments. Name the trust boundary: a mid-run steering channel is a prompt-injection surface, so restrict it to the operator (issue owner / a trusted set), not arbitrary commenters. Low risk on Kai's single-operator forge, but the design must call it out rather than assume it away.
  • Delivery into the running session. How each driver injects. For Claude Code, feed the comment as a queued user message surfaced at the next turn boundary (not mid-tool-call, to avoid corrupting an in-flight action). Codex / goose need their own injection primitive. A driver with no injection path degrades to "note it, agent picks it up at its next checkpoint."
  • Interrupt vs queue. Default to the turn-boundary queue (safe). An explicit urgent/stop marker convention could hard-interrupt, but keep that optional.
  • Ack. The agent posts a brief reply when it ingests a mid-run comment, so the human knows it landed - closing the "reaches only human readers" gap the current design leaves open.

Relationship to ward#494 - complementary, not conflicting

#494 (conversation lock) and this (mid-run check) are two controls toward the same goal: don't let an engineer implement something incomplete. They are not opposite directions - they are the optimistic and pessimistic strategies for it:

  • #494 is the optimistic control - assume the seed is final, freeze the thread so the run proceeds on a known-final body; no late edit can silently desync the seed from what the operator now wants.
  • #601 (this) is the pessimistic control - assume a correction may still arrive, so actively check for new operator comments mid-run and fold them in before finishing.

They compose. Design them to interlock, not to pick a winner and not to change #494. A natural shape: the lock keeps untrusted / no-op churn off the thread, while a genuine operator comment is still detected and delivered into the run. The advisor should specify exactly how the two work together (what the lock still blocks, what the delivery channel still lets through, and how the operator's mid-run comment reaches the agent under the lock).

Doctrine impact

This is the pessimistic complement to "the engineer seeds once and never re-reads." Adopting it refines that invariant (a delivered operator comment is now a second, controlled input channel alongside "a new issue, dispatched fresh"), so the reservation-comment text and the container-agent AGENTS doctrine should be updated in the same change to describe both channels rather than only the new-issue one.

Deliverable (advisor)

A recommended mechanism, the per-driver injection approach, the trust-boundary handling, and the #494 reconciliation - posted as a design comment an engineer can implement from. No code change in this pass.

Refs

  • ward#507 comment (the seeded-once / never-re-reads statement).
  • ward#494 (conversation lock - the direct tension).
  • Container-agent reservation doctrine ("a correction goes to a new issue, dispatched fresh").

Provenance: director surface session, 2026-07-04.

## Ask (Kai) The harness driver should let the running agent know when a **comment arrives mid-run**. Kai is not certain of the mechanism - this issue is to **design** it (advisor pass first, then an engineer implements from the recommendation). ## Why Today the engineer seeds the issue body once at launch and **never re-reads it**, so a comment posted mid-run reaches only human readers, never the running agent - the reservation comment states this, and the only correction channel is "a new issue, dispatched fresh." That workaround is heavy for a small mid-course correction ("actually the param is X", "skip file Y", "reuse the existing SSM key"). A lightweight in-run steering channel would catch these without a full re-dispatch. (This very director session hit the pattern several times - every correction to a reserved run had to become a fresh issue.) ## Design surface to resolve - **Detection.** The driver (`ward agent`, per `--driver` claude/codex/goose/opencode) polls the issue comments on an interval, diffing against the set present at launch to spot new ones. - **Filtering / trust.** Surface only genuine human comments - skip bot / reservation / CI / self comments. Name the trust boundary: a mid-run steering channel is a **prompt-injection surface**, so restrict it to the operator (issue owner / a trusted set), not arbitrary commenters. Low risk on Kai's single-operator forge, but the design must call it out rather than assume it away. - **Delivery into the running session.** How each driver injects. For Claude Code, feed the comment as a **queued user message surfaced at the next turn boundary** (not mid-tool-call, to avoid corrupting an in-flight action). Codex / goose need their own injection primitive. A driver with no injection path degrades to "note it, agent picks it up at its next checkpoint." - **Interrupt vs queue.** Default to the turn-boundary queue (safe). An explicit urgent/stop marker convention could hard-interrupt, but keep that optional. - **Ack.** The agent posts a brief reply when it ingests a mid-run comment, so the human knows it landed - closing the "reaches only human readers" gap the current design leaves open. ## Relationship to ward#494 - complementary, not conflicting #494 (conversation lock) and this (mid-run check) are **two controls toward the same goal: don't let an engineer implement something incomplete.** They are not opposite directions - they are the optimistic and pessimistic strategies for it: - **#494 is the optimistic control** - assume the seed is final, freeze the thread so the run proceeds on a known-final body; no late edit can silently desync the seed from what the operator now wants. - **#601 (this) is the pessimistic control** - assume a correction may still arrive, so actively check for new operator comments mid-run and fold them in before finishing. They **compose**. Design them to interlock, not to pick a winner and not to change #494. A natural shape: the lock keeps untrusted / no-op churn off the thread, while a genuine **operator** comment is still detected and delivered into the run. The advisor should specify exactly how the two work together (what the lock still blocks, what the delivery channel still lets through, and how the operator's mid-run comment reaches the agent under the lock). ## Doctrine impact This is the pessimistic complement to "the engineer seeds once and never re-reads." Adopting it refines that invariant (a delivered operator comment is now a second, controlled input channel alongside "a new issue, dispatched fresh"), so the reservation-comment text and the container-agent AGENTS doctrine should be updated in the same change to describe both channels rather than only the new-issue one. ## Deliverable (advisor) A recommended mechanism, the per-driver injection approach, the trust-boundary handling, and the #494 reconciliation - posted as a design comment an engineer can implement from. No code change in this pass. ## Refs - ward#507 comment (the seeded-once / never-re-reads statement). - ward#494 (conversation lock - the direct tension). - Container-agent reservation doctrine ("a correction goes to a new issue, dispatched fresh"). Provenance: director surface session, 2026-07-04.
coilysiren changed title from ward agent: deliver mid-run comments to the running agent (design; reconcile with the #494 conversation-lock) to ward agent: deliver mid-run comments to the running agent (design; the pessimistic complement to the #494 optimistic lock) 2026-07-04 08:43:16 +00:00
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#601
No description provided.