RECEIVED COPY — authored cross-fence (RTOpacks side), relayed by Tim 2026-07-02. Original of record lives in the RTOpacks repo. Per FENCE-PROTOCOL-01 §4 this copy is never edited and never promoted into home canon; local force comes from UCCA-RESPONSE-CONTENT-PAYLOAD-01 and the stamped UCCA-CONTRACT-PACK-01 §4.1.
title: RTOPACKS-REVIEW — the §4.1 content-payload candidate shape, reviewed for render doc_id: RTOPACKS-REVIEW-CONTENT-PAYLOAD-01 status: READY to cross. Answers the §4.1 sendback; also acknowledges UCCA-CORRECTION-01. Verdict: RENDERABLE — freeze §4.1 after four typed changes and one question back. layer: crossing artefact (original of record filed RTOpacks side, crossings/sent/) canonical: false authored: 2026-07-01 NYC — architect review against STUDIO-SPEC-01 (canvas anchor model) and the crossed contract; Tim relays relates_to: UCCA-QR1A-CONTENT-PAYLOAD-SCHEMA-01 (received); UCCA-CONTRACT-PACK-01 §4.1, §4.2, §4.3; RTOPACKS-RESPONSE-TO-ASSESSMENT-01 Q-R1c, Q-R3; UCCA-CORRECTION-01 (received)
Review: the Content-Payload Candidate Shape¶
1. UCCA-CORRECTION-01 — acknowledged¶
Accepted whole. CHCPRT025 / 2026-03-09 is consistent with our own records of the engine state, so the correction lands as confirmation, not surprise. Our crossed documents that echo "Dec 2025" remain verbatim (the fence forbids editing the as-crossed record); our exchange log now carries the reading note per your C-3. The ruling's formulation — an event without an artefact is a memory, and the ledger deals in artefacts — is adopted into our own vocabulary with attribution. Third retirement today; same lesson each time.
2. Verdict on the shape: RENDERABLE — with four changes before freeze¶
modules[].content_html + quiz.questions[] map cleanly onto our canvas content-node
model. The shape as a whole is a sound freeze basis. But the schema as sent is
observation-typed — derived faithfully from three runs — and a contract must be
intent-typed. Four changes:
2.1 Instance-nulls must become intent types. meta.source_hash: {type: null},
meta.source_unit_version: {type: null}, artifacts[].content_uri: {type: null} encode
"was always null in the three runs," not "is null by contract." For source_hash
specifically: in the contracted world this is the triumvirate-hash echo and must be
required and non-null — a payload that cannot cite its input fails our provenance
chain at the first link. The others: type them ["string","null"] with the null
semantics stated, or drop them.
2.2 Provenance belongs to §4.3, not inside the payload. meta{} duplicates
provenance concerns (run timestamp, source hash, generator mode, spec path) that the
contract already assigns to the §4.3 provenance block — one of our four parsed surfaces,
with a completeness test. Two authorities for the same facts is a divergence engine.
Recommend: the contractual payload shape excludes meta (or marks it explicitly
non-contractual/opaque — we will not parse it). Provenance has one home. This also
disposes of spec_path entirely: a local filesystem path is engine-internal and has no
business in contract surface, redacted or otherwise.
2.3 De-require the contextualisation fossils. target_job and
meta.spec_generation_target_job are instance values from the engine's hand-steered era
— your own annotations say so. Under the ruled model (Q-R3: one opaque
contextualisation_brief, ID + hash echoed in §4.3 provenance), a hardcoded job-title
string has no contractual place. Optional at most; recommend dropped from the required
set entirely.
2.4 De-require generator_extras. Video scripts and scenes are welcome — our fill
spectrum's full-production point consumes exactly these — but not every generation job
wants them. Required-by-observation should become optional-by-intent, presence governed
by the generation request.
3. The question back (Q-B4.1): element addressability¶
The one thing the schema cannot tell us and the freeze depends on. Our canvas anchors
the unit's elements and performance criteria as locked anchors; content nodes attach
to them; coverage renders per-PC. The §4.2 trace map is what drives that display — its
entries point requirement_ref → element_ref into this payload.
So: what does element_ref resolve to, at what granularity, and is it stable?
- Module level exists (
module_index,ucca_code) — coarse but workable. - Below module, nothing carries an ID: content blocks within
content_htmlare opaque HTML, quiz questions have no identifier,learning_outcomesare bare strings, andinternal_outcome_numberis internal to an unstated scheme. - If the trace map references finer than module — which per-PC coverage wants — the payload needs minted, stable element IDs at that granularity (content-block and question level), stable across re-generation of the same job.
Answer this and §2's four changes, and we confirm freeze on the revised schema — no further round needed from our side if the answer is "module-level at v1, finer IDs when diagnosis lands," which we would accept with the limitation noted.
4. For the record¶
The honest flags in your README are the right way to send a schema: the provenance mismatch surfaced before freeze instead of fossilising under it, and the scrubbed fields arrived annotated instead of silently absent. Received-copy filed verbatim, including flags.
Renderable, and close to freezable: type the intent instead of the observation, give provenance one home, retire the fossils from the required set, and tell us what an element_ref points at. Then §4.1 is v1.0 and the pack is whole.