docs: api-artifacts contract revision 4 (luna re-review residuals F1-F4/F6 + F7/F8)
ci/woodpecker/pr/ci Pipeline was canceled

This commit is contained in:
fred
2026-08-26 20:46:07 -05:00
parent 54f6ccf717
commit 6ea6b020f0
+268 -76
View File
@@ -8,9 +8,16 @@ human-readable endpoint, authentication, permission, and error index —
both declared, neither present (the webui-audit REPORT's prerequisite both declared, neither present (the webui-audit REPORT's prerequisite
9). `docs/SITEMAP.md` records that canonical scope requires maintainer 9). `docs/SITEMAP.md` records that canonical scope requires maintainer
approval; ratification of this contract by the repository maintainer approval; ratification of this contract by the repository maintainer
supplies that approval for these two artifacts. Contract 5 supplies that approval for these two artifacts. Contract 5 is the
(`tool-gateway-mapping.md`) §4 binds the per-operation **Tool↔Gateway Mapping Contract (D8)** — S2 contract 5, PR #1438,
request/result/error/audit envelope; this contract binds only how the landing as `docs/requirements/tool-gateway-mapping.md` in the same S2
ruling batch as this contract; it is not yet on the integration trunk,
so its file does not exist in this branch's tree. Its §4 binds the
per-operation request/result/error/audit envelope, and its §4.2
defines the closed per-family error taxonomy this contract's
references bind to. Every "contract 5" reference in this document
resolves against that document as ratified; §6.5 states the ordering
dependency. This contract binds only how the
two artifacts are produced, what they must cover, and how they are two artifacts are produced, what they must cover, and how they are
kept true. kept true.
@@ -45,6 +52,35 @@ and the legacy-derivation rule, and §7.6 pins a named validator (F4).
get a machine-checkable delegation allowlist with a below-prefix get a machine-checkable delegation allowlist with a below-prefix
boundary check (F6). boundary check (F6).
Revision 4 (luna re-review residuals + F7/F8): the route-metadata
record is redefined as the route's **registration input** — the
registration primitive consumes the record and derives the installed
auth guard and permission enforcement from it, so record-vs-code
divergence on those fields is structurally impossible, and a new
source-consistency witness (§7.7) cross-checks the remaining fields
(F1). The auth-class enumeration is pinned in this contract (four
values, amendment-only), and Socket.IO event records get
direction-specific field semantics replacing the status-code response
map (F1). The scan roots are `apps/`, `packages/`, and `plugins/`
all three named everywhere — and registration-primitive detection is
by TypeScript symbol identity against the framework's type
declarations, closing the wrapper/alias/dynamic-name escapes (F2).
§2.2 defines an exact entry grammar (heading form, literal field
labels, cardinality, link syntax, anchor syntax, event-item syntax)
and §7.5's reject rules cover every Markdown node type plus a
one-entry-per-operationId uniqueness rule (F3, and the covering-entry
ambiguity in F4). §7.4 defines cycle handling, `$ref` scope,
per-(path, method) matching, no-body equality, and a common
representation for error-code comparison (F4). The delegation
boundary requires the named module to contain exactly the mount call
and nothing below the prefix from any module, with field-by-field
mirror equality (F6). The exclusion list gets a closed, machine-
checked eligibility rule: an excluded route emitted by any
production-profile inventory pass is a witness failure (F7). The
contract 5 dependency is named explicitly — PR #1438, same ruling
batch — with an ordering clause and a contingency amendment rule
(F8).
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).
@@ -69,23 +105,45 @@ documentation placement rules stay with the docs atlas
§4.4 delegation allowlist is a delegated surface; any other prefix §4.4 delegation allowlist is a delegated surface; any other prefix
is ordinary surface, documented route-by-route. is ordinary surface, documented route-by-route.
5. **Production route**: any HTTP or SSE route, or Socket.IO event 5. **Production route**: any HTTP or SSE route, or Socket.IO event
(either direction), registered by production source (`apps/` and (either direction), registered by production source (`apps/`,
`packages/`, tests excluded) under ANY deployment profile (§4.5), `packages/`, and `plugins/` — the three production roots, named
identically in every scan in this contract; tests excluded) under
ANY deployment profile (§4.5),
excluding only entries on the §4.1 exclusion list and routes below excluding only entries on the §4.1 exclusion list and routes below
a §4.4 delegated prefix. The term is decidable: a route is a a §4.4 delegated prefix. The term is decidable: a route is a
production route iff the §7.2 inventory emits it, and the §7.2 production route iff the §7.2 inventory emits it, and the §7.2
scan definition — not intent — is the boundary. scan definition — not intent — is the boundary.
6. **Route metadata record**: the closed per-route generator input 6. **Route metadata record**: the closed per-route registration input
(§3.1). Its fields, all REQUIRED: a unique operation id; the HTTP (§3.1). The record is not documentation of a handler — it IS the
method and path template (or the SSE marker, or the Socket.IO handler's registration configuration: the registration primitive
event name and direction); the request schema reference (or an consumes the record, and the installed authentication guard and
explicit no-body marker); the response map — every documented permission enforcement are DERIVED from the record's declared auth
status code mapped to a schema reference, with at least one class and permission rule reference, so the record cannot diverge
success entry; the authentication requirement, one value from the from the code on those fields; a route registered without a record,
closed auth-class enumeration the implementing PR declares in the or with enforcement not derived from its record, fails §7.7. Its
shared types package; the permission rule reference (owning fields, all REQUIRED for HTTP and SSE routes: a unique operation
contract plus rule identifier); and the error-code set, drawn from id; the HTTP method and path template (or the SSE marker); the
the contract 5 §4.2 closed taxonomy. **Completeness predicate**: 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
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,
cross-checked by §7.7); the authentication requirement, one value
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
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
fields in place of the response map: an inbound event record has
the event name, direction, payload schema reference, and an ack
schema reference or an explicit no-ack marker; an outbound event
record has the event name, direction, and payload schema
reference; the success-entry rule is defined as inapplicable to
event records. **Completeness predicate**:
every field present AND every reference resolvable, evaluated per every field present AND every reference resolvable, evaluated per
field; a violation names the route and the exact failing field. field; a violation names the route and the exact failing field.
@@ -97,19 +155,39 @@ documentation placement rules stay with the docs atlas
are documented in `ENDPOINTS.md` and referenced from the OpenAPI are documented in `ENDPOINTS.md` and referenced from the OpenAPI
description block; inventing a pseudo-path encoding for them inside description block; inventing a pseudo-path encoding for them inside
`OPENAPI.yaml` is non-conformant. `OPENAPI.yaml` is non-conformant.
2. **`ENDPOINTS.md`** is the human index, in a structured entry 2. **`ENDPOINTS.md`** is the human index, in an exact entry grammar:
format: one entry per endpoint family, carrying (a) the family's the file is a sequence of entries, each entry exactly one `##`
behavior summary, (b) its operations referenced by `operationId` heading whose text is the endpoint family name (unique in the
link into `OPENAPI.yaml` — never by restated definition, (c) the file), followed by a bullet list whose items begin with exactly
authentication requirement, (d) the permission/authorization rule one of the literal field labels `Summary:`, `Operations:`,
naming the owning contract (contract 2 for chain authorization, the `Auth:`, `Permissions:`, `Errors:`, `Events:` — each label at most
SOT for workspace membership), (e) error semantics including the once per entry; `Summary:`, `Operations:`, `Auth:`,
contract 5 §4.2 taxonomy, and (f) Socket.IO event entries (both `Permissions:`, and `Errors:` REQUIRED in every entry, `Events:`
directions) for event families. `ENDPOINTS.md` MUST NOT contain REQUIRED for a family with Socket.IO events and absent otherwise.
Field contents: `Summary:` — the family's behavior summary, free
prose; `Operations:` — one or more Markdown links, each with link
text equal to an `operationId` and link target
`./OPENAPI.yaml#operation/{operationId}` (the anchor grammar:
the fragment is the literal string `operation/` followed by the
`operationId`; the link RESOLVES iff that `operationId` exists as
an operation in the committed `OPENAPI.yaml`) — operations are
referenced by link only, never by restated definition, and each
`operationId` is linked from exactly one entry in the whole file;
`Auth:` — the `ApiAuthClass` value (§1.6); `Permissions:` — the
permission/authorization rule naming the owning contract
(contract 2 for chain authorization, the SOT for workspace
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.
`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: no `requestBody`/`responses`/ in `OPENAPI.yaml` (mechanical rule: the reserved tokens
schema-fragment blocks for such operations — witness §7.5). This `requestBody`, `responses`, `parameters`, `schema`, `properties`
no-duplication rule and the entry format are new policy disclosed appear nowhere in the file, in any Markdown node type — witness
§7.5; entry prose must avoid the reserved tokens, a disclosed
strictness). This
no-duplication rule and the entry grammar are new policy disclosed
in §8 (the `docs/API/README.md` boundary as written binds guide in §8 (the `docs/API/README.md` boundary as written binds guide
books, not `ENDPOINTS.md` itself). books, not `ENDPOINTS.md` itself).
3. Both artifacts are committed repository files, reviewed in PRs like 3. Both artifacts are committed repository files, reviewed in PRs like
@@ -135,7 +213,12 @@ documentation placement rules stay with the docs atlas
every §1.6 field into its OpenAPI operation (operation id, every §1.6 field into its OpenAPI operation (operation id,
schemas, per-status responses, security requirement, and the schemas, per-status responses, security requirement, and the
permission reference and error-code set as declared extension permission reference and error-code set as declared extension
fields). Today's local-DTO, inline-typed, and raw-handler routes fields). Because the record is the registration input (§1.6), the
generator's input and the route's installed enforcement share one
source; §7.7 witnesses that no route bypasses record-derived
enforcement and that the record fields the framework does not
consume (error-code set, response map) match the code. Today's
local-DTO, inline-typed, and raw-handler routes
therefore migrate to complete metadata records in the implementing therefore migrate to complete metadata records in the implementing
PR. The generated output is committed, and CI regenerates and PR. The generated output is committed, and CI regenerates and
byte-compares it (§7.1). Hand edits to `OPENAPI.yaml` are byte-compares it (§7.1). Hand edits to `OPENAPI.yaml` are
@@ -168,6 +251,15 @@ documentation placement rules stay with the docs atlas
server-emitted events. Test-only and development-only surfaces are server-emitted events. Test-only and development-only surfaces are
excluded via an exclusion list that is explicit in the generation 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`, 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
or build-time flag — that prevents its registration in every
§4.5 production profile; eligibility is DEFINED as "not emitted
by the §7.2 inventory in any production profile", and the §7.2
witness fails if any excluded entry is emitted by any
production-profile pass. A live route added to the list is
therefore a witness failure, not a silent omission. The
exclusion and delegation lists are new policy disclosed in §8. exclusion and delegation lists are new policy disclosed in §8.
2. Every documented operation carries: its authentication requirement; 2. Every documented operation carries: its authentication requirement;
its authorization rule by reference to the owning contract; its its authorization rule by reference to the owning contract; its
@@ -187,11 +279,18 @@ documentation placement rules stay with the docs atlas
constraint); a reference to the engine's own route contract (the constraint); a reference to the engine's own route contract (the
engine package's published API document); and the one production engine package's published API document); and the one production
module that registers the mount. The §7.2 witness enforces the module that registers the mount. The §7.2 witness enforces the
boundary: any route registration whose path falls under an boundary in both halves: (a) the named registration module
allowlisted prefix but does not originate from that entry's named contains exactly one registration-primitive call — the mount
registration module fails the witness — an app-owned handler itself — and no other; (b) any route registration, from ANY
cannot hide under a delegated prefix. `ENDPOINTS.md`'s module including the named one, whose path resolves below an
delegated-surface entries mirror the allowlist one-to-one. allowlisted prefix fails the witness — the single mount call is
the only permitted registration under the prefix, so an app-owned
handler cannot hide there, inside or outside the named module.
`ENDPOINTS.md`'s delegated-surface entries mirror the allowlist
**field-by-field**: prefix, engine package name and version
constraint, engine contract reference, and registering module are
each equal by string comparison after whitespace trimming —
"mirror one-to-one" means this equality, checked by §7.5.
5. **Deployment profiles.** The authoritative profile set is the 5. **Deployment profiles.** The authoritative profile set is the
closed deployment-tier enumeration in the Gateway's configuration closed deployment-tier enumeration in the Gateway's configuration
schema (the same enumeration the conditional registrations branch schema (the same enumeration the conditional registrations branch
@@ -200,13 +299,18 @@ documentation placement rules stay with the docs atlas
declared condition extension field naming the profile(s) it exists declared condition extension field naming the profile(s) it exists
in. A conditional branch on anything outside the named enumeration in. A conditional branch on anything outside the named enumeration
fails the §7.2 witness. fails the §7.2 witness.
6. **Event-name discipline.** Every Socket.IO event name, in both 6. **Event-name discipline.** The event registry is two exported
directions, is a literal member of one exported typed event `as const` readonly records in the shared types package — one
registry in the shared types package; emitting or subscribing with inbound, one outbound — whose values are unique string literals;
a dynamically constructed name, or through a helper that does not that shape is part of this contract, not implementing-PR
take its name from the registry, is non-conformant (§7.2 scans for discretion. Every Socket.IO event name, in both directions, is a
non-registry names). The registry is the comparison target for the member of the applicable registry, referenced by symbol (a
event inventory. registry property access), never by a re-typed string; emitting or
subscribing with a dynamically constructed name, or through a
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.
## 5. Legacy migration ## 5. Legacy migration
@@ -237,6 +341,17 @@ documentation placement rules stay with the docs atlas
`ENDPOINTS.md` entry in its implementing PR. `ENDPOINTS.md` entry in its implementing PR.
4. The phase placement and rollout sequencing in this section are 4. The phase placement and rollout sequencing in this section are
disclosed in §8. disclosed in §8.
5. **Contract 5 ordering dependency.** This contract's taxonomy and
envelope references bind to the Tool↔Gateway Mapping Contract
(S2 contract 5, PR #1438, `docs/requirements/tool-gateway-
mapping.md`), ratified in the same S2 batch but not yet on the
integration trunk. No implementing PR under this contract may
land before contract 5's document is on the trunk and the
shared-types taxonomy enums it requires exist. If contract 5 is
not ratified, every §4.2-taxonomy reference here is unresolvable
and this contract requires amendment before implementation —
stated so the dependency is explicit rather than a dangling
file reference (disclosed, §8).
## 7. Verification requirements ## 7. Verification requirements
@@ -253,18 +368,29 @@ scanned source roots, and compared files.
reference, error-code set) — each makes generation fail naming the reference, error-code set) — each makes generation fail naming the
route and field, not emit a partial document. route and field, not emit a partial document.
2. **Coverage witness:** an independent surface inventory — static 2. **Coverage witness:** an independent surface inventory — static
enumeration over ALL production code in `apps/` and `packages/`, enumeration over ALL production code in `apps/`, `packages/`, and
`plugins/` (the §1.5 production roots),
tests excluded (the A5 §1.2 inventory style), not limited to the tests excluded (the A5 §1.2 inventory style), not limited to the
bootstrap module — covering: framework-decorated controllers and bootstrap module — covering: framework-decorated controllers and
gateways; every raw registration primitive of the HTTP framework gateways; every raw registration primitive of the HTTP framework
(the implementing PR enumerates the primitive list — route, hook, (the implementing PR enumerates the primitive list — route, hook,
middleware-mount, and plugin-registration calls — and the witness middleware-mount, and plugin-registration calls — and the witness
asserts the list against the framework's registration API surface) asserts the list against the framework's registration API surface)
wherever it occurs, including plugins and middleware modules; SSE wherever it occurs, including middleware modules; SSE
routes; conditional registrations evaluated per §4.5 profile and routes; conditional registrations evaluated per §4.5 profile and
unioned; and delegated-surface mounts, with the §4.4 boundary unioned; and delegated-surface mounts, with the §4.4 boundary
check that nothing app-owned registers below an allowlisted check (exactly-one-mount rule and the all-module below-prefix
prefix. The inventory equals the documented set in both prohibition). **Detection is by symbol identity, not text:** the
scan identifies registration-primitive call sites through the
TypeScript type-checker, resolving each callee to its declaration
in the framework package's type declarations — so an alias, a
re-export, or a wrapper cannot escape (a wrapper's internal call
to the primitive is itself a detected call site); a dynamic
property access on the framework's registration object, or a
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
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
@@ -278,48 +404,81 @@ scanned source roots, and compared files.
3. **Content and taxonomy witness:** every `ENDPOINTS.md` entry 3. **Content and taxonomy witness:** every `ENDPOINTS.md` entry
carries the §2.2 required fields — behavior, operation links, carries the §2.2 required fields — behavior, operation links,
authentication requirement, owning-contract link, error semantics authentication requirement, owning-contract link, error semantics
— presence-checked mechanically against the structured entry — presence-checked mechanically against the §2.2 entry grammar;
format; every error response documented in `OPENAPI.yaml` uses a every error response documented in `OPENAPI.yaml` uses a
code from the contract 5 §4.2 closed enums, and each family's code from the contract 5 §4.2 closed enums **as exported from the
shared types package** (contract 5 §4.1's package; the
implementing PR that lands the enums names the exports, and this
witness compares against those exports — §6.5 orders the
dependency), and each family's
documented codes exactly match the enum in the shared types documented codes exactly match the enum in the shared types
package; where the no-oracle rule applies, the documented refusal package; where the no-oracle rule applies, the documented refusal
and not-found responses are identical in code, status, and shape. and not-found responses are identical in code, status, and shape.
4. **Retirement witness:** before `docs/openapi-tess.yaml` is deleted, 4. **Retirement witness:** before `docs/openapi-tess.yaml` is deleted,
an automated comparison proves each of its 17 paths is covered by an automated comparison proves each of its 17 paths is covered by
`OPENAPI.yaml` under this equivalence algorithm, exactly: `OPENAPI.yaml` under this equivalence algorithm, exactly:
(a) canonicalize both documents — dereference every `$ref` with (a) canonicalize both documents — dereference every `$ref`
cycle detection, delete the annotation-only keywords in-document only (an external `$ref` is a canonicalization
failure naming the reference), with cycle detection that replaces
a re-entered `$ref` by a canonical cycle marker carrying the
cycle's entry pointer (deterministic, so two documents with the
same cycle structure canonicalize identically), delete the
annotation-only keywords
(`description`, `summary`, `example`, `examples`, `title`, (`description`, `summary`, `example`, `examples`, `title`,
`deprecated`), rename path-template parameters positionally, `deprecated`), rename path-template parameters positionally,
lowercase HTTP methods, then sort all object keys; (b) per legacy lowercase HTTP methods, then sort all object keys; (b) per legacy
path: deep structural equality of the canonicalized request and **operation** — each (path, method) pair independently, so a
response schemas, equality of the security/authentication multi-method legacy path yields one match per method: deep
requirement sets, and equality of the documented error-code sets — structural equality of the canonicalized request and
a legacy error-code set is DERIVED as the legacy operation's response schemas (an absent request body matches only the
documented non-2xx status codes plus any error-code enum values in canonical no-body marker; equality is evaluated over the
its response schemas; where the legacy document does not express a 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
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
codes) and the taxonomy-code set as plain strings (any error-code
enum values in the legacy response schemas vs the covering
route's §1.6 error-code set; where the legacy schemas express no
taxonomy codes, this component's comparison target is the
covering route's §1.6 record alone, i.e. the record is asserted
present and closed, exactly as the permissions dimension below);
where the legacy document does not express a
dimension at all (permissions), the comparison target is the live dimension at all (permissions), the comparison target is the live
§1.6 metadata record of the covering route instead; (c) the §1.6 metadata record of the covering route instead; (c) the
covering `ENDPOINTS.md` entry — selected as the entry containing covering `ENDPOINTS.md` entry — unique by §7.5's
one-entry-per-`operationId` rule, selected as the entry containing
the `operationId` link of the operation that matched the legacy the `operationId` link of the operation that matched the legacy
path in (b) — must carry a permission rule reference equal operation in (b) — must carry a permission rule reference equal
(same owning contract, same rule identifier) to that covering (same owning contract, same rule identifier) to that covering
route's §1.6 permission reference. The comparison emits the exact route's §1.6 permission reference. The comparison emits the exact
per-path differences on failure. A repository-wide reference scan per-operation differences on failure. A repository-wide reference scan
shows no remaining consumer (including generated clients) resolves shows no remaining consumer (including generated clients) resolves
the legacy file. the legacy file.
5. **Boundary witness:** the repository checker script (shipped by 5. **Boundary witness:** the repository checker script (shipped by
the implementing PR and run in CI alongside §7.1) parses the implementing PR and run in CI alongside §7.1) parses
`ENDPOINTS.md` into the §2.2 entry structure via a Markdown AST `ENDPOINTS.md` into the §2.2 entry grammar via a Markdown AST
and rejects, exactly: (a) an entry missing any §2.2 required and rejects, exactly: (a) an entry violating the grammar — a
field; (b) an operation mention that is not a Markdown link whose non-`##` entry heading, a duplicate family name, a missing
target is an `OPENAPI.yaml` `operationId` anchor and whose link required field label, a duplicated field label, or an `Events:`
text is that `operationId`; (c) a fenced code block, anywhere in field on a non-event family; (b) an operation mention that is not
the file, containing any of the OpenAPI schema keywords a Markdown link in the §2.2 anchor grammar (link text =
`operationId`, target = `./OPENAPI.yaml#operation/{operationId}`);
(c) any of the reserved tokens
`requestBody`, `responses`, `parameters`, `schema`, or `requestBody`, `responses`, `parameters`, `schema`, or
`properties` — schema content belongs only in `OPENAPI.yaml`; `properties` appearing in ANY Markdown node type — fenced code,
(d) an `operationId` link that does not resolve; (e) an event indented code, HTML block, table, inline code, or prose —
entry whose event name is not in the §4.6 registry. The witness anywhere in the file (schema content belongs only in
`OPENAPI.yaml`);
(d) an `operationId` link that does not resolve, per the §2.2
resolution rule; (e) an event
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
equal to the §4.4 allowlist entry (string comparison after
whitespace trimming). 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.)
@@ -328,6 +487,25 @@ scanned source roots, and compared files.
repository devDependency (substituting a different validator is an repository devDependency (substituting a different validator is an
amendment to this contract); the witness proves it can fail by a amendment to this contract); the witness proves it can fail by a
control run against an invalidated copy. control run against an invalidated copy.
7. **Source-consistency witness:** for the record fields the
registration derivation (§1.6) does not structurally guarantee,
the witness cross-checks record against code: (a) **derivation
closure** — every production route's installed authentication
guard and permission enforcement originate from its record's
declared `ApiAuthClass` and permission rule reference (static
assertion that no route installs a guard or permission check
through any path other than record derivation), with a control
route that installs a bypassing guard failing the assertion;
(b) **error-code closure** — per route family, the set of
contract 5 §4.2 taxonomy codes referenced by the family's
production code (by symbol identity against the shared-types
enum exports) equals the union of the family's records'
error-code sets, in both directions, with one control per
direction (a code emitted but not declared; a code declared but
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.
## 8. Drafting additions (PRD §12.1 disclosure) ## 8. Drafting additions (PRD §12.1 disclosure)
@@ -359,18 +537,32 @@ severable:
drift gate as a required trunk check from first commit, and the drift gate as a required trunk check from first commit, and the
build-first documentation sequencing. build-first documentation sequencing.
11. The §1.5/§1.6 definitions themselves — the production-route 11. The §1.5/§1.6 definitions themselves — the production-route
boundary and the closed route-metadata record with its per-field boundary over the three named roots, the closed route-metadata
completeness predicate — and the §4.4 delegation allowlist with record with its per-field completeness predicate, its
its below-prefix boundary rule, the §4.5 profile enumeration and record-as-registration-input derivation rule, the pinned
condition field, and the §4.6 typed event registry with the four-value `ApiAuthClass` enumeration, and the event-record
literal-name rule. 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.
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 and bidirectional 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, family/operation checks, the §7.3 content and taxonomy witness,
the §7.5 checker script with its five reject rules, the §7.6 the §7.5 checker script with its seven reject rules, the §7.6
pinned validator (Redocly CLI), the per-field fail-closed 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/ controls in §7.1, and the §7.4 canonicalization/derivation/
covering-entry algorithm. covering-entry algorithm.
13. The §2.2 entry grammar as exact syntax (heading form, literal
field labels and cardinality, link and anchor grammar, event-item
syntax, the one-entry-per-`operationId` rule, and the
reserved-token prohibition including its prose strictness).
14. The §4.1 exclusion-list eligibility rule (closed, machine-checked
against every production-profile inventory pass).
15. The §6.5 contract 5 ordering dependency and its contingency
amendment rule.
## Ruling request ## Ruling request