npx claudepluginhub jmagly/aiwg --plugin sdlcThis skill uses the workspace's default tool permissions.
Detect breaking changes in API contracts across REST, GraphQL, and gRPC interfaces.
Enforces C++ Core Guidelines for writing, reviewing, and refactoring modern C++ code (C++17+), promoting RAII, immutability, type safety, and idiomatic practices.
Provides patterns for shared UI in Compose Multiplatform across Android, iOS, Desktop, and Web: state management with ViewModels/StateFlow, navigation, theming, and performance.
Implements Playwright E2E testing patterns: Page Object Model, test organization, configuration, reporters, artifacts, and CI/CD integration for stable suites.
Detect breaking changes in API contracts across REST, GraphQL, and gRPC interfaces.
This skill detects API contract regressions by:
When triggered, this skill:
Identifies API contract scope:
Compares contracts to baseline:
Classifies changes by severity:
Validates semantic versioning:
Runs consumer contract tests:
Generates compatibility report:
rest_breaking_changes:
removed:
- endpoint: "DELETE /api/v1/users/{id}"
severity: BREAKING
reason: "Endpoint removed entirely"
- field: "email" from "User" response
severity: BREAKING
reason: "Required field removed from response"
- enum_value: "PENDING" from "OrderStatus"
severity: BREAKING
reason: "Enum value removed"
modified:
- field: "created_at"
from_type: "string"
to_type: "integer"
severity: BREAKING
reason: "Field type changed"
- field: "email"
from_required: false
to_required: true
severity: BREAKING
reason: "Optional field made required in request"
- constraint: "password"
from: "minLength: 6"
to: "minLength: 12"
severity: BREAKING
reason: "Stricter validation on request field"
renamed:
- endpoint: "GET /api/v1/user/{id}"
to: "GET /api/v1/users/{id}"
severity: BREAKING
reason: "Path renamed without redirect/alias"
- parameter: "userId"
to: "user_id"
severity: BREAKING
reason: "Parameter renamed without backward compatibility"
graphql_breaking_changes:
removed:
- field: "User.email"
severity: BREAKING
reason: "Field removed from type"
- argument: "Query.users(filter: UserFilter)"
severity: BREAKING
reason: "Required argument removed"
- type: "Address"
severity: BREAKING
reason: "Type removed from schema"
modified:
- field: "User.age"
from_type: "Int"
to_type: "String"
severity: BREAKING
reason: "Field type changed"
- field: "User.email"
from_nullable: true
to_nullable: false
severity: BREAKING
reason: "Field made non-nullable"
- argument: "Query.user(id: ID)"
from_optional: true
to_optional: false
severity: BREAKING
reason: "Argument made required"
interface_changes:
- interface: "Node"
removed_implementation: "User"
severity: BREAKING
reason: "Type no longer implements interface"
grpc_breaking_changes:
removed:
- field: "UserMessage.email"
field_number: 3
severity: BREAKING
reason: "Field removed from message"
- service: "UserService"
severity: BREAKING
reason: "Service removed"
- rpc: "UserService.GetUser"
severity: BREAKING
reason: "RPC method removed"
modified:
- field: "UserMessage.age"
from_type: "int32"
to_type: "string"
severity: BREAKING
reason: "Field type changed"
- field: "UserMessage.name"
from_label: "optional"
to_label: "required"
severity: BREAKING
reason: "Field made required"
- field_number: 5
from_reserved: false
to_reserved: true
severity: BREAKING
reason: "Field number reserved (deletion)"
renamed:
- message: "User"
to: "UserAccount"
severity: BREAKING
reason: "Message type renamed"
- enum: "Status"
to: "OrderStatus"
severity: BREAKING
reason: "Enum renamed"
openapi_tools:
primary: openapi-diff
alternatives:
- oasdiff
- swagger-diff
- api-diff
usage:
install: "npm install -g openapi-diff"
compare: |
openapi-diff \
.aiwg/api/baselines/openapi-v1.yaml \
.aiwg/api/current/openapi.yaml \
--format markdown \
--breaking-only
output: ".aiwg/api/compatibility/openapi-diff.md"
configuration:
strict_mode: true
ignore_descriptions: true
treat_as_breaking:
- removed_endpoints
- removed_fields
- type_changes
- required_field_additions
- enum_value_removals
graphql_tools:
primary: graphql-inspector
alternatives:
- apollo-cli (schema:check)
- graphql-schema-diff
usage:
install: "npm install -g @graphql-inspector/cli"
compare: |
graphql-inspector diff \
.aiwg/api/baselines/schema-v1.graphql \
.aiwg/api/current/schema.graphql \
--onComplete report.json
output: ".aiwg/api/compatibility/graphql-diff.json"
configuration:
fail_on_breaking: true
include_dangerous: true
schema_extensions: true
protobuf_tools:
primary: buf
alternatives:
- prototool
- protoc-gen-validate
usage:
install: "brew install buf" # or "go install github.com/bufbuild/buf/cmd/buf@latest"
setup: |
# Create buf.yaml
version: v1
breaking:
use:
- FILE
lint:
use:
- DEFAULT
compare: |
buf breaking \
.aiwg/api/current \
--against .aiwg/api/baselines/v1
output: "Breaking change detection via buf CLI"
configuration:
breaking_rules:
- FIELD_SAME_TYPE
- FIELD_NO_DELETE
- ENUM_VALUE_NO_DELETE
- RPC_NO_DELETE
- MESSAGE_NO_DELETE
semver_validation:
rules:
breaking_change:
requires: major_version_bump
examples:
- "v1.2.3 → v2.0.0"
violations:
- detected: breaking_change
version_change: "v1.2.3 → v1.3.0"
verdict: VIOLATION
message: "Breaking change detected but only minor version bumped"
non_breaking_addition:
requires: minor_version_bump
examples:
- "v1.2.3 → v1.3.0"
acceptable:
- "v1.2.3 → v2.0.0" # Major bump also acceptable
bug_fix:
requires: patch_version_bump
examples:
- "v1.2.3 → v1.2.4"
acceptable:
- "v1.2.3 → v1.3.0" # Minor/major also acceptable
enforcement:
block_deployment: true # Block if version mismatch
require_override: true # Allow manual override with justification
pact_integration:
provider: api-service
consumers:
- name: web-frontend
pact_file: ".aiwg/api/pacts/web-frontend.json"
criticality: high
- name: mobile-app
pact_file: ".aiwg/api/pacts/mobile-app.json"
criticality: high
- name: partner-api
pact_file: ".aiwg/api/pacts/partner-api.json"
criticality: medium
verification:
run: |
npm run test:pact
# Verifies provider meets all consumer contracts
on_failure:
action: block_deployment
notification: consumers_affected
compatibility_matrix:
provider_version: v2.0.0
consumers:
- consumer: web-frontend
version: v1.5.0
compatible: true
tests_passing: 45/45
- consumer: mobile-app
version: v2.1.0
compatible: false
tests_passing: 38/42
failing_tests:
- "POST /api/users - email field type mismatch"
- "GET /api/users/{id} - missing 'phone' field"
- consumer: partner-api
version: v1.0.0
compatible: true
tests_passing: 12/12
spring_cloud_contract:
contracts_location: ".aiwg/api/contracts/"
consumers:
- name: order-service
contracts: "contracts/order-service/**/*.groovy"
- name: payment-service
contracts: "contracts/payment-service/**/*.groovy"
verification:
run: "./mvnw clean test"
stub_generation: true
publish_stubs: true
compatibility_check:
baseline: v1.0.0
current: v2.0.0
results:
- consumer: order-service
compatible: true
contracts_verified: 8/8
- consumer: payment-service
compatible: false
contracts_verified: 5/7
failures:
- "User schema missing 'email' field"
- "Order status enum missing 'PENDING'"
# API Compatibility Report
**Date**: 2026-01-28
**Baseline**: v1.5.0 (OpenAPI)
**Current**: v2.0.0
**API Type**: REST (OpenAPI 3.0)
## Executive Summary
**Status**: ⚠️ BREAKING CHANGES DETECTED
**Severity**: HIGH
**Breaking Changes**: 5
**Non-Breaking Changes**: 12
**Version Compliance**: ✅ CORRECT (major bump)
**Consumer Impact**: 2 of 4 consumers affected
## Version Validation
| Aspect | Baseline | Current | Required | Status |
|--------|----------|---------|----------|--------|
| Version | v1.5.0 | v2.0.0 | v2.x.x | ✅ CORRECT |
| Reason | - | Breaking changes detected | Major bump | ✅ VALID |
## Breaking Changes
### 1. Removed Endpoint
**Endpoint**: `DELETE /api/v1/users/{id}`
**Severity**: BREAKING
**Impact**: HIGH
**Details**:
- Endpoint removed entirely from API
- No replacement or redirect provided
- Used by 2 consumers: `web-frontend`, `admin-panel`
**Consumer Impact**:
- web-frontend: 3 call sites affected
- admin-panel: 1 call site affected
**Recommendation**:
- Provide migration path: Use `POST /api/v1/users/{id}/deactivate` instead
- Update consumer documentation
- Consider deprecation period instead of immediate removal
### 2. Field Removed: `User.email`
**Resource**: `User` (GET /api/v1/users/{id} response)
**Field**: `email`
**Severity**: BREAKING
**Impact**: CRITICAL
**Details**:
- Required field `email` removed from User response
- Breaking for consumers expecting this field
- No alternative field provided
**Consumer Impact**:
- web-frontend: AFFECTED (displays user email in profile)
- mobile-app: AFFECTED (uses email for contact)
- partner-api: NOT AFFECTED (does not use email)
**Recommendation**:
- DO NOT REMOVE - Add deprecation warning instead
- Or provide migration: Add `contactInfo.email` as replacement
- Document migration path clearly
### 3. Field Type Changed: `created_at`
**Field**: `created_at`
**From**: `string` (ISO-8601)
**To**: `integer` (Unix timestamp)
**Severity**: BREAKING
**Impact**: HIGH
**Details**:
- Field type incompatible change
- All consumers parsing as ISO-8601 will break
- No backward compatibility layer
**Consumer Impact**:
- ALL CONSUMERS AFFECTED (4/4)
- Requires code changes in all consumers
**Recommendation**:
- Add `created_at_unix` as new field (non-breaking)
- Deprecate `created_at` string format
- Maintain both for 2 versions before removing string format
### 4. New Required Field: `password_policy`
**Endpoint**: `POST /api/v1/users`
**Field**: `password_policy`
**Severity**: BREAKING
**Impact**: MEDIUM
**Details**:
- New field added as required in request body
- Consumers not sending this field will get 400 errors
- Breaking for existing integrations
**Consumer Impact**:
- web-frontend: AFFECTED (user registration form)
- mobile-app: AFFECTED (sign-up flow)
**Recommendation**:
- Make field optional with sensible default
- Or add default value if not provided
- Document new requirement clearly
### 5. Enum Value Removed: `OrderStatus.PENDING`
**Enum**: `OrderStatus`
**Value**: `PENDING`
**Severity**: BREAKING
**Impact**: HIGH
**Details**:
- Enum value removed without replacement
- Consumers comparing against `PENDING` will break
- Orders in `PENDING` state require migration
**Consumer Impact**:
- order-service: CRITICAL (manages pending orders)
- payment-service: AFFECTED (checks pending status)
**Recommendation**:
- DO NOT REMOVE - Deprecate instead
- Or provide mapping: `PENDING` → `AWAITING_CONFIRMATION`
- Migrate existing data before API deployment
## Non-Breaking Changes
### Safe Additions
| Change | Type | Impact |
|--------|------|--------|
| New endpoint: `GET /api/v2/users/search` | Addition | None |
| New optional field: `User.avatar_url` | Addition | None |
| New enum value: `OrderStatus.CANCELLED` | Addition | None |
| New query parameter: `?include_inactive` | Addition | None |
### Deprecations
| Item | Deprecated In | Remove In | Replacement |
|------|---------------|-----------|-------------|
| `GET /api/v1/users/list` | v2.0.0 | v3.0.0 | `GET /api/v2/users` |
| Field `User.phone` | v2.0.0 | v3.0.0 | `User.contactInfo.phone` |
## Consumer Contract Test Results
### Pact Verification
| Consumer | Version | Compatible | Tests | Failures |
|----------|---------|------------|-------|----------|
| web-frontend | v1.5.0 | ❌ NO | 38/45 | 7 |
| mobile-app | v2.1.0 | ❌ NO | 40/42 | 2 |
| partner-api | v1.0.0 | ✅ YES | 12/12 | 0 |
| admin-panel | v0.9.0 | ❌ NO | 15/18 | 3 |
### Failing Contract Tests
**web-frontend failures**:
1. `GET /api/v1/users/{id}` - Missing `email` field in response
2. `POST /api/v1/users` - Missing required field `password_policy`
3. `DELETE /api/v1/users/{id}` - Endpoint not found (404)
**mobile-app failures**:
1. `GET /api/v1/users/{id}` - Field type mismatch: `created_at`
2. `POST /api/v1/users` - Validation error: `password_policy` required
**admin-panel failures**:
1. `DELETE /api/v1/users/{id}` - Endpoint removed
2. `GET /api/v1/orders` - Enum value `PENDING` not recognized
3. `GET /api/v1/users/{id}` - Missing `email` field
## Backward Compatibility Analysis
```yaml
compatibility_assessment:
backward_compatible: false
reason: "5 breaking changes detected"
migration_effort:
web-frontend: HIGH (7 changes required)
mobile-app: MEDIUM (2 changes required)
partner-api: NONE (no changes needed)
admin-panel: HIGH (3 changes required)
recommended_strategy:
option_1:
name: "Parallel API versions"
description: "Maintain v1 and v2 simultaneously"
effort: HIGH
timeline: "6 months dual support"
option_2:
name: "Phased migration"
description: "Reduce breaking changes, migrate in phases"
effort: MEDIUM
timeline: "3 months migration window"
preferred: true
option_3:
name: "Hard cutover"
description: "Deploy v2, deprecate v1 immediately"
effort: LOW
timeline: "1 month notice"
risk: HIGH
password_policy field optional with default valuecreated_at_unix alongside created_at stringemail field - deprecate with timeline insteadPENDING → AWAITING_CONFIRMATION enum mapping// User profile display
- const email = user.email;
+ const email = user.contactInfo?.email || user.email;
// User registration
const userData = {
username: form.username,
password: form.password,
+ password_policy: 'default',
};
// Delete user
- await api.delete(`/api/v1/users/${id}`);
+ await api.post(`/api/v1/users/${id}/deactivate`);
// Timestamp parsing
- const createdAt = new Date(user.created_at); // ISO string
+ const createdAt = user.created_at_unix
+ ? new Date(user.created_at_unix * 1000)
+ : new Date(user.created_at);
// User registration
const userData = {
...
+ password_policy: 'default',
};
$ openapi-diff baseline.yaml current.yaml --breaking-only
BREAKING CHANGES DETECTED (5):
1. DELETE /api/v1/users/{id}
- Endpoint removed
2. GET /api/v1/users/{id}
- Response schema changed
- Field 'email' removed
3. POST /api/v1/users
- Request schema changed
- Field 'password_policy' now required
4. OrderStatus enum
- Value 'PENDING' removed
5. Multiple endpoints
- Field 'created_at' type changed: string → integer
See full report: openapi-diff-report.md
## Usage Examples
### Detect REST API Regression
User: "Check API contract for breaking changes"
Skill executes:
Output: "API Compatibility Report
Status: BREAKING CHANGES DETECTED Breaking: 5 Non-Breaking: 12 Version: v1.5.0 → v2.0.0 (CORRECT major bump) Consumer Impact: 3 of 4 consumers affected
Critical Issues:
See full report: .aiwg/api/compatibility/report-2026-01-28.md
Recommendation: Revert breaking changes or add compatibility layer"
### Detect GraphQL Schema Regression
User: "API breaking change check for GraphQL"
Skill executes:
Output: "GraphQL Schema Compatibility
Status: BREAKING CHANGES DETECTED Breaking: 2 Dangerous: 3 Safe: 8
Breaking Changes:
Dangerous Changes:
Recommendation: Review breaking changes before deployment"
### Consumer Contract Verification
User: "Run consumer contract tests"
Skill executes:
Output: "Consumer Contract Verification
Status: INCOMPATIBLE CONSUMERS DETECTED Compatible: 1/4 Failing: 3/4
Results: ✅ partner-api (12/12 tests passing) ❌ web-frontend (38/45 passing, 7 failures) ❌ mobile-app (40/42 passing, 2 failures) ❌ admin-panel (15/18 passing, 3 failures)
Common Failures:
Action Required: Update consumers or revert breaking changes"
## Integration
This skill uses:
- `regression-baseline`: Store API contract baselines
- `regression-bisect`: Find commit that introduced breaking change
- `regression-report`: Generate comprehensive regression report
- `project-awareness`: Detect API framework (OpenAPI, GraphQL, gRPC)
## Agent Orchestration
```yaml
agents:
detection:
agent: api-designer
focus: Identify and classify API changes
analysis:
agent: architecture-designer
focus: Assess impact and recommend migration
testing:
agent: test-engineer
focus: Run consumer contract tests
approval:
agent: tech-lead
focus: Approve breaking changes or require fixes
api_contract_detection:
api_types:
- rest_openapi
- graphql
- grpc_protobuf
tools:
rest: openapi-diff
graphql: graphql-inspector
grpc: buf
baselines:
storage: .aiwg/api/baselines/
naming: "{api-name}-{version}.{ext}"
strict_mode: true # Fail on any breaking change
semver_enforcement: true
breaking_rules:
rest:
- removed_endpoints
- removed_fields
- type_changes
- new_required_fields
- enum_value_removals
- stricter_validations
graphql:
- removed_fields
- removed_types
- type_changes
- non_nullable_additions
- argument_removals
grpc:
- removed_services
- removed_rpcs
- removed_fields
- type_changes
- required_field_additions
consumer_contracts:
enabled: true
framework: pact # or spring-cloud-contract
pact:
broker_url: https://pact-broker.example.com
publish_verification: true
contracts_location: .aiwg/api/contracts/
fail_on_incompatibility: true
.aiwg/api/baselines/{api-name}-{version}.{yaml|graphql|proto}.aiwg/api/compatibility/report-{date}.md.aiwg/api/compatibility/diff-{baseline}-to-{current}.md.aiwg/api/pact-results/.aiwg/api/migration/{version}/MIGRATION.md