Byspec
Documentation

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 --agents installs an instruction block (between <!-- byspec:start --> and <!-- byspec:end -->) into CLAUDE.md, AGENTS.md, .kiro/steering/byspec.md, .cursor/rules/byspec.mdc, and .github/copilot-instructions.md, plus a Claude Code Stop hook and /byspec command. Running it again replaces the block instead of duplicating it.
  • The hook runs byspec verify --changed --no-judge --format agent --frozen-spec. The agent format is short and ANSI-free: line 1 is BYSPEC VERDICT: PASS|FAIL|UNVERIFIABLE, then counts, then one block per non-passing criterion, closing with Fix the implementation, not the spec. If a criterion is wrong, report it to the human.
  • --frozen-spec makes 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 mcp exposes three MCP tools over stdio: lint, verify, and explain_failure (the failing check and its full evidence, without re-running).
  • byspec import <file> --from kiro|speckit converts existing Kiro acceptance criteria or Spec Kit functional requirements and acceptance scenarios into criteria with empty verify lists; they are UNVERIFIABLE until checks are added, and lint warns L06 on 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).

ToolInstruction fileFast-path triggerMCP
Claude CodeCLAUDE.mdStop hook in .claude/settings.json; /byspec command in .claude/commands/; skill in .claude/skills/byspec/.mcp.json
CodexAGENTS.mdInstruction-file rule (run before reporting completion); MCP verifyCodex MCP config
Kiro.kiro/steering/byspec.mdAgent hook on task completion; the importer reads .kiro/specs/*/requirements.mdKiro MCP config
Cursor.cursor/rules/byspec.mdc (and AGENTS.md)Hook where available, otherwise rule.cursor/mcp.json
Copilot coding agent.github/copilot-instructions.mdRuns in Actions, so the GitHub Action (Section 15) is the triggern/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 to max_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`