docs: api-artifacts contract revision 8 (luna r7 residuals F1/F2/NF1/NF2 + NF7)
ci/woodpecker/pr/ci Pipeline was canceled

- §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)
This commit is contained in:
fred
2026-08-26 22:22:34 -05:00
parent 82afd633a2
commit f988513300
+212 -34
View File
@@ -159,6 +159,34 @@ pinned-version citation plus a runtime probe (NF1). §2.2 requires
every family to have a non-empty surface, rejected by a new §7.5 rule
(NF6).
Revision 8 (luna r7 residuals F1/F2/NF1/NF2 + NF7): §7.7(d)(2)
attributes interception components to their actual execution
pipeline — framework components (all four binding scopes) attach to
framework-routed routes ONLY, adapter-level hooks attach to exactly
the routes their dispatch predicate accepts, and a raw-mounted route
(dispatched by a hook before the framework router) never carries a
framework component's status — with a raw-hook phantom control (F1).
The §7.2 raw-mount rule gains method-partition exhaustiveness: every
control-flow path is an acceptance path (pinned to one method
constant, one record), a refusal path (constant-status refusal, no
forwarding — the only place a complement or unguarded test is
admissible), or a scan failure; a forwarding edge into a
non-production package escapes failure only through a declared
external method contract, which then defines the branch's record set
(F2, NF2). The §7.7(d)(5) default rule becomes an exhaustive
inventory: total emitting/non-emitting classification over every
option key of the pinned framework and adapter options types plus
every configured composition-root option, an unclassified key a
witness failure (the adapter body-size limit is the migration
example), citation-plus-probe per emitting entry (NF1). §2.2 defines
three entry kinds — surface, delegated-surface (`Delegated:` with
exact four-sub-item syntax mirroring the §4.4 allowlist), and
exclusion (`Excluded:` with exact per-route sub-item syntax
mirroring the §4.1 script list) — so non-surface entries are
grammatical without phantom operations; §7.5(k) becomes the
kind-partition rule and new rule (l) checks the exclusion mirror
(NF7).
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).
@@ -295,17 +323,30 @@ documentation placement rules stay with the docs atlas
heading whose text is the endpoint family name (unique in the
file), followed by a bullet list whose items begin with exactly
one of the literal field labels `Summary:`, `Operations:`,
`Auth:`, `Permissions:`, `Errors:`, `Events:` — each label at most
once per entry; `Summary:`, `Auth:`, `Permissions:`, and
`Errors:` REQUIRED in every entry; `Operations:` REQUIRED for a
`Auth:`, `Permissions:`, `Errors:`, `Events:`, `Delegated:`,
`Excluded:` — each label at most once per entry. **Entry
kinds**: every entry is exactly one of three kinds, decided by
its labels. A **surface entry** carries `Summary:`, `Auth:`,
`Permissions:`, and `Errors:` (REQUIRED) and neither
`Delegated:` nor `Excluded:`; within a surface entry,
`Operations:` is REQUIRED for a
family with at least one `OPENAPI.yaml` operation and ABSENT for
an **event-only family** (a family whose entire surface is
Socket.IO events — such a family MUST carry `Events:`, which is
how it satisfies the grammar with no operations to link);
`Events:` REQUIRED for a family with Socket.IO events and absent
otherwise. **Non-empty surface**: every entry carries at least
how it satisfies the grammar with no operations to link), and
`Events:` is REQUIRED for a family with Socket.IO events and
absent otherwise. A **delegated-surface entry** carries exactly
`Summary:` and `Delegated:` and no other label. An **exclusion
entry** carries exactly `Summary:` and `Excluded:` and no
other label, and the file contains at most one exclusion entry
(absent when the §4.1 exclusion list is empty). **Non-empty
surface**: every surface entry carries at least
one of `Operations:` or `Events:` — a family with neither
documents nothing and is not grammatical (reject rule §7.5(k)),
documents nothing; a delegated-surface or exclusion entry
documents its surface through `Delegated:`/`Excluded:`
instead, needing no phantom operation. An entry matching no
kind, or more than one, is not grammatical (reject rule
§7.5(k)),
so a stale zero-surface family cannot survive the grammar.
Field contents: `Summary:` — the family's behavior summary, free
prose; `Operations:` — one or more Markdown links, each with link
@@ -325,7 +366,19 @@ documentation placement rules stay with the docs atlas
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.
pair appears at most once in the whole file; `Delegated:`
exactly four bullet sub-items, each exactly one of
`prefix {mount-prefix}`, `engine {package-name}
{version-constraint}`, `contract {engine-contract-reference}`,
and `module {registering-module}` (each sub-item label exactly
once), whose values mirror one §4.4 allowlist entry
field-by-field (string equality after whitespace trimming —
the §4.4 mirror rule, reject rule §7.5(g)); `Excluded:` — one
bullet sub-item per excluded route, each exactly
`{HTTP-method} {path-template} {reason-class} {guard}` where
`{reason-class}` is `test-only` or `dev-only`, mirroring the
§4.1 generation-script exclusion list field-by-field under the
same string equality (reject rule §7.5(l)).
`ENDPOINTS.md` MUST NOT contain
request/response schema definitions for any operation that exists
in `OPENAPI.yaml` (mechanical rule: the reserved tokens
@@ -390,13 +443,15 @@ documentation placement rules stay with the docs atlas
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
documented as delegated-surface entries (the §2.2 entry kind,
`Delegated:` field) 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
script and enumerated in `ENDPOINTS.md` (the §2.2 exclusion
entry, one `Excluded:` sub-item per route), never implicit. The
list has a **closed, machine-checked eligibility rule**: each
entry names the route, its reason class (`test-only` or
`dev-only`), and the exact guard — the deployment-profile branch
@@ -592,7 +647,38 @@ scanned source roots, and compared files.
accepts a longer non-boundary URL (a bare prefix test accepting
`/mcpfoo` under the prefix `/mcp`) is a scan failure naming the
site: the code is corrected to a boundary test; the widened
match is never absorbed by documentation. For path-bearing sites, the effective
match is never absorbed by documentation.
**Method-partition exhaustiveness**: enumerating constant
method comparisons is necessary but not sufficient — the
checker proves the callback's dispatch partitions its control
flow. Every path from callback entry to a request-terminating
action (a response emission or a forwarding of the request) is
classified as exactly one of: (i) an **acceptance path**
dominated by positive equality tests of the request method
against string constants that pin the path to exactly one
method; that (prefix, method) pair carries a record; (ii) a
**refusal path** — the ONLY classification where a complement
test (`method !== X`) or an unguarded path is admissible: the
path terminates in a constant-status refusal emission (by the
§7.7(d)(4) emission-site rules) and forwards the request
nowhere; or (iii) a **scan failure** — a complement-guarded or
unguarded path that forwards the request (into a handler,
another dispatcher, or any package) accepts an unbounded
method set and fails naming the site. One carve-out mirrors
the §7.7(d)(4) delegated-emission rule: a forwarding edge into
a non-production package may instead carry a **declared
external method contract** — the accepted-method set the
external package's pinned version documents for that entry
point, declared alongside the edge's external status
contract; the branch then contributes exactly one
(prefix × method) record per documented method, the branch's
record set equal to the declared set in both directions, and a
forwarding edge with neither dominating single-method tests
nor a declared method contract is a scan failure naming the
edge (the live MCP existing-session path, which forwards
requests of any method into the external transport, is the
migration example; its sibling non-`POST` complement branch
must classify as a refusal path). For path-bearing sites, the effective
path is computed by the framework's composition rules before
comparison: the class-level prefix (a string or an array — an
array expands to one route per element) concatenated with the
@@ -614,7 +700,13 @@ handler)`, a computed decorator value) is a scan FAILURE naming
raw-mount method branch with no matching record fails; a
raw-mount record no branch accepts fails; a non-constant method
comparison fails; a non-boundary prefix predicate — accepting
`/mcpfoo` under `/mcp` — fails). The inventory equals the documented set in both
`/mcpfoo` under `/mcp` — fails; a complement method branch that
forwards the request fails; a complement branch terminating in
a constant-status refusal is admitted as a refusal path; a
forwarding edge with a declared external method contract
yields exactly the contract's records; a forwarding edge with
neither single-method domination nor a declared method
contract 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
@@ -746,7 +838,7 @@ handler)`, a computed decorator value) is a scan FAILURE naming
`ENDPOINTS.md` into the §2.2 entry grammar via a Markdown AST
and rejects, exactly: (a) an entry violating the grammar — a
non-`##` entry heading, a duplicate family name, a missing
required field label under the §2.2 conditional rule (including
required field label under the §2.2 per-kind rules (including
`Operations:` absent from a family with operations, or present
on an event-only family), a duplicated field label, or an
`Events:` field on a non-event family; (b) an operation mention that is not
@@ -763,9 +855,13 @@ handler)`, a computed decorator value) is a scan FAILURE naming
item not matching the §2.2 `inbound {name}` / `outbound {name}`
syntax or whose event name is not in the §4.6 registry's matching
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 `Delegated:` sub-item
values are not field-by-field
equal to the §4.4 allowlist entry (string comparison after
whitespace trimming); (h) a (direction, event-name) item appearing
whitespace trimming), a §4.4 allowlist entry with no
delegated-surface entry, a `Delegated:` prefix naming no
allowlist entry, or a malformed `Delegated:` sub-item (not the
exact §2.2 four-sub-item syntax); (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
@@ -774,9 +870,20 @@ handler)`, a computed decorator value) is a scan FAILURE naming
equal the registry union), a family name in the map with no
entry in the file, or an event name present in both the inbound
and outbound registries (the §4.6 disjointness rule); (k) an
entry carrying neither `Operations:` nor `Events:` (the §2.2
entry that is not exactly one §2.2 kind — a surface entry
carrying neither `Operations:` nor `Events:` (the
non-empty-surface rule — a zero-surface family documents
nothing). The witness
nothing), an entry mixing kind-defining labels (`Delegated:`
or `Excluded:` together with `Operations:`/`Events:`, or with
each other), a delegated-surface or exclusion entry carrying
any label beyond its exact §2.2 set, or a second exclusion
entry in the file; (l) an exclusion mismatch — an `Excluded:`
sub-item not field-by-field equal to a §4.1 generation-script
exclusion entry (string comparison after whitespace trimming),
a script exclusion entry with no sub-item, a sub-item with no
script entry (both directions), or a malformed sub-item (not
the exact §2.2 `{HTTP-method} {path-template} {reason-class}
{guard}` syntax). 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.)
@@ -830,11 +937,39 @@ handler)`, a computed decorator value) is a scan FAILURE naming
filter's mapped status — the live interaction controller's
runtime-approval-denied filter emitting 403 is the migration
example), attributed to exactly the routes its binding scope
covers: global to every route, controller-scoped to the
declaring class's routes, route-scoped to that route alone. A
binding site in any of the four scopes the scan does not
enumerate, and a bound component with no source-asserted
status set, are each a witness failure naming the site; (3)
covers WITHIN the component's execution pipeline.
**Execution-pipeline attribution**: the production surface
partitions into **framework-routed routes** — registered
through the framework's routing primitives (decorated
controllers/gateways and framework route registrations) and
dispatched by the framework router — and **raw-mounted
routes** — the §7.2 raw-mount records, dispatched by a hook
callback before or outside the framework router. Framework
interception components in all four binding scopes execute
only in the framework dispatch pipeline, so they attribute to
framework-routed routes ONLY: global (by call or by DI token)
to every framework-routed route, controller-scoped to the
declaring class's routes, route-scoped to that route alone; a
framework component's status attributed to a raw-mounted
route is a phantom — the component never runs for it — and
the bidirectional comparison rejects it exactly as it rejects
any other phantom map status. A raw-mounted route's
interception statuses come instead from the **adapter hook
chain**: every non-path-bearing hook registration (§7.2)
whose callback can emit a response (per the class-(4) rules
over the callback closure) is an interception component
attributed to exactly the routes whose URLs its dispatch
predicate accepts — a hook with no URL dispatch attributes to
every route, framework-routed and raw alike; a raw mount's
own dispatch attributes to its (prefix × method) records
alone (the live raw MCP hook, which answers before the
framework router runs and is therefore untouched by the
framework's global pipes and guards, is the motivating
example). A binding site in any of the four scopes the scan
does not enumerate, a bound component with no source-asserted
status set, and an emitting hook registration with no
dispatch-derived route attribution, are each a witness
failure naming the site; (3)
decorator status metadata — the framework's
route-level status metadata (explicit status-code decorators,
each method decorator's default status, and the implicit
@@ -866,16 +1001,35 @@ handler)`, a computed decorator value) is a scan FAILURE naming
send-with-status calls, status-carrying error constructors) AND
against Node's `http.ServerResponse` declarations (`writeHead`,
`statusCode` assignment), so raw handlers are covered; (5)
framework error defaults — the framework's own route-level
default error statuses (the default unhandled-error status, the
default validation/parse-failure statuses, the default
not-found on a matched mount): each default the implementing PR
declares route-attributable carries BOTH a citation into the
pinned framework version's source or documentation for that
default AND a runtime probe that triggers the default and
asserts the observed status; a declared default missing its
citation or its probe is a witness failure — declaration alone
attributes nothing. Every site's status argument must resolve
framework and adapter defaults — an EXHAUSTIVE default
inventory, not a declared-only list: the implementing PR
classifies, as response-emitting (with the emitted status and
triggering condition) or non-emitting, every member of a
closed domain with two mechanically enumerated parts — (i)
every property key of the pinned framework
application-options type AND the pinned adapter
construction-options type, resolved from the packages' type
declarations, and (ii) every key of every options object the
composition root actually passes to the framework/adapter
construction and server-setup calls (call sites identified by
symbol identity). The classification is TOTAL: a domain key
absent from the inventory is a witness failure naming the
key, so an applicable default cannot be omitted by silence
(the adapter-level body-size limit set at the composition
root — an adapter rejection path the revision-7 declared-only
rule could silently omit — is the migration example). The
framework's documented route-level default statuses (the
default unhandled-error status, the default
validation/parse-failure statuses, the default not-found on a
matched mount) are fixed members of the inventory regardless
of configuration. Each response-emitting entry carries BOTH a
citation into the pinned version's source or documentation
for that behavior AND a runtime probe that triggers the
default and asserts the observed status; a response-emitting
entry missing its citation or its probe is a witness failure,
and each entry's status attributes to the routes the option's
scope covers (a server-wide option to every route on that
server). Every site's status argument must resolve
to a literal or compile-time constant; an unresolvable status
is a FAILURE naming the site. Both directions: every resolved
status is a member of the route's record response map, AND
@@ -888,11 +1042,21 @@ handler)`, a computed decorator value) is a scan FAILURE naming
global-pipe status absent from the map fails; a route-scoped
filter status absent from the map fails; a component bound
through a DI binding token is detected and attributed; a
framework global component's status attributed to (or
required of) a raw-mounted fixture route fails as a phantom —
the raw-hook control; a fixture adapter hook emitting a
constant status with no URL dispatch is attributed to every
route, raw mounts included; a
fixture handler passing the reply object into a stub external
package with no declared external status contract fails; a
decorator
status absent from the map fails; a raw `writeHead` status
absent from the map fails; a phantom map status fails; the
absent from the map fails; a phantom map status fails; an
option key present in the pinned adapter options type but
absent from the default inventory fails; a configured
composition-root option key absent from the inventory fails;
the body-size-limit probe triggers the adapter rejection and
asserts its observed status; the
implicit default success status is attributed to the route and
must appear in its response map; (e) **guard-equivalence**
for each `ApiAuthClass`, the witness asserts the derived
@@ -980,7 +1144,7 @@ severable:
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 eleven reject rules, the §7.6
the §7.5 checker script with its twelve 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/
@@ -1035,6 +1199,20 @@ severable:
status contract and the §7.7(d)(5) citation-plus-probe rule
for framework defaults; and the §2.2 non-empty-surface rule
with §7.5 reject rule (k).
19. The revision-8 closure rules: the §7.7(d)(2)
execution-pipeline attribution — framework interception
components to framework-routed routes only, adapter
hook-chain components attributed by dispatch predicate,
phantom rejection for raw-mounted routes, with the raw-hook
control; the §7.2 method-partition exhaustiveness rule with
its acceptance/refusal path classification, forwarding
complement-branch failure, and declared external method
contract; the §7.7(d)(5) exhaustive default inventory (total
classification over the pinned options-type keys and the
configured composition-root options, citation-plus-probe per
emitting entry); and the §2.2 entry kinds with the
`Delegated:`/`Excluded:` field syntax, the revised §7.5(k)
kind-partition rule, and the §7.5(l) exclusion mirror.
## Ruling request