docs: api-artifacts contract revision 5 (luna r4 residuals F1/F2/F4 + F9)
ci/woodpecker/pr/ci Pipeline was canceled
ci/woodpecker/pr/ci Pipeline was canceled
This commit is contained in:
@@ -81,6 +81,27 @@ contract 5 dependency is named explicitly — PR #1438, same ruling
|
||||
batch — with an ordering clause and a contingency amendment rule
|
||||
(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
|
||||
model (§3), coverage obligations (§4), legacy migration (§5), phase
|
||||
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
|
||||
request schema reference (or an explicit no-body marker); the
|
||||
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
|
||||
maps to under the contract 5 §4.2 status mapping (so the reachable
|
||||
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
|
||||
shared types package with exactly the values `none`
|
||||
(unauthenticated), `session` (authenticated account), `api-key`
|
||||
(agent/service key), and `bootstrap` (identity §3 pre-epoch
|
||||
surface) — amendment-only, pinned here rather than deferred; the
|
||||
(agent/service key), `admin` (the alternation guard: an
|
||||
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);
|
||||
and the error-code set, drawn from the contract 5 §4.2 closed
|
||||
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
|
||||
§4.2 taxonomy codes; `Events:` — one bullet sub-item per event,
|
||||
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
|
||||
request/response schema definitions for any operation that exists
|
||||
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
|
||||
symbol identity, §7.2) to a registry member, is non-conformant
|
||||
(§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
|
||||
|
||||
@@ -390,14 +436,32 @@ scanned source roots, and compared files.
|
||||
callee the type-checker cannot resolve, is a scan FAILURE naming
|
||||
the site, never a silent skip — with one control per case
|
||||
(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,
|
||||
each conditional operation carrying its §4.5 condition field, each
|
||||
delegated surface present exactly once. Socket.IO events are
|
||||
inventoried in both directions — inbound subscription handlers by
|
||||
handler scan, server-emitted events by emit-call scan — with the
|
||||
§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
|
||||
every `ENDPOINTS.md` operation reference resolves to an existing
|
||||
`operationId` — both directions, mechanical.
|
||||
@@ -431,10 +495,19 @@ scanned source roots, and compared files.
|
||||
multi-method legacy path yields one match per method: deep
|
||||
structural equality of the canonicalized request and
|
||||
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),
|
||||
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
|
||||
HTTP error-status set (the legacy operation's documented non-2xx
|
||||
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;
|
||||
(g) a delegated-surface entry whose fields are not field-by-field
|
||||
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
|
||||
duplication a scanner cannot see is handled by review, but every
|
||||
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
|
||||
error entries are exactly the HTTP statuses its error-code set
|
||||
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)
|
||||
|
||||
@@ -540,17 +632,19 @@ severable:
|
||||
boundary over the three named roots, the closed route-metadata
|
||||
record with its per-field completeness predicate, its
|
||||
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
|
||||
its exactly-one-mount and all-module below-prefix rules and
|
||||
field-by-field mirror equality, the §4.5 profile enumeration and
|
||||
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
|
||||
with its registration-primitive list, symbol-identity detection
|
||||
with its failure-not-skip rule, and bidirectional
|
||||
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
|
||||
witness, the per-field fail-closed
|
||||
controls in §7.1, and the §7.4 canonicalization/derivation/
|
||||
@@ -563,6 +657,16 @@ severable:
|
||||
against every production-profile inventory pass).
|
||||
15. The §6.5 contract 5 ordering dependency and its contingency
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user