From 6043b9ebffa7d811caa906c7ad9599494e7741ed Mon Sep 17 00:00:00 2001 From: fred Date: Wed, 26 Aug 2026 20:02:49 -0500 Subject: [PATCH] docs: api-artifacts contract revision 2 (luna review F1-F5) F1: declared route-metadata layer as complete generator input; generator fails closed on any route lacking extractable metadata; migration of local-DTO/inline-typed/raw-handler routes named as implementing-PR scope. F2: coverage closed over raw framework mounts, delegated surfaces, tier-conditional controllers, SSE, and both-direction Socket.IO events; explicit exclusion and delegation lists. F3: ENDPOINTS.md structured entry format with operationId links; the no-duplication rule reattributed as new disclosed policy with a mechanical boundary witness. F4: witnesses added for OpenAPI 3.1 validity, family coverage in ENDPOINTS.md, per-entry required content, fail-closed generator control, and a defined retirement equivalence algorithm. F5: section 8 disclosure completed (10 items); Authority paragraph restated in the sitemap's own terms. --- docs/requirements/api-artifacts.md | 240 ++++++++++++++++++++--------- 1 file changed, 170 insertions(+), 70 deletions(-) diff --git a/docs/requirements/api-artifacts.md b/docs/requirements/api-artifacts.md index a63d3ac2..474b38a2 100644 --- a/docs/requirements/api-artifacts.md +++ b/docs/requirements/api-artifacts.md @@ -7,12 +7,30 @@ 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 +approval; ratification of this contract by the repository maintainer +supplies that approval for these two artifacts. 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. +Revision 2 (luna review F1–F5): the generation model now defines its +complete input — a declared route-metadata layer every production +route must carry, with the generator failing closed on any route +lacking extractable metadata, and the migration of today's local-DTO, +inline-typed, and raw-handler routes named as implementing-PR scope +(F1). The §7.2 inventory is closed over the real surface: raw +framework mounts, delegated surfaces, conditional/tier-gated +controllers, SSE, and Socket.IO events in both directions, with an +explicit delegation/exclusion list (F2). The `ENDPOINTS.md` +no-duplication rule is reattributed as a new disclosed policy with a +structured entry format and a mechanical checker (F3). Witnesses are +added or made executable for 3.1 validity, family coverage in +`ENDPOINTS.md`, per-entry required content, and the retirement +equivalence algorithm (F4). §8 discloses every untraced binding rule, +and the SITEMAP approval claim is restated in the sitemap's own terms +(F5). + 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). @@ -24,39 +42,63 @@ documentation placement rules stay with the docs atlas 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. +2. **Coverage**: the set of Gateway HTTP routes (however registered), + SSE routes, and Socket.IO events (both directions) 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. + surface it documents — an undocumented live route or event, a + documented phantom, or a divergent schema/auth/error description. +4. **Delegated surface**: a mounted path prefix whose request handling + is delegated wholesale to an embedded third-party engine (for + example an auth engine's own route tree): the Gateway registers the + mount; the engine defines the routes. ## 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). +1. **`OPENAPI.yaml`** is one file, valid OpenAPI 3.1 (witness §7.6), + 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, in a structured entry + format: one entry per endpoint family, carrying (a) the family's + behavior summary, (b) its operations referenced by `operationId` + link into `OPENAPI.yaml` — never by restated definition, (c) the + authentication requirement, (d) the permission/authorization rule + naming the owning contract (contract 2 for chain authorization, the + SOT for workspace membership), (e) error semantics including the + contract 5 §4.2 taxonomy, and (f) Socket.IO event entries (both + directions) for event families. `ENDPOINTS.md` MUST NOT contain + request/response schema definitions for any operation that exists + in `OPENAPI.yaml` (mechanical rule: no `requestBody`/`responses`/ + schema-fragment blocks for such operations — witness §7.5). This + no-duplication rule and the entry format are new policy disclosed + in §8 (the `docs/API/README.md` boundary as written binds guide + books, not `ENDPOINTS.md` itself). 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`. + the Gateway source by a deterministic repository script whose input + is a **declared route-metadata layer**: every production HTTP/SSE + route carries machine-extractable metadata — route decorators plus + typed request/response schemas (the contract 5 §4.1 shared DTOs + where the operation is a mapped tool family; declared per-route + schemas elsewhere) and its error-code set. **The generator fails + closed:** a production route lacking complete extractable metadata + is a generation error, never a silently omitted or partially + emitted operation. Today's local-DTO, inline-typed, and + raw-handler routes therefore migrate to declared metadata in the + implementing PR — that migration is in the implementing PR's + scope, and §7.2's independent inventory is the cross-check that no + route escaped it. 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 @@ -65,14 +107,25 @@ documentation placement rules stay with the docs atlas 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. + extraction), against the §7.2 coverage and §7.3 content witnesses. ## 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. +1. **Closure over the real surface.** Coverage extends to every + production route however registered: framework-decorated + controllers and gateways AND raw framework mounts registered + outside them (the bootstrap's own route/hook registrations), SSE + routes, and conditionally registered (deployment-tier-gated) + controllers — documented in the union, each conditional route + marked with its condition. **Delegated surfaces** (§1.4) are + documented as delegated-surface entries naming the mount, the + delegating engine, and that engine's own contract — not + re-documented route-by-route. **Socket.IO events are covered in + both directions:** subscribed (inbound handler) events and + server-emitted events. Test-only and development-only surfaces are + excluded via an exclusion list that is explicit in the generation + script and enumerated in `ENDPOINTS.md`, never implicit. The + exclusion and delegation lists are new policy disclosed in §8. 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. @@ -83,7 +136,7 @@ documentation placement rules stay with the docs atlas 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 + needed `ENDPOINTS.md` entry in the same PR, enforced by the §7.1 drift gate — there is no "docs to follow" state. ## 5. Legacy migration @@ -93,23 +146,28 @@ documentation placement rules stay with the docs atlas 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. + §7.4's equivalence algorithm. 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. + canonical for anything beyond its own 17 paths. (The + deletion-in-reviewed-PR form and the interim-consumer restriction + are disclosed in §8.) ## 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. +1. The artifacts, the metadata migration (§3.1), 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. + `ENDPOINTS.md` entry in its implementing PR. +4. The phase placement and rollout sequencing in this section are + disclosed in §8. ## 7. Verification requirements @@ -119,51 +177,93 @@ 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. + against a mutated copy. A second control proves the generator's + fail-closed rule (§3.1): a fixture route stripped of its metadata + makes generation fail, not emit a partial document. +2. **Coverage witness:** an independent surface inventory — static + enumeration over `apps/` production code, tests excluded (the A5 + §1.2 inventory style), covering framework-decorated controllers + and gateways, raw mount/hook registrations in the bootstrap + path, SSE routes, conditional registrations (evaluated per + deployment profile and unioned), and delegated-surface mounts — + equals the documented set in both directions: no undocumented live + route, no documented phantom, each conditional route carrying its + condition, each delegated surface present as a delegated-surface + entry. Socket.IO events are inventoried in both directions — + inbound subscription handlers by handler scan, server-emitted + events by emit-call scan over production code — and compared to + `ENDPOINTS.md`'s event entries in both directions. Additionally, + every HTTP route family in `OPENAPI.yaml` has an `ENDPOINTS.md` + entry, and every `ENDPOINTS.md` operation reference resolves to an + existing `operationId` — both directions, mechanical. +3. **Content and taxonomy witness:** every `ENDPOINTS.md` entry + carries the §2.2 required fields — behavior, operation links, + authentication requirement, owning-contract link, error semantics + — presence-checked mechanically against the structured entry + format; 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 + `OPENAPI.yaml` under a defined equivalence algorithm: both + documents canonicalized (references dereferenced, keys sorted), + then per path — structural schema equality, security/authentication + requirement equality, and documented error-code set equality — + with permissions compared against the covering `ENDPOINTS.md` + entries, and the comparison emitting the exact per-path + differences on failure. 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. +5. **Boundary witness:** `ENDPOINTS.md` contains no schema definition + for any operation that exists in `OPENAPI.yaml` — mechanically: no + `requestBody`/`responses`/schema-fragment block attached to a + linked operation, and every operation mention is an `operationId` + link (§2.2's structured format makes this checkable); the witness + proves it can fail by a control run against a mutated copy + containing an inline schema block. +6. **Validity witness:** `OPENAPI.yaml` parses and validates as + OpenAPI 3.1 under a named validator run in CI; the witness proves + it can fail by a control run against an invalidated copy. ## 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 two artifacts, their roles, and the retirement verification +dimensions 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. +1. The generated-with-committed-output production model, the declared + route-metadata layer with its fail-closed generator, the metadata + migration scope, and the 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). +3. The explicit exclusion list and the delegated-surface + documentation form (§4.1). 4. The Socket.IO placement rule (events in `ENDPOINTS.md`, no - pseudo-paths) (§2.1). + pseudo-paths) and the both-direction event coverage (§2.1, §4.1). 5. The no-oracle documentation requirement (§4.2). +6. The `ENDPOINTS.md` structured entry format and its no-duplication + rule with the mechanical boundary witness (§2.2, §7.5). +7. The committed-repository-file rule — neither artifact exists only + in CI (§2.3). +8. The normative-direction rule — generation documents, never + ratifies (§3.2). +9. The retirement deletion-in-reviewed-PR form and the + interim-consumer restriction (§5.2), and the §7.4 equivalence + algorithm. +10. The §6 phase placement: implementing-PR-after-ratification, the + drift gate as a required trunk check from first commit, and the + build-first documentation sequencing. ## 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? +from Gateway source through a declared, fail-closed route-metadata +layer 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, and fail-closed metadata makes +incompleteness a build error) — or hand-authored contract-first, with +code conformance to the hand-written contract enforced by witnesses +instead?