@binclusive/a11y-contract
v0.15.0
Published
The public accessibility finding contract — a zod schema (type + wire parser) shared by the Binclusive OSS engine and platform.
Readme
@binclusive/a11y-contract
The public accessibility finding contract: one zod schema that is both the
type and the wire parser. The OSS engine (@binclusive/a11y) emits findings
against it; the private platform (auditer + kontrol) parses them against the same
schema. Single-sourcing the contract in one published package keeps both sides
from forking it.
The shape
A Finding is a zod discriminated union on provenance (HOW it was judged):
deterministic— an automated rule engine surfaced it. Lean base metadata plus the corpustierthe rule belongs to.agent— the agentic tester judged it. Carries arationaleand an optional natural-languagesuggestion; no corpustier.asserted— an authored claim (a human or a coding agent filed it), neither a scan nor a model verdict. Carries base metadata plus an optionalsuggestion.
Orthogonal to provenance is the optional origin dimension — WHICH lane
produced the occurrence: usability_test | ci_cd | local | mcp | manual.
provenance answers how it was judged; origin answers which lane produced it.
The lanes come in two halves, and the split is load-bearing rather than
descriptive. Scan lanes (SCAN_ORIGIN_VALUES — usability_test, ci_cd,
local) mean "one of our own scanners observed this", so no client may stamp
one. Authored lanes (AUTHORED_ORIGIN_VALUES — mcp, manual) mean somebody
asserted it, and the authored-write path accepts only those. A lane added to the
scan half is therefore closed to every caller the moment it is named.
A third, independent axis is the optional platform dimension — WHICH surface
the occurrence lives on: web | ios | android | unity | unknown (Sentry's coarse
per-event platform enum). The engine's emit boundary maps its rich scan-kind onto
this coarse enum, so a persisted finding knows its surface; unknown is the
fail-safe default (Sentry's other). The three axes are independent: origin
(which lane), platform (which surface), provenance (how judged).
The arms share the metadata aligned to the persisted agentic_finding model:
criterion (WCAG SC), severity, element (a DOM locator, never source),
evidence, and the declared scan scope.
Metadata-only by construction
Every object is .strict(), so the schema is a closed allowlist with no field
capable of carrying customer source, and no unknown key can be smuggled in — a
payload bearing a source snippet fails the parse. This is the zero-data-retention
guarantee made structural, not promised in prose.
Usage
import { parseFindingPayload } from "@binclusive/a11y-contract";
// Parse untrusted input at the trust boundary (throws ZodError on any violation).
const payload = parseFindingPayload(await request.json());
for (const finding of payload.findings) {
if (finding.provenance === "agent") console.log(finding.rationale);
}