docs: API contract artifacts contract (S2 contract 9) #1443

Merged
fred merged 10 commits from contract/api-artifacts into next 2026-08-27 19:18:39 +00:00
Collaborator

S2 contract 9 of 9 (final REPORT.md prerequisite): binds how docs/API/OPENAPI.yaml and ENDPOINTS.md are produced and kept true — artifact definitions per the docs/API/README.md declaration, production model (generated OPENAPI.yaml with committed output + CI drift gate, hand-authored ENDPOINTS.md), coverage obligations (full route inventory both directions, contract 5 §4.2 error taxonomy, no-oracle documentation), openapi-tess.yaml retirement conditions, phase timing (implementing PR after ratification, S4-phase), 5 witness families, PRD §12.1 disclosure, one-sentence ruling (generated+drift-gate vs contract-first).

Docs-only, one new file. No self-merge before independent review (gate 16). Model review to follow.

S2 contract 9 of 9 (final REPORT.md prerequisite): binds how docs/API/OPENAPI.yaml and ENDPOINTS.md are produced and kept true — artifact definitions per the docs/API/README.md declaration, production model (generated OPENAPI.yaml with committed output + CI drift gate, hand-authored ENDPOINTS.md), coverage obligations (full route inventory both directions, contract 5 §4.2 error taxonomy, no-oracle documentation), openapi-tess.yaml retirement conditions, phase timing (implementing PR after ratification, S4-phase), 5 witness families, PRD §12.1 disclosure, one-sentence ruling (generated+drift-gate vs contract-first). Docs-only, one new file. No self-merge before independent review (gate 16). Model review to follow.
fred added 1 commit 2026-08-27 00:45:05 +00:00
fred added 1 commit 2026-08-27 01:02:55 +00:00
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.
fred added 1 commit 2026-08-27 01:11:53 +00:00
F1: route metadata record defined as a closed required-field list with
a per-field completeness predicate; production route made a decidable
term; generator computes the inventory route set first and fails
naming route and field.
F2: inventory scans all production source in apps/ and packages/ with
an enumerated registration-primitive list; deployment profiles bound
to the closed tier enumeration with a declared condition field; event
names bound to one typed registry with a literal-name rule.
F3: ENDPOINTS.md checker defined as a repository script with five
exact reject rules over a Markdown AST parse, one control per rule.
F4: retirement equivalence algorithm fully enumerated
(canonicalization steps, legacy error-code derivation, covering-entry
selection, permission equality); validator pinned to Redocly CLI.
F5: section 8 items 11-12 disclose the definitions and the witness
machinery.
F6: delegation allowlist (prefix, engine package, engine contract,
registering module) with a below-prefix boundary check; non-allowlisted
prefixes are ordinary route-by-route surface.
fred added 1 commit 2026-08-27 01:46:10 +00:00
fred added 1 commit 2026-08-27 02:05:59 +00:00
fred added 1 commit 2026-08-27 02:34:15 +00:00
fred added 1 commit 2026-08-27 02:58:52 +00:00
fred added 1 commit 2026-08-27 03:22:43 +00:00
- §7.7(d)(2): execution-pipeline attribution — framework interception
  components attach to framework-routed routes only; adapter hook-chain
  components attributed by dispatch predicate; raw-mounted routes never
  carry framework-component statuses (phantom rejection + raw-hook
  control) (F1)
- §7.2: method-partition exhaustiveness — acceptance/refusal path
  classification; forwarding complement or unguarded branch fails;
  declared external method contract for non-production forwarding edges
  (F2, NF2)
- §7.7(d)(5): exhaustive default inventory — total classification over
  pinned options-type keys plus configured composition-root options;
  unclassified key fails; bodyLimit migration example (NF1)
- §2.2/§7.5: three entry kinds; Delegated:/Excluded: exact sub-item
  syntax mirroring §4.4 allowlist and §4.1 exclusion list; revised (k)
  kind-partition rule; new (l) exclusion mirror; twelve reject rules
  (NF7)
fred added 1 commit 2026-08-27 03:44:25 +00:00
fred added 1 commit 2026-08-27 03:58:42 +00:00
rev-code-01 approved these changes 2026-08-27 04:15:23 +00:00
rev-code-01 left a comment
Member

APPROVED — rev-code-01, pinned to head 1168c4b0d418761dd26a4e0989eae0b3abcb99e7 (re-verified unmoved immediately before posting).

Scope: doc-only, single new file docs/requirements/api-artifacts.md (+1360 lines, 10 revisions). This is the largest of the S2 set; verified independently of the luna r1-r10 chain, with the load-bearing factual claims measured by me at this head:

  1. Artifact anchors exact: docs/API/README.md declares exactly OPENAPI.yaml (canonical machine-readable) + ENDPOINTS.md (human index), both "Planned; not present yet" — neither file exists, as the contract's authority paragraph states. docs/SITEMAP.md:69 carries the "canonical scope requires maintainer approval" line the ruling request resolves, and openapi-tess.yaml exists with exactly 17 paths (the retirement conditions' input).
  2. Raw-mount exemplars verified to the line: mcp.controller.ts:28-30 registers fastify.addHook('onRequest', …) and hijacks at :40, with the dispatch predicate req.url.startsWith('/mcp') at :35 — exactly the rev-10 disposition's factual basis; auth.controller.ts:17-24 registers the same onRequest phase for /api/auth/ and hijacks at :44/:50. The startsWith prefix predicate genuinely lacks segment-boundary semantics (/mcp-anything would dispatch) — luna's pre-existing implementation gap is real and I confirm it is an implementation defect the contract's §7.2 segment-boundary rule makes non-conformant, not a contract defect.
  3. ApiAuthClass six-value enumeration is representable in the live tree: the admin alternation is real (admin.guard.ts tries bearer token first, falls back to session — the alternation guard the contract refuses to collapse into session); federation mTLS exists (federation-auth.guard.ts validates client certificates and grant serials); bootstrap pre-epoch surface exists (bootstrap.controller.ts); api-key/session/none are trivially present.
  4. Fastify pin: gateway declares fastify: ^5.0.0; lockfile resolves 5.8.2 (direct) and 5.7.4 (platform) plus an unrelated 11.x under plugins — matching luna's note that the implementing witness must cite the runtime adapter resolution it scans. The rev-10 lifecycle-map requirement (pinned-version citation per emitting default) is consistent with this split resolution.
  5. Inventory classes exist: SSE (text/event-stream, interaction.controller), 7 @SubscribeMessage inbound socket events, tier-gated controllers, and two raw mounts — all the §4.1 closure classes the inventory must cover.
  6. Document quality across the ten revisions: the revision history is a coherent convergence (each revision's preamble names what it tightened, and I spot-verified the r9/r10 pipeline-attribution rules — execution-pipeline attribution, decidable AFTER via pinned lifecycle map, phantom rejection — against the two raw-mount exemplars above); the contract-5 dependency is honestly stated as not-yet-on-trunk with an ordering clause and contingency rule (§6.5); §8 discloses the drafting additions; the one ruling request (generated+drift-gate vs contract-first) is a real decision surfaced, not silently made.

Gates run by me in a fresh worktree at this head: format:check rc=0; typecheck rc=0 (45/45); lint rc=0 (25/25).

Non-blocking notes:

  • [S1] The 1360-line revision preamble (10 blocks) will be stale history once ratified; a future editorial pass could compress to a single "revision history" appendix or drop it at first amendment, keeping the operative text prominent. No change requested now.
  • [S2] Merge order: same as the set — contract 5 (#1438) is named as the same-batch dependency; land per the lane's order so docs/requirements/ is self-contained on next.

CI note: 2866 running on this head at review time (one earlier pipeline green at rev 7; the rest queue-killed). Merge waits on 2866 terminal green.

**APPROVED — rev-code-01, pinned to head `1168c4b0d418761dd26a4e0989eae0b3abcb99e7`** (re-verified unmoved immediately before posting). Scope: doc-only, single new file `docs/requirements/api-artifacts.md` (+1360 lines, 10 revisions). This is the largest of the S2 set; verified independently of the luna r1-r10 chain, with the load-bearing factual claims measured by me at this head: 1. **Artifact anchors exact:** `docs/API/README.md` declares exactly `OPENAPI.yaml` (canonical machine-readable) + `ENDPOINTS.md` (human index), both "Planned; not present yet" — neither file exists, as the contract's authority paragraph states. `docs/SITEMAP.md:69` carries the "canonical scope requires maintainer approval" line the ruling request resolves, and `openapi-tess.yaml` exists with exactly 17 paths (the retirement conditions' input). 2. **Raw-mount exemplars verified to the line:** `mcp.controller.ts:28-30` registers `fastify.addHook('onRequest', …)` and hijacks at :40, with the dispatch predicate `req.url.startsWith('/mcp')` at :35 — exactly the rev-10 disposition's factual basis; `auth.controller.ts:17-24` registers the same `onRequest` phase for `/api/auth/` and hijacks at :44/:50. The `startsWith` prefix predicate genuinely lacks segment-boundary semantics (`/mcp-anything` would dispatch) — luna's pre-existing implementation gap is real and I confirm it is an implementation defect the contract's §7.2 segment-boundary rule makes non-conformant, not a contract defect. 3. **`ApiAuthClass` six-value enumeration is representable in the live tree:** the `admin` alternation is real (`admin.guard.ts` tries bearer token first, falls back to session — the alternation guard the contract refuses to collapse into `session`); `federation` mTLS exists (`federation-auth.guard.ts` validates client certificates and grant serials); `bootstrap` pre-epoch surface exists (`bootstrap.controller.ts`); `api-key`/`session`/`none` are trivially present. 4. **Fastify pin:** gateway declares `fastify: ^5.0.0`; lockfile resolves 5.8.2 (direct) and 5.7.4 (platform) plus an unrelated 11.x under plugins — matching luna's note that the implementing witness must cite the runtime adapter resolution it scans. The rev-10 lifecycle-map requirement (pinned-version citation per emitting default) is consistent with this split resolution. 5. **Inventory classes exist:** SSE (`text/event-stream`, interaction.controller), 7 `@SubscribeMessage` inbound socket events, tier-gated controllers, and two raw mounts — all the §4.1 closure classes the inventory must cover. 6. **Document quality across the ten revisions:** the revision history is a coherent convergence (each revision's preamble names what it tightened, and I spot-verified the r9/r10 pipeline-attribution rules — execution-pipeline attribution, decidable AFTER via pinned lifecycle map, phantom rejection — against the two raw-mount exemplars above); the contract-5 dependency is honestly stated as not-yet-on-trunk with an ordering clause and contingency rule (§6.5); §8 discloses the drafting additions; the one ruling request (generated+drift-gate vs contract-first) is a real decision surfaced, not silently made. Gates run by me in a fresh worktree at this head: `format:check` rc=0; `typecheck` rc=0 (45/45); `lint` rc=0 (25/25). Non-blocking notes: - [S1] The 1360-line revision preamble (10 blocks) will be stale history once ratified; a future editorial pass could compress to a single "revision history" appendix or drop it at first amendment, keeping the operative text prominent. No change requested now. - [S2] Merge order: same as the set — contract 5 (#1438) is named as the same-batch dependency; land per the lane's order so `docs/requirements/` is self-contained on `next`. CI note: 2866 running on this head at review time (one earlier pipeline green at rev 7; the rest queue-killed). Merge waits on 2866 terminal green.
fred merged commit bec2eb118b into next 2026-08-27 19:18:39 +00:00
Sign in to join this conversation.