# CONTRACT-API-GOVERNANCE-BASELINE-012: Aggregate OpenAPI Spec & SDK Generation > **Status:** Published > **Version:** 1.0.0 > **Published:** 2025-12-05 > **Owners:** API Governance Guild, SDK Generator Guild > **Unblocks:** SDKGEN-63-001, SDKGEN-63-002, SDKGEN-63-003, SDKGEN-63-004, SDKGEN-64-001, SDKGEN-64-002 ## Overview This contract defines the aggregate OpenAPI specification freeze process, versioning rules, and SHA256 commitment mechanism that enables deterministic SDK generation across TypeScript, Python, Go, and Java targets. ## Aggregate Specification ### Source Location ``` src/Api/StellaOps.Api.OpenApi/stella.yaml ``` ### Composition Process The aggregate spec is generated by `compose.mjs` from per-service specs: | Service | Source Spec | Tag Prefix | |---------|-------------|------------| | Authority | `authority/openapi.yaml` | `authority.*` | | Export Center | `export-center/openapi.yaml` | `export.*` | | Graph | `graph/openapi.yaml` | `graph.*` | | Orchestrator | `orchestrator/openapi.yaml` | `orchestrator.*` | | Policy | `policy/openapi.yaml` | `policy.*` | | Scheduler | `scheduler/openapi.yaml` | `scheduler.*` | ### Current Version ```yaml openapi: 3.1.0 info: title: StellaOps Aggregate API version: 0.0.1 ``` --- ## Freeze Process ### 1. Version Tagging When freezing for SDK generation: ```bash # Compute SHA256 of aggregate spec sha256sum src/Api/StellaOps.Api.OpenApi/stella.yaml > stella.yaml.sha256 # Tag the commit git tag -a api/v0.1.0-alpha -m "API freeze for SDK Wave B generation" ``` ### 2. SHA256 Commitment SDK generators must validate the spec hash before generation: ```bash # Environment variable for hash guard export STELLA_OAS_EXPECTED_SHA256="" # Generator validates before running if [ "$(sha256sum stella.yaml | cut -d' ' -f1)" != "$STELLA_OAS_EXPECTED_SHA256" ]; then echo "ERROR: Spec hash mismatch - regenerate after spec freeze" exit 1 fi ``` ### 3. Published Artifacts On freeze, publish: | Artifact | Location | Purpose | |----------|----------|---------| | Tagged spec | `api/v{version}` git tag | Version reference | | SHA256 file | `stella.yaml.sha256` | Hash verification | | Changelog | `CHANGELOG-api.md` | Breaking changes | --- ## SDK Generation Contract ### Generator Configuration | Language | Config | Output | |----------|--------|--------| | TypeScript | `ts/config.yaml` | ESM/CJS with typed errors | | Python | `python/config.yaml` | sync/async clients, type hints | | Go | `go/config.yaml` | context-first API | | Java | `java/config.yaml` | builder pattern, OkHttp | ### Toolchain Lock ```yaml # toolchain.lock.yaml openapi-generator-cli: 7.4.0 jdk: 21.0.1 node: 22.x python: 3.11+ go: 1.21+ ``` ### Hash Guard Implementation Each generator emits `.oas.sha256` for provenance: ```bash # Example: TypeScript generation echo "$STELLA_OAS_EXPECTED_SHA256 stella.yaml" > dist/.oas.sha256 ``` --- ## Versioning Rules ### Semantic Versioning ``` MAJOR.MINOR.PATCH[-PRERELEASE] - MAJOR: Breaking API changes - MINOR: New endpoints/fields (backwards compatible) - PATCH: Bug fixes, documentation - PRERELEASE: alpha, beta, rc ``` ### Breaking Change Detection ```bash # Run API compatibility check npm run api:compat -- --old scripts/__fixtures__/api-compat/old.yaml \ --new src/Api/StellaOps.Api.OpenApi/stella.yaml ``` ### Version Matrix | API Version | SDK Versions | Status | |-------------|--------------|--------| | 0.0.1 | - | Current (unfrozen) | | 0.1.0-alpha | TS/Py/Go/Java alpha | Target freeze | --- ## Freeze Checklist Before SDK generation can proceed: - [ ] All per-service specs pass `npm run api:lint` - [ ] Aggregate composition succeeds (`node compose.mjs`) - [ ] Breaking change review completed - [ ] SHA256 computed and committed - [ ] Git tag created (`api/v{version}`) - [ ] Changelog entry added - [ ] SDK generator configs updated with hash --- ## Current Freeze Status ### Pending Actions | Action | Owner | Due | Status | |--------|-------|-----|--------| | Compute SHA256 for stella.yaml | API Governance Guild | 2025-12-06 | TODO | | Create api/v0.1.0-alpha tag | API Governance Guild | 2025-12-06 | TODO | | Update SDKGEN configs with hash | SDK Generator Guild | 2025-12-06 | TODO | ### Immediate Unblock Path To immediately unblock SDK generation: ```bash # 1. Compute current spec hash cd src/Api/StellaOps.Api.OpenApi SHA=$(sha256sum stella.yaml | cut -d' ' -f1) echo "Current SHA256: $SHA" # 2. Create hash file echo "$SHA stella.yaml" > stella.yaml.sha256 # 3. Tag for SDK generation git add stella.yaml.sha256 git commit -m "chore(api): freeze aggregate spec for SDK Wave B" git tag -a api/v0.1.0-alpha -m "API freeze for SDK generation" # 4. Set environment for generators export STELLA_OAS_EXPECTED_SHA256="$SHA" ``` --- ## SDK Generation Commands Once freeze is complete: ```bash # TypeScript cd src/Sdk/StellaOps.Sdk.Generator/ts ./generate-ts.sh # Python cd ../python ./generate-python.sh # Go cd ../go ./generate-go.sh # Java cd ../java ./generate-java.sh # Run all smoke tests npm run sdk:smoke ``` --- ## Governance ### Change Process 1. **Propose:** Open PR with spec changes 2. **Review:** API Governance Guild reviews for breaking changes 3. **Test:** Run `api:lint` and `api:compat` 4. **Merge:** Merge to main 5. **Freeze:** Tag and compute SHA256 when ready for SDK ### Stakeholders - **API Governance Guild:** Spec ownership, breaking change review - **SDK Generator Guild:** Generation toolchain, language packs - **Platform Security:** Signing key provisioning (SDKREL-63-001) --- ## Signing Keys ### Development Key (Available Now) A development signing key is available for staging/testing: | File | Purpose | |------|---------| | `tools/cosign/cosign.dev.key` | Private key (password: `stellaops-dev`) | | `tools/cosign/cosign.dev.pub` | Public key for verification | **Usage for SDK staging:** ```bash # Set environment for SDK signing export COSIGN_KEY_FILE=tools/cosign/cosign.dev.key export COSIGN_PASSWORD=stellaops-dev export COSIGN_ALLOW_DEV_KEY=1 # Or use CI workflow with allow_dev_key=1 ``` ### Production Keys (Pending) Production signing requires: - Sovereign crypto key provisioning (Action #7) - `COSIGN_PRIVATE_KEY_B64` CI secret - Optional `COSIGN_PASSWORD` for encrypted keys ### Key Resolution Order 1. `COSIGN_KEY_FILE` environment variable 2. `COSIGN_PRIVATE_KEY_B64` (decoded to temp file) 3. `tools/cosign/cosign.key` (production drop-in) 4. `tools/cosign/cosign.dev.key` (only if `COSIGN_ALLOW_DEV_KEY=1`) --- ## Reference - Aggregate spec: `src/Api/StellaOps.Api.OpenApi/stella.yaml` - Composition script: `src/Api/StellaOps.Api.OpenApi/compose.mjs` - Toolchain lock: `src/Sdk/StellaOps.Sdk.Generator/TOOLCHAIN.md` - SDK generators: `src/Sdk/StellaOps.Sdk.Generator/{ts,python,go,java}/` --- ## Changelog | Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0.0 | 2025-12-05 | API Governance Guild | Initial contract |