Repository navigation
Description
Part of #2438 (PR 2 of the epic's PR plan, Wave 2). Starts after PR 1 merges. Can be developed in parallel with PR 3; they don't touch the same files.
Goal
Ship the first real HarnessAdapter, built on the Claude Agent SDK (TypeScript), so squad_backend_send_message admits turns instead of returning unavailable. This is the critical path for promoting the v0.2 profiles: client-harness-adapters-v0.2 §15.1 needs contract tests against Copilot plus one non-Copilot host, and client-backend-decoupling-v0.2 §14.4 needs at least one real execution harness.
Kept as its own PR so spec reviewers can read it against harness-adapters §15 and decoupling §14 without unrelated changes.
Settle before implementing
Record the answer in #2438 or the PR description:
- Open question 2: does the harness run subagents through the Agent SDK's
agentsoption (onequery()per conversation), or onequery()per member run? This decides howtaskevents map to broker run identity (harness-adapters §7.2).
Scope
Interface: HarnessAdapter in packages/squad-sdk/src/backend/types.ts (~L382). Registry: packages/squad-sdk/src/backend/harness-registry.ts.
- Adapter with id
claude-agent-sdk:-
submit→query(). Stream assistant and tool messages asmessageevents, and subagent work astaskevents. Deduplicate by(conversationId, runId, seq)oroperationIdacross retries and restarts. -
approval-requested→ thecanUseToolcallback. The harness supplies the opaquehash(decoupling §8): SHA-256 of the canonical tool name and input. -
respondApprovalresolves the pendingcanUseToolpromise, idempotently byoperationId. -
cancel(runId)aborts the query, idempotently byoperationId. - Stamp every outbound event with the submission
epoch(decoupling §9). - Declare
extensionNamespaces: ['x-claude'].
-
- Add the Claude Agent SDK as an optional peer dependency, loaded lazily. Without it installed, nothing changes.
@github/copilot-sdkstays a hard dependency (making it optional is a separate change). - Register the harness with
squad state-mcp --experimental-backendwhen the SDK is available (packages/squad-cli/src/cli/core/backend-mcp.ts), soexecutionAvailablebecomes true. Without a harness the bridge keeps returningunavailable. - Auth: the harness takes
ANTHROPIC_API_KEY,ANTHROPIC_BASE_URL, or Bedrock/Vertex settings, not a personal claude.ai login. Check Anthropic's current terms for products built on the Agent SDK.
Tests
- Unit tests use a fake SDK transport; no network.
- Contract tests: the same
HarnessAdapterassertions run against Copilot and Claude (harness-adapters §15.1, §15.5). - Golden trace:
test-fixtures/spec/suite-v0.2/golden-trace.json(G1–G9) against the real Claude harness (decoupling §14.4). - Approval traces: approve, deny, hash mismatch and replay round-trip through
canUseTool(harness-adapters §15.3, decoupling §14.3). - Live tests run only when
SQUAD_REAL_CLI_TESTS=1, astest/clients-real-cli.test.tsalready does.
Evidence: run the live contract and golden-trace tests against a direct Anthropic API, Bedrock or Vertex endpoint. A Copilot bridge serves the model from Copilot's backend and translates the protocol, so it isn't independent non-Copilot evidence. If a bridge is used anyway, say so in the evidence string.
Handoff note: the live tests need an Anthropic API key (or Bedrock/Vertex credentials), billed separately from any Claude subscription. If whoever implements this can't run them, land the unit and contract tests with the fake transport, and leave the live runs to someone with credentials or a CI secret.
Done when
- The adapter, optional dependency and registration are in.
- The unit tests and fake-transport contract tests pass.
- The live contract and golden-trace runs pass with
SQUAD_REAL_CLI_TESTS=1, with the endpoint recorded. - The regression guards from PR 1 stay green.
Activity
github-actions commentedon Nov 9, 2026
📋 Assigned to sdk-runtime-dev (SDK Runtime Engineer)
Issue: #2441 — Claude host PR 2: Claude Agent SDK HarnessAdapter (#2438 Phase 1)
sdk-runtime-dev will pick this up in the next Copilot session.
bradygaster commentedon Nov 10, 2026
Kickoff notes (from the #2442 session)
Context for whoever picks this up. #2442 (Phases 2, 3, 4 and 6, Claude projection v2) is open as #2450.
Testing approach (proposed): live-first, with only a thin fake.
SQUAD_REAL_CLI_TESTS=1: submit and subscribe, the golden trace G1–G9, and approve or deny throughcanUseTool. These runs are the evidence anyway, and they can't drift from the real SDK the way a full fake transport can.Credentials: an Anthropic API key, or Bedrock or Vertex settings, set in the environment before the session starts. Live runs record the endpoint; a Copilot bridge doesn't count as independent evidence.
Estimate: about 9–13 hours of implementation. That's lower than first thought, because
@github/copilot-sdkstays a hard dependency, as this issue says. The biggest unknown is how cleanlycanUseToolmaps onto the harness approval contract (hash, scope, replay); if it doesn't, add roughly 4–6 hours.Can run in parallel with #2443 (plugin), which waits on #2450 merging. The two don't touch the same files.
🤖 Generated with Claude Code
fix(backend): harden harness turn lifecycle; redact approval records
fix(backend): redact header- and env-style credentials in approval re…
fix(backend): mask bare tokens and URL passwords in approval records
fix(backend): drop approval payloads, isolate Copilot config, bound m…
test(backend): live-verify the claude-agent-sdk harness; record it
fix(backend): harness durability, Claude credentials and deny rules, …
ci(release): explain the env-gated live harness tests in test reconci…
test(backend): live-verify copilot-sdk after event correlation; isola…
feat(backend): claude-agent-sdk and copilot-sdk execution harnesses (#…
test(backend): tighten live golden trace review assertions
test(backend): validate golden Bash execution options