Api contract reviewer
Skill ralvarezdev/ralvaskills/skills/quality/api-contract-reviewer
My personal, ever-growing collection of AI skills for OpenCode and Claude Code. Enforces strict clean architecture and professional standards.
npx -y skills add ralvarezdev/ralvaskills --skill api-contract-reviewerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Reviews REST + gRPC contracts for stability, versioning, completeness, backwards compatibility. References rest-api-architect / protobuf-architect / grpc-architect for rules; runs `buf breaking` / `openapi-diff`. Severity-keyed findings. Use when reviewing a new endpoint, proto change, or before a breaking-change release.
SKILL.md
9.9 KB, as published. Nobody here has run it
API Contract Reviewer
Reviews contracts — REST OpenAPI specs and protobuf .proto files — for stability, versioning hygiene, and completeness. Catches the contract issues architects encoded rules against before they ship to clients.
1. When to invoke
- A PR changes
.protofiles, OpenAPI YAML, or any handler that affects the wire contract. - Before publishing a new major version of an API.
- Before deprecating a field or method.
- Periodic audit of an existing API for drift between spec and implementation.
2. Output format
Same shape as security-reviewer §2 — findings table with severity, then a one-line summary.
| Severity | Rule | Location | Evidence | Fix |
|---|---|---|---|---|
| Critical | Breaking change to v1 | `proto/orders/v1/order.proto:23` | Field `status` type changed `string` → `int32` | Revert; introduce `status_v2` as a new field in v1, deprecate `status`, or bump to v2 |
| High | Versioning mismatch | `openapi.yaml` | Endpoint `/orders` lacks `/v1/` prefix | Add `/v1/` prefix per rest-api-architect §4 |
| Medium | Missing OpenAPI example | `openapi.yaml:42` | `CreateOrderRequest` has no `example:` | Add a realistic example — drives SDK gen + docs |
| Low | Inconsistent error shape | `openapi.yaml` | 404 returns `{detail: ...}` while 422 returns RFC 7807 | Standardize on RFC 7807 per rest-api-architect §7 |
Severity guide:
- Critical — wire-breaking change in a stable version (clients break on deploy).
- High — convention violation that's expensive to fix later (versioning, error shape).
- Medium — completeness gap that hurts client experience (missing examples, undocumented errors).
- Low — polish (inconsistent casing, missing descriptions).
3. Review approach
- Mechanical pass (REST:
openapi-diff; gRPC:buf breaking) — surfaces wire-breaking changes. - Convention pass — read the spec / proto files against the architect rules in §4.
- Completeness pass — every endpoint, every model, every error has the metadata clients need (examples, descriptions, types).
4. What to check — by category
Versioning
Per rest-api-architect §4 and protobuf-architect §4:
- REST: every endpoint under
/v1/,/v2/, etc. Not in headers, not in query params. - gRPC / proto: version is part of the package path (
acme.shop.orders.v1), never appended to message names (OrderV1is wrong). - Additive changes don't bump the version — new optional field, new endpoint, new enum value, new RPC method. Stay in the existing version.
- Breaking changes always bump the major version — field removal, type change, semantic change, required-field tightening. New
vNpackage + run side-by-side. - Deprecate before remove — add
[deprecated = true](proto) ordeprecated: true(OpenAPI), setDeprecation/Sunsetheaders (RFC 9745 / 8594) for REST.
Field & method hygiene (proto)
- Field numbers never reused. Removed field →
reserved N;+reserved "name";. - Field type never changed.
int32 → stringis wire-breaking even if the runtime value fits both. - Field numbers 1–15 reserved for fields read on every request (1-byte wire encoding).
- Enum:
*_UNSPECIFIED = 0mandatory. Enum value namesUPPER_SNAKE_CASEprefixed with the enum name. - No primitive wrappers (
StringValue,Int32Value) — useoptionalinstead.
Error contracts
Per rest-api-architect §7 for REST and grpc-architect §2 for gRPC:
- REST: every error returns
application/problem+json(RFC 7807) —type,title,status,detail,instance,correlation_id. Never{"detail": "..."}and{"errors": [...]}mixed in one API. - gRPC:
status.Errorwith a standard code. Domain-error → code mapping is centralized; no handler invents its own. typeURLs are stable once published — clients switch on them.- 422 validation errors include the structured field list per rest-api-architect §7.
- 5xx responses always include
correlation_idties to server logs.
Idempotency and concurrency
Per rest-api-architect §8 and §9:
Idempotency-Keymandatory on POST/PATCH. Missing →400. Documented in OpenAPI as a required header.ETag+If-Matchmandatory on PUT/PATCH. Stale →412. Documented.- Cursor pagination, not offset. Documented
next_cursorandlimitin response.
JSON shape & encoding
snake_caseJSON field names.- ISO 8601 timestamps, string-encoded with timezone.
- Money as strings (
"99.99"), never JSON numbers. - UUIDs as canonical hex with dashes, UUID v7 preferred.
null≠ missing — both are documented behaviors in PATCH.
OpenAPI completeness (REST)
- Tag, summary, description on every operation. They drive docs and SDK code-gen.
responses:documents non-default codes (401,403,404,409,412,422).examples:on every request / response model. SDKs render them; integration tests use them.requestBody.required: truewhen the body is mandatory — default isfalse, easy to miss.securitySchemesdeclared (Bearer / OAuth2) and referenced per-endpoint.servers:andinfo.contactset — these aren't FastAPI defaults but matter for published specs.info.versionmatches the API major version (1.0.0, not0.1.7).
gRPC service hygiene
Per grpc-architect §1:
- One service per file.
- Every RPC takes a
<Verb><Noun>Requestand returns<Verb><Noun>Response. Nevergoogle.protobuf.Emptyas input. ListXRequest/ListXResponseuse cursor pagination matching REST conventions.google.protobuf.Emptyonly for fire-and-forget responses with no useful return.- Streaming pattern justified in proto comments (server-stream vs client-stream vs bidi).
Documentation drift
The spec is the contract; drift between code and spec is a contract failure:
- OpenAPI generated from code, not hand-written. Per rest-api-architect §15.
- Snapshot test in CI: the spec is asserted against a committed snapshot file. Any change is reviewed.
- gRPC equivalent: generated code is committed under
gen/per protobuf-architect §6. PR shows the generated diff alongside the proto diff.
5. Tooling
Run these on the diff before the read pass; their output goes into the report.
| Tool | Catches |
|---|---|
buf breaking --against '.git#branch=main,subdir=proto' | Wire-breaking changes in .proto files |
buf lint | proto3 style + Buf-style package naming |
openapi-diff <old> <new> | Wire-breaking changes in OpenAPI specs (additions, removals, type changes) |
swagger-cli validate openapi.yaml (or redocly lint) | OpenAPI 3.1 validity + completeness rules |
| Snapshot diff in CI | assert(app.openapi() == snapshot) per fastapi-architect §10 |
These run in CI per rest-api-architect §15 and protobuf-architect §8 — review they're actually wired and failing builds on findings.
6. What this skill does NOT do
- Performance review. Slow queries, blocking I/O — see performance-reviewer.
- Security review. Auth, injection, secrets — see security-reviewer.
- Architecture review. Whether the API surface is shaped right at the boundary level — see improve-codebase-architecture.
This skill is about whether the contract is stable and complete, not whether the underlying implementation is fast or safe.
7. Cross-skill ties
- rest-api-architect — REST rules this skill verifies.
- protobuf-architect — proto rules +
buf breaking/buf lint. - grpc-architect — gRPC service-definition conventions + error codes.
- fastapi-architect / gin-architect / nethttp-architect — implementation skills; reviewer confirms code matches the contract.
- security-reviewer — when contract issues are also security issues (tokens in query params, sensitive data in URLs), promote severity.
- commit-author — breaking changes get the
BREAKING CHANGE:footer in the commit.