Repository navigation
feat(sdk): advertise real team capabilities in squad.agent.md - #1881
Conversation
Generate a `Team Capabilities` block into `.github/agents/squad.agent.md` so an outer Agentic Workflows coordinator can see what this squad actually is: which specialists exist, what task types they cover, where to route a given domain, and — critically — what the squad cannot do. Everything is derived from live state (`.squad/team.md`, `.squad/routing.md`, the casting registry, and agent charters) via the existing roster/routing parsers and `parseAgentDoc`; no second routing model is introduced. Routing rows that point at agents who are no longer on the roster are dropped, and registry entries whose status is not `active` are excluded, so recasting or retiring a member cannot leave a stale name behind. Capability boundaries are evidence-based rather than aspirational: a capability is only claimed when some agent's role, focus, or charter supports it, and every unclaimed capability is listed explicitly under "Cannot". Authority (review / edit / advisory) is derived the same way and defaults to advisory when nothing is proven. All metadata is treated as untrusted data. Values are sanitized against markdown table breakage, HTML and comment injection, canary/marker forgery, invisible and bidi characters, and common prompt-injection phrasings before being embedded, and the block states inline that its contents are data. The block is rewritten on `squad init`, on `squad upgrade`, and whenever a cast is created, and is idempotent — identical inputs produce byte-identical output, and prose outside the markers is preserved. Closes #1608 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f92af31f-6e1f-48bc-b291-b206c4ba54a0
🟠 Impact Analysis — PR #1881Risk tier: 🟠 HIGH 📊 Summary
🎯 Risk Factors
📦 Modules Affectedci-workflows (1 file)
root (2 files)
squad-cli (3 files)
squad-sdk (6 files)
templates (1 file)
tests (2 files)
|
🏗️ Architectural Review
Automated architectural review — informational only. |
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 3 commits — consider squashing before review |
| ✅ | Not in draft | Ready for review |
| ❌ | Branch up to date | dev is 1 commit(s) ahead — rebase recommended |
| ❌ | 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 | 0 active Copilot thread(s) resolved (3 outdated skipped) |
| ✅ | CI passing | All checks passing |
Files Changed (15 files, +1776 −18)
| File | +/− |
|---|---|
.changeset/1608-team-capability-advertisement.md |
+10 −0 |
.github/agents/squad.agent.md |
+14 −3 |
.squad-templates/squad.agent.md |
+13 −2 |
packages/squad-cli/src/cli/core/cast.ts |
+18 −0 |
packages/squad-cli/src/cli/core/upgrade.ts |
+24 −7 |
packages/squad-cli/templates/squad.agent.md.template |
+13 −2 |
packages/squad-sdk/src/config/agent-doc.ts |
+13 −0 |
packages/squad-sdk/src/config/index.ts |
+1 −0 |
packages/squad-sdk/src/config/init.ts |
+11 −0 |
packages/squad-sdk/src/config/team-capabilities.ts |
+740 −0 |
packages/squad-sdk/src/ralph/triage.ts |
+25 −0 |
packages/squad-sdk/templates/squad.agent.md.template |
+13 −2 |
templates/squad.agent.md.template |
+13 −2 |
test/team-capabilities-lifecycle.test.ts |
+254 −0 |
test/team-capabilities.test.ts |
+614 −0 |
Total: +1776 −18
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
There was a problem hiding this comment.
🟡 Changes recommended
There are a few concrete robustness/security issues in team-capabilities.ts (sanitization gap for long HTML tags and insertion logic mismatch with documented behavior) that should be addressed before merging.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR implements “Team Capabilities” advertisement generation for squad.agent.md, so an outer coordinator can see the squad’s real specialist roster, supported task types, routing hints, and explicit capability boundaries derived from evidence (not aspiration).
Changes:
- Adds a new capability-profile builder + renderer + splice/sync workflow in the SDK, with strong sanitization to treat all metadata as untrusted data.
- Wires regeneration into lifecycle points (
squad init,squad upgrade, and casting) and avoids upgrade “local-backup churn” by stripping the generated block during template comparison. - Adds comprehensive unit + lifecycle tests and updates templates to include a marker-delimited placeholder region.
File summaries
| File | Description |
|---|---|
| test/team-capabilities.test.ts | New unit tests covering profile building, rendering, determinism/idempotence, stale-name rejection, sanitization, and budget bounds. |
| test/team-capabilities-lifecycle.test.ts | New lifecycle tests proving the agent file is rewritten on cast changes and that the file is overwrite-on-upgrade. |
| templates/squad.agent.md.template | Adds marker-delimited “Team Capabilities (generated)” placeholder region. |
| packages/squad-sdk/templates/squad.agent.md.template | Mirrors the root template placeholder update for SDK template distribution. |
| packages/squad-cli/templates/squad.agent.md.template | Mirrors the root template placeholder update for CLI template distribution. |
| .squad-templates/squad.agent.md | Updates canonical .squad-templates/ copy to include the placeholder region. |
| .github/agents/squad.agent.md | Updates repo’s checked-in agent doc with the placeholder region and tweaks model fallback wording. |
| packages/squad-sdk/src/ralph/triage.ts | Exports name-normalization and roster-resolution wrappers to reuse triage matching semantics. |
| packages/squad-sdk/src/config/team-capabilities.ts | New SDK module: builds capability profile, sanitizes metadata, renders marker block, and syncs it into squad.agent.md. |
| packages/squad-sdk/src/config/init.ts | Calls syncTeamCapabilities after writing/stamping the agent file (best-effort). |
| packages/squad-sdk/src/config/index.ts | Re-exports the new team-capabilities module from the config barrel. |
| packages/squad-sdk/src/config/agent-doc.ts | Extends agent-doc parsing to extract Expertise from the Identity section (for focus grounding). |
| packages/squad-cli/src/cli/core/upgrade.ts | Strips generated capabilities block during “local customization” comparison and re-syncs block after upgrade (best-effort). |
| packages/squad-cli/src/cli/core/cast.ts | Re-syncs block after casting changes (best-effort). |
| .changeset/1608-team-capability-advertisement.md | Changeset documenting the new generated capabilities block behavior. |
Review details
- Files reviewed: 15/15 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Regenerate capability advertisements after coordinator-managed add and retire flows, neutralize invisible comment delimiters, avoid negation-blind edit authority, and surface lifecycle sync failures. Closes #1608 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f92af31f-6e1f-48bc-b291-b206c4ba54a0
Require a plain charter map, insert generated capabilities before a leading Init Mode heading, and pin overlong HTML-like tag sanitization. Closes #1608 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: f92af31f-6e1f-48bc-b291-b206c4ba54a0
Closes #1608
What changed
Generated
.github/agents/squad.agent.mdnow contains a marker-delimited, schema-versioned Team Capabilities block for an outer Agentic Workflows coordinator:The block lists active specialists with role, authority, and charter-grounded focus; task types and domain routing from the current routing tables; and evidence-based
Can/Cannotboundaries.Authoritative data sources
.squad/team.mdvia the existingparseRoster.squad/routing.mdvia existingparseRoutingRulesandparseModuleOwnership.squad/casting/registry.jsonfor active/retired status.squad/agents/*/charter.mdvia the existingparseAgentDocNo second routing model is introduced. Routing rows whose agents are absent or retired are dropped, so recast and retire cannot preserve stale default-cast names.
Synchronization lifecycle
The generated block refreshes during:
squad initsquad upgradecreateTeam)squad upgradeafter the cast files changeIdentical inputs produce byte-identical output. Text outside the markers is preserved, and upgrade ignores the generated block when detecting user customizations. Sync failures are surfaced as warnings rather than silently swallowed.
Safety and capability boundaries
All roster, routing, and charter values are treated as untrusted data. Sanitization removes invisible/bidi/control characters before parsing delimiters, strips HTML comments/tags, neutralizes residual opening brackets, code fences, table pipes, heading structure, canary/marker forgery, and common prompt-injection phrases, then clamps cell length.
Authority (
review,edit,advisory) and the fixed capability vocabulary are evidence-driven. Negated claims such as “does not implement” and review-only phrases do not grant edit authority. Unknown roles default to advisory; absent capabilities are emitted underCannot.Tests and budget
n/no-syncwarnings only).origin/dev: +441 bytes. Generated sections cap specialists, task types, routing rows, and cell lengths; oversized-cast budget coverage remains under 8 KB.test/gh-aw-quality.test.ts: 156 passed, with the existing gh-aw lifecycle overwrites a merged cast with the default preset on later runs #1657 roster-guard case still failing unchanged fromdev.Changeset
Patch changeset for both
@bradygaster/squad-sdkand@bradygaster/squad-cli.