Skip to content

feat(sdk,cli): add Devil's Advocate as a built-in always-on agent (companion to Fact Checker)#1294

Closed
tamirdresher wants to merge 1 commit into
bradygaster:devfrom
tamirdresher:squad/add-devils-advocate-agent
Closed

feat(sdk,cli): add Devil's Advocate as a built-in always-on agent (companion to Fact Checker)#1294
tamirdresher wants to merge 1 commit into
bradygaster:devfrom
tamirdresher:squad/add-devils-advocate-agent

Conversation

@tamirdresher

Copy link
Copy Markdown
Collaborator

squad init, squad cast, and squad upgrade already auto-scaffold Scribe, Ralph, RAI, and Fact Checker as always-on built-ins (per merged #1223). This adds a fifth: Devil's Advocate (😈) — a design challenger that owns counter-arguments, pre-mortems, assumption-surfacing, and alternative-approach exploration.

Why separate from Fact Checker

The pre-existing fact-checker role declared dual operating mode ("Devil's Advocate & Verification Agent") and its routingPatterns included "devil's advocate". In practice these are two distinct skills:

Question Owned by
"Is this claim true? Does this URL / version / API exist?" Fact Checker (empirical verification)
"Is this plan wise? What is the strongest argument against it? What would we do if X was forbidden?" Devil's Advocate (design challenge)

Mixing them blurs the role and makes it unclear which mode the agent is operating in. Splitting gives each a sharp scope.

Changes

  • New role devils-advocate in packages/squad-sdk/src/roles/catalog-engineering.ts (category: quality, emoji 😈) with design-challenge routing patterns: devil's advocate, steelman, pre-mortem, counter-argument, what could go wrong, challenge the plan, alternative approach, play devil.
  • New charter template packages/squad-cli/templates/devils-advocate-charter.md used by squad upgrade (ensureBuiltinAgents). Documents methodology (Steelman → Surface assumptions → Pre-mortem → Alternatives → Risk acceptance) and explicitly delineates from Fact Checker.
  • init.ts — adds devils-advocate to the default agents: array. Fresh squad init produces .squad/agents/devils-advocate/.
  • upgrade.ts — adds devils-advocate to ensureBuiltinAgents. Idempotent: never overwrites a customized charter.
  • cast.tsdevilsAdvocateMember(), devilsAdvocateCharter(), hasDevilsAdvocate check in createTeam, charter-dispatch branch, roster banner line. Interactive squad cast now offers Devil's Advocate as an always-on advisory agent.
  • AGENT_TEMPLATES map entry for devils-advocate; fact-checker entry clarified to reflect its now verification-only focus.
  • TEMPLATE_MANIFEST entry for devils-advocate-charter.mdtemplates/devils-advocate-charter.md.
  • Fact Checker cleanup: removed "devil's advocate" from fact-checker's routingPatterns so the new role owns that routing exclusively. Fact Checker's expertise / voice remain unchanged.

Test coverage

  • New test/devils-advocate-role.test.ts — 7 assertions: catalog presence, routing patterns, distinct expertise (does NOT claim "claim verification"), boundary delegation to Fact Checker, template file existence, differs-from-Fact-Checker section, methodology section.
  • Updated test/fact-checker-role.test.ts — asserts "devil's advocate" is no longer in fact-checker's routing.
  • Updated test/template-routing.test.ts — TEMPLATE_MANIFEST pin includes the new entry.

Verified:

  • npm run lint — passes
  • 310/310 tests pass across init / cli/init / sdk / cast / role / template suites

Out of scope

packages/squad-sdk/templates/ does not currently mirror fact-checker-charter.md either (only Rai is in both); the SDK runtime path reads from CLI templates via getTemplatesDir(). Mirroring all charter templates to SDK templates is a separate cleanup that should not block this addition.

…mpanion to Fact Checker)

squad init/cast/upgrade already auto-scaffold Scribe, Ralph, RAI, and Fact
Checker as always-on built-ins (bradygaster#1223). This adds a fifth: Devil's Advocate
(`devils-advocate`, emoji 😈) — a design challenger that owns
counter-arguments, pre-mortems, assumption-surfacing, and alternative-approach
exploration.

Why separate from Fact Checker:

The fact-checker role declared dual operating mode ("Devil's Advocate &
Verification Agent") and its routingPatterns included `devil's advocate`.
In practice these are two distinct skills:

* Fact Checker — "Is this claim true? Does this URL/version/API exist?"
  (empirical verification)
* Devil's Advocate — "Is this plan wise? What is the strongest argument
  against it? What would we do if X was forbidden?" (design challenge)

Splitting them gives each agent a sharp scope and a distinct charter.

Changes:

* New role devils-advocate in roles/catalog-engineering.ts (category: quality,
  emoji 😈) with design-challenge routingPatterns (devil's advocate, steelman,
  pre-mortem, counter-argument, ...).
* New charter template packages/squad-cli/templates/devils-advocate-charter.md
  used by `squad upgrade` (ensureBuiltinAgents).
* init.ts — adds devils-advocate to the default agents[] array. Fresh
  `squad init` produces .squad/agents/devils-advocate/.
* upgrade.ts — adds devils-advocate to ensureBuiltinAgents. Idempotent
  (never overwrites a customized charter).
* cast.ts — devilsAdvocateMember/devilsAdvocateCharter, hasDevilsAdvocate
  check in createTeam, charter-dispatch branch, roster banner line.
* AGENT_TEMPLATES entry for devils-advocate; fact-checker entry clarified to
  reflect its now verification-only focus.
* TEMPLATE_MANIFEST entry for devils-advocate-charter.md.
* Fact Checker cleanup: removed `devil's advocate` from fact-checker's
  routingPatterns so the new role owns that routing exclusively.

Test coverage:

* New test/devils-advocate-role.test.ts — 7 assertions (catalog presence,
  routing patterns, distinct expertise, boundary delegation to Fact Checker,
  template file existence, differs-from-Fact-Checker section, methodology).
* Updated test/fact-checker-role.test.ts — asserts `devil's advocate` is
  no longer in fact-checker's routing.
* Updated test/template-routing.test.ts — TEMPLATE_MANIFEST pin includes
  devils-advocate-charter.md.

Verified: 310/310 tests pass across init/cli/init/sdk/cast/role/template
suites. `npm run lint` clean.

Out of scope: mirroring the new charter template to packages/squad-sdk/
templates/. Only Rai-charter.md is in both today; fact-checker-charter.md
is only in CLI templates. The SDK runtime reads via CLI's getTemplatesDir(),
so this works. A general charter-template mirroring cleanup is separate.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 13, 2026 07:55
@github-actions

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit 304ff55

PR Scope: 📦🔧 Mixed (product + infrastructure)

⚠️ 2 item(s) to address before review

Status Check Details
Single commit 1 commit — clean history
Not in draft Ready for review
Branch up to date Up to date with dev
Copilot review No Copilot review yet — it may still be processing
Changeset present Changeset file found
Scope clean No .squad/ or docs/proposals/ files
No merge conflicts No merge conflicts
Copilot threads resolved No Copilot review threads
CI passing 7 check(s) still running

Files Changed (11 files, +329 −3)

File +/−
.changeset/add-devils-advocate-agent.md +42 −0
packages/squad-cli/src/cli/core/cast.ts +76 −0
packages/squad-cli/src/cli/core/init.ts +5 −0
packages/squad-cli/src/cli/core/templates.ts +6 −0
packages/squad-cli/src/cli/core/upgrade.ts +1 −0
packages/squad-cli/templates/devils-advocate-charter.md +69 −0
packages/squad-sdk/src/config/init.ts +5 −1
packages/squad-sdk/src/roles/catalog-engineering.ts +44 −1
test/devils-advocate-role.test.ts +74 −0
test/fact-checker-role.test.ts +6 −1
test/template-routing.test.ts +1 −0

Total: +329 −3


This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.

@github-actions

Copy link
Copy Markdown
Contributor

🟡 Impact Analysis — PR #1294

Risk tier: 🟡 MEDIUM

📊 Summary

Metric Count
Files changed 11
Files added 3
Files modified 8
Files deleted 0
Modules touched 4

🎯 Risk Factors

  • 11 files changed (6-20 → MEDIUM)
  • 4 modules touched (2-4 → MEDIUM)

📦 Modules Affected

root (1 file)
  • .changeset/add-devils-advocate-agent.md
squad-cli (5 files)
  • packages/squad-cli/src/cli/core/cast.ts
  • packages/squad-cli/src/cli/core/init.ts
  • packages/squad-cli/src/cli/core/templates.ts
  • packages/squad-cli/src/cli/core/upgrade.ts
  • packages/squad-cli/templates/devils-advocate-charter.md
squad-sdk (2 files)
  • packages/squad-sdk/src/config/init.ts
  • packages/squad-sdk/src/roles/catalog-engineering.ts
tests (3 files)
  • test/devils-advocate-role.test.ts
  • test/fact-checker-role.test.ts
  • test/template-routing.test.ts

This report is generated automatically for every PR. See #733 for details.

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Architectural Review

⚠️ Architectural review: 1 warning(s), 1 info.

Severity Category Finding Files
🟡 warning bootstrap-area 4 file(s) in the bootstrap area (packages/squad-cli/src/cli/core/) were modified. These files must maintain zero external dependencies. Review carefully. packages/squad-cli/src/cli/core/cast.ts, packages/squad-cli/src/cli/core/init.ts, packages/squad-cli/src/cli/core/templates.ts, packages/squad-cli/src/cli/core/upgrade.ts
ℹ️ info template-sync Template files changed in packages/squad-cli/templates/ but not in other template locations. If these templates should stay in sync, consider updating the others too. Changed: packages/squad-cli/templates/, Unchanged: templates/, .squad-templates/, .github/workflows/

Automated architectural review — informational only.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new built-in, always-on Devil’s Advocate agent as a companion to Fact Checker, wiring it through the SDK role catalog and CLI onboarding flows (init, cast, upgrade) and extending the template manifest and tests accordingly.

Changes:

  • Add devils-advocate role to the SDK engineering role catalog (with dedicated routing patterns) and remove Devil’s Advocate routing from Fact Checker.
  • Add a Devil’s Advocate charter template and propagate it via CLI template manifest + ensureBuiltinAgents() during squad upgrade.
  • Wire Devil’s Advocate into CLI init defaults and cast (member creation, charter dispatch, and summary banner), plus add/adjust tests.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/squad-sdk/src/roles/catalog-engineering.ts Adds the new devils-advocate role and removes DA routing from Fact Checker.
packages/squad-sdk/src/config/init.ts Adds devils-advocate to AGENT_TEMPLATES and refocuses Fact Checker description.
packages/squad-cli/templates/devils-advocate-charter.md New charter template for Devil’s Advocate.
packages/squad-cli/src/cli/core/templates.ts Adds template-manifest entry for devils-advocate-charter.md.
packages/squad-cli/src/cli/core/init.ts Adds Devil’s Advocate to the default always-on agents list for squad init.
packages/squad-cli/src/cli/core/upgrade.ts Ensures Devil’s Advocate is scaffolded as a built-in on squad upgrade.
packages/squad-cli/src/cli/core/cast.ts Adds Devil’s Advocate as an always-on built-in in squad cast (member + charter + banner).
test/devils-advocate-role.test.ts New test coverage for the new role + charter template content.
test/fact-checker-role.test.ts Updates assertion to ensure Fact Checker no longer routes Devil’s Advocate work.
test/template-routing.test.ts Updates TEMPLATE_MANIFEST pin to include the new charter template.
.changeset/add-devils-advocate-agent.md Declares minor bumps for SDK/CLI and documents the addition.

Comment on lines +505 to +507
function devilsAdvocateMember(): CastMember {
return { name: "Devil's Advocate", role: "Devil's Advocate", scope: 'Design challenge, pre-mortem analysis, assumption surfacing, alternative-approach exploration', emoji: '😈' };
}
Comment on lines +784 to +785
} else if (member.name === "Devil's Advocate" && !hasDevilsAdvocate) {
charter = devilsAdvocateCharter();
Comment on lines 209 to 216
'fact-checker': {
displayName: 'Fact Checker',
description: 'Devil\'s advocate and verification agent — validates claims, detects hallucinations, and runs counter-hypotheses.'
description: 'Verification agent — validates claims, detects hallucinations, checks that URLs / package versions / API endpoints actually exist.'
},
'devils-advocate': {
displayName: "Devil's Advocate",
description: 'Design challenger and pre-mortem analyst — surfaces hidden assumptions, constructs the strongest counter-argument, and sketches alternative approaches before the team converges.'
}
@tamirdresher

Copy link
Copy Markdown
Collaborator Author

Closing per design correction.

I re-read the source-of-truth issues + PRs after Tamir's review feedback:

Fact Checker IS the Devil's Advocate. Splitting them into two separate agents (as this PR did) contradicts the design and creates a redundant role. The right approach for further work in this area is to enrich the existing single fact-checker agent's charter to better surface the dual-mode behavior — that's what #1254 is already doing.

User input on 2026-06-13: "fact checker and devils advicate are one subagnet and not 2, look at the issues and other PRs that i did about it to make sure you understnad"

The reverted change is also rolled back from the local stabilization stack branch (tamirdresher/v010-stabilization-stack) at commit cf95e8fc. No follow-up code changes needed.

tamirdresher pushed a commit to tamirdresher/squad that referenced this pull request Jun 13, 2026
@tamirdresher tamirdresher deleted the squad/add-devils-advocate-agent branch June 13, 2026 09:34
tamirdresher added a commit that referenced this pull request Jun 13, 2026
…#1299) (#1300)

* fix(docs): tell coordinator to roster Fact Checker on first-time cast (#1299)

squad init correctly creates .squad/agents/fact-checker/ on disk (per
merged PR #1223). But when the user opens copilot --agent squad and the
coordinator runs first-time casting, it OMITS Fact Checker from the
team.md ## Members table while including Scribe, Ralph, and Rai.

Root cause: .squad-templates/squad.agent.md had two gaps:
1. Line 56 said "team size (typically 4-5 + Scribe)" — naming only Scribe
2. Rai had a dedicated ## Rai section with explicit "Rai always appears
   in team.md" instruction — Fact Checker had no equivalent section

So the model added Rai (because instructed to) but had no instruction to
add Fact Checker, even though the agent dir was scaffolded on disk.

Fix:
* Update team-size line to name all 4 always-on built-ins: Scribe + Ralph
  + Rai + Fact Checker
* Add full ## Fact Checker — Verification & Devil's Advocate section
  mirroring the Rai pattern: roster-entry instruction, dual operating
  mode (per #789 + #1254), trigger phrase table, confidence ratings, DA
  brief structure, boundaries, state location

Sync via sync-templates.mjs --sync propagates squad.agent.md changes to
all 4 mirror targets: .squad-templates/, templates/, packages/squad-cli/
templates/, packages/squad-sdk/templates/, .github/agents/.

Tests: new test/squad-agent-roster.test.ts runs against all 4 template
targets and asserts:
* The "Determine team size" line names all 4 built-ins
* A ## Fact Checker section exists with "always appears in team.md"
* The section declares dual operating mode (anchors #789 + #1254 design
  so a future PR can't accidentally split Fact Checker and Devil's
  Advocate again — cf. closed PR #1294)
* Existing Ralph + Rai sections still present
16/16 pass.

Closes #1299

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* doc(squad.agent.md): clarify Fact Checker is exempt from casting + correct on-demand reference path

Reviewer follow-ups on #1300:

1. Team-size phrasing — the line read 'typically 4-5 + Scribe + Ralph +
   Rai + Fact Checker' which a model could parse as arithmetic
   (4-5 + 4 = 8-9, but it could also collapse). Rewrote it to make the
   composition explicit: '4-5 cast (user-domain) agents + 4 always-on
   built-ins = 8-9 total roster entries'.

2. Cast-exemption parity — Scribe, Ralph, and Rai each have an
   explicit 'exempt from casting' bullet but Fact Checker did not.
   Added the matching bullet right after Rai's.

3. Bad on-demand reference path — the FC section pointed at
   '.squad/templates/fact-checker-charter.md'. That file IS shipped
   (TEMPLATE_MANIFEST destination 'templates/fact-checker-charter.md')
   but only AFTER 'squad init' or 'squad upgrade' has populated
   .squad/templates/. A reader of squad.agent.md on an
   un-initialized repo (or in .github/agents/ on the cloud agent
   surface) would follow a dead link. Repointed to the
   '.squad/agents/fact-checker/charter.md' instance that
   ensureBuiltinAgents creates as part of the same init/upgrade
   path — that's where the rich charter actually lives at runtime
   per #1299 + #1301.

All 4 mirrored copies re-synced via scripts/sync-templates.mjs.
fact-checker-role.test.ts: 8/8 pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
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.

2 participants