npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

coderifts

v8.6.11

Published

Signed, offline-verifiable authorization for AI-agent contract changes. Only a granted change can proceed.

Readme

CodeRifts CLI

Signed, offline-verifiable authorization for AI-agent contract changes. Only a granted change can proceed. Works locally or with the CodeRifts cloud API.

Installation

npm install -g coderifts

Or run without installing:

npx coderifts diff old-api.yaml new-api.yaml

Quick Start

# Compare two specs locally
coderifts diff old-api.yaml new-api.yaml

# Use cloud API for full governance report
coderifts login
coderifts diff old-api.yaml new-api.yaml --cloud

# CI mode — exit 1 if risk score exceeds threshold
coderifts diff old-api.yaml new-api.yaml --ci --threshold 50

Commands

coderifts diff <old-spec> <new-spec>

Compare two OpenAPI specs and report breaking changes.

| Flag | Description | Default | |------|-------------|---------| | -f, --format <format> | Output format: terminal, json, markdown | terminal | | --ci | CI mode — exit code 1 if breaking changes exceed threshold | false | | --threshold <number> | Risk score threshold for CI mode (0-100) | 50 | | --cloud | Use CodeRifts cloud API instead of local analysis | false | | -c, --config <path> | Path to .coderifts.yml config file | auto-detect |

Output formats:

  • terminal — Colored tables and risk score box (default)
  • json — Full structured report for programmatic use
  • markdown — Markdown table for CI comments

A coderifts-report.json file is always saved to the current directory.

coderifts init

Interactive configuration generator. Creates a .coderifts.yml file with industry-specific presets:

  • startup-lean
  • growth-balanced
  • fintech-strict
  • public-api-safe
  • microservices-internal
  • ai-agent-platform

coderifts init --agents

One command that wires this repository for governed agent work. Re-run is a no-op. Existing JSON is merged (never clobbered); a .bak sits next to any file it modifies.

coderifts init --agents                  # all hosts, all four pieces
coderifts init --agents --dry-run        # plan only — writes nothing
coderifts init --agents --hosts=claude   # Claude Code only
coderifts init --agents --hosts=cursor   # Cursor only
coderifts init --agents --hosts=copilot  # GitHub Copilot / VS Code only
coderifts init --agents --no-hook        # skip host hook install
coderifts init --agents --no-workflow    # skip .github/workflows/coderifts.yml
coderifts init --agents --strict         # STRICT: require-verified-monitoring + require-grant (cr.exec.v2 primary)
coderifts init --strict --atomic-v2      # ATOMIC_V2 config + fail-closed wiring (implies --agents --strict)
coderifts verify atomic-v2               # 0 TARGET_ENFORCEMENT_VERIFIED; 2 WIRING_REQUIRED; 3 VERIFICATION_FAILED; 1 usage
coderifts keys create --email … --name … --use-case "Local development" [--save]
coderifts bind --repo owner/repo [--commit] [--prove]
coderifts claim --installation-id <id>
coderifts init --agents --check          # which of the four pieces are present

| Piece | What it writes | Host-specific shape | |-------|----------------|---------------------| | MCP config | .mcp.json (Claude Code), .cursor/mcp.json (Cursor), .vscode/mcp.json (Copilot / VS Code) | Three shapes, never normalised into one: Claude mcpServers + type: "http" + url; Cursor mcpServers + url only (no type); Copilot servers (not mcpServers) + type: "http" + url. Never httpUrl (that is Gemini, extension-level — this command does not write it). | | Agent rules | generated host files via agent-setup's writer | AGENTS.md is always written. Claude also gets CLAUDE.md; Cursor also gets .cursor/rules/coderifts.mdc; Copilot also gets .github/copilot-instructions.md. --hosts=all adds LangGraph and OpenAI instructions. (coderifts init agent is a different command — it writes a .coderifts.yml template.) | | Host hook | .claude/settings.json, .cursor/hooks.json | Reuses hook install --claude / --cursor (JSON-merge, backup, idempotent). Copilot shares Claude's .claude/settings.json — VS Code reads it by default. | | CI workflow | .github/workflows/coderifts.yml | coderifts/contract-gate@v0. Default: require-verified-monitoring commented (honest default: false). --strict: the same file with require-verified-monitoring: 'true' and require-grant: 'true' (teaches cr.exec.v2) |

Grant versions (these names are not interchangeable; field-by-field matrix: Grant versions):

| What | Who uses it | What it proves | |------|-------------|----------------| | cr.exec.v2 | coderifts init --agents --strict (require-grant); Guard/SDK when grantVersion: 'v2' | Canonical production execution grant. Not the same bytes as v1. Mint with grantVersion: 'v2'. | | cr.exec.v1 | capability-demo; legacy/migration | Older reference grant bound to operation ∥ target_id ∥ after_payload. Not the installer default. The gate still accepts it so a migration is not a hard cut. | | ENFORCING_STRICT | Guard withCodeRifts({ profile }) | Permanent alias of ENFORCING_STRICT_V1 (must resolve to _V1 forever). Installer-reachable production lock. Not a grant format. Different axis from ENFORCING_ATOMIC_V1/V2 — those require customer-held executor wiring this installer does not emit. |

--strict turns on require-grant and require-verified-monitoring in the workflow; it teaches cr.exec.v2 as the grant to mint. It does not emit ENFORCING_ATOMIC_V2.

--atomic-v2 writes .coderifts/atomic-v2.json plus fail-closed unconfiguredCapability wiring placeholders. Init may exit 0 with PROFILE_CONFIGURED / WIRING_REQUIRED (state: ATOMIC_V2_CONFIGURED, atomic_v2_verified: false). That is configuration, not target enforcement. coderifts verify atomic-v2 is the verifier and must not exit 0 while placeholders remain:

| Exit | Meaning | |------|---------| | 0 | TARGET_ENFORCEMENT_VERIFIED — customer target fully verified | | 2 | WIRING_REQUIRED — config installed, placeholders still throw | | 3 | VERIFICATION_FAILED — wiring present but verification failed (including a document that claimed verified:true with incomplete wiring) | | 1 | usage / missing config |

Never emit state: ENFORCING_ATOMIC_V2 with atomic_v2_verified: true while any of the adapter-contract (atomic-v2-adapter/1) operations is missing: state_challenge, consume, conditional_write, mutate, executor_attestation, provider_readback. Discovery is a machine probe, not a customer boolean. Exit 0 is target-bound (--target --environment --executor-identity --operation --adapter-id); a reference-executor success is not inherited. customer_target_verified:false and production_ready:true cannot be constructed together. The names are PROFILE_CONFIGURED / TARGET_ENFORCEMENT_VERIFIED, not STRICT-vs-ATOMIC (that pairing would read as a weaker-but-acceptable end state).

Next manual step: add CODERIFTS_API_KEY to the repository secrets. The CLI never writes a key anywhere.

This command does not: enable branch protection (see ENFORCEMENT.md), make raw host tools inescapable, or enforce the workflow until CodeRifts / contract-gate is a required check in repo settings.

The three separate commands this replaces for a fresh repo: coderifts agent-setup, coderifts hook install --claude (and --cursor), plus a hand-copied workflow file. Repo-level MCP config was generated by nothing before 4.6.0.

coderifts login

Save your CodeRifts API key for cloud features. Get a free key at app.coderifts.com/api/signup.

coderifts publish-gate

Gate npm publish on the same contract-preflight family as the pre-push hook: before = last published / merge-base baseline, after = working tree. Exit 0 only when execution_action permits publish; BLOCK, resolver errors, empty before, and preflight unreachability all exit 1 (fail-closed). Empty before is never treated as a silent NEW_ARTIFACT pass.

| Flag | Description | Default | |------|-------------|---------| | --spec <path> | Contract artifact path | git config coderifts.specPath or api/openapi.yaml | | --json | Machine-readable result | false |

Recommended package.json wiring:

{
  "scripts": {
    "prepublishOnly": "coderifts publish-gate"
  }
}

Before resolution order (fail-closed):

  1. Git tag of package.json version (vX.Y.Z, then X.Y.Z)
  2. git merge-base HEAD origin/main (fallbacks: origin/master, main, master)
  3. Exit 1 with a clear error — never invent an empty baseline

On success the command prints a receipt reference when the preflight path issues one.

coderifts deploy-gate

Gate a deploy on the current { environment, artifact } using a signed preflight receipt. Fail-closed by default (842 / hook pattern). The CD sibling of publish-gate / the merge-gate App check.

Verification contract split (4.4.1 / guard 9.0.0):

  • Verdict: @coderifts/agent-guard deployGate TOKEN mode is the verifier of record. The CLI passes { token, decision_result, registry | pinnedKeyPem } — it never sends an unstamped currently_authorized view.
  • WHY (842): the CLI still runs the app kernel (verifyReceipt + evaluateVerifyAuthorization) to corroborate verify_status and to print envelope blocking_reasons. That is not a second verdict: one cause (the gate reason), one WHY.

Crypto is not reimplemented in the CLI. No scoring is reimplemented.

--receipt contract: the file MUST carry the signed chain receipt token (token / chain_receipt / receipt.token / decision_result.receipt.token) and the decision envelope (decision_result, or the file itself when it is the envelope). A hand-written { currently_authorized: true } is not a receipt. currently_authorized as an input field is untrusted — the gate computes it from verification and logs a warning naming the field.

Default: no token / failed verification / unbound context / missing / invalid / expired receipt / scope mismatch / deny-class exits 1 (policy BLOCK). stderr prints WHY (verify_status + computed currently_authorized + gate reason + renderDecisionWhy when a body exists) and set CODERIFTS_DEPLOY_ADVISORY=1 to soften.

Advisory opt-out: CODERIFTS_DEPLOY_ADVISORY=1|true (also CODERIFTS_ADVISORY=1|true) prints the verdict, always prints ADVISORY MODE — this gate did not block, and exits 0. A forged / unsigned file still prints the unsigned-receipt truth loudly.

--enforce / CODERIFTS_DEPLOY_ENFORCE=true: accepted silently (no-op for exit — default is already fail-closed). This is a host claim that the step is ENFORCING. It does not set inescapable_deploy. That field is true only from queried pipeline protection (coderifts enforce --check). CODERIFTS_DEPLOY_NO_BYPASS is recorded as a host claim and does not clear bypass_possible.

Infra vs policy: missing --env / --artifact, malformed receipt JSON, or an unreachable --keys registry prints distinct INFRA wording plus retryable: true and this is not a policy BLOCK. Still fail-closed by default; advisory softens it too. A missing receipt file is a policy fail (no_receipt), not infra. A missing token on a present file is policy (unsigned_receipt).

Keys: --keys <file|url> (default https://app.coderifts.com/.well-known/coderifts-keys.json, ID131). Air-gapped CI: --pinned-key <pem> (skips the registry fetch).

Happy path (signature verifies, envelope binds, currently_authorized computed true for this env+artifact+deploy) exits 0.

| Flag | Description | Default | |------|-------------|---------| | --env <environment> | Target environment (e.g. production, staging) | required | | --artifact <artifact_id> | Immutable artifact identity (content digest or commit SHA) | required | | --receipt <file> | Signed chain_receipt token + decision envelope JSON | none | | --fingerprint <fp> | Optional intended fingerprint the receipt must match | none | | --keys <file-or-url> | Ed25519 key registry (file or URL) | live /.well-known/coderifts-keys.json | | --pinned-key <file> | Air-gapped PEM public key (skips registry fetch) | none | | --json | Binding result as JSON | false | | --enforce | Accepted silently (exit already fail-closed). Still attests ENFORCING. | false |

coderifts deploy-gate --env production --artifact "$SHA" --receipt receipt.json
coderifts deploy-gate --env production --artifact "$SHA" --receipt receipt.json --keys ./coderifts-keys.json
coderifts deploy-gate --env production --artifact "$SHA" --receipt receipt.json --pinned-key ./coderifts-current.pem
CODERIFTS_DEPLOY_ADVISORY=1 coderifts deploy-gate --env production --artifact "$SHA" --receipt receipt.json

coderifts outcome <kind>

Report a post-hoc observed outcome for a past decision_id to POST /api/v1/outcomes. Records the caller's assertion (your deploy job knows success/failure) — the command does not itself verify the deploy.

kind is a closed set: deploy_succeeded, deploy_failed, rolled_back, consumer_break_reported, remediation_verified_working, false_positive_reported, other_reported.

Requires a cloud API key (coderifts login or CODERIFTS_API_KEY). Reporter is derived from the key. Exit 0 on success, 1 on usage / API error.

| Flag | Description | Default | |------|-------------|---------| | --decision <decision_id> | decision_result.decision_id (required) | none | | --observed-at <iso> | When the outcome was observed (ISO-8601) | now | | --details <json> | Optional JSON object/array bound to the row | none | | --json | Print the API response JSON | false |

coderifts outcome deploy_succeeded --decision "$DECISION_ID"
coderifts outcome deploy_failed --decision "$DECISION_ID" --json

coderifts registry-gate [dir]

Local registry admission gate for a directory of OpenAPI/Swagger specs (audit 3.4/9). Runs the pure registry-validation core offline — no cloud calls — so a registry CI step does not depend on CodeRifts uptime to admit specs.

Discovers *.yaml / *.yml / *.json under [dir] (default: .), skips node_modules and dotdirs, skips non-spec files (no openapi/swagger field), and fails closed on unreadable files (GATE_ERROR) or zero specs (REGISTRY_EMPTY).

| Flag | Description | Default | |------|-------------|---------| | [dir] | Registry root to scan | . | | --glob <pattern> | Filter paths with @coderifts/agent-guard matchGlob (relative to dir) | all candidates | | --errors-only | Fail only on ERROR severity (warnings printed, exit 0) | off | | --warn-only | Advisory: print findings, always exit 0 | off |

Severity (important): core endpoint_collision is a WARNING and leaves valid: true. This gate fails on ERROR + WARNING by default — it does not branch on valid alone. Info findings are printed and do not fail.

GitHub Actions (minimal):

- uses: actions/checkout@v4
- name: Registry admission
  run: npx coderifts registry-gate specs/

Git hook (coderifts hook install)

Installs a pre-push hook that diffs the configured OpenAPI path against a resolved baseline (remote tip, or for new branches a merge-base with the default branch). Empty-before allow is not used. The hook prefers closed-set execution_action from the diff API (legacy omega_decision only when action is absent). Configure with git config coderifts.apiKey or CODERIFTS_API_KEY, and optional git config coderifts.specPath. Installed with no key: the hook exits 1 (absence is not permission). Explicit opt-out: CODERIFTS_ADVISORY=1 (same flag as claude-hook / deploy-gate). Loud skip: CODERIFTS_SKIP=1.

After upgrading the coderifts CLI, re-run coderifts hook install so the installed hook matches the package (already-installed hooks are not auto-updated).

2-minute Claude Code path: coderifts hook install --claude writes a PreToolUse hook (matcher: Write|Edit|MultiEdit → coderifts claude-hook) into .claude/settings.json (JSON-merge, backup first, idempotent). --global writes ~/.claude/settings.json. --log <path> embeds CODERIFTS_GUARD_EVENT_LOG and CODERIFTS_SESSION_ID in the command. Unparseable settings JSON → refuse, no write.

Claude Code PreToolUse (coderifts claude-hook) — ID824

Tool-call-time gate for Claude Code: blocks contract-touching Write / Edit / MultiEdit when authorize preflight returns BLOCK/STOP. The matcher is tool-level (Write|Edit|MultiEdit); the path family is enforced inside the hook.

Default governed family (from SUPPORTED_TYPES + @coderifts/contract-path looksLikeContractPath / CONTRACT_EXT; agent_tools via *tool-schema*.json):

  • **/*openapi*.{yaml,yml,json} and **/*swagger*.{yaml,yml,json} (openapi)
  • **/*.{graphql,gql} (graphql)
  • **/*.proto (grpc)
  • **/*asyncapi*.{yaml,yml,json} (asyncapi)
  • **/*mcp*.{json,yaml,yml} (mcp_manifest)
  • **/*tool-schema*.json (agent_tools)

node_modules/ and vendor/ are not governed (same as the path detector). git config --add coderifts.specPath <path-or-glob> is additive (never replaces the family). git config --add coderifts.specPathExclude <path-or-glob> opts one path out. A not-governed path exits 0 and prints coderifts claude-hook: not governed: <path> on stderr — the hook is never silent on a write/edit.

Exit map (Claude Code semantics — fixed):

| Exit | Meaning | |------|---------| | 2 | BLOCK — tool call cancelled; stderr is shown to the model. Default fail-closed: no key, API down, unreadable spec, parse-gap, missing file_path | | 0 | Allow (CONTINUE), or skip (non-spec path / identical content). CODERIFTS_ADVISORY=1 restores soft-allow on could-not-run sites | | 1 | Never used for deny — Claude treats exit 1 as non-blocking (action proceeds) |

Push-time equivalent (git exit 1 on BLOCK): coderifts hook install.

Install path: coderifts hook install --claude (or agent-setup writes project .claude/settings.json when absent). Then set key; spec path is optional and additive:

git config coderifts.apiKey 'cr_live_…'          # or: coderifts login / CODERIFTS_API_KEY
git config --add coderifts.specPath extra/spec.yaml          # additive; does not drop the family
git config --add coderifts.specPathExclude docs/openapi.yaml # opt out one false positive

Recipe — project (.claude/settings.json) or user (~/.claude/settings.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "coderifts claude-hook",
            "timeout": 60
          }
        ]
      }
    ]
  }
}
  • Project .claude/settings.json — shared with the repo (commit if the team wants the gate).
  • User ~/.claude/settings.json — personal; applies to all projects on this machine.
  • Matcher is case-sensitive tool names/regex. Exit-2 blocking is Claude Code semantics; the same decision discipline at push-time is the git pre-push hook above.

Fail-closed default: missing API key, API unreachable, disk unreadable, or edit-apply failure on the spec path is exit 2 (enforce_indeterminate) — absence of a key is not ALLOW. REQUEST_APPROVAL is exit 2 (approval_required). CONTINUE_WITH_MONITORING is exit 2 (monitoring_unwired) unless the host asserts a sink (CODERIFTS_MONITORING_SINK_WIRED=1 or git config coderifts.monitoringSinkWired true) — a host claim, not delivery proof.

CODERIFTS_ADVISORY=1|true: explicit opt-out that restores soft-allow on “governance could not run” sites. Not implied by a missing key.

CODERIFTS_STRICT=1|true: same fail-closed as the default; cannot be weakened by CODERIFTS_ADVISORY.

CODERIFTS_ADVISORY=1 coderifts claude-hook

GitHub Copilot / VS Code agent mode

Measured (VS Code 1.110, Agent hooks Preview, 2026-08-24): VS Code reads .claude/settings.json by default. coderifts hook install --claude therefore arms Copilot agent mode — there is no separate --copilot hook installer. VS Code Agent hooks are deny-capable: PreToolUse honours permissionDecision allow|deny|ask and exit 2.

Property names (CLI 4.8.0): VS Code passes camelCase (toolName / toolInput / filePath / targetFile). The hook accepts those alongside Claude's snake_case (tool_name / tool_input / file_path). Flattened payloads (path on the root object) are accepted. Garbage input is still fail-closed.

Matcher limitation (host behaviour, not a CLI bug): VS Code parses hook matchers (Write|Edit|MultiEdit) but does not apply them. The hook fires on every tool call. Non-governed tools (Read, Bash, …) and non-contract paths exit 0 silently with no network and no API key required — cheap and fail-open for anything that is not a Write/Edit/MultiEdit of the spec. It is noisy (every tool call invokes the process) and safe (irrelevant tools are not blocked). A spec-path write without a key is still fail-closed.

Honest boundary: hooks gate the agent, not the human. Inline completions (ghost text) are not tool calls and are not governed. A developer typing in the editor is not a PreToolUse event.

MCP: coderifts init --agents (and --hosts=copilot) writes .vscode/mcp.json with root key servers — a third shape. Claude Code and Cursor use mcpServers; Copilot cloud Settings paste also uses mcpServers. Do not copy one file onto another host.

coderifts status [repo]

Prints three lines derived from this process's actual config, not a static string: Runtime / Merge / Deploy = PREVENTS or REPORTS.

| Line | PREVENTS when | REPORTS when | |------|----------------|--------------| | Runtime | host wrap fail-closed (CODERIFTS_ADVISORY unset) | CODERIFTS_ADVISORY=1\|true | | Merge | MERGEGATE_ENFORCE=true (exact string; 1 is not enough) | otherwise (the App default) | | Deploy | deploy-gate fail-closed | CODERIFTS_DEPLOY_ADVISORY=1\|true or CODERIFTS_ADVISORY=1\|true |

REPORTS is REPORTS — this does not claim a wrap or required check is installed on a repository. With [repo] / --repo owner/repo, also calls GET /api/v1/enforcement-status and prints the statuses the endpoint measured (API key required for that half). No GitHub writes. Pair with coderifts enforce (that command acts; this one only shows). Distinct from coderifts hook status. Exit 0 on the local three-liner or a successful cloud read, 1 on invalid repo, missing key (when a repo is given), or API error.

| Flag | Description | Default | |------|-------------|---------| | [repo] / --repo <owner/repo> | Repository (cloud report) | none (local posture only) | | --json | Machine-readable JSON (local posture, or raw API body when a repo is given) | false | | --paths | Per-path ENFORCING / ADVISORY / NOT_CONFIGURED from the measured install (GitHub required check, Claude Code hook, MCP, Docker gateway). Offline. | false |

--paths is the J.4 report: it grades what is on disk, not the env-default three-liner. A missing .claude/settings.json is NOT_CONFIGURED even though coderifts status Runtime still prints PREVENTS. GitHub ENFORCING needs an issuer-bound required check (1104); a local workflow alone is ADVISORY. MCP is never a merge gate. Docker gateway is MEASURE and never ENFORCING from a compose file (gateway_enforcing_requires_external_negative_control).

coderifts status
coderifts status --paths
coderifts status --paths --json
coderifts status owner/repo
coderifts status --repo owner/repo --json

coderifts drift

J.5. Compare the installer pins (wire-digest sha256:7d6fe4a0…, SKILL sha256, .mcp.json digest, required-check context CodeRifts / contract-gate) to this repository. Live tools/list is fetched; unreachable live with a clean local tree is not a match.

| Exit | Meaning | |------|---------| | 0 | No drift | | 1 | Named drift + next step | | 2 | Not measurable (live wire unreachable; local pins clean) |

coderifts drift
coderifts drift --json
coderifts drift --out /path/to/repo

coderifts enforce [repo]

Close enforcement gaps by chaining existing setup commands: Merge → setup-required-check; Runtime → hook install (apply only) + agent-guard guidance; Deploy → deploy-gate CD-step guidance; Content → guidance only. Dry-run by default (--apply to mutate). Does not bypass underlying command safety. Does not label Runtime/Content as server ENFORCING. Does not upgrade UNKNOWN.

Requires a cloud API key for the status read. Merge --apply uses your local gh credentials, not the CodeRifts API key. Exit 0 when no chained step failed, 1 on missing repo/key, API error, or any apply failure.

| Flag | Description | Default | |------|-------------|---------| | [repo] / --repo <owner/repo> | Repository | none (required) | | --apply | Run underlying setup commands | dry-run | | --check | Query GitHub + local workflows (read-only evidence) | false | | --env <name> | With --check: GitHub Environment to query | none | | --branch <name> | With --check: branch (default: repo default) | default branch | | --provider <name> | With --check: provider adapter. github only; others report UNVERIFIABLE and are never stubbed | github | | --head-sha <sha> | With --check: pull-request head commit, so the required-workflow pin can be compared with the bytes being merged | none | | --require-workflow-binding | With --check: exit non-zero when the required workflow is not sha-pinned to the head (workflow_binding.grants_pass !== true). Scope: the CLI's own audit verdict on the Action path — it is not the App-path merge clamp, which is decided server-side and is a separate control. Default OFF — without the flag the evidence is byte-identical, the verdict is unchanged and the exit code stays 0 (advisory) | false | | --json | Machine-readable JSON result | false |

coderifts enforce owner/repo
coderifts enforce --repo owner/repo --apply
coderifts enforce --check --repo owner/repo --env production --json

coderifts enforce --check

Provider-native pipeline-protection evidence. This is not a host claim: --enforce and CODERIFTS_DEPLOY_NO_BYPASS do not set inescapable_deploy. The field is true only when every layer below is VERIFIED and MERGEGATE_ENFORCE is observably true. A VERIFIED required-check binding whose reason names the unobservable clamp is not an inescapable deploy.

| Layer | VERIFIED when | |-------|----------------| | required_check | Default-branch protection required_status_checks.checks[] lists CodeRifts / contract-gate bound to the CodeRifts GitHub App app_id (public metadata: GET https://api.github.com/apps/coderifts). Name-only checks[] (app_id null) is no_issuer_binding. The legacy contexts array has no issuer field → legacy_contexts_no_issuer_binding. Both are NOT_VERIFIED (ID621). | | enforce_admins | enforce_admins.enabled is true (admins cannot bypass). false = NOT_VERIFIED (admin bypass open) | | strict_status_checks | required_status_checks.strict is true | | environment_protection | --env names a GitHub Environment with protection rules and an active deploy-gate job sets that same environment: (mismatch → environment_mismatch) | | workflow_contract_gate | an active job (not if: false) has a step whose uses: is coderifts/contract-gate at a pinned major. Comments, string literals, and commented-out steps are NOT_VERIFIED | | workflow_deploy_gate | an active job step invokes coderifts deploy-gate (not echo of the string; not a comment) |

Invariant: any layer whose evidence cannot be bound to an issuer (our GitHub App id) or to an active job is NOT_VERIFIED or UNVERIFIABLE — never VERIFIED. inescapable_deploy remains true only when every layer is VERIFIED and MERGEGATE_ENFORCE is observably true.

Statuses: VERIFIED / NOT_VERIFIED / UNVERIFIABLE(reason). Auth: GITHUB_TOKEN (never printed). No token → API layers UNVERIFIABLE with the instruction to set GITHUB_TOKEN (repo + administration:read). The CodeRifts GitHub App cannot query branch protection (permissions are contents / pull requests / checks — not administration:read).

--json is the quotable evidence document (spec: provider-enforcement-evidence.v2 — VERIFIED now requires issuer binding and an active YAML-AST job; v1 treated name-only checks and text search as VERIFIED): each layer's status, reason_code, the API endpoint consulted, queried_at. Exit 0 when a report was produced (evidence, not a gate). GitLab/Bitbucket: no adapter — UNVERIFIABLE, never stubbed.

coderifts provider-canary [repo]

Negative canary: open an ephemeral PR with the contract-gate check failing or absent and ask GitHub to merge it. Blocked is the healthy result. On a repository that does not block, the canary leaves a merge+revert commit pair on base (that is the finding, stated) — an admin token's revert bypasses required checks.

| Flag | Description | Default | |------|-------------|---------| | [repo] / --repo <owner/repo> | Repository | none (required) | | --confirm | Required for a real run: this creates a branch and a pull request | none — without it (and without --dry-run) the command exits 2 rather than touching the repo | | --dry-run | Do not touch the provider; report the shape only | false | | --json | Machine-readable evidence document | false |

Exit 0 only when the provider refused the merge. A merge that succeeds is the finding: blocked:false, status NOT_VERIFIED, exit 1.

coderifts provider-canary --repo owner/repo --dry-run
coderifts provider-canary --repo owner/repo --confirm
coderifts provider-canary --repo owner/repo --confirm --json

coderifts grant publish

Encodes an already-signed execution grant plus the PR head sha into a comment marker on stdout, for the 1094 PR-comment delivery slot. It does not mint a grant (src/commands/grant-publish.js:4) — the token must already be a signed cr.exec.v1 or cr.exec.v2 (see Grant versions above).

| Flag | Description | Default | |------|-------------|---------| | --head-sha <sha> | Required. 40-hex PR head sha the grant binds | none | | --grant <token> | Required. cr.exec.v1 or cr.exec.v2 token | none | | --after-payload-hash <hash> | sha256:… of the after-payload | empty string |

Writes <!-- coderifts-grant-v2 --> followed by one JSON line. Pipe it to gh api or post it as a PR comment. Bad --head-sha or a missing --grant exits 2 with usage.

coderifts grant publish --head-sha "$HEAD" --grant "$TOKEN" > /tmp/marker.txt

Reaching the gate today: the contract-gate Action reads a grant from its execution-grant: input, not from PR comments — main() in the gate does not pass grantComments, so the comment path is not yet wired end to end. Until it is, deliver the token through the CODERIFTS_EXECUTION_GRANT repository variable, and note that a grant binds one after-payload, so a pinned variable covers exactly one diff.

Agent host files (coderifts agent-setup)

Writes the six CodeRifts agent-host rule files plus the Claude Code PreToolUse hook settings into the current repo (or --out <dir>):

| File | Host | |------|------| | AGENTS.md | multi-agent / open convention | | CLAUDE.md | Claude Code | | .cursor/rules/coderifts.mdc | Cursor | | .github/copilot-instructions.md | GitHub Copilot | | coderifts-langgraph-policy.js | LangGraph | | openai-agent-instructions.md | OpenAI Agents SDK | | .claude/settings.json | Claude Code PreToolUse → coderifts claude-hook (fail-closed) |

The generated .claude/settings.json matches the recipe above (matcher Write|Edit|MultiEdit, command coderifts claude-hook, timeout 60). Default is fail-closed (missing key / API down → exit 2). Explicit opt-out: CODERIFTS_ADVISORY=1|true. CODERIFTS_STRICT=1 cannot be weakened by ADVISORY. Existing files are skipped unless --force. --force replaces the entire .claude/settings.json (no merge into permissions / other hooks). If the file already exists, add the PreToolUse recipe by hand or accept a full replace.

coderifts agent-setup              # write (skip existing files)
coderifts agent-setup --force      # overwrite
coderifts agent-setup --check      # drift vs embedded content
coderifts agent-setup --out ./docs # custom root

Content is vendored from the app generator (scripts/generate-agent-host-files.js); re-sync with node scripts/sync-cli-agent-host-embed.js when the rule source changes.

Policy template for agent/MCP APIs: coderifts init ai-agent (aliases: agent, mcp).

Copilot MCP configs (coderifts copilot-setup)

Writes GitHub Copilot MCP configs from the canonical tool names. Root keys differ: VS Code uses servers; Copilot cloud Settings paste uses mcpServers.

coderifts copilot-setup              # write (skip existing files)
coderifts copilot-setup --force      # overwrite
coderifts copilot-setup --check      # drift vs embedded content (exit 1 on drift)
coderifts copilot-setup --out ./docs # custom root

| Flag | Description | Default | |------|-------------|---------| | --out <dir> | Target directory | cwd | | --check | Exit 0 if on-disk files match embedded content; exit 1 on drift | false | | --force | Overwrite existing files | skip collisions |

Writes: .vscode/mcp.json, copilot-cloud-agent-mcp.json, copilot-custom-agent-mcp.frontmatter.md, docs/copilot-mcp.md. Unknown flags exit 1 (never silently ignored).

Required check wizard (coderifts setup-required-check)

Guided setup so CodeRifts / contract-gate is a required status check on your default branch (audit 3.4/1 + 3.5; registry admission is 3.4/9 via coderifts registry-gate). The wizard:

  1. Resolves owner/repo from git remote origin (or --repo)
  2. Observes classic branch protection via gh api (your login — never a CodeRifts API key)
  3. Detects repository rulesets that already require the check (honest report; classic GET /protection does not include rulesets)
  4. Default dry-run: prints the exact gh api --method PUT … --input - read-modify-write command that adds the check without clobbering existing protection settings
  5. --apply: runs that PUT with your credentials, then re-reads and only reports success if the check is required
  6. --bind-workflow: create/update a repository ruleset workflows rule pinning .github/workflows/coderifts.yml (the STRICT template filename) to its current blob sha on the target branch (enforcement: active, bypass_actors: []). Dry-run unless combined with --apply. Read-back uses github-workflow-pin.js; reports APPLIED only on VERIFIED.

Why the App never writes protection: mutating branch protection needs administration:write — a trust jump we refuse. Your credentials do the write.

Merge queues: when this check is required, the GitHub App also handles the merge_group webhook (checks_requested) and posts CodeRifts / contract-gate on the merge group head (same gate as PR heads), so the queue does not stall.

| Flag | Description | Default | |------|-------------|---------| | --repo <owner/repo> | Override owner/repo | git remote origin | | --branch <name> | Branch to protect | repo default branch | | --apply | Apply the protection change | print the gh command only | | --bind-workflow | Create/update a ruleset workflows rule pinning .github/workflows/coderifts.yml (STRICT template) by blob sha | false | | --enforce-admins | Set enforce_admins:true on create | false — admins can bypass; the gate reports admin_bypass_open | | --json | Machine-readable JSON result | false |

# Observe + print command (safe default)
coderifts setup-required-check

# Apply + re-verify
coderifts setup-required-check --apply

# Pin the STRICT workflow by blob sha (ruleset `workflows` rule)
coderifts setup-required-check --bind-workflow --apply

# Admins cannot bypass either (opt-in; NOT the default)
coderifts setup-required-check --apply --enforce-admins

# One-liner for CI docs
coderifts setup-required-check --branch main

coderifts lock [repo]

Fetch the observed agent-contract lockfile (coderifts.lock v1) from GET /api/v1/lock, or --check MCP drift of a locked manifest against a live one (scoreMcpRisk). --check is monitor only — it does not block. Unreachable live → status unreachable (not drift). Lock v1 records agents/ops, not MCP tool bodies; pass --locked-manifest (or additive mcp_manifests on the lockfile) for --check.

Requires a cloud API key for write mode.

| Flag | Description | Default | |------|-------------|---------| | [repo] / --repo <owner/repo> | Repository | none (write mode) | | --out <path> | Output path | coderifts.lock | | --json | stdout-only JSON (write: lock doc; check: drift report) | false | | --check | Compare locked vs live MCP manifest | false | | --locked-manifest <path> | Baseline MCP manifest JSON (tools[]) for --check | none | | --live-manifest <path> | Live MCP manifest JSON for --check | none | | --live-url <url> | Fetch live MCP manifest JSON from URL for --check | none | | --lockfile <path> | Read coderifts.lock for additive mcp_manifests | none |

coderifts lock owner/repo
coderifts lock --check --locked-manifest mcp.json --live-manifest live.json

--check exit codes (from lock.js): 0 unchanged; 3 drift; 2 unreachable / missing locked or live (not clean); 1 usage/error.

coderifts adopt

Counterfactual report: what CodeRifts would have done on contract-artifact changes in local git history. Extracts spec-only paths (not source files whose names happen to contain “openapi”), then runs buildCounterfactualReport. Step B (GitHub API + outcome correlation) is not this command. Not a git repository → fail-closed (GIT_ERROR, exit 1). Success → exit 0.

| Flag | Description | Default | |------|-------------|---------| | --days <n> | Look back N days (git log --since) | last 50 commits if neither flag set | | --commits <n> | Last N commits | last 50 commits if neither flag set | | --json | Machine-readable JSON report (analyzer logs silenced) | false |

coderifts adopt
coderifts adopt --days 30
coderifts adopt --commits 20 --json

CI/CD Integration

GitHub Actions

- name: Check API breaking changes
  run: npx coderifts diff old-api.yaml new-api.yaml --ci --format json

GitLab CI

api-check:
  script:
    - npx coderifts diff old-api.yaml new-api.yaml --ci --threshold 40

Jenkins

sh 'npx coderifts diff old-api.yaml new-api.yaml --ci'

Reproduce our accuracy corpus

We publish the accuracy claims as a runnable proof matrix. Reproduce it yourself with one command — no repo, no API key, no cloud:

npx coderifts corpus verify

This evaluates every trust vector (false-positive / false-negative cases, including MCP prompt-injection "poison" vectors) through the real engine and prints a per-vector PASS/FAIL table plus precision/recall. It exits 0 only when every evaluated vector passes (CI-friendly). Add --json for machine-readable output.

Two honest modes:

  • MCP vectors (13) run on bundled pure-JS engines — always verified offline.

  • OpenAPI vectors (9) need the oasdiff engine. The command auto-detects it: if present, all 22/22 are verified with the exact engine semantics our service uses; if absent, the 9 OpenAPI vectors are skipped (not failed) with a "13 of 22 verified" note. We do not substitute a weaker JS diff engine, because it would report different verdicts. To verify all 22 offline:

    brew install oasdiff            # macOS
    go install github.com/tufin/oasdiff@latest   # any platform with Go
    npx coderifts corpus verify

Environment Variables

| Variable | Description | |----------|-------------| | CODERIFTS_API_KEY | API key (alternative to coderifts login) | | CODERIFTS_OASDIFF_BIN | Explicit path to the oasdiff binary (overrides auto-detect) | | CODERIFTS_STRICT | claude-hook: 1 or true pins fail-closed (cannot be weakened by CODERIFTS_ADVISORY). Default is already fail-closed. | | CODERIFTS_ADVISORY | claude-hook: 1 or true is the explicit soft-allow opt-out on “governance could not run” sites. Absence of a key is not this flag. Also accepted by deploy-gate as the same opt-out as CODERIFTS_DEPLOY_ADVISORY. Pre-push: 1 or true allows a push when no API key is configured (explicit opt-out; default is exit 1). | | CODERIFTS_SKIP | Pre-push: 1 is the loud escape hatch (CodeRifts: CODERIFTS_SKIP=1 set — push allowed (explicit override). on stderr, exit 0). Not the missing-key default. Same class as git push --no-verify. | | CODERIFTS_MONITORING_SINK_WIRED | claude-hook: 1 or true host-asserts a monitoring sink so CONTINUE_WITH_MONITORING may exit 0. Not delivery proof. | | CODERIFTS_DEPLOY_ADVISORY | deploy-gate: 1 or true is the explicit opt-out — print the verdict, print ADVISORY MODE — this gate did not block, exit 0. | | CODERIFTS_DEPLOY_ENFORCE | deploy-gate: true attests ENFORCING (same as --enforce; no-op for exit — default is already fail-closed); unknown is explicitly unobservable (never assume ENFORCING) | | NO_COLOR | Disable colored output |

Exit Codes

| Code | Meaning | |------|---------| | 0 | Success: no breaking changes (or below threshold); deploy-gate allow, or advisory opt-out; lock --check unchanged; adopt / status / outcome success | | 1 | Breaking changes (CI mode), analysis/usage/API failure, or deploy-gate policy/infra fail (fail-closed default) | | 2 | claude-hook BLOCK (Claude Code cancel); lock --check unreachable / missing locked or live | | 3 | lock --check drift detected (monitor only — does not block the package) |

status --paths --live --doctor

The four installation probes have their own three-code contract, and the third code is the one that matters:

| Code | Meaning | What a CI job should do | |------|---------|-------------------------| | 0 | Every probe ran and found nothing to fix | proceed | | 1 | A probe ran and found something — each finding carries a next_step | fail the job; the report names the command | | 2 | A probe could not run — nothing was measured on that axis | fail the job, but do not report a misconfiguration |

⚠ 2 is not a worse 1. They mean opposite things: 1 says we looked and it is wrong, 2 says we did not look. Collapsing them lets an outage read as a clean bill of health on the one axis a CI job branches on. This mirrors status --paths --live, which already exits 2 rather than degrading to the offline report.

⚠ --doctor is opt-in precisely because it changes the exit code. status --paths --live has an exit contract that existing CI jobs branch on; turning a finding into exit 1 for everyone on upgrade would break them.

Finding codes

Every finding carries a next_step that is a command or a named action, never prose.

| Code | Means | Next step | |------|-------|-----------| | SETUP_REQUIRED | No API key, or the stored key is rejected | coderifts login | | INSTALLATION_MISSING | The CodeRifts App is not installed on the repository | Install it, then re-run with --live | | WORKSPACE_NOT_BOUND | The server reports no claimed binding for this tenant | coderifts claim | | REQUIRED_CHECK_NOT_CONFIGURED | Installed, but the check is not a required status check | coderifts setup-required-check --repo <owner/repo> | | ISSUER_MISMATCH | Required by context name only, or bound to a different app id | Re-bind the required check to the CodeRifts App | | SURFACE_DRIFT | What the installer pinned and what the repository serves have diverged | coderifts drift --live <owner/repo> |

⚠ ISSUER_MISMATCH is not a milder REQUIRED_CHECK_NOT_CONFIGURED. A check required by name with no app binding is satisfiable by any repository writer posting that context: it looks enforcing and is not.

Links