The fan-out restored in 6683da5 had no degrade path for a target with no
spawn tool, which reproduces the silent degradation #116 was written
against. Step 4 now says to read serially and reduce each page to notes
when spawning is unavailable.
The change restores existing behaviour, so the version bump is a patch
(1.0.2) per skill-author's convention, not a minor. The body is trimmed
from 717 to under the 600-word ADR-0020 target without dropping any
instruction. ADR-0027 is updated to match.
Refs #116
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EGHFJextYtVQseaHPDDhxB
48 lines
3.4 KiB
Markdown
48 lines
3.4 KiB
Markdown
# `research` gets its fan-out back and keeps its tool list; a body must not disclaim spawning
|
|
|
|
**Status:** Accepted (2026-09-21)
|
|
|
|
`plugins/bin/.apm/skills/research/SKILL.md` once told the agent to "spawn one subagent per URL"
|
|
while its `allowed-tools` listed nothing that spawns. `WebFetch` was listed, so nothing hard-failed:
|
|
the skill degraded to serial fetches in the orchestrator's own context, and the "in parallel"
|
|
wording, the page cap and the "subagents summarise, orchestrator writes" gotcha quietly stopped
|
|
meaning anything. The #99 retrofit rewrote steps 4 and 5 as serial reads and said in the text that
|
|
no subagent tool was granted (#116).
|
|
|
|
**What #116 did not establish.** It read the missing tool as the cause. The repo's own sources
|
|
describe `allowed-tools` as pre-approval, not restriction: `skill-author/references/create.md:113`
|
|
("space-separated pre-approved tools; reduces permission prompts"), the agentskills.io
|
|
specification, and the Copilot plugin docs. On that reading an unlisted spawn tool would prompt, not
|
|
fail. What Claude Code, Copilot and Codex actually do with an unlisted tool is **not verified
|
|
here**, and neither is whether omitting the field grants anything. What is documented is that the
|
|
serial behaviour followed the step text, which told the agent to go serial.
|
|
|
|
**Decision.** `research` keeps its `allowed-tools` list and gets its parallel fan-out back in steps
|
|
4 and 5, with the "subagents read and summarise; the orchestrator writes every file" gotcha
|
|
restored (version 1.0.1 → 1.0.2). A skill body that instructs spawning must not be paired with text
|
|
saying spawning is unavailable. Step 4 carries a serial fallback for a target with no spawn tool, so
|
|
an unavailable spawn degrades visibly instead of silently.
|
|
|
|
The spawn tool is **not** added to the list. Its name is sourced for Claude Code (`Agent`) only; the
|
|
Copilot and Codex names are not known. On Claude Code, spawns therefore prompt instead of being
|
|
pre-approved. Add the tool once its name is sourced for each target.
|
|
|
|
**Corpus facts, with limits.** `write-docs`, `improve-codebase-architecture` and `forge` all omit
|
|
`allowed-tools` and instruct spawning subagents — `forge` from `references/author-routes.md` and
|
|
`references/version-bump.md`, not from its `SKILL.md`. That shows they spawn, not that a run
|
|
succeeded. `skill-author/SKILL.md:24` forbids spawning a subagent to recheck one's own work, which
|
|
is a different question and unaffected here. `CONTEXT.md` says a plugin-scope agent delegates to
|
|
skills because it cannot disclose to itself; nothing there bans a skill from delegating.
|
|
|
|
**The security cost is real and not mitigated.** "The orchestrator alone writes files" is prose,
|
|
not enforcement. The subagents read untrusted web pages, and nothing restricts what tools they
|
|
hold. Not done, by decision: an instruction to treat fetched page content as data, a cap on the
|
|
number of subagents (user-supplied URLs are uncapped, and the step 5 page cap bounds less once
|
|
reads run in parallel), and read-only subagents. `docs/research/ai-coding-factory/
|
|
ai-coding-factory-principles.md:53` recommends applying `allowed-tools` restrictions, which is why
|
|
the list was kept.
|
|
|
|
Rejected: dropping `allowed-tools` on the premise that it blocked spawning (unsupported by the
|
|
repo's own sources, and it widens the tool surface for nothing), and banning spawning in skills
|
|
(three skills instruct it, and `CONTEXT.md` does not forbid it).
|