diff --git a/docs/requirements/api-artifacts.md b/docs/requirements/api-artifacts.md new file mode 100644 index 00000000..a63d3ac2 --- /dev/null +++ b/docs/requirements/api-artifacts.md @@ -0,0 +1,169 @@ +# 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 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.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?