Expressiveness Contract — API exposure plan (Task #4)
Lift render-node’sAGENT_EXPRESSIVENESS_CONTRACT.md (§1–§6, on render-node
main = production) into the public API so agents can author everything the
engine renders. Production runs the C++ engine only — the contract’s
“Rust path: warn-skip” deltas do not gate exposure, so capabilities advertise
the full contract flat (no engine-aware lower bound).
The pipeline (every feature moves these together)
Verification
- Unit: schema accepts; translator emits the contract’s exact field names/values.
- Golden payloads:
render-node:tests/mainTests/ReferenceVideoExitTests.cppholds the exact engine JSON for the 4 target scenes — assert translator output matches it. - Pixel parity (follow-up): drive render-node’s headless runner + probe frames (needs Task #3’s runner; not wired yet — noted so it isn’t mistaken for done).
Phase status
Phase 1 — §1 common transform/looks
- Blend modes — enum 10→17 (separable + W3C non-separable);
BLEND_MODE_MAP→ camelCase; un-rejected; emitted on video/text/sticker/progress/audioViz. - Perspective tilt —
rotation:{x,y,z}object on video/sticker (overrides scalar); un-rejected. -
maskShape(circle/diamond/hexagon/star/heart/triangle) — analytic SDF mask on all visual elements -
backdropBlur— frosted-glass panel (radius px) on all visual elements; shared_common_visualhelper - [~] nested
shadow/borderalready emitted; per-cornercornerRadiusobject deferred (uniform works) - full
filtersgrade — +temperature/tint/vibrance/highlights/shadows on video+sticker
Phase 2 — new element kinds → milestone: 4 exit-test scenes authorable
-
gradients[](§5e — golden-payload verified) · [x]groups[]+ stack layout (§5) · [x]shapes[]SVG path/stroke/morph/trim (§5b — golden-verified)
Phase 3 — §4 text + §3 animations
- per-word
style(W3 — golden-verified, completes the 4-scene milestone) · [x] rangeselector(W2) · [x] valuecounter· textWrap/[x]glow/RTL - audio generators · [x]
customAnimationsregistries · loop/calculateTimings (present) · [x] keyframed effect intensity (§2)
Phase 4 — §5c/5d expressive ✅
- speed ramps (
playbackRateKeyframes) · motion blur (params.motionBlur) · track mattes (matte) · animated masks (mask+maskKeyframes)
Phase 5 — §6 canvas + §2 tail ✅
-
background.gradient· aurora + generic effect props · W3 transitions (whipPan/cinematicZoom/burnEdge/shatter/domainWarp) · watermark - chroma_key: already exposed via
chroma_settings(HSV); the newer keyR/keyG/keyB YCbCr path deferred (verify before touching working code)
Phase 6 — consolidation
- capabilities completeness audit (verified: 7 element kinds, 17/17 blend modes, aurora, W3 transitions, gradient/shape fields — all advertised, CI-enforced by test_capabilities)
- SDK version bump 0.1.0 → 0.2.0
- Remaining (infra-blocked / decisions): elements reference docs; deprecate flat legacy fields (breaking — needs SemVer decision #2); render-parity CI gate needs the headless runner (Task #3) — interim coverage is golden-payload assertions against ReferenceVideoExitTests.cpp
Status: Phases 1–5 complete; Phase 6 audit + version bump done. ~22 commits, full suite 1091 pass.
Open API-design decisions
- Groups public shape — top-level
groups[]onRenderRequest(matches engine) vs element-nesting sugar. - Legacy field migration — deprecate-and-map the flat
x_rotation/border_radius-px fields, or keep both (SemVer impact on SDK)?
exposure-catch-up-task, api-engine-capability-drift, render-node-main-is-production.
