Files
stack/docs/requirements/api-artifacts.md
T
2026-08-26 19:45:03 -05:00

8.5 KiB
Raw Blame History

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

  1. The artifacts: docs/API/OPENAPI.yaml and docs/API/ENDPOINTS.md, exactly as declared by docs/API/README.md.
  2. Coverage: the set of Gateway HTTP routes and Socket.IO events the artifacts describe.
  3. 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

  1. OPENAPI.yaml is 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 in ENDPOINTS.md and referenced from the OpenAPI description block; inventing a pseudo-path encoding for them inside OPENAPI.yaml is non-conformant.
  2. ENDPOINTS.md is 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 to OPENAPI.yaml; it does not duplicate endpoint definitions (the docs/API/README.md authoring boundary).
  3. 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

  1. Generation (per the ruling). OPENAPI.yaml is 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 to OPENAPI.yaml are non-conformant — a description that cannot be expressed from source annotations goes into the annotations, or into ENDPOINTS.md.
  2. 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.
  3. ENDPOINTS.md is hand-authored (its content — permission rationale, cross-contract links, event semantics — is judgment, not extraction), against the §7.2 coverage witness.

4. Coverage obligations

  1. Every production Gateway HTTP route appears in OPENAPI.yaml; every route family appears in ENDPOINTS.md. Test-only and development-only surfaces are excluded and the exclusion list is explicit in the generation script, not implicit.
  2. 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.
  3. New surface ships documented: a PR that adds or changes a Gateway route or event lands with the regenerated OPENAPI.yaml and any needed ENDPOINTS.md row in the same PR, enforced by the §7.1 drift gate — there is no "docs to follow" state.

5. Legacy migration

  1. docs/openapi-tess.yaml (17 paths, Tess-scoped) remains labeled a scoped legacy artifact until the consolidated OPENAPI.yaml demonstrably covers it: the docs/API/README.md retirement rule (verify paths, schemas, authentication, permissions, error behavior, and generated/client references) is binding, witnessed by §7.4.
  2. 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

  1. 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.
  2. From the first commit of OPENAPI.yaml onward, 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.
  3. The build-first tool families (A5 ranks, contracts 13, 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.md row in its implementing PR.

7. Verification requirements

Binding on the implementing PRs; each witness names its commands, scanned source roots, and compared files.

  1. Drift witness: CI regenerates OPENAPI.yaml with 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.
  2. 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 against ENDPOINTS.md.
  3. Taxonomy witness: every error response documented in OPENAPI.yaml uses 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.
  4. Retirement witness: before docs/openapi-tess.yaml is deleted, an automated comparison proves each of its 17 paths is covered by OPENAPI.yaml with equivalent schemas, auth, permissions, and error behavior, and a repository-wide reference scan shows no remaining consumer (including generated clients) resolves the legacy file.
  5. Boundary witness: ENDPOINTS.md contains no endpoint definition duplicated from OPENAPI.yaml (machine-checkable: no path+verb table row whose content restates the generated operation instead of linking it), per the docs/API/README.md authoring 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:

  1. The generated-with-committed-output production model and CI drift gate (§3.1, §7.1) — the ruling below.
  2. The same-PR documentation rule for surface changes (§4.3).
  3. The explicit exclusion list for test/development surfaces (§4.1).
  4. The Socket.IO placement rule (events in ENDPOINTS.md, no pseudo-paths) (§2.1).
  5. 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?