doctrine: prefer a sibling warded dispatch over an in-session subagent (architect capture-and-dispatch block) #374

Closed
opened 2026-06-26 07:28:05 +00:00 by coilysiren · 2 comments
Owner

What

Add a doctrine rule to the architect capture-and-dispatch block: when work is
delegable, prefer a sibling warded dispatch over an in-session subagent.

This encodes a reflex confirmed in practice: in a read-only architect session,
reaching for warded advisor #N (to design/research) or warded engineer #N (to
build) is better than fanning the same work out to an in-session subagent,
whenever reasonable. The sibling lands a durable, attributable artifact on the
canonical surface (an issue-thread comment, a pushed commit) that outlives the
session and the next carry can read. A subagent's output returns into the calling
agent's context and dies in this conversation's scrollback. In a read-only clone a
subagent also buys no extra reach - it reads the same substrate the caller already
can, so it is "the caller in parallel," not a durable hand-off.

The rule to add (tune the wording, keep the substance)

Prefer a sibling dispatch over an in-session subagent. When the work is
delegable - a design proposal, a research dig, an implementation - reach for a
sibling warded run (warded advisor #N to design or research, warded engineer #N to build) before an in-session subagent. The sibling lands a durable,
attributable artifact on the canonical surface (the issue thread, a pushed
commit) that outlives this session, and the next carry can read it. A subagent's
output dies in this conversation's scrollback. Reserve an in-session subagent for
read-only fan-out that only feeds your immediate reasoning and never needs to
outlive the session.

Where it lands (denormalized pair + doc + test)

The architect doctrine text is authored in three kept-in-sync places. Edit all:

  1. cmd/ward/container_bootstrap.go - the composed-into-context copy, inside the
    capture-and-dispatch block (around L697-712, after "Do not let a work item die
    in the conversation...").
  2. cmd/ward/containerassets/entrypoint.sh - the entrypoint's mirror of the same
    block (around L465-472). Keep the two byte-aligned the way they are today.
  3. docs/agent-architect.md - the human doc; add the same rule prose.
  4. cmd/ward/agent_architect_test.go - pins the doctrine text; update the
    assertion(s) so the new sentence is covered, not bypassed.

Scope note (open fork for Kai)

This lands the rule in the architect doctrine - the pure capture-and-dispatch
discipline where the sibling-vs-subagent choice is most live, and where it just
fired. The same reflex arguably applies to the director loop and any
dispatch-capable warded role. Left as a deliberate non-goal for this carry: a
role-agnostic ward agent-doctrine version. If the engineer sees a clean shared
home (e.g. a common agent-doctrine fragment both architect and director compose),
note it in a follow-up issue rather than widening this edit.

It does not belong in agentic-os AGENTS.md: that is the public-safe
universal base, and warded/its roles are not available to every reader, so a
warded-coupled rule there would break that file's scope contract.

Acceptance

  • The rule appears in all three doctrine surfaces (go heredoc, entrypoint, doc),
    byte-aligned where they already mirror.
  • agent_architect_test.go covers the new sentence and is green.
  • make build test vet lint (or the repo's ward-routed equivalent) green before
    push.

Filed from a read-only architect session (Kai asked to encode the reflexive
sibling-dispatch preference after it fired live on ward#373).

## What Add a doctrine rule to the architect **capture-and-dispatch** block: when work is delegable, prefer a **sibling warded dispatch** over an **in-session subagent**. This encodes a reflex confirmed in practice: in a read-only architect session, reaching for `warded advisor #N` (to design/research) or `warded engineer #N` (to build) is better than fanning the same work out to an in-session subagent, **whenever reasonable**. The sibling lands a durable, attributable artifact on the canonical surface (an issue-thread comment, a pushed commit) that outlives the session and the next carry can read. A subagent's output returns into the calling agent's context and dies in this conversation's scrollback. In a read-only clone a subagent also buys no extra reach - it reads the same substrate the caller already can, so it is "the caller in parallel," not a durable hand-off. ## The rule to add (tune the wording, keep the substance) > **Prefer a sibling dispatch over an in-session subagent.** When the work is > delegable - a design proposal, a research dig, an implementation - reach for a > sibling warded run (`warded advisor #N` to design or research, `warded engineer > #N` to build) before an in-session subagent. The sibling lands a durable, > attributable artifact on the canonical surface (the issue thread, a pushed > commit) that outlives this session, and the next carry can read it. A subagent's > output dies in this conversation's scrollback. Reserve an in-session subagent for > read-only fan-out that only feeds *your* immediate reasoning and never needs to > outlive the session. ## Where it lands (denormalized pair + doc + test) The architect doctrine text is authored in three kept-in-sync places. Edit all: 1. `cmd/ward/container_bootstrap.go` - the composed-into-context copy, inside the capture-and-dispatch block (around L697-712, after "Do not let a work item die in the conversation..."). 2. `cmd/ward/containerassets/entrypoint.sh` - the entrypoint's mirror of the same block (around L465-472). Keep the two byte-aligned the way they are today. 3. `docs/agent-architect.md` - the human doc; add the same rule prose. 4. `cmd/ward/agent_architect_test.go` - pins the doctrine text; update the assertion(s) so the new sentence is covered, not bypassed. ## Scope note (open fork for Kai) This lands the rule in the **architect** doctrine - the pure capture-and-dispatch discipline where the sibling-vs-subagent choice is most live, and where it just fired. The same reflex arguably applies to the **director** loop and any dispatch-capable warded role. Left as a deliberate non-goal for this carry: a role-agnostic ward agent-doctrine version. If the engineer sees a clean shared home (e.g. a common agent-doctrine fragment both architect and director compose), note it in a follow-up issue rather than widening this edit. It does **not** belong in agentic-os `AGENTS.md`: that is the public-safe **universal** base, and `warded`/its roles are not available to every reader, so a warded-coupled rule there would break that file's scope contract. ## Acceptance - The rule appears in all three doctrine surfaces (go heredoc, entrypoint, doc), byte-aligned where they already mirror. - `agent_architect_test.go` covers the new sentence and is green. - `make build test vet lint` (or the repo's ward-routed equivalent) green before push. Filed from a read-only architect session (Kai asked to encode the reflexive sibling-dispatch preference after it fired live on ward#373).
Author
Owner

🔒 Reserved by ward agent --driver claude — container engineer-claude-ward-374 on host 05ef6753c628 is carrying this issue (reserved 2026-06-26T07:28:13Z). 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 `engineer-claude-ward-374` on host `05ef6753c628` is carrying this issue (reserved 2026-06-26T07:28:13Z). 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

WARD-OUTCOME: done - sibling-dispatch-over-subagent rule landed in both mirrored architect doctrine surfaces, the doc, and a pinning test; merged and pushed to main.

Honest retro: the rule edit itself was the easy 20%. The substance was clear from the issue, and the go heredoc / entrypoint.sh pair stayed trivially byte-aligned since the inserted markdown is identical (the go side just wraps backticks). The one bite was the test: I first pinned a phrase that the doc-width line-wrap split across a newline ("conversation's\nscrollback"), so the substring check failed - switched to a phrase that lives on one line.

The real fight was docs/agent-architect.md already sitting flush against the 80-line / 4000-char documentation-layout cap. Adding any real prose busted it, so most of the work became tightening the surrounding doc (intro, the enforce-list bullets, the flag enumeration) to claw back ~800 chars without losing substance. It landed at exactly 77 lines / 3999 chars - which is a smell: this doc is one sentence away from forcing a split next time someone touches it. Worth a follow-up to either raise the cap for this file or split out the "what read-only enforces" table into its own doc.

Confidence is high on correctness - build/test/vet green, byte-alignment verified, issue auto-closed by the trailer. One pre-existing note unrelated to this carry: make lint is already red on main (revive/unconvert/unparam findings in agent_telemetry.go, ci.go, broker.go, etc.), none in my files; left untouched as out of scope. The deliberate non-goal (a role-agnostic agent-doctrine fragment shared by architect + director) still stands as a clean follow-up if the same reflex is wanted in the director loop.

WARD-OUTCOME: done - sibling-dispatch-over-subagent rule landed in both mirrored architect doctrine surfaces, the doc, and a pinning test; merged and pushed to main. Honest retro: the rule edit itself was the easy 20%. The substance was clear from the issue, and the go heredoc / entrypoint.sh pair stayed trivially byte-aligned since the inserted markdown is identical (the go side just wraps backticks). The one bite was the test: I first pinned a phrase that the doc-width line-wrap split across a newline ("conversation's\nscrollback"), so the substring check failed - switched to a phrase that lives on one line. The real fight was `docs/agent-architect.md` already sitting flush against the 80-line / 4000-char documentation-layout cap. Adding any real prose busted it, so most of the work became tightening the surrounding doc (intro, the enforce-list bullets, the flag enumeration) to claw back ~800 chars without losing substance. It landed at exactly 77 lines / 3999 chars - which is a smell: this doc is one sentence away from forcing a split next time someone touches it. Worth a follow-up to either raise the cap for this file or split out the "what read-only enforces" table into its own doc. Confidence is high on correctness - build/test/vet green, byte-alignment verified, issue auto-closed by the trailer. One pre-existing note unrelated to this carry: `make lint` is already red on main (revive/unconvert/unparam findings in agent_telemetry.go, ci.go, broker.go, etc.), none in my files; left untouched as out of scope. The deliberate non-goal (a role-agnostic agent-doctrine fragment shared by architect + director) still stands as a clean follow-up if the same reflex is wanted in the director loop.
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#374
No description provided.