fix(#2771): advisor mode spawns registered gsd-advisor-researcher subagent instead of general-purpose (#2884)

* test(#2771): advisor mode must spawn gsd-advisor-researcher, not general-purpose

* fix(#2771): spawn registered gsd-advisor-researcher subagent instead of general-purpose in advisor mode

universal-anti-patterns rule 10 (injected into discuss-phase via <required_reading>)
says NEVER use non-GSD agent types. The advisor mode spawned general-purpose and
manually told the agent to read the def — but gsd-advisor-researcher IS registered,
so spawning by type auto-loads it. Drop the manual-read prompt line (re-specifying
the def is a drift risk) and use the registered type.

* chore(#2771): changeset fragment (mentions follow-up #2883)

* test(#2771): widen manual-read-line regex to deny phrasing variants (review minor)

/read\s+@.*gsd-advisor-researcher\.md/i (case-insensitive, any 'read @' lead-in)
so a drift variant like 'Read @' or 'Load @' can't sneak the manual-def-read back in.

* chore(#2771): backfill changeset PR number (2884)

---------

Co-authored-by: Test <test@example.com>
This commit is contained in:
Tom Boucher
2026-07-30 17:25:55 -04:00
committed by GitHub
parent 185da024cb
commit dbb0a653be
3 changed files with 50 additions and 4 deletions

View File

@@ -0,0 +1,5 @@
---
type: Fixed
pr: 2886
---
**Discuss-phase advisor mode now spawns the registered `gsd-advisor-researcher` subagent instead of `general-purpose`** — resolving a contradiction with the universal-anti-patterns rule (injected into the same context) that forbids non-GSD agent types. The manual "read the agent def" prompt line is dropped (spawning by type auto-loads it). (#2771; the sibling assumptions-site needs a design decision — filed as #2883)

View File

@@ -92,16 +92,14 @@ research agents.
```
Agent(
prompt="First, read @~/.claude/agents/gsd-advisor-researcher.md for your role and instructions.
<gray_area>{area_name}: {area_description from gray area identification}</gray_area>
prompt="<gray_area>{area_name}: {area_description from gray area identification}</gray_area>
<phase_context>{phase_goal and description from ROADMAP.md}</phase_context>
<project_context>{project name and brief description from PROJECT.md}</project_context>
<calibration_tier>{resolved calibration tier: full_maturity | standard | minimal_decisive}</calibration_tier>
Research this gray area and return a structured comparison table with rationale.
${AGENT_SKILLS_ADVISOR}",
subagent_type="general-purpose",
subagent_type="gsd-advisor-researcher",
model="{ADVISOR_MODEL}",
description="Research: {area_name}"
)

View File

@@ -0,0 +1,43 @@
// allow-test-rule: structural-implementation-guard (#2771)
'use strict';
// Regression guard for #2771: the discuss-phase advisor mode must spawn the REGISTERED
// `gsd-advisor-researcher` subagent (auto-loads the agent def), not `general-purpose` —
// which contradicts universal-anti-patterns rule 10 (injected into discuss-phase via
// <required_reading>): "NEVER use non-GSD agent types — ALWAYS use gsd-{agent}".
// Spawning general-purpose + a manual "read the agent def" prompt re-specifies what the
// def already owns (a drift risk; the same shape assumptions's answer_validation hit).
const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('fs');
const path = require('path');
const ADVISOR_MD = path.join(
__dirname, '..', 'gsd-core', 'workflows', 'discuss-phase', 'modes', 'advisor.md'
);
test('advisor mode spawns the registered gsd-advisor-researcher subagent, not general-purpose (#2771)', () => {
const src = fs.readFileSync(ADVISOR_MD, 'utf8');
// Locate the Agent() block that researches gray areas.
const agentIdx = src.indexOf('subagent_type=');
assert.ok(agentIdx !== -1, 'advisor.md must contain an Agent() subagent_type declaration');
assert.ok(
src.includes('subagent_type="gsd-advisor-researcher"'),
'advisor mode must spawn subagent_type="gsd-advisor-researcher" (the registered agent def auto-loads) — not general-purpose (#2771, universal-anti-patterns rule 10)'
);
assert.ok(
!src.includes('subagent_type="general-purpose"'),
'advisor mode must NOT spawn subagent_type="general-purpose" (contradicts universal-anti-patterns rule 10, injected into the same context) (#2771)'
);
// The manual "read @.../gsd-advisor-researcher.md" prompt line must be gone —
// spawning by type auto-loads the def; re-specifying it is a drift risk. Deny the
// full class (any "read @" lead-in, case-insensitive) so a phrasing variant can't
// sneak the drift back in.
assert.ok(
!/read\s+@.*gsd-advisor-researcher\.md/i.test(src),
'advisor mode must not manually instruct reading the agent def — spawning by type auto-loads it (#2771)'
);
});