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
|
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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user