This commit is contained in:
@@ -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?
|
||||
Reference in New Issue
Block a user