Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save jeremylongshore/5b2de7ba9baca1eaaa0a757b5b0c48db to your computer and use it in GitHub Desktop.

Select an option

Save jeremylongshore/5b2de7ba9baca1eaaa0a757b5b0c48db to your computer and use it in GitHub Desktop.

pr-to-spec v0.8.0

The flight envelope for agentic coding.

Turn any code change — a GitHub PR, a local branch, staged edits — into a structured, agent-consumable spec with intent drift detection. CLI and MCP server.

CI License: MIT npm

Links: GitHub · npm · Docs


One-Pager

The Problem

Agents make code changes without guardrails. There is no structured way to declare intent, detect scope drift, or surface risk signals before review. Teams discover scope creep, forbidden file touches, and risk escalation only after the fact — or not at all.

The Solution

declare intent → make changes → pr-to-spec check → structured spec + drift signals
  1. Declare intent: Tell pr-to-spec what you're building, what scope is allowed, and your risk ceiling
  2. Make changes: Work normally in your branch
  3. Check drift: pr-to-spec check --json produces a structured spec + drift signals
  4. Agent consumes: Any agent reads the envelope and acts accordingly

Works as both a CLI tool and an MCP server for IDE integration.

Who / What / Where / When / Why

Who Engineering teams using AI coding agents
What CLI + MCP server for intent drift detection
Where Node.js (npm install -g pr-to-spec)
When During code review / PR analysis / pre-commit checks
Why Prevents scope creep and surfaces hidden risks before merge

Stack

Component Technology
Language TypeScript / Node.js
Protocol MCP (Model Context Protocol) via stdio transport
Integration GitHub API (Octokit), local git
Output Agent protocol envelope (JSON), YAML, Markdown
AI (optional) Anthropic, OpenAI for enhanced summaries

Key Differentiators

  1. Intent-first — declare what you're building before coding, not after
  2. Drift detection — automatic forbidden-file, scope-creep, risk-escalation, and size-overrun signals
  3. Agent protocol envelope — structured JSON output with version, status, exit codes, and typed signals
  4. Dual mode — CLI for pipelines + MCP server for IDE integration (Claude Code, Cursor, Windsurf)
  5. Deterministic core — heuristics, not LLMs. Reproducible and auditable by default

Operator-Grade System Analysis

Architecture

src/
  servers/        MCP server (6 tools via stdio transport)
  cli/            CLI entrypoints (analyze, scan, intent, check)
  action/         GitHub Action entrypoint
  core/
    schema/       Zod schema for the canonical prompt-spec format
    github/       Octokit-based PR data fetching
    sources/      DiffSource abstraction (GitHub PR, local branch, staged, commits)
    parsing/      Deterministic spec generation from diff metadata
    risk/         Rule-based risk classification heuristics
    intent/       Intent schema and YAML storage (.pr-to-spec/intent.yaml)
    drift/        Drift detection against declared intent
    protocol/     Agent protocol envelope (version, status, exit_code)
    rendering/    YAML, Markdown, JSON, and PR comment renderers
    ai/           Optional AI enhancement (Anthropic, OpenAI)
    diff/         Spec version diffing

Design Principles

  • Deterministic first: Core spec uses heuristics, not LLMs. Reproducible and auditable.
  • No execution: Never runs code — metadata and diffs only.
  • Agent-native: JSON envelope output, clean exit codes, field extraction. Built for piping.
  • Local-first: Works on local branches and staged changes without GitHub.
  • Minimal trust surface: Read-only by default. Zod-validated output.

Risk Classification

Built-in heuristic rules flag changes to:

Category Severity Triggers
authentication high Auth, login, session, OAuth, JWT files
secrets high .env, .key, .pem, credentials files
database high Migrations, .sql, schema files
permissions high RBAC, ACL, policy files
payment high Stripe, billing, subscription files
dependencies medium Lockfiles, package managers
infrastructure medium Docker, Terraform, k8s, deploy configs
destructive-operations medium DROP TABLE, DELETE FROM in patches
security-config medium CORS, CSP, security headers
large-change low 300+ line changes in a single file

Agent Protocol

All --json output is wrapped in the agent protocol envelope:

{
  "version": 1,
  "command": "check",
  "status": "drift_detected",
  "exit_code": 3,
  "signals": [
    {
      "type": "forbidden_touch",
      "description": "1 forbidden file(s) modified",
      "severity": "high",
      "details": ["src/db/schema.ts"]
    }
  ],
  "spec": { ... },
  "intent": { ... }
}

Exit Codes

Code Meaning
0 Clean — no issues
1 Error
2 High-risk changes detected
3 Drift from declared intent
4 Gate policy failed

Drift Signals

Signal Trigger
scope_creep Files changed outside expected_scope
forbidden_touch Files matching forbidden_scope were modified
risk_escalation Detected risk level exceeds max_risk
size_overrun Total LOC changed exceeds size_budget
type_mismatch Inferred change type doesn't match expected_type

MCP Server Tools

Tool Description
analyze_pr Analyze a GitHub PR and generate a structured spec
scan_local Scan local git changes (branch, staged, commits)
check_drift Check changes against declared intent for drift
set_intent Declare what a code change should accomplish
show_intent Show the current intent declaration
analyze_assumptions Surface implicit decisions with 2x2 matrix

Environment Variables

Variable Required Description
GITHUB_TOKEN For GitHub PRs GitHub token with PR read access
ANTHROPIC_API_KEY No For AI-enhanced summaries
OPENAI_API_KEY No Alternative AI provider
PR_TO_SPEC_DIR No Config directory (default: .pr-to-spec)

Reference

Quick Start

# Install
npm install -g pr-to-spec

# Analyze a GitHub PR
pr-to-spec --repo owner/repo --pr 42 --json

# Scan local branch changes
pr-to-spec scan --json

# Declare intent and check for drift
pr-to-spec intent set --goal "Add user auth" --scope "src/auth/**" --forbid "src/db/**" --max-risk medium
pr-to-spec check --json

Plugin Installation

Install as a Claude Code plugin:

claude plugin add jeremylongshore/pr-to-spec

Or add to your project's .mcp.json:

{
  "mcpServers": {
    "pr-spec-analyzer": {
      "command": "node",
      "args": ["path/to/dist/servers/pr-spec-analyzer.js"]
    }
  }
}

CLI Reference

pr-to-spec (analyze a GitHub PR)

Options:
  --repo <owner/name>      GitHub repository (required)
  --pr <number>            Pull request number (required)
  --out <directory>        Output directory (default: ./output)
  --token <token>          GitHub token (or set GITHUB_TOKEN env var)
  --format <format>        Output: yaml, markdown, json, both (default: both)
  --stdout                 Print to stdout instead of files
  --quiet                  Suppress logging
  --field <path>           Extract a single field (dot notation)
  --json                   Shorthand for --format json --stdout --quiet
  --comment                Post spec summary as a PR comment
  --ai-enhance             Enhance spec with AI-generated insights
  --debug                  Log API requests, git commands, and timing
  -V, --version            Show version
  -h, --help               Show help

pr-to-spec scan (analyze local changes)

Options:
  --branch <ref>           Base branch to diff against (default: main)
  --diff <n>               Diff last N commits
  --staged                 Analyze staged changes only
  --out <directory>        Output directory (default: ./output)
  --format <format>        Output: yaml, markdown, json, both
  --stdout                 Print to stdout
  --quiet                  Suppress logging
  --json                   Shorthand for --format json --stdout --quiet
  --field <path>           Extract a single field

pr-to-spec intent (manage intent declaration)

Subcommands:
  set                      Set the intent for this project
  show                     Show the current intent
  analyze                  Analyze assumptions and surface decisions
  approve                  Approve the current intent (draft → approved)
  lock                     Lock the current intent (approved → locked)
  gate                     Evaluate intent gate policy

intent set Options:
  --goal <text>            What this change is trying to achieve (required)
  --scope <glob...>        Expected file globs (repeatable)
  --forbid <glob...>       Forbidden file globs (repeatable)
  --max-risk <level>       Maximum acceptable risk: low, medium, high
  --type <type>            Expected change type: feature, bugfix, refactor, etc.
  --size-budget <n>        Max total lines changed
  --json                   Output as JSON

pr-to-spec check (drift detection)

Options:
  --branch <ref>           Base branch to diff against
  --diff <n>               Diff last N commits
  --staged                 Analyze staged changes only
  --quiet                  Suppress logging
  --json                   Output as JSON agent protocol envelope

pr-to-spec contract (verification contracts)

Subcommands:
  add                      Add a new contract
  list                     List all contracts
  remove                   Remove a contract by ID

contract add Options:
  --type <type>            Contract type (required)
  --description <text>     Contract description
  --params <json>          Contract parameters as JSON
  --severity <level>       blocking or warning (default: blocking)
  --json                   Output as JSON

Contract types: no_new_dependencies, no_file_outside_scope,
  max_files_changed, no_pattern_in_diff, require_pattern_in_diff,
  no_new_exports

pr-to-spec graph (intent DAG)

Subcommands:
  query                    Query ancestors or descendants of a node
  impact                   Show nodes impacted by changes
  stats                    Show graph statistics

graph query Options:
  --node <id>              Node ID to query (required)
  --direction <dir>        up (ancestors) or down (descendants)
  --json                   Output as JSON

pr-to-spec feedback (review/CI feedback)

Subcommands:
  review                   Ingest a code review result
  ci                       Ingest CI pipeline results
  status                   Show current feedback and graph status

feedback review Options:
  --reviewer <name>        Reviewer name (required)
  --status <status>        approved, changes_requested, commented (required)
  --comment <text...>      Review comments (repeatable)
  --target <id...>         Target node IDs (required)
  --json                   Output as JSON

Changelog

[Unreleased]

[0.8.0] - 2026-03-18

Added

  • MCP Server (servers/pr-spec-analyzer.ts) — 6-tool Model Context Protocol server exposing analyze_pr, scan_local, check_drift, set_intent, show_intent, and analyze_assumptions via stdio transport
  • Claude Code plugin metadata (.claude-plugin/plugin.json, .mcp.json) — enables pr-to-spec as a standalone MCP plugin for Claude Code, Cursor, and Windsurf
  • @modelcontextprotocol/sdk dependency for MCP protocol compliance
  • --debug flag for CLI — logs API request URLs, git commands, and timing info to stderr
  • PR_TO_SPEC_DIR env var — configurable storage directory (default: .pr-to-spec)
  • Security test suite (tests/security.test.ts) — webhook URL validation, custom_command rejection, prototype pollution guard
  • API error test suite (tests/github-errors.test.ts) — 401, 403, 404, 422, rate limit, large PR truncation
  • README: documented all subcommands (intent, check, contract, graph, feedback)
  • README: exit code 4 (gate_failed)
  • README: troubleshooting section with common errors

Security

  • Removed custom_command contract type — eliminated command injection vector from arbitrary shell execution. The type is preserved in the schema but always fails with a clear deprecation message.
  • Webhook SSRF prevention — validates webhook URLs: requires HTTPS, rejects localhost, private IPs (10.x, 172.16-31.x, 192.168.x), and link-local addresses (169.254.x).
  • Reduced GitHub Action permissionscontents: writecontents: read (the action only reads PRs and posts comments).
  • Prototype pollution guard--field extraction blocks __proto__, constructor, and prototype traversal.
  • Secret masking — webhook URLs are masked in error output to prevent leaking sensitive endpoints.

Fixed

  • Version sync — CLI and Action version strings updated from stale 0.6.0 to 0.8.0
  • API error messages — GitHub API errors now return user-friendly messages instead of raw Octokit exceptions (401, 403, 404, 422, rate limit)
  • Git error messagesscan/check commands now surface clear messages for "not a git repo" and "unknown revision" errors
  • Large PR warning — warns when GitHub API returns 300 files (the per-page maximum), indicating truncation

Changed

  • 384 tests passing (all existing tests updated for security changes)

[0.7.0] - 2026-03-17

Added

  • Intent DAG: Graph-based intent tracking with spec fragments, decision taxonomy, and propagation engine
  • graph subcommand — query ancestors/descendants, compute impact, view graph stats
  • contract subcommand — declarative contract verification (no_new_dependencies, no_file_outside_scope, max_files_changed, no_pattern_in_diff, require_pattern_in_diff, no_new_exports, custom_command)
  • intent approve / intent lock — approval workflow (draft → approved → locked)
  • intent gate — evaluate gate policy (min_confidence, require_no_stale, require_no_must_ask)
  • Graph materialization — gate and contract results become audit trail nodes
  • Feedback ingestion — learn from reviews to improve future classifications
  • 364 tests (84 new tests for Intent DAG)

Changed

  • Contract evaluator: smarter no_new_dependencies detection (lock files vs manifest files)
  • Protocol envelope: gate_failed status with exit code 4
  • check subcommand: integrated contract evaluation and gate checks

[0.6.0] - 2026-03-17

Changed

  • Renamed: pr-to-promptpr-to-spec
  • Positioning: "The flight envelope for agentic coding"

Added

  • DiffSource abstraction — works on any diff (local branches, staged changes, GitHub PRs)
  • scan subcommand — analyze local git changes without GitHub
  • intent subcommand — declare expected scope, risk ceiling, change type
  • check subcommand — scan + drift detection against declared intent
  • Drift signals: scope_creep, forbidden_touch, risk_escalation, size_overrun, type_mismatch
  • Agent protocol envelope wraps all --json output
  • Claude Code skill manifest (.claude/skills/pr-to-spec/SKILL.md)

Backwards Compatible

  • pr-to-spec --repo owner/repo --pr 42 --json still works unchanged

[0.5.0] - 2026-03-09

Added

  • JSON output format with --format json for agent-friendly piping (#7)
  • Bash-friendly CLI flags: --quiet, --field <path>, --json shorthand (#8)
  • Exit code semantics: 0=success, 1=error, 2=high-risk PR detected (#8)
  • decision_prompt field in spec for agent-driven review decisions (#12)
  • Webhook notifications via webhook_url input in GitHub Action (#11)
  • Example integrations: claude-code.md, bash-agent.sh, github-action-chain.yml (#10)

Changed

  • README rewritten with agent-first positioning and piping examples (#9)

[0.4.0] - 2026-03-09

Added

  • Review parsing with parseReviews() for aggregated review summaries
  • Monorepo detection with detectMonorepo() for workspace-aware specs
  • Semantic diff analysis with analyzeSemanticDiff() for change categorization
  • Spec diffing with diffSpecs() for comparing spec versions
  • Review comments integration in PR data and rendered outputs

[0.3.0] - 2026-03-09

Added

  • GitHub Marketplace release as official Action
  • Action bundle with @vercel/ncc for single-file distribution

[0.2.0] - 2026-03-09

Added

  • AI enhancement with --ai-enhance flag (Anthropic/OpenAI support)
  • Compact spec output via compactSpec() for smaller payloads
  • GitHub Action for automated PR spec generation

[0.1.0] - 2026-03-09

Added

  • Initial release
  • Core PR parsing with generateSpec()
  • Risk classification with severity levels
  • YAML and Markdown rendering
  • PR comment posting via --comment flag
  • GitHub API client with Octokit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment