UCCA Input-Path Contract Pack — v1.0¶
What this is. The engine's API boundary, specified for build: the gate, the job model, the envelope, and the schemas that freeze. Implementing it delivers R-1, R-3, R-4, implements D-1..D-4, and severs the worlds/ residue from the engine — the build proof that mints ADR-0002's remedy.
Reading rule: everything here is either (a) assembled from crossed agreements (cited) or (b) an engine term stated under the fence's authorship rule (marked ENGINE TERM). Nothing is a new ask of the client except one custody statement (§6).
1. The boundary at a glance¶
Client world (their jurisdiction, their warranty)
corpus acquisition → normalisation → CONFORMER/ADAPTER
translates · validates semantically · signs · submits
│
signed triumvirate job ← only this crosses
▼
════════════════ THE GATE (engine edge) ═══════════════════
verifies independently: structure · schema version ·
signature · reference integrity (structural) · size/rate
→ malformed bounces WHOLE (no partial acceptance)
════════════ warranty changes hands here ══════════════════
▼
Engine (UCCA jurisdiction, UCCA warranty)
async job execution → UCCO envelope → returned
retains: hashes, structural traces, audit events,
signatures — NEVER content bodies
Trust boundary = warranty boundary = corporate boundary (ADR-0003; Ruling 2). No warranty before the gate; full warranty after it.
2. The gate (ENGINE TERM — implements Ruling 1, engine side)¶
The gate performs structural verification only — it has no domain knowledge by construction (ADR-0002):
| Check | Rejects with |
|---|---|
| Authentication (per-client key; deployment note §10) | GATE_AUTH |
| Triumvirate schema version accepted | GATE_SCHEMA_VERSION |
| Structural validation: required fields, types, enums, non-empty arrays | GATE_STRUCTURE |
| Adapter signature verifies over envelope | GATE_SIGNATURE |
| Structural reference integrity (IDs resolve within the job; acyclic prerequisites) | GATE_REFERENCES |
| Validation block present and self-consistent (adapter's own validate() ran) | GATE_UNVALIDATED |
| Size / rate limits | GATE_LIMITS |
Semantics (do the packaging rules make sense? is the clause mapping faithful?) are the conformer's warranty, checked client-side, never re-checked here — the engine cannot and does not judge domain sense. Error objects follow the March error model shape (machine code, severity, phase, affected element, message, remediation); the March ING_/TRN_ taxonomies are conformer-side and out of contract scope.
3. The job model (agreed: response Q-R1b)¶
Async-first, one model, two directions. No synchronous generation call exists.
POST /v1/jobs— submit. Body:{ job_type, triumvirate, ...type-specific }. Returns202 { job_id, status: "accepted" }after gate checks pass (gate failures return4xxwith the error object; nothing enters the engine).GET /v1/jobs/{job_id}— status:accepted | running | complete | failed, with the UCCO envelope oncomplete.POST /v1/webhooks— optional completion callback registration, per client.- No latency guarantee in-contract (client's explicit position). Latency may scale with requested density; SLA is a future commercial term.
Job types at v1:
| job_type | Status | Notes |
|---|---|---|
generation |
live | R-1 + R-3. Carries optional contextualisation_brief (§5). |
diagnosis |
honest stub | R-4/R-2: the endpoint exists, the gate checks RUN in full (integration is real), then returns 501 { reason: "diagnosis_not_yet_available", contract_version }. Body shape reserved: { triumvirate, documents[] } per §6. When R-2 lands, the 501 is removed — nothing else changes. |
4. The UCCO envelope — four parsed surfaces frozen (agreed: response Q-R1c)¶
The client parses exactly four surfaces; these version with the contract. Everything else in the envelope is opaque pass-through the engine may evolve freely.
4.1 Content payload. — FROZEN v1, intent-typed. Generated material, structured for the
client's rendering. Shape frozen to ucca-content-payload-schema-v1.json (issued alongside
this pack), ruled from the QR1A samples via RTOPACKS-REVIEW-CONTENT-PAYLOAD-01 §2 and
UCCA-RESPONSE-CONTENT-PAYLOAD-01 §1–2. Key terms:
- Intent-typed, not observation-typed — the schema states what the engine promises, not what three runs emitted.
- Provenance has one home (§4.3), not the payload.
meta{}is excluded (non-contractual opaque pass-through per Q-R1c);target_jobandspec_pathare dropped (contextualisation fossils); the triumvirate-hash /source_hashecho lives in §4.3, required and non-null. - Three-level addressability: the payload mints
module_id,block_id,question_id, stable within an artefact version. Re-generation yields a new artefact version with new IDs; cross-version continuity lives on the requirement side (elements/PCs from the triumvirate). Trace map (§4.2)element_refresolves to the finest ID actually traced, module-level minimum. generator_extrasandartifacts[].content_uriare optional/nullable by intent.
4.2 Trace map. requirement ↔ generated element at source_ref granularity —
each entry: { requirement_ref (instrument, id, source_ref), element_ref, relation }.
This is the "traceable by construction" property made inspectable (R-1 as assessed:
property, not method), and the raw material for the client's pre-use-review rendering
(Q-A3.A).
4.3 Provenance block. Verified complete against the client's Q-A3 completeness test — every field below satisfiable from the envelope alone, no side channel:
| Field | Source of requirement |
|---|---|
run_id, timestamps |
Q-A3 |
direction (forward / backward) — engine vocabulary; client maps to product modes |
A-2, B-5, assessment §4 flag |
triumvirate_schema_version + triumvirate_hash |
Q-A3, Q-D3 |
corpus_citation — pointer: dated raw snapshot key + hash; attestation: normalised hash (explicitly non-reconstructable; marked kind: attestation) |
Correction C-3, ACK §3 |
contextualisation_brief_id + hash (echo; content never retained) |
Q-R3 |
Diagnosis jobs additionally: report_id (dated, versioned, citable), hand_raises[] each with stable ID + exact requirement ref at source_ref granularity |
A-4, A-5, Q-A3.C |
document_citations[] (diagnosis): raw_document_hash → canonical_form_hash |
Correction C-4 — distinct fields from corpus_citation; never merged |
4.4 Signatures. Engine signature over the envelope; adapter signature carried through from submission. Machine signatures attest provenance only — D-5 as ruled: nothing in the envelope carries, implies, or substitutes for a human compliance signature.
Output vocabulary constraint (canon-bound, A-2 + B-1): every emitted field and phrase speaks about material — trace / no-trace, present / not-traceable — never compliant/non-compliant, competent/not-competent, pass/fail. No field of the envelope is a verdict. This is testable at review and will be tested.
5. Contextualisation slot (agreed: response Q-R3)¶
One slot: contextualisation_brief: { id, hash, payload } — payload opaque to the
engine, applied as generation guidance only, never persisted, ID + hash echoed in
provenance. Client-side structure may evolve indefinitely without contract change.
6. Canonical document schema (ENGINE TERM — the one new statement in this pack)¶
Diagnosis jobs carry human-authored material as a canonical document representation (structured text + images, JSON-shaped, versioned). Agreed: raw client formats never cross the gate (response Q-R2a ruling; conformer principle applied to documents).
Custody, stated as an engine term: the canonical document schema is engine-published contract surface — authored UCCA-side, versioned like the triumvirate schema, shaped in v1 by Client One's real needs. Rationale = the drift-check: a client-owned format inside the gate's contract only works while there is one client; N clients would return the engine to parsing N formats — the exact disease the triumvirate cures for obligations, cured the same way for documents. The client's normalisation pipeline, quality floor, and hash chain (raw_document_hash → canonical_form_hash) are unchanged; only the schema's pen moves. Response as drafted says "ours, spec'd in the contract" — this term answers that line; if the client reads it differently, that is a re-cross, not a redline.
7. What the engine retains (agreed: Q-B2, verbatim)¶
Hashes, structural traces (shape and reference: requirement IDs, element IDs, counts, versions), audit events, and signatures. Never content bodies — not corpus, not documents, not outputs, not contextualisation payloads.
8. Warranty clause (canon: Ruling 2, restated for the contract's face)¶
No warranty before the gate; full warranty after it. The client warrants the semantic fidelity of every submitted triumvirate (and canonical document), regardless of whose reference code produced it. UCCA warrants, over every job passing the gate: gate determinism, provenance completeness (§4.3), envelope integrity, output vocabulary (§4.4 constraint), and the never-sign property.
9. Versioning & freeze¶
- Contract version travels in every response; triumvirate schema (1.0), canonical document schema, and the four parsed surfaces version explicitly and independently (March D7, kept).
- Frozen at stamp: endpoints + job model, gate checks + error codes, the four surfaces' field sets, citation semantics (pointer vs attestation), vocabulary constraint, warranty clause.
- FREEZE-STAMP APPLIED 2026-07-02 — v1.0 FROZEN. Both held conditions cleared:
§4.1 content-payload shape frozen to
ucca-content-payload-schema-v1.json(samples QR1A verified 2026-07-01; review RTOPACKS-REVIEW-CONTENT-PAYLOAD-01; response UCCA-RESPONSE-CONTENT-PAYLOAD-01 applying the four deltas + Q-B4.1); and §6 custody accepted (RTOPACKS-ACK-CONTRACT-PACK-01). The pack is whole. - ERRATUM 2026-07-03 (Tim ruling), schema
$idonly, shape unchanged. The frozenucca-content-payload-schema-v1.jsoncarried an invalid$id(a non-empty URI fragment the JSON Schema metaschema forbids → standardjsonschema.validate()failed on the schema itself). Corrected to a valid absolute URI (https://ucca.online/ns/ucco/v1/content-payload-schema.json) and re-frozen; every field and constraint is unchanged. Closes UCCA-SCHEMA-FITNESS-FINDING-01. - ERRATUM 2026-07-31 (ruling
UCCA-RULING-OUTCOME-NUMBER-TYPE-2026-07-31) — a type this pack never declared. The input triumvirate'soutcomes[].outcome_numberis a non-empty string. It was undeclared, not merely under-specified: before this erratum the field appeared in no frozen schema in the engine repo, and neitheroutcome_numbernor its containeroutcomesappeared anywhere in this pack — §2'sGATE_STRUCTURErow promised type checking against a type nobody had written down. Both shapes exist in pre-erratum history: of 41 storedgenerationpayloads, 34 carry a stringoutcome_number, 5 carry integers, and 2 carry no outcomes. None was ever checked, because no gate can check a type nobody declared. That history is residue, not contract. It is not amended, re-sealed or re-judged by this erratum; closed jobs stay closed and job rows are permanent. Why string and notstring|number: an integer expresses only a numbering convention, and cannot carry§4(a),PC1.3orArt. 6(1)(b)— the identifier shapes regulated obligations outside the first domain actually use. The drift-check (ADR-0002) rejects it, and the engine's own domain-neutral internal model already types this concept as a string. A union would be paid for at every comparison site, forever, by every consumer; a single type is paid for once, by whoever stringifies. Declared here before it is enforced — the gate's forward structural check is brought to this type in the same pass, not ahead of it. Owed and not done here: the input triumvirate has no frozen JSON schema at all; this erratum types one field of it and does not stand in for that schema.
10. Build notes (engine-side, for Alex — not contract surface)¶
- Skin/body split: gate at the Cloudflare edge; reasoner in its real runtime behind it (the substrate ruling). Per-client isolation per March (subdomain, keys, audit namespace) — deployment detail, not contract.
- Definition of done includes ADR-0002's proof event: the input path live, a
conformed job exercised gate→engine→envelope to terminal effect, AND
worlds/severed from the engine repo. The register flips ADR-0002's remedy to minted on that day, per the lifecycle. - Drift-check on every implementation decision, as always: does this only work because the client is VET?
The engine's boundary, on paper before it is in code: one gate, one async job model, four frozen surfaces, two citation kinds, one opaque brief, one engine-published document schema, and a warranty that changes hands exactly where the trust does. Built from fourteen YESes, five §5 answers, two rulings, one correction, and zero fictions — every claim in it traces to a crossing. The actor changes; the obligation does not.