Skip to content

docs(architecture): Agent-Boundary Doctrine + audit every hand-off (#230)#241

Merged
azalio merged 1 commit into
mainfrom
feat/230-agent-boundary-doctrine
Jun 19, 2026
Merged

docs(architecture): Agent-Boundary Doctrine + audit every hand-off (#230)#241
azalio merged 1 commit into
mainfrom
feat/230-agent-boundary-doctrine

Conversation

@azalio

@azalio azalio commented Jun 19, 2026

Copy link
Copy Markdown
Owner

What

Resolves #230 — writes down the Agent-Boundary Doctrine and audits every live agent hand-off independent | relay.

Doctrine (in docs/ARCHITECTURE.md → "Agent-Boundary Doctrine")

Keep a separate sub-agent only when it adds an independent / adversarial perspective; collapse any pure-relay hop (a context whose only job is to paraphrase a prior agent's output, emitting no new verdict) into its caller.

It is a substance rule, not a wiring rule — what matters is whether the agent emits an independent verdict, not how many skills call it.

Audit (ground truth = subagent_type="…" dispatch sites in skill *.jinja sources, not docs)

All 9 shipped agents classified with file:line dispatch citations. The 8 pipeline-dispatched agents (task-decomposer, research-agent, actor, monitor, predictor, evaluator, final-verifier, reflector) each emit an independent verdict — none is a relay.

No relay hops remain. The only relay hops the doctrine condemns — the Self-MoA synthesizer (paraphrased 3× Actor/Monitor into one, no new verdict) and debate-arbiter — were already collapsed/removed in PR #240 (17c69bc). That is the keep/collapse decision acceptance criterion 3 names for the Synthesizer hop: the decision was collapse, already executed (the agent no longer exists, so a fresh cost/approval delta is moot).

Orphan resolved: documentation-reviewer → deliberate keep

Verified repo-wide: it has zero skill dispatch sites. But unlike the removed relays it is not a relay — it emits a unique docs-vs-source-architecture verdict (URL validation, completeness scoring, consistency). Under the substance rule it passes the doctrine; its missing caller is a discoverability gap, not redundancy. Retained as an optional, user-dispatchable agent (Task(subagent_type="documentation-reviewer", …)), now self-declaring a Dispatch status: annotation. Wiring it into a pipeline is deferred feature work, out of scope here.

Disposition decided via llm-council (unanimous on "keep + annotate", not remove or wire-in), per the convention to consult the council on changes with documented eval risk.

Enforcement

tests/test_agent_dispatch_audit.py makes the invariant a gate: any agent shipped with no dispatch site and not in DOCUMENTED_OPTIONAL_AGENTS (with a Dispatch status: annotation) fails — a silent orphan can't recur. Includes a non-empty discovery guard.

Why

#240 removed two orphaned relay agents but never wrote down the criterion that justified it. This codifies that criterion so future agent-boundary decisions are principled, and pins the one remaining ambiguity (documentation-reviewer) as a deliberate, documented choice.

Testing

  • make check2572 passed, 3 skipped, lint clean, check-render confirms generated trees match templates_src (agent annotation rendered to .claude/agents/ + templates/agents/).
  • New test negative-proofed: planting a dummy undispatched agent turns the guard red (Silent orphan agent(s): ['zzz-orphan-probe']); removing it restores green.

Scope notes

  • Doc-and-audit change only. No runtime behavior change.
  • Historical docs (e.g. docs/model-tier-trigger-experiment.md) left intact as dated records; only source-of-truth ARCHITECTURE.md updated.

🤖 Generated with Claude Code

…off (#230)

Document the explicit criterion in docs/ARCHITECTURE.md: keep a separate
sub-agent ONLY when it adds an independent/adversarial perspective; collapse
any pure-relay hop (a context that only paraphrases a prior agent's output,
emitting no new verdict) into its caller. It is a substance rule, not a
wiring rule.

Audit (ground truth = subagent_type="…" dispatch sites in the skill jinja
sources, not docs): all 8 pipeline-dispatched agents emit independent
verdicts and none is a relay. The only relay hops the doctrine condemns —
the Self-MoA synthesizer/debate-arbiter — were already collapsed in #240.

Resolve the orphaned documentation-reviewer (zero skill dispatch sites) as a
deliberate keep: unlike the removed relays it emits a unique, non-relay
docs-vs-source verdict, so it is retained as an optional, user-dispatchable
agent and now self-declares a "Dispatch status:" annotation.

Add tests/test_agent_dispatch_audit.py to enforce the invariant going
forward: any agent shipped with no dispatch site and not marked optional
fails the gate, preventing a silent orphan from recurring.

Closes #230
@azalio azalio merged commit 63635e5 into main Jun 19, 2026
6 checks passed
@azalio azalio deleted the feat/230-agent-boundary-doctrine branch June 19, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent-boundary doctrine: collapse pure-relay hand-offs, reserve multi-agent for adversarial roles (Atlassian Rovo "Long Horizon")

1 participant