170 lines
8.5 KiB
Markdown
170 lines
8.5 KiB
Markdown
# 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?
|