# Contract Invariant Gates

## Purpose
Define non-negotiable API contract checks that must fail CI on violation.

## Scope
- Primary: `doc/api/openapi.draft.yaml`
- Secondary: `doc/api/asyncapi.draft.yaml`

## Critical Invariants (Blocker)
1. Money model must use minor units:
- Require `Money.amount_minor` as `integer`.
- Require `Money.currency` as 3-letter ISO code.
- Forbid financial fields using floating `number`.

2. Sensitive realtime auth must not use query-token auth:
- Forbid query parameter `token` on sensitive endpoints.
- Terminal and notification websocket auth must use `Sec-WebSocket-Protocol` (browser) or `Authorization` header (non-browser).

3. Versioned public API paths:
- All public HTTP paths must start with `/api/v1/`.

4. Pagination must exist on list endpoints:
- Any endpoint with `operationId` beginning with `list` must accept `cursor` and `page_size`.
- Any list response must include `pagination.next_cursor` and `pagination.page_size`.

5. Public node schema must not expose infrastructure coordinates:
- User-facing `NodeSummary` must not contain `host`, `port`, `ssh_username`, password fields, or secret material.
- Infra coordinates allowed only in admin schema.

6. Allocation status state machine completeness:
- Public allocation status enum must include:
  - `requested`
  - `provisioning`
  - `active`
  - `releasing`
  - `released`
  - `failed`

7. Async force-release payload completeness:
- `provisioning.force_release_requested` payload must include `allocation_ids`.

8. Async observability fields:
- Event metadata must include `event_id`, `event_type`, `occurred_at`, `version`, `correlation_id`.
- All five fields are required in `EventMetadata`; `correlation_id` is mandatory for cross-service tracing (OBS-001/OBS-003).

9. WebSocket auth transport safety:
- WebSocket auth tokens must not be transported via URL query parameters.
- Terminal channel must use path allocation identifier and header-based auth/token transport.

10. Admin Ops contract parity:
- If `/admin/ops` is present in UX route inventory (`doc/product/UX_Implementation_Spec.md`),
  OpenAPI must include `GET /api/v1/admin/ops/overview`.

11. Admin Ops runbook metadata parity:
- If `/admin/ops` includes runbook panel behavior in UX/docs,
  OpenAPI must include:
  - `GET /api/v1/admin/runbooks`
  - `GET /api/v1/admin/runbooks/{runbook_id}`
- `/api/v1/admin/ops/overview` must expose explicit runbook mapping fields
  (`*_runbook_id`) for degraded/operator-action states.

12. Node-agent internal contract parity:
- If node-agent is MVP-canonical (`doc/architecture/Node_Agent_Spec.md`),
  OpenAPI must include:
  - `POST /internal/v1/nodes/enroll`
  - `POST /internal/v1/nodes/{node_id}/cert/renew`
  - `GET /internal/v1/nodes/{node_id}/tasks/wait`
  - `POST /internal/v1/nodes/{node_id}/tasks/{task_id}/result`

## CI Implementation Note
- Enforce with Spectral rules where possible.
- For complex structural checks, run explicit invariant scripts (e.g., `yq`/`jq`/custom checks) in `contracts_validate`.
- Treat all critical invariant failures as blocking.
