Remove the nested v3/ subdirectory by moving all active source code, tests, configs, and assets directly to the project root. Archive v2/ (dead code, 847MB) to v2-archive.tar.gz. Key changes: - Move v3/src/ → src/, v3/tests/ → tests/, v3/packages/ → packages/ - Move v3/tsconfig.json, v3/vitest.config.ts to root - Merge v3/package.json into root package.json (ESM, scripts, deps, exports) - Merge v3/scripts/ into scripts/, v3/implementation/ into docs/implementation/ - Update all CI workflows to remove "cd v3 &&" and v3/ path prefixes - Fix all init installer path resolution (3-level-up → 2-level-up) - Fix hooks to use "node ./dist/cli/bundle.js" instead of bare "aqe" - Update settings.json ADR/DDD directories to docs/implementation/ - Fix helper scripts (statusline, adr-compliance, ddd-tracker, guidance-hooks) - Update 58 agent definitions: aqe/v3/ → aqe/ memory namespaces - Update 15 guidance shards: v3/src/ → src/ path references - Fix sync interfaces: remove v3/ and v2/ path references - Fix test path calculations (process.cwd() + '..' no longer needed) - Fix flaky perf test threshold (500ms → 1000ms for CI environments) - Fix complexity-analyzer test to match ADR-051 keyword-based eligibility Build passes, 17,901 tests pass, CLI and MCP bundles verified. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
11 KiB
Contract Testing Domain
Bounded Context Overview
Domain: Contract Testing
Responsibility: API contracts, consumer-driven contracts, schema validation
Location: src/domains/contract-testing/
The Contract Testing domain ensures API compatibility between services through consumer-driven contracts, schema validation, breaking change detection, and migration planning.
Ubiquitous Language
| Term | Definition |
|---|---|
| API Contract | Formal specification of API behavior |
| Consumer | Service that calls an API |
| Provider | Service that exposes an API |
| Breaking Change | Incompatible API modification |
| Schema | Data structure specification |
| Pact | Consumer-driven contract format |
| Verification | Testing provider against consumer contracts |
| Migration | Process of updating to new API version |
Domain Model
Aggregates
ApiContract (Aggregate Root)
Complete API contract definition.
interface ApiContract {
id: string;
name: string;
version: Version;
type: ContractType;
provider: ServiceInfo;
consumers: ServiceInfo[];
endpoints: ContractEndpoint[];
schemas: SchemaDefinition[];
}
VerificationResult (Aggregate Root)
Result of contract verification.
interface VerificationResult {
contractId: string;
provider: string;
consumer: string;
passed: boolean;
failures: ContractFailure[];
warnings: ContractWarning[];
timestamp: Date;
}
Entities
ContractEndpoint
Individual API endpoint in contract.
interface ContractEndpoint {
path: string;
method: HttpMethod;
requestSchema?: string;
responseSchema?: string;
headers?: Record<string, string>;
examples: EndpointExample[];
}
BreakingChange
Detected incompatible change.
interface BreakingChange {
type: BreakingChangeType;
location: string;
description: string;
impact: 'high' | 'medium' | 'low';
affectedConsumers: string[];
migrationPath?: string;
}
SchemaDefinition
Schema specification.
interface SchemaDefinition {
id: string;
name: string;
type: 'json-schema' | 'openapi' | 'graphql' | 'protobuf' | 'avro';
content: string;
}
Value Objects
ContractType
type ContractType = 'rest' | 'graphql' | 'grpc' | 'event' | 'message';
HttpMethod
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
BreakingChangeType
type BreakingChangeType =
| 'removed-endpoint'
| 'removed-field'
| 'type-change'
| 'required-field-added'
| 'enum-value-removed'
| 'response-code-change';
FailureType
type FailureType =
| 'missing-endpoint'
| 'schema-mismatch'
| 'status-code-mismatch'
| 'header-mismatch'
| 'response-body-mismatch'
| 'timeout'
| 'connection-error';
ServiceInfo
Service identification.
interface ServiceInfo {
readonly name: string;
readonly version: string;
readonly team?: string;
readonly repository?: string;
}
Domain Services
IContractTestingCoordinator
Primary coordinator for the domain.
interface IContractTestingCoordinator {
registerContract(contract: ApiContract): Promise<Result<string>>;
verifyAllConsumers(providerName: string, providerUrl: string): Promise<Result<ProviderVerificationReport>>;
preReleaseCheck(providerName: string, newContractPath: FilePath): Promise<Result<PreReleaseReport>>;
importFromOpenAPI(specPath: FilePath): Promise<Result<ApiContract>>;
exportToOpenAPI(contractId: string): Promise<Result<string>>;
prioritizeContracts(contracts: ApiContract[], context: ContractPrioritizationContext): Promise<Result<ContractPrioritizationResult>>;
// MinCut integration (ADR-047)
setMinCutBridge(bridge: QueenMinCutBridge): void;
isTopologyHealthy(): boolean;
getDomainWeakVertices(): WeakVertex[];
// Consensus integration (MM-001)
isConsensusAvailable(): boolean;
getConsensusStats(): ConsensusStats | undefined;
verifyContractViolation(violation: ContractViolationInfo, confidence: number): Promise<boolean>;
verifyBreakingChange(change: BreakingChangeInfo, confidence: number): Promise<boolean>;
}
IContractValidationService
Contract structure validation.
interface IContractValidationService {
validateContract(contract: ApiContract): Promise<Result<ValidationReport>>;
validateRequest(request: unknown, schema: SchemaDefinition): Promise<Result<SchemaValidationResult>>;
validateResponse(response: unknown, schema: SchemaDefinition): Promise<Result<SchemaValidationResult>>;
validateOpenAPI(spec: string): Promise<Result<OpenAPIValidationResult>>;
}
IContractVerificationService
Provider verification against contracts.
interface IContractVerificationService {
verifyProvider(providerUrl: string, contracts: ApiContract[]): Promise<Result<VerificationResult[]>>;
verifyConsumerContract(providerUrl: string, contract: ApiContract, consumerName: string): Promise<Result<VerificationResult>>;
verifyWithMocks(contract: ApiContract, mocks: MockResponse[]): Promise<Result<VerificationResult>>;
}
IApiCompatibilityService
Breaking change detection.
interface IApiCompatibilityService {
compareVersions(oldContract: ApiContract, newContract: ApiContract): Promise<Result<CompatibilityReport>>;
isBackwardCompatible(oldContract: ApiContract, newContract: ApiContract): Promise<Result<boolean>>;
getBreakingChanges(oldContract: ApiContract, newContract: ApiContract): Promise<Result<BreakingChange[]>>;
generateMigrationGuide(breakingChanges: BreakingChange[]): Promise<Result<MigrationGuide>>;
}
ISchemaValidationService
Schema format validation.
interface ISchemaValidationService {
validateJsonSchema(data: unknown, schema: object): Promise<Result<SchemaValidationResult>>;
validateGraphQLSchema(schema: string): Promise<Result<GraphQLValidationResult>>;
compareSchemas(oldSchema: SchemaDefinition, newSchema: SchemaDefinition): Promise<Result<SchemaComparisonResult>>;
inferSchema(samples: unknown[]): Promise<Result<SchemaDefinition>>;
}
Domain Events
| Event | Trigger | Payload |
|---|---|---|
ContractVerifiedEvent |
Verification complete | { contractId, provider, consumer, passed, failureCount } |
BreakingChangeDetectedEvent |
Breaking change found | { contractId, changes, affectedConsumers } |
ContractPublishedEvent |
Contract published | { contractId, version, provider } |
ConsumerContractCreatedEvent |
Consumer contract added | { contractId, consumer, provider, interactionCount } |
SARSA RL Integration
The domain uses SARSA reinforcement learning for contract prioritization:
interface ContractPrioritizationContext {
readonly urgency: number; // 0-1 urgency level
readonly providerLoad: number; // Current provider load
readonly consumerCount: number; // Number of consumers
}
interface ContractPrioritizationResult {
readonly orderedContracts: ApiContract[];
readonly strategy: string;
readonly confidence: number;
}
Repositories
interface IContractRepository {
findById(id: string): Promise<ApiContract | null>;
findByProvider(provider: string): Promise<ApiContract[]>;
findByConsumer(consumer: string): Promise<ApiContract[]>;
findLatestVersion(name: string): Promise<ApiContract | null>;
save(contract: ApiContract): Promise<void>;
publish(contract: ApiContract): Promise<void>;
}
interface IVerificationResultRepository {
findByContractId(contractId: string): Promise<VerificationResult[]>;
findLatest(contractId: string, consumer: string): Promise<VerificationResult | null>;
findFailed(since: Date): Promise<VerificationResult[]>;
save(result: VerificationResult): Promise<void>;
}
Context Integration
Upstream Dependencies
- OpenAPI/Swagger specifications
- GraphQL schemas
- Protobuf definitions
Downstream Consumers
- Quality Assessment: Contract compliance in gates
- Security Compliance: API security validation
- CI/CD pipelines: Pre-release checks
Anti-Corruption Layer
The domain abstracts different contract formats (Pact, OpenAPI, GraphQL SDL) through the ApiContract interface and format-specific importers.
Task Handlers
| Task Type | Handler | Description |
|---|---|---|
register-contract |
registerContract() |
Add new contract |
verify-provider |
verifyAllConsumers() |
Verify against all consumers |
pre-release-check |
preReleaseCheck() |
Breaking change detection |
import-openapi |
importFromOpenAPI() |
Import from spec |
prioritize-contracts |
prioritizeContracts() |
RL-based prioritization |
Configuration Constants
const CONTRACT_CONSTANTS = {
DEFAULT_TIMEOUT_MS: 60000,
QUICK_TIMEOUT_MS: 10000,
MAX_CACHED_VALIDATIONS: 1000,
CACHE_TTL_MS: 3600000,
CONTRACT_TTL_SECONDS: 86400,
MIGRATION_TTL_SECONDS: 86400 * 90,
MAX_RECURSION_DEPTH: 10,
MAX_SCHEMA_DEPTH: 20,
MAX_MIGRATION_STEPS: 50,
DEFAULT_SEARCH_LIMIT: 100,
HIGH_IMPACT_THRESHOLD: 5,
BREAKING_CHANGE_THRESHOLD: 10,
DEFAULT_PROVIDER_LOAD: 50,
HIGH_PROVIDER_LOAD_THRESHOLD: 80,
};
Breaking Change Detection
function detectBreakingChanges(
oldContract: ApiContract,
newContract: ApiContract
): BreakingChange[] {
const changes: BreakingChange[] = [];
// Check for removed endpoints
for (const oldEndpoint of oldContract.endpoints) {
const newEndpoint = findEndpoint(newContract, oldEndpoint.path, oldEndpoint.method);
if (!newEndpoint) {
changes.push({
type: 'removed-endpoint',
location: `${oldEndpoint.method} ${oldEndpoint.path}`,
description: 'Endpoint was removed',
impact: 'high',
affectedConsumers: oldContract.consumers.map(c => c.name),
});
}
}
// Check for schema changes
for (const oldSchema of oldContract.schemas) {
const newSchema = findSchema(newContract, oldSchema.id);
if (newSchema) {
const schemaChanges = compareSchemas(oldSchema, newSchema);
changes.push(...schemaChanges);
}
}
return changes;
}
ADR References
- ADR-047: MinCut topology for distributed verification
- MM-001: Consensus for breaking change verification