api-contract-enforcement
Skill3 starsChanged 8 days agoMITView on GitHub
Flag PRs that change the shape, semantics, or error behavior of a public API without versioning, deprecation, or migration notes. Catches removed fields, renamed parameters, changed status codes, broken pagination, and silent enum drift. Apply when reviewing HTTP routes, gRPC services, GraphQL schemas, SDK exports, CLI flags, or any other interface a downstream consumer depends on.
In this repository66 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- clud-bug-collaborationSkill
- critical-issues-onlySkill
- evidence-based-reviewSkill
- respect-existing-conventionsSkill
- skill-frontmatter-qualitySkill
- apca-contrastSkill
- brand-voice-reviewSkill
- chroma-harmonizationSkill
- clud-bug-collaborationSkill
- component-sizing-principlesSkill
- component-sizingSkill
- composing-a-screenSkill
- consuming-a-design-systemSkill
- conventions-templateSkill
- critical-issues-onlySkill
- curating-a-skill-catalogSkill
- designing-a-design-systemSkill
- designing-elite-uiSkill
- design-system-consistencySkill
- design-token-namingSkill
- dtcg-formatSkill
- empirical-design-principlesSkill
- evidence-based-reviewSkill
- finding-a-catalog-skillSkill
- frontend-a11ySkill
- guarding-a-regressionSkill
- ios-safari-surfacesSkill
- line-height-gridSkill
- logmindSkill
- motion-continuitySkill
- oklch-color-spaceSkill
- orchestrating-agent-delegationSkill
- orchestrating-a-multi-agent-runSkill
- orchestrating-elite-agent-qaSkill
- palette-relationshipsSkill
- pii-and-complianceSkill
- proving-an-absenceSkill
- respect-existing-conventionsSkill
- retiring-a-superseded-decisionSkill
- reviewing-design-workSkill
- semver-design-tokensSkill
- session-heartbeatSkill
- skillforgeSkill
- skill-frontmatter-qualitySkill
- spacing-systemSkill
- technical-writingSkill
- test-disciplineSkill
- thrill-designSkill
- token-frugal-toolingSkill
- token-naming-conventionsSkill
- type-scaleSkill
- udts-component-sizing-laddersSkill
- udts-dtcg-extensionsSkill
- udts-linter-rulesSkill
- udts-naming-conventionSkill
- udts-reviewSkill
- udts-semver-defaultsSkill
- udts-spacing-defaultsSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 5 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 84
Every caller now passes arguments in the wrong slots.
- Distinctive: line 166
Before posting a finding, search the codebase (or the PR's commit history) for evidence the migration was already considered:
- Very specific: line 168
Look for a CHANGELOG entry, migration guide, or BREAKING: prefix in the commit message.
- Distinctive: line 169
Look for a deprecated alias or fallback alongside the rename.
- Distinctive: line 170
Look for a version-bump commit (major SemVer, new endpoint path, new schema version).
- Distinctive: line 172
If you find one, downgrade the finding to "verify migration plan is sufficient" rather than flagging it as missed.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
API contract enforcement
A public API is a promise. This skill reviews PRs for unannounced changes to that promise — the kind of edit that ships green CI in your repo but breaks every consumer the moment it lands.
What counts as "public API" for this skill
In rough order of consequence:
- HTTP routes and request/response shapes — REST endpoints, JSON-RPC methods, OpenAPI schemas.
- gRPC services and message definitions — protobuf field numbers, deprecated tags, oneof variants.
- GraphQL schemas — types, fields, arguments, directives, enum values.
- SDK exports — anything a package's
index.ts/__init__.py/ package's main entry re-exports. Types AND runtime values. - CLI flags, subcommands, and exit codes — anything documented in
--helpor relied on by scripts. - Database column names, view definitions, materialized views — when the schema is consumed by readers outside the PR's own service.
- Event payload shapes — Kafka topics, webhook bodies, queue messages.
- Configuration file schemas — when a config file is read by code outside the PR's service.
What this skill is not for: internal helper functions, private classes, package-internal modules. Convention says those can change.
Breaking-change patterns to flag
For each, the finding shape is: quote the diff, explain why it breaks consumers, propose the migration path (deprecate-then-remove, versioned endpoint, additive change, etc.).
1. Removed or renamed fields
- response.user_id
+ response.userIdThis is a breaking change in two ways: removing user_id and adding userId. Old consumers reading user_id now get undefined. The fix is either an additive change (ship userId alongside user_id, deprecate the old field in docs, remove later) or a versioned endpoint (/v2/users/...).
2. Tightened input validation
- email: z.string()
+ email: z.string().email().max(254)This rejects requests that previously succeeded. Even if the previously-accepted inputs were "wrong," consumers may be sending them today. Flag and ask whether existing data has been audited — if not, this needs a deprecation window with logged warnings.
3. Changed status codes or error shapes
- res.status(404).json({ error: 'Not found' })
+ res.status(410).json({ code: 'GONE', message: 'Not found' })Three breakages: status code 404 → 410 (clients that switch on status), key error → message (clients that read it), new key code (clients with strict-shape validation may reject extra fields).
4. Reordered required fields or positional arguments
- function createUser(name: string, email: string, role: Role)
+ function createUser(email: string, name: string, role: Role)Every caller now passes arguments in the wrong slots. Tests within the PR's own repo are updated; downstream consumers aren't.
5. Silently dropped enum values
type Status = 'active' | 'paused' | 'archived'
- type Status = 'active' | 'paused' | 'archived'
+ type Status = 'active' | 'archived'A consumer that holds a 'paused' value loses it on the next round-trip. Surface the migration: what happens to existing 'paused' records?
6. Changed pagination contract
- res.json({ items, total, page, pageSize })
+ res.json({ items, nextCursor })Two paradigms — offset/limit vs cursor — can't coexist transparently for consumers. Either keep both response shapes during a transition window, or version the endpoint.
7. Stricter rate limits or auth scopes
A previously-permissive endpoint suddenly returning 429 or 403 to existing tokens is a breaking change even though the response shape is identical. Flag a missing changelog entry or migration warning.
8. Changed default behavior of optional parameters
- function get(opts = { includeDeleted: false })
+ function get(opts = { includeDeleted: true })Existing callers who omit opts.includeDeleted now get different data. Make the change opt-in or feature-flag it.
9. Removed CLI flags or shortened forms
- program.option('-v, --verbose')
+ program.option('--verbose')Scripts using -v break silently. Either leave the short form, or version the CLI.
10. Database column rename without view + dual-write
- CREATE TABLE users (id, user_name TEXT)
+ ALTER TABLE users RENAME COLUMN user_name TO nameAny reader still issuing SELECT user_name FROM users breaks at the moment of deploy. Migration pattern: add the new column, dual-write, deprecate readers of the old column, then drop.
When this skill should be silent
- The PR doesn't touch any public API surface — pure internal refactor, test changes, build config.
- The change is purely additive — adding a new optional field, new endpoint, new CLI flag — with no removal or behavior change to existing surface.
- The breaking change is explicitly versioned (new endpoint path, new SDK major version, new gRPC service version) AND a migration path / deprecation window is documented in the PR.
- The change is in a clearly marked unstable / experimental / internal surface (
@experimental,@internal,/v0/,__private__, etc.).
In any of those cases, post a single line and stop:
[api-contract-enforcement] n/a — no public-API changes in this diff. (or: change is additive / explicitly versioned)
Finding-shape template
[api-contract-enforcement] Breaking change without deprecation:
<file>:<line><the offending diff>Who breaks: <which consumer pattern this breaks — e.g. "any client that reads
response.user_id">Migration path:
- <step 1 — usually: keep the old form too>
- <step 2 — usually: deprecate the old form in docs>
- <step 3 — usually: remove in a versioned/major release>
Specific > general. Quote the diff. Name the consumer pattern. Don't say "this might break clients" — name the broken access path.
Checking your work
Before posting a finding, search the codebase (or the PR's commit history) for evidence the migration was already considered:
- Look for a CHANGELOG entry, migration guide, or
BREAKING:prefix in the commit message. - Look for a deprecated alias or fallback alongside the rename.
- Look for a version-bump commit (major SemVer, new endpoint path, new schema version).
If you find one, downgrade the finding to "verify migration plan is sufficient" rather than flagging it as missed. The author may have already done the work.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

