Skip to content

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 }. Returns 202 { job_id, status: "accepted" } after gate checks pass (gate failures return 4xx with the error object; nothing enters the engine).
  • GET /v1/jobs/{job_id} — status: accepted | running | complete | failed, with the UCCO envelope on complete.
  • 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_job and spec_path are dropped (contextualisation fossils); the triumvirate-hash / source_hash echo 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_ref resolves to the finest ID actually traced, module-level minimum.
  • generator_extras and artifacts[].content_uri are 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_citationpointer: 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 $id only, shape unchanged. The frozen ucca-content-payload-schema-v1.json carried an invalid $id (a non-empty URI fragment the JSON Schema metaschema forbids → standard jsonschema.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's outcomes[].outcome_number is 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 neither outcome_number nor its container outcomes appeared anywhere in this pack — §2's GATE_STRUCTURE row promised type checking against a type nobody had written down. Both shapes exist in pre-erratum history: of 41 stored generation payloads, 34 carry a string outcome_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 not string|number: an integer expresses only a numbering convention, and cannot carry §4(a), PC1.3 or Art. 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.