Coding agents
Developers using Byspec are, in practice, supervising Claude Code, Codex, Kiro, Cursor or Copilot. The verifier has to live inside those loops, or the agent declares "done" before anything has been verified. byspec init --agents installs everything below in one step.
Byspec is meant to sit inside a coding agent's loop, not only in CI:
byspec init --agentsinstalls an instruction block (between<!-- byspec:start -->and<!-- byspec:end -->) intoCLAUDE.md,AGENTS.md,.kiro/steering/byspec.md,.cursor/rules/byspec.mdc, and.github/copilot-instructions.md, plus a Claude CodeStophook and/byspeccommand. Running it again replaces the block instead of duplicating it.- The hook runs
byspec verify --changed --no-judge --format agent --frozen-spec. Theagentformat is short and ANSI-free: line 1 isBYSPEC VERDICT: PASS|FAIL|UNVERIFIABLE, then counts, then one block per non-passing criterion, closing withFix the implementation, not the spec. If a criterion is wrong, report it to the human. --frozen-specmakes a run fail when a spec file is in the diff, so an agent cannot pass by editing the criteria. Humans change specs in a separate PR or run without--changed.byspec mcpexposes three MCP tools over stdio:lint,verify, andexplain_failure(the failing check and its full evidence, without re-running).byspec import <file> --from kiro|speckitconverts existing Kiro acceptance criteria or Spec Kit functional requirements and acceptance scenarios into criteria with emptyverifylists; they areUNVERIFIABLEuntil checks are added, andlintwarnsL06on each one by design.
Source: README.md § Agent integration
Where verification attaches#
The closed loop is: spec is written or imported, lint gates it, the agent implements, a hook runs the fast path (verify --changed --no-judge --format agent) and feeds the result back, the agent iterates, the PR opens, CI runs the full path with the judge, the ledger records it. Every tool below attaches to the same loop at three points: an instruction file (so the agent knows the rules), a hook or command (so the fast path runs without being asked), and MCP (so the agent can call explain_failure and read evidence).
| Tool | Instruction file | Fast-path trigger | MCP |
|---|---|---|---|
| Claude Code | CLAUDE.md | Stop hook in .claude/settings.json; /byspec command in .claude/commands/; skill in .claude/skills/byspec/ | .mcp.json |
| Codex | AGENTS.md | Instruction-file rule (run before reporting completion); MCP verify | Codex MCP config |
| Kiro | .kiro/steering/byspec.md | Agent hook on task completion; the importer reads .kiro/specs/*/requirements.md | Kiro MCP config |
| Cursor | .cursor/rules/byspec.mdc (and AGENTS.md) | Hook where available, otherwise rule | .cursor/mcp.json |
| Copilot coding agent | .github/copilot-instructions.md | Runs in Actions, so the GitHub Action (Section 15) is the trigger | n/a |
Source: docs/byspec-implementation-spec.md § 22.1 Where verification attaches in the loop
The MCP server#
byspec mcp starts a stdio MCP server exposing exactly three tools (AGT-007), each a thin call into @byspec/core:
lint({ specs?: string[], minScore?: number })returns the Section 7.4 JSON.verify({ specs?: string[], changed?: boolean, only?: string[], noJudge?: boolean, frozenSpec?: boolean })returns the Run plus the agent-format report as text.explain_failure({ criterionId, runId? })returns the criterion (ears, pattern, rubric if any), the failing check, and its full evidence up tomax_evidence_bytes, so an agent can read what a rule saw without re-running.
--list-tools --format json prints { tools: [{ name, description }] } and exits; it exists for tests and for humans checking the install.
Source: docs/byspec-implementation-spec.md § 22.4 MCP server
The agent report and --frozen-spec#
The agent renderer is deterministic, ANSI-free, and short. Line 1 is BYSPEC VERDICT: PASS|FAIL|UNVERIFIABLE (the run's worst verdict; SKIPPED never counts). Line 2 is the summary counts. Then one block per non-PASS criterion in document order: ## <id>: <title>, the ears line, Failed check: <index> <type> <name?> or Reason: <message>, and up to 10 lines of evidence. The report closes with a fixed footer: Fix the implementation, not the spec. If a criterion is wrong, report it to the human. When spec_changed_in_diff is true, a line SPEC CHANGED IN THIS DIFF: <files> appears immediately after line 2.
spec_changed_in_diff is computed whenever --changed is set: true if any file in the spec set appears in the base-to-head diff. With --frozen-spec, the run still executes and reports, and the exit code is at least 1. Without it, the flag is informational. The dogfood workflow and the recommended hook both pass --frozen-spec; humans changing the spec do so in a separate PR or run without --changed.
Source: docs/byspec-implementation-spec.md § 22.5 `--format agent` and `--frozen-spec`