docs: api-artifacts contract revision 5 (luna r4 residuals F1/F2/F4 + F9)
ci/woodpecker/pr/ci Pipeline was canceled

This commit is contained in:
fred
2026-08-26 21:05:54 -05:00
parent 6ea6b020f0
commit 26b3560ca2
+118 -14
View File
@@ -81,6 +81,27 @@ contract 5 dependency is named explicitly — PR #1438, same ruling
batch — with an ordering clause and a contingency amendment rule batch — with an ordering clause and a contingency amendment rule
(F8). (F8).
Revision 5 (luna r4 residuals F1/F2/F4 + F9): the auth-class
enumeration grows to six values so the live alternation guards are
representable — `admin` (session-with-admin-privilege OR admin bearer
token) and `federation` (mTLS client identity plus federation grant)
— and the generator carries a closed `ApiAuthClass` → OpenAPI
security-requirement mapping (F1, F4). §7.7 gains an emitted-status
closure: every status-emission site in a route's handler closure must
resolve to a literal status contained in the record's response map,
with unresolvable emissions a scan failure (F1). The §7.2 scan
requires every registered path argument and decorator path value to
resolve to a compile-time string constant equal to the record's path
template; an unresolvable or mismatched path is a scan failure (F2).
The response map admits an explicit no-body marker per status, and
§7.4 canonicalizes body-less responses (including legacy
description-only responses) to that marker so the deep equality has a
defined input (F4). The §4.6 registry gains a total, single-valued
event-ownership map to `ENDPOINTS.md` family names; §2.2 binds each
event item to its owning family's entry; §7.5 rejects duplicate and
wrong-family event items; and §7.2/§7.5 assert bidirectional set
equality between the event inventory and the file's event items (F9).
This contract binds the artifact definitions (§2), the production This contract binds the artifact definitions (§2), the production
model (§3), coverage obligations (§4), legacy migration (§5), phase model (§3), coverage obligations (§4), legacy migration (§5), phase
timing (§6), witnesses (§7), and disclosed drafting additions (§8). timing (§6), witnesses (§7), and disclosed drafting additions (§8).
@@ -125,7 +146,9 @@ documentation placement rules stay with the docs atlas
id; the HTTP method and path template (or the SSE marker); the id; the HTTP method and path template (or the SSE marker); the
request schema reference (or an explicit no-body marker); the request schema reference (or an explicit no-body marker); the
response map — every status code the route can emit, mapped to a response map — every status code the route can emit, mapped to a
schema reference, with at least one success entry, and with one schema reference **or an explicit no-body marker** (a body-less
response is declared, never implied by omission), with at least
one success entry, and with one
error entry per HTTP status the route's declared error-code set error entry per HTTP status the route's declared error-code set
maps to under the contract 5 §4.2 status mapping (so the reachable maps to under the contract 5 §4.2 status mapping (so the reachable
error statuses are exactly the declared taxonomy's statuses, error statuses are exactly the declared taxonomy's statuses,
@@ -133,8 +156,20 @@ documentation placement rules stay with the docs atlas
from the closed enumeration **`ApiAuthClass`**, exported from the from the closed enumeration **`ApiAuthClass`**, exported from the
shared types package with exactly the values `none` shared types package with exactly the values `none`
(unauthenticated), `session` (authenticated account), `api-key` (unauthenticated), `session` (authenticated account), `api-key`
(agent/service key), and `bootstrap` (identity §3 pre-epoch (agent/service key), `admin` (the alternation guard: an
surface) — amendment-only, pinned here rather than deferred; the authenticated session holding platform-admin privilege OR the
admin bearer token — the alternation itself is the class, so the
live admin surface is representable without collapsing it into
`session`), `federation` (mTLS client identity plus a valid
federation grant — both required), and `bootstrap` (identity §3
pre-epoch surface) — amendment-only, pinned here rather than
deferred. Each `ApiAuthClass` value maps to exactly one OpenAPI
security-requirement set under a closed mapping table carried by
the generation script (§3.1): `none` maps to the empty security
array, and each other value maps to a named security-scheme
requirement set the implementing PR defines once in
`OPENAPI.yaml`'s components; the mapping is total over the
enumeration, and §7.4(b) compares security through it; the
permission rule reference (owning contract plus rule identifier); permission rule reference (owning contract plus rule identifier);
and the error-code set, drawn from the contract 5 §4.2 closed and the error-code set, drawn from the contract 5 §4.2 closed
taxonomy. **Socket.IO event records** carry direction-specific taxonomy. **Socket.IO event records** carry direction-specific
@@ -179,7 +214,10 @@ documentation placement rules stay with the docs atlas
membership); `Errors:` — error semantics including the contract 5 membership); `Errors:` — error semantics including the contract 5
§4.2 taxonomy codes; `Events:` — one bullet sub-item per event, §4.2 taxonomy codes; `Events:` — one bullet sub-item per event,
each exactly `inbound {event-name}` or `outbound {event-name}` each exactly `inbound {event-name}` or `outbound {event-name}`
where `{event-name}` is a member of the §4.6 event registry. where `{event-name}` is a member of the §4.6 event registry, the
item appears in exactly the entry of the family the §4.6
ownership map assigns to that event, and each (direction, name)
pair appears at most once in the whole file.
`ENDPOINTS.md` MUST NOT contain `ENDPOINTS.md` MUST NOT contain
request/response schema definitions for any operation that exists request/response schema definitions for any operation that exists
in `OPENAPI.yaml` (mechanical rule: the reserved tokens in `OPENAPI.yaml` (mechanical rule: the reserved tokens
@@ -310,7 +348,15 @@ documentation placement rules stay with the docs atlas
helper whose name argument does not resolve (by the type-checker's helper whose name argument does not resolve (by the type-checker's
symbol identity, §7.2) to a registry member, is non-conformant symbol identity, §7.2) to a registry member, is non-conformant
(§7.2 scans for non-registry names). The registry is the (§7.2 scans for non-registry names). The registry is the
comparison target for the event inventory. comparison target for the event inventory. **Event ownership:**
the shared types package additionally exports one `as const`
readonly ownership record mapping every registry event name (both
directions) to exactly one `ENDPOINTS.md` family name (the §2.2
`##` heading text). The map is total over the union of both
registries and single-valued — every event has exactly one owning
family — and it is the deterministic rule for which entry
documents which event; a registry event absent from the map, or
mapped to a family with no `ENDPOINTS.md` entry, fails §7.5.
## 5. Legacy migration ## 5. Legacy migration
@@ -390,14 +436,32 @@ scanned source roots, and compared files.
callee the type-checker cannot resolve, is a scan FAILURE naming callee the type-checker cannot resolve, is a scan FAILURE naming
the site, never a silent skip — with one control per case the site, never a silent skip — with one control per case
(aliased call detected; wrapped call detected; dynamic-name (aliased call detected; wrapped call detected; dynamic-name
access fails). The inventory equals the documented set in both access fails). **Path-argument resolution:** for every detected
registration call site and every route decorator, the path
argument must be a string literal or resolve through the
type-checker to a compile-time string constant; the resolved
string is then compared for exact equality with the route's §1.6
record path template. A path argument the checker cannot resolve
to a constant (`app.get(computedPath(), handler)`, a decorator
with a computed path value) is a scan FAILURE naming the site,
never an inventory entry with an undefined path — with one
control per case (computed path argument fails; computed
decorator path fails; a resolved path unequal to its record's
template fails). The inventory equals the documented set in both
directions: no undocumented live route, no documented phantom, directions: no undocumented live route, no documented phantom,
each conditional operation carrying its §4.5 condition field, each each conditional operation carrying its §4.5 condition field, each
delegated surface present exactly once. Socket.IO events are delegated surface present exactly once. Socket.IO events are
inventoried in both directions — inbound subscription handlers by inventoried in both directions — inbound subscription handlers by
handler scan, server-emitted events by emit-call scan — with the handler scan, server-emitted events by emit-call scan — with the
§4.6 registry as the comparison target and a scan failure on any §4.6 registry as the comparison target and a scan failure on any
non-literal or non-registry event name. Additionally, every HTTP non-literal or non-registry event name. **Event-set closure:** the
inventoried event set (both directions) and the set of `Events:`
sub-items across all `ENDPOINTS.md` entries are equal as sets —
every inventoried event appears as an item in its owning family's
entry, and every item corresponds to an inventoried event; an
inventoried event absent from the file, and a documented event the
inventory does not emit, each fail the witness, with one control
per direction. Additionally, every HTTP
route family in `OPENAPI.yaml` has an `ENDPOINTS.md` entry, and route family in `OPENAPI.yaml` has an `ENDPOINTS.md` entry, and
every `ENDPOINTS.md` operation reference resolves to an existing every `ENDPOINTS.md` operation reference resolves to an existing
`operationId` — both directions, mechanical. `operationId` — both directions, mechanical.
@@ -431,10 +495,19 @@ scanned source roots, and compared files.
multi-method legacy path yields one match per method: deep multi-method legacy path yields one match per method: deep
structural equality of the canonicalized request and structural equality of the canonicalized request and
response schemas (an absent request body matches only the response schemas (an absent request body matches only the
canonical no-body marker; equality is evaluated over the canonical no-body marker; a response entry with no body schema —
including a legacy response carrying only a description with no
`content` — canonicalizes to the same explicit no-body marker, so
the deep equality is defined for body-less responses and a
no-body response matches only a no-body response; equality is
evaluated over the
canonical forms, so no-body vs any schema is a difference), canonical forms, so no-body vs any schema is a difference),
equality of the security/authentication equality of the security/authentication
requirement sets, and equality of the documented error semantics requirement sets — compared through the §1.6
`ApiAuthClass` → security-requirement mapping, i.e. the legacy
operation's security requirement set is compared with the set the
mapping assigns to the covering route's declared auth class —
and equality of the documented error semantics
compared in a **common representation with two components** — the compared in a **common representation with two components** — the
HTTP error-status set (the legacy operation's documented non-2xx HTTP error-status set (the legacy operation's documented non-2xx
status codes vs the covering operation's emitted non-2xx status status codes vs the covering operation's emitted non-2xx status
@@ -478,7 +551,12 @@ scanned source roots, and compared files.
direction; (f) an `operationId` linked from more than one entry; direction; (f) an `operationId` linked from more than one entry;
(g) a delegated-surface entry whose fields are not field-by-field (g) a delegated-surface entry whose fields are not field-by-field
equal to the §4.4 allowlist entry (string comparison after equal to the §4.4 allowlist entry (string comparison after
whitespace trimming). The witness whitespace trimming); (h) a (direction, event-name) item appearing
more than once in the file, whether within one entry or across
entries; (i) an event item in an entry other than the one the
§4.6 ownership map assigns to that event; (j) a §4.6 registry
event absent from the ownership map, or mapped to a family name
with no entry in the file. The witness
proves it can fail with one control per reject rule. (Prose proves it can fail with one control per reject rule. (Prose
duplication a scanner cannot see is handled by review, but every duplication a scanner cannot see is handled by review, but every
structural duplication channel above is mechanical.) structural duplication channel above is mechanical.)
@@ -505,7 +583,21 @@ scanned source roots, and compared files.
never emitted); (c) **response-map closure** — each record's never emitted); (c) **response-map closure** — each record's
error entries are exactly the HTTP statuses its error-code set error entries are exactly the HTTP statuses its error-code set
maps to under the contract 5 §4.2 status mapping (mechanical maps to under the contract 5 §4.2 status mapping (mechanical
recomputation), with a mutated-record control. recomputation), with a mutated-record control; (d)
**emitted-status closure** — for every production route, every
status-emission site in the handler and its production-source
callee closure (each site identified by symbol identity against
the framework's reply/response type declarations — the status
setter, shorthand send-with-status calls, and framework error
constructors carrying a status) must resolve, as a literal or a
compile-time constant, to a status present in the route's record
response map; a status argument the checker cannot resolve, or a
resolved status absent from the record's response map, is a
witness FAILURE naming the site — with controls: a handler
emitting an unclassified status (`reply.status(418)`) fails; a
computed status argument fails; a framework-default emission
path (implicit 200) is attributed to the route and must appear
in its response map.
## 8. Drafting additions (PRD §12.1 disclosure) ## 8. Drafting additions (PRD §12.1 disclosure)
@@ -540,17 +632,19 @@ severable:
boundary over the three named roots, the closed route-metadata boundary over the three named roots, the closed route-metadata
record with its per-field completeness predicate, its record with its per-field completeness predicate, its
record-as-registration-input derivation rule, the pinned record-as-registration-input derivation rule, the pinned
four-value `ApiAuthClass` enumeration, and the event-record six-value `ApiAuthClass` enumeration with its closed
security-requirement mapping, and the event-record
field semantics — and the §4.4 delegation allowlist with field semantics — and the §4.4 delegation allowlist with
its exactly-one-mount and all-module below-prefix rules and its exactly-one-mount and all-module below-prefix rules and
field-by-field mirror equality, the §4.5 profile enumeration and field-by-field mirror equality, the §4.5 profile enumeration and
condition field, and the §4.6 typed event registry with its condition field, and the §4.6 typed event registry with its
two-record `as const` shape and symbol-reference rule. two-record `as const` shape, symbol-reference rule, and total
single-valued event-ownership map.
12. The §7 witness machinery as such: the §7.2 independent inventory 12. The §7 witness machinery as such: the §7.2 independent inventory
with its registration-primitive list, symbol-identity detection with its registration-primitive list, symbol-identity detection
with its failure-not-skip rule, and bidirectional with its failure-not-skip rule, and bidirectional
family/operation checks, the §7.3 content and taxonomy witness, family/operation checks, the §7.3 content and taxonomy witness,
the §7.5 checker script with its seven reject rules, the §7.6 the §7.5 checker script with its ten reject rules, the §7.6
pinned validator (Redocly CLI), the §7.7 source-consistency pinned validator (Redocly CLI), the §7.7 source-consistency
witness, the per-field fail-closed witness, the per-field fail-closed
controls in §7.1, and the §7.4 canonicalization/derivation/ controls in §7.1, and the §7.4 canonicalization/derivation/
@@ -563,6 +657,16 @@ severable:
against every production-profile inventory pass). against every production-profile inventory pass).
15. The §6.5 contract 5 ordering dependency and its contingency 15. The §6.5 contract 5 ordering dependency and its contingency
amendment rule. amendment rule.
16. The revision-5 closure rules: the `admin` and `federation` auth
classes representing the live alternation and mTLS-plus-grant
guards (§1.6); the response-map no-body marker and its §7.4
body-less canonicalization; the §7.2 path-argument resolution
rule (compile-time constant, equal to the record's path
template, failure otherwise); the §7.7(d) emitted-status
closure; and the event-set closure machinery — the §4.6
ownership map, the §2.2 owning-family and at-most-once item
rules, the §7.2 bidirectional event-set equality, and §7.5
reject rules (h)(j).
## Ruling request ## Ruling request