8.5 KiB
API Contract Artifacts Contract (S2 contract 9)
Status: DRAFT — awaiting ratification (webui-audit S2, contract 9 of 9).
Authority: docs/API/README.md declares the single API documentation
boundary: docs/API/OPENAPI.yaml as the canonical machine-readable
HTTP/WebSocket contract and docs/API/ENDPOINTS.md as the
human-readable endpoint, authentication, permission, and error index —
both declared, neither present (the webui-audit REPORT's prerequisite
9). docs/SITEMAP.md records that canonical scope requires maintainer
approval; this contract's ratification is that approval path. Contract
5 (tool-gateway-mapping.md) §4 binds the per-operation
request/result/error/audit envelope; this contract binds only how the
two artifacts are produced, what they must cover, and how they are
kept true.
This contract binds the artifact definitions (§2), the production
model (§3), coverage obligations (§4), legacy migration (§5), phase
timing (§6), witnesses (§7), and disclosed drafting additions (§8).
Operation semantics stay with contract 5 and the owning S2 contracts;
documentation placement rules stay with the docs atlas
(docs/README.md).
1. Definitions
- The artifacts:
docs/API/OPENAPI.yamlanddocs/API/ENDPOINTS.md, exactly as declared bydocs/API/README.md. - Coverage: the set of Gateway HTTP routes and Socket.IO events the artifacts describe.
- Drift: any difference between an artifact and the production surface it documents — an undocumented live route, a documented phantom route, or a divergent schema/auth/error description.
2. Artifact contract
OPENAPI.yamlis one file, valid OpenAPI 3.1, and the canonical machine-readable contract for the Gateway's HTTP surface. Socket.IO events, which OpenAPI cannot express natively, are documented inENDPOINTS.mdand referenced from the OpenAPI description block; inventing a pseudo-path encoding for them insideOPENAPI.yamlis non-conformant.ENDPOINTS.mdis the human index: per endpoint family, the behavior, authentication requirement, permission/authorization rule (naming the owning contract — contract 2 for chain authorization, the SOT for workspace membership), and error semantics including the contract 5 §4.2 taxonomy. It links to owning contracts and toOPENAPI.yaml; it does not duplicate endpoint definitions (thedocs/API/README.mdauthoring boundary).- Both artifacts are committed repository files, reviewed in PRs like any contract text; neither is a build output that exists only in CI.
3. Production model
- Generation (per the ruling).
OPENAPI.yamlis GENERATED from the Gateway source (route decorators plus the shared request/result DTOs of contract 5 §4.1) by a deterministic repository script; the generated output is committed, and CI regenerates and byte-compares it (§7.1). Hand edits toOPENAPI.yamlare non-conformant — a description that cannot be expressed from source annotations goes into the annotations, or intoENDPOINTS.md. - Normative direction. Generation documents the code; it does not ratify it. The S2 contracts and their witnesses remain the normative gates on what the surface may be; the artifacts make the measured surface visible and machine-checkable. A generated description of a non-conformant route is drift evidence against that route's owning contract, not authority for it.
ENDPOINTS.mdis hand-authored (its content — permission rationale, cross-contract links, event semantics — is judgment, not extraction), against the §7.2 coverage witness.
4. Coverage obligations
- Every production Gateway HTTP route appears in
OPENAPI.yaml; every route family appears inENDPOINTS.md. Test-only and development-only surfaces are excluded and the exclusion list is explicit in the generation script, not implicit. - Every documented operation carries: its authentication requirement; its authorization rule by reference to the owning contract; its error responses drawn from the contract 5 §4.2 closed taxonomy. Where contract 2's no-existence-oracle rule applies, the documentation shows authorization refusal and not-found as indistinguishable on the wire — documenting a distinguishing response there is a coverage defect, not a documentation style choice.
- New surface ships documented: a PR that adds or changes a Gateway
route or event lands with the regenerated
OPENAPI.yamland any neededENDPOINTS.mdrow in the same PR, enforced by the §7.1 drift gate — there is no "docs to follow" state.
5. Legacy migration
docs/openapi-tess.yaml(17 paths, Tess-scoped) remains labeled a scoped legacy artifact until the consolidatedOPENAPI.yamldemonstrably covers it: thedocs/API/README.mdretirement rule (verify paths, schemas, authentication, permissions, error behavior, and generated/client references) is binding, witnessed by §7.4.- Retirement is deletion in a reviewed PR after the §7.4 witness passes; until then no consumer may treat the legacy artifact as canonical for anything beyond its own 17 paths.
6. Phase timing
- The artifacts and the generation script are produced by an implementing PR after this contract is ratified; they are S4-phase platform work, not part of any S2 ruling PR.
- From the first commit of
OPENAPI.yamlonward, the §7.1 drift gate is a required CI check on the integration trunk; the §4.3 same-PR rule binds every subsequent surface-changing PR. - The build-first tool families (A5 ranks, contracts 1–3, 5, 8) are
documented as they land, under the same rule — the roll-up query,
for example, ships with its OpenAPI operation and its
ENDPOINTS.mdrow in its implementing PR.
7. Verification requirements
Binding on the implementing PRs; each witness names its commands, scanned source roots, and compared files.
- Drift witness: CI regenerates
OPENAPI.yamlwith the repository script and fails on any byte difference from the committed file; the witness proves it can fail by a control run against a mutated copy. - Coverage witness: an independent route inventory (static
enumeration of Gateway controllers and gateways over
apps/, production code, tests excluded — the A5 §1.2 inventory style) equals the documented path set in both directions: no undocumented live route, no documented phantom. Socket.IO events are inventoried the same way againstENDPOINTS.md. - Taxonomy witness: every error response documented in
OPENAPI.yamluses a code from the contract 5 §4.2 closed enums, and each family's documented codes exactly match the enum in the shared types package; where the no-oracle rule applies, the documented refusal and not-found responses are identical in code, status, and shape. - Retirement witness: before
docs/openapi-tess.yamlis deleted, an automated comparison proves each of its 17 paths is covered byOPENAPI.yamlwith equivalent schemas, auth, permissions, and error behavior, and a repository-wide reference scan shows no remaining consumer (including generated clients) resolves the legacy file. - Boundary witness:
ENDPOINTS.mdcontains no endpoint definition duplicated fromOPENAPI.yaml(machine-checkable: no path+verb table row whose content restates the generated operation instead of linking it), per thedocs/API/README.mdauthoring boundary.
8. Drafting additions (PRD §12.1 disclosure)
The two artifacts, their roles, the single-boundary rule, and the
legacy retirement conditions are traced to docs/API/README.md and
docs/SITEMAP.md. Proposed drafting additions, visible here for
ratification, each severable:
- The generated-with-committed-output production model and CI drift gate (§3.1, §7.1) — the ruling below.
- The same-PR documentation rule for surface changes (§4.3).
- The explicit exclusion list for test/development surfaces (§4.1).
- The Socket.IO placement rule (events in
ENDPOINTS.md, no pseudo-paths) (§2.1). - The no-oracle documentation requirement (§4.2).
Ruling request
Ruling requested (one decision): shall OPENAPI.yaml be generated
from Gateway source with a committed output and a CI drift gate
(recommended — the 45-controller surface already exists, so
generation is the only route that starts true and stays true) — or
hand-authored contract-first, with code conformance to the
hand-written contract enforced by witnesses instead?