Oshun Platform · Features

Composition Surface and Cinematographic Technique Catalog

A focused page within the Oshun Platform Features documentation. The full map and every sibling page live in the Features hub.

13sections22 minread12tables

On this page

The Composition Surface is the customer- and creator-facing affordance that arranges Segments into a Scene Score. The Cinematographic Technique Catalog is the named layer that maps creator intent — "match cut," "L-cut," "smash cut" — onto the Blend Kernel's mechanical transition primitives, gated per Segment pair, per template, and per Lilith tone band. This page is part of the Living Scenes core (see Living Scenes — Concept and Customer Promise and Scene Score Schema); it sits one layer above the Blend Kernel's transition contracts and one layer below the rendered video that the Conductor streams. Everything documented here is deterministic, pure decision logic — the catalog, the compatibility scorer, the tone gates, and the compose-assist budgets are all real, contract-backed TypeScript with tests. The pixel-level work they govern (latent video generation, optical-flow warps, FVD computation, GPU determinism) lives downstream and is consumed only as score inputs, never computed in these modules.

What is real vs. what is modeled. The honest boundary matters here. The Blend Kernel (@yemaya/blend-kernel) "owns the contracts + parameter validation"; its own header states "Implementations of the actual DSP / shader code live downstream." The compatibility scorer is a pure function over its inputs (same pair → same scores). FVD, flicker, color-jump and motion-vector numbers are thresholds the pure functions compare against, not measurements these modules take. When this page says a technique "requires a shape-similarity score ≥ 0.78" it is describing an eval threshold the catalog declares, not an embedding distance computed in this code — see the Accuracy notes at the end.

Where the Code Lives#

Concern Package / file
Technique catalog (12 entries), tone gating @yemaya/blend-kernel v0.1.0 — libs/yemaya/blend-kernel/src/catalog/cinematographic-catalog.ts, tone-gating.ts
Transition primitives + parameter validation libs/yemaya/blend-kernel/src/transitions.ts
Segment-pair compatibility scorer libs/yemaya/blend-kernel/src/compatibility/scorer.ts
Conductor runtime, compose-assist, cue parser @yemaya/living-scenes-runtime v0.1.0 — libs/yemaya/living-scenes-runtime/src/{conductor/conductor.ts, compose-assist/compose-assist.ts, cues/cue-parser.ts}
Score / Segment / RenderEnvelope Zod contracts libs/contracts/src/living-scene/score.ts
Template catalog + per-template eval gates libs/isis/workflow-classes/src/living-scene/template-catalog.ts
Tara sub-variant breath cycles libs/isis/workflow-classes/src/living-scene/tara.ts
Scene telemetry events (Live Direction channel) libs/oshun/embodiment-psyche/src/events/scene-events.ts
Customer compose surface (web / mobile) apps/oshun/web/src/app/studio/compose/ComposeClient.tsx, apps/oshun/mobile/app/compose.tsx
AAA / operator Score editors apps/yemaya/studio-web/src/score-editor/ScoreEditorPage.tsx, apps/oshun/web/src/app/lilith-studio/scenes/TaraSceneEditor.tsx
Public scene viewer + BFF apps/oshun/web/src/app/scene/[id]/{page.tsx,embed,report}, apps/oshun/bff/src/routes/living-scenes.ts

Customer-Tier Composition Surface#

V1 adds a curated composition affordance to the customer tier — distinct from the Live Direction Channel (which steers a single template in real time) and from the operator-tier Scene Score Editor (which exposes the full schema). The customer surface lets users assemble a Score from existing Segments and preview the resulting arc before committing.

  • Surfaces: web at apps/oshun/web/src/app/studio/compose/ (the ComposeClient.tsx client component) and mobile at apps/oshun/mobile/app/compose.tsx. Tablet gets the desktop affordance with touch-first interactions.

  • Affordances: drag-arrange Segment cards on a timeline; tap a boundary to open the Technique Picker (showing only catalog entries compatible with the Segment pair and allowed by the current template and tier, via templateAllowsCompositionTechnique(...)); scrub-preview the boundary at the picked technique's overlapWindowRange; one-tap accept an AI-suggested cut.

  • Sources of Segments (modeled as CompositionSegmentSource with a kind discriminant in compose-assist.ts): (a) kept-living-scene Segments the user owns — re-composable across templates only when the destination allows it and the source is userOwned; (b) per-template segment libraries (Tara breath-cycle anchors, Nyx celestial anchors, Veritas topic-hub anchors, Metis lesson-step anchors, Arete intention-derived anchors); (c) tenant-rights-import Segments, gated on the composition-import rights tag. This logic is the real canUseSegmentSource(...) function.

  • Tier caps (CompositionTier = 'free' | 'paid' | 'aaa', enforced by the literal TIER_CAPS table in compose-assist.ts:447-452):

    Tier Max Segments Max duration Behavior
    free 6 90 s curated compose surface
    paid 24 8 min (480 s) curated compose surface
    aaa — (no cap) routesToStudioEditor: true — full Scene Score Editor in Yemaya Studio

    Crisis frame disables composition entirely: when crisisFrameActive is true, validateCompositionDraft returns allowed: false with reason crisis-frame-composition-lock before tier caps are even evaluated. Active sessions complete on the technique already picked; no new composition is permitted while the frame is active.

  • Score lifecycle: composition produces a CompositionDraft; promotion to a renderable Score (promoteCompositionDraft) requires every boundary to clear the continuity gate (continuityPreScore ≥ 0.85, enforced both at the draft level and per boundary — compose-assist.ts:585 and :688 respectively), every Segment to pass workflowClassPolicyAllowed, and every Segment source to clear canUseSegmentSource. Promoted Scores route through the standard Conductor + Render Envelope path (see Direction, Conductor, and Blend).

  • Live Direction co-existence: a customer-composed Score still accepts Live Direction cues at runtime under the verb vocabulary, with the composition-time technique respected unless a cue overrides it. The real resolveRuntimeTechnique function shows the precedence: a kill cue always wins (returns 'kill'); a linger cue extends the current technique (returns ${techniqueId}:linger-extended); otherwise the planned technique stands.

  • Reduced-motion variant: every promoted Score ships a reduced-motion mapping automatically. promoteCompositionDraft builds reducedMotionTechniquesByBoundary by running every boundary technique through reducedMotionTechniqueFor(...), which reads the per-technique REDUCED_MOTION_TECHNIQUE_FALLBACKS table (e.g. whip-pan → fade-to-black, match-cut → dissolve, montage → still-frame).

Cinematographic Technique Catalog#

The catalog is a versioned, frozen, contract-backed taxonomy. Each entry binds creator intent to one or more Blend-Kernel primitives, declares its constraints, and ships per-technique continuity-eval thresholds. V1 launches with exactly twelve techniques (TECHNIQUE_IDS, cinematographic-catalog.ts:16-29), each with a provenanceTag of the form technique:<id> recorded in the Render Envelope; the catalog is extensible behind Isis release gates and pins versions per kept artifact so deprecation never breaks playback.

Technique Schema#

The CinematographicTechnique interface (cinematographic-catalog.ts:54-67) is richer than the prose summary:

ts
interface CinematographicTechnique {
  id: TechniqueId; // one of the 12
  displayName: string;
  kernelComposition: readonly TransitionKind[]; // which Blend-Kernel primitives
  overlapWindowRange: { minSeconds; maxSeconds };
  requires: readonly string[]; // semantic preconditions
  forbids: readonly string[];
  toneBands: readonly ToneBand[]; // contemplative|pedagogical|narrative|cinematic|entertainment
  templateAllowlist: readonly string[]; // canonical template IDs
  evalThresholds: EvalThresholds; // maxFvd, maxFlicker, maxColorJump, maxMotionVectorDelta, minNarrationAlignment
  accessibilityNote: string;
  reducedMotionFallback:
    | 'hard-cut'
    | 'dissolve'
    | 'fade-to-black'
    | 'still-frame';
  provenanceTag: string; // matches /technique:[a-z0-9-]+/
}

ToneBand here (contemplative, pedagogical, narrative, cinematic, entertainment) is the catalog's tone vocabulary; it is distinct from the Score-level ToneClass enum on a Segment (contemplative, gentle-instructive, celebratory, reverent, reflective, wonder) defined in score.ts:28-35.

V1 Launch Catalog — Kernel Composition and Eval Thresholds#

The table below is taken verbatim from V1_TECHNIQUE_CATALOG. The maxFvd, maxFlicker, maxColorJump, maxMVΔ (motion-vector delta), and minNarrAlign (narration alignment) columns are the actual per-entry numbers — the values the downstream continuity scorecard is checked against, not measurements taken in this module.

Technique Kernel composition (TransitionKinds) Overlap (s) maxFvd maxFlicker maxColorJump maxMVΔ minNarrAlign Reduced-motion fallback
hard-cut (none — instant) 0–0 0.40 0.04 0.12 0.40 0.90 hard-cut
match-cut latent-warm-start, optical-flow-morph, motion-descriptor-handoff, color-lut-match 0.5–2.0 0.30 0.04 0.10 0.30 0.92 dissolve
l-cut audio-crossfade, color-lut-match 1.0–4.0 0.40 0.04 0.12 0.40 0.94 hard-cut
j-cut audio-crossfade, color-lut-match 1.0–4.0 0.40 0.04 0.12 0.40 0.94 hard-cut
dissolve latent-warm-start, optical-flow-morph, color-lut-match, audio-crossfade 0.5–3.0 0.30 0.03 0.08 0.30 0.90 dissolve
smash-cut motion-descriptor-reset, audio-level-jump 0–0.2 0.50 0.06 0.18 0.60 0.85 hard-cut
whip-pan optical-flow-morph, motion-descriptor-handoff, variable-rate-sequencer 0.2–0.8 0.50 0.05 0.18 0.70 0.85 fade-to-black
jump-cut motion-descriptor-reset, variable-rate-sequencer 0–0 0.60 0.06 0.20 0.60 0.85 dissolve
match-action latent-warm-start, optical-flow-morph, motion-descriptor-handoff 0.3–1.5 0.35 0.04 0.12 0.35 0.90 dissolve
cross-cut narrative-pivot, audio-crossfade 0–0 0.40 0.05 0.15 0.45 0.88 hard-cut
montage variable-rate-sequencer, audio-crossfade, color-lut-match 1.0–6.0 0.45 0.05 0.15 0.50 0.85 still-frame
fade-to-black color-lut-match, audio-crossfade, motion-descriptor-reset 0.5–2.0 0.30 0.03 0.10 0.30 0.92 fade-to-black

Notable per-entry semantics drawn from requires/forbids:

  • hard-cut and dissolve both carry forbids: ['active-narration-mid-sentence'] — you may not hard-cut or dissolve through a spoken sentence.
  • match-cut requires shared-shape-anchor; l-cut/j-cut require audio-bus-continuity; smash-cut requires percussive-audio-spike and forbids: ['contemplative-tone-band']; whip-pan requires camera-pan-continuity and likewise forbids the contemplative band; jump-cut forbids both contemplative-tone-band and pedagogical-tone-band; cross-cut requires parallel-action; montage requires a shared-music-bed.
  • fade-to-black is the universal fallback: it has empty requires/forbids, is on ALL_TEMPLATES, and is the recovery transition the policy gate demands for crisis boundaries. It is the graceful default for end-of-arc, section breaks, and any cut that fails every other technique's compatibility check.

Kernel Primitives the Catalog Composes#

The kernelComposition column references the nine TransitionKinds defined in transitions.ts:13-23. The doc historically listed only five; the real array is nine, each with its own typed parameter object and validated range (validateTransition, transitions.ts:106-222):

TransitionKind Validated parameters and ranges
latent-warm-start bridgeSteps ∈ [2, 12] (integer); optional cfgScale ∈ [0, 30] or null
optical-flow-morph morphFrames ∈ [1, 48]; warpStrength ∈ [0, 1]
color-lut-match non-empty sourceLutId/targetLutId; matchFrames ∈ [1, 240]
audio-crossfade fadeMs ∈ [50, 8000]; curve ∈ {linear, equal-power, log}
narrative-pivot non-empty pivotPromptId; resetMotionDescriptor boolean
motion-descriptor-handoff non-empty source/target descriptor ids; blendFrames ∈ [1, 120]
motion-descriptor-reset resetStrategy ∈ {clean-break, new-anchor}; holdFrames ∈ [0, 48]
audio-level-jump deltaDb ∈ [-18, 18]; recoveryMs ∈ [0, 3000]
variable-rate-sequencer non-empty beatGridId; minRate ≥ 0.25, maxRate ≤ 4, minRate ≤ maxRate

TransitionValidationError carries a discriminated code of 'out-of-range', 'unknown-kind', or 'missing-required', so callers can react to why a parameter was rejected, not just that it was.

Continuity Scorecard Gate#

Independent of the per-technique catalog thresholds, the Blend Kernel exposes a ContinuityScorecard ({ fvd, flickerScore, colorJump, motionVectorContinuity, audioRmsDeltaDb }) and isBlendContinuityAcceptable(...). This gate first rejects any non-finite metric, then checks each band (FVD/flicker/colorJump below their max, motionVectorContinuity above its min, |audioRmsDeltaDb| below its max) and returns { acceptable, reasons[] }. The §25.18 release gates consume this: any score below the configured threshold blocks promotion.

Catalog Governance and Versioning#

Every technique carries a provenanceTag recorded in the Render Envelope; the audit trail on a kept artifact shows which techniques the AI assist selected vs. which the user overrode. Catalog versions are pinned per artifact via PinnedTechnique { artifactId, techniqueId, catalogVersion }; deprecation never breaks playback, and canReshareDeprecatedTechnique(...) returns true only when the pinned catalogVersion equals the current version — i.e. re-share of a deprecated-technique artifact requires a re-render against the current catalog.

Segment-Pair Compatibility Matrix#

Composition is not free-form. The compatibility scorer (scorer.ts, scoreSegmentPair) runs at composition time (when the user places a Segment) and at runtime (before the Blend Kernel executes), and gates Technique Picker availability. It is a pure function over its inputs — same pair → same scores — which is what makes the determinism release gate testable.

Scoring Dimensions#

The scorer computes seven per-dimension scores in [0, 1] (COMPATIBILITY_DIMENSIONS, scorer.ts:21-29); the composite is the simple mean of the seven (compositeOf, summed and divided by 7):

Dimension How it scores (real implementation)
style-anchor Exact ID equality: styleAnchorId === styleAnchorId ? 1 : 0.35. Not a CLIP-embedding distance (see accuracy notes).
motion-descriptor Exact equality: 1 if descriptors match, else 0.5.
audio-role Role-pair table: identical roles 1; narration↔ambient 0.85; music-bed↔silence 0.3 (harsh); any other mismatch 0.6.
narration 1 if narrationTone matches, else 0.5.
tone-band 1 if toneBand matches, else 0.4.
grounding Dice coefficient over groundingSourcePinHashes sets (both empty → 1). Real overlap measure: 2·|A∩B| / (|A| + |B|).
persona 1 if personaId matches, else 0.55.

The verdict is a discriminated union: hard-incompatible (policy block, technique-agnostic), soft-incompatible (composite below compositeThresholdSoft or below compositeThresholdCompatible, with a human-readable rationale like composite 0.421 below soft threshold 0.6), or compatible. Malformed inputs (non-finite or inverted thresholds, empty required fields) themselves return hard-incompatible with a reason — the scorer fails loud rather than scoring garbage.

Hard-Incompatible Pairs (Policy Gate)#

policyGate(...) runs before any dimensional scoring and short-circuits four classes of pair regardless of mechanical compatibility:

  1. Crisis ↔ non-crisis (crisisLabel !== 'safe' on exactly one side) without a fade-to-black recovery transition → hard-incompatible, reason "crisis ↔ non-crisis pair requires recovery transition (fade-to-black)".
  2. Pedagogical ↔ entertainment tone bands within the same Score → blocked.
  3. Tara contemplative ↔ forbidden technique: when templateId === 'tara-contemplative-arc' and the chosen transition is smash-cut, whip-pan, or jump-cut → blocked.
  4. Veritas mutually-retracted pins: under veritas-grounded-explainer, a pair where both segments cite only Sophia source pins present in retractedSophiaPinHashes → blocked (no CorrectionNote bridge).

Soft-incompatible pairs are surfaced as warnings with the rationale string; the user can override at AAA tier, never at customer tier, and overrides are audited. Promoted Scores carry the final scores so audit and replay can reconstruct why a technique was chosen.

AI Compose Assist#

The compose assist is a constrained agent that suggests next Segments, ranks candidate cinematographic techniques per pair, and explains its reasoning. It runs through Isis as an agent run with explicit budget caps, tool grants, and operator audit (see Agent Invocation, Budgets, Memory, and Feedback Loops).

  • Request shape (ComposeAssistRequest): { requestId, templateId, locale, tier, priorSegmentSummary, budget, grants }, where tier is one of contemplative | curated-creator | aaa-creator | operator-admin, budget is an AgentRunBudget { maxTokens, maxCostCents, maxLatencyMs }, and grants is AgentRunGrants { toolIds[], allowEgress[] }.
  • Suggestion shape (ComposeAssistSuggestion): a candidateSegment (styleAnchorId, motionDescriptor, audioRole, toneBand), an ordered rankedTechniques list where each TechniqueSuggestion carries a confidence: [low, high] band, a rationale string, and a continuityPreScore.
  • Budget enforcement: isBudgetExceeded(...) aborts the run the instant any observed metric (tokens / cost cents / latency ms) crosses its cap. Every assist call therefore produces an audit-reconstructable envelope.
  • Gating of suggestions: filterComposeAssistTechniqueSuggestions(...) runs every ranked technique through templateAllowsCompositionTechnique(...), so the assist can only offer a technique the destination template, crisis state, Metis-assessment lock, and Arete operator grant all permit.
  • Soft refusal is mandatory: softRefuse(reason) returns a { kind: 'soft-refusal', explanation } verdict — the customer-tier promise is that the assist must produce a viable suggestion or explicitly decline ("there isn't a clean bridge from here yet — try a different anchor"); silent failure is forbidden.
  • Champion–challenger gold sets: assist quality is tracked with evaluateGoldSet(...), which returns { precision, recall, refusalRate, correctRefusals, falseRefusals }. Precision is tp/(tp+fp), recall is tp/(tp+fn) (both default to 1 on empty denominators), and correctRefusals counts cases where a "should refuse" item was correctly declined, while falseRefusals counts viable bridges wrongly refused. gateChampionChallenger(...) promotes a challenger only when it meets the floor on all three top-line metrics and is no worse than the champion on each. Fixtures include high-compatibility golden paths, low-compatibility "should refuse" pairs, and adversarial intent traces that try to bypass tone gating, evaluated across V1 launch locales and per template.

Per-Template Availability and Tone Gating#

The catalog is identical across templates, but each template publishes its own technique allowlist and tone gating policy. The Customer Technique Picker only surfaces allowed entries. Compose Assist only considers allowed entries. The AAA-tier Scene Score Editor surfaces all entries but blocks promotion of a Score that uses a disallowed technique for the target template. The five canonical machine template IDs are tara-contemplative-arc, nyx-sky-briefing, veritas-grounded-explainer, metis-lesson-visualizer, and arete-living-offering (the friendly names "Tara Contemplative Arcs," etc., are display strings; the IDs above are the keys used in code).

Technique Tara Nyx Veritas Metis Arete
hard-cut
match-cut
l-cut
j-cut
dissolve
match-action
cross-cut
montage
fade-to-black
whip-pan
smash-cut
jump-cut

✓ allowed · — disallowed · ◆ operator-curated only (Arete).

The ◆ entries are the OPERATOR_CURATED_ARETE_TECHNIQUES set ({smash-cut, whip-pan, jump-cut}). For Arete, these three require operatorCuratedTechniqueGrant === true and strictestLilithToneBand !== true to be admitted; under the strictest Lilith tone band they are blocked outright. (whip-pan also appears on Nyx's standard allowlist, for "pan across the sky" — it is operator-curated only on Arete.) The same allowlist data is mirrored in two places that must stay in sync: the per-technique templateAllowlist[] in cinematographic-catalog.ts and the TEMPLATE_TECHNIQUE_ALLOWLISTS table in compose-assist.ts. They currently agree for all five templates, but they are a duplicated source of truth that can drift — a known maintenance hazard.

Enforcement Points and Crisis Collapse#

assertTechniqueAllowed(...) (tone-gating.ts) is enforced at three ENFORCEMENT_POINTScustomer-picker, compose-assist, and score-promotion — and evaluates gates in a deliberate precedence order:

  1. Crisis-frame collapse takes precedence over everything. When inCrisisFrame is true, the allowlist collapses to the CRISIS_COLLAPSE_ALLOWLIST{hard-cut, dissolve, fade-to-black} — for every template; anything else throws crisis-frame-collapse. The tests require this to happen within 1 frame of crisis-frame activation, and Compose Assist explicitly declines to suggest a continuation.
  2. Themis interlock for Metis. When the template is metis-lesson-visualizer and the Segment's node is in metisAssessmentLockedNodes, every technique is blocked (themis-assessment-locked) — you cannot cut into or out of an in-progress assessment item.
  3. Per-template allowlist — disallowed technique → technique-not-in-template-allowlist.
  4. Arete operator-curated guard — strictest Lilith tone → strictest-lilith-tone-block; missing grant → operator-curated-technique-required.

Tara additionally locks its tone-band swing to 0 (strictestToneBand: true in the template catalog), which is why match-cut/match-action are admitted only in their gentle forms and the high-energy techniques never are.

The Conductor Runtime State Machine#

A promoted Score is streamed by the Conductor (@yemaya/living-scenes-runtime/conductor/conductor.ts). The Conductor is pure scheduling logic; its header is explicit: "Actual GPU dispatch lives outside this module." It models each Segment as a SegmentSlot whose SegmentRenderState walks a fixed lifecycle:

text
pending → pre-warming → ready → streaming → done
                                          ↘ aborted
Function Role
initialiseConductor({ score }) Builds one SegmentSlot per Segment, all pending, seeds each slot's carryStateInbound from the Segment's inboundCarryState, playhead at 0.
planPreWarm({ state, nowUnixSeconds }) Marks pending slots in the window [playheadIdx+1, playheadIdx+minLookaheadSegments] as pre-warming. If backpressureActive, the lookahead truncates to 1 — only the immediate next slot pre-warms.
completePreWarm({ state, segmentId, ... }) pre-warming → ready; throws invalid-transition if the slot is in any other state.
advancePlayhead({ state, carryStateOutbound, ... }) Marks the current slot done with its outbound carry-state, then promotes the next slot to streaming — but only if it is already ready or streaming, else throws invalid-transition. Carry-state propagates: carryStateInbound = carryStateOutbound ?? next.carryStateInbound.
setBackpressure({ state, active }) Toggles the backpressure flag that throttles lookahead.
planReconnect({ state, atSegmentId }) Mid-segment reconnect: returns { resumable, resumeCarryState, reason }; resumable only if the slot is streaming or ready, in which case it hands back that slot's inbound carry-state for the client to resume from.

ConductorError codes are invalid-playhead, invalid-transition, missing-carry-state, segment-not-found.

Carry-State Handoff#

The continuity protocol the Conductor threads between Segments is the CarryState schema (score.ts:38-44), and it maps almost one-to-one onto the "CLIP-style style anchor / last-frame conditioning / motion-vector descriptor / color-LUT alignment / audio tail" the customer promise describes — but with concrete field names and constraints:

Field Constraint
clipAnchorAssetId non-empty string
lastFrameConditioningHash matches /^[0-9a-f]{32,}$/ (≥ 32 hex chars)
motionDescriptor 1–120 chars
lutId non-empty string
audioTailDescriptor 1–120 chars

Render Envelope Pins the Reproducibility Frame#

planPreWarm reads minLookaheadSegments straight off the RenderEnvelope (score.ts:91-107), which is far richer than "engine version + model hashes" prose. Every field is a literal union, so an out-of-range value fails at parse time:

Field Type / allowed values
envelopeId, displayName strings (≤ 120 chars for display name)
widthPx literal 1080 | 1440 | 1920 | 2560 | 3840
heightPx positive int ≤ 7680
fps literal 24 | 30 | 60
maxBitrateKbps positive int
gpuClass literal rtx-4090 | a100-40gb | a100-80gb | h100-80gb
minLookaheadSegments literal 2 | 3 | 4

The lookahead is also a release-gate invariant: deepParseScore (score.ts:151-168) re-checks minLookaheadSegments < 2 after schema parsing and throws "renderEnvelope must require ≥ 2 lookahead segments" — a belt-and-suspenders guard so no Score can stream with too little pre-warm headroom even if the literal union were widened. deepParseScore also enforces segment-id uniqueness and that every cue's appliesToSegmentId resolves to a real segment (or the wildcard *).

Live Direction Channel Telemetry — Scene Events#

The Conductor's decisions and the policy interventions around them surface to the viewer and the Score editor as a uniform, traceable event feed on the Psyche envelope (scene-events.ts). There are eight SCENE_EVENT_KINDS:

Event Payload highlights
scene.segment-start segment ref, plannedDurationSeconds, engineVersion, workflowClassVersion
scene.segment-end actualDurationSeconds, endReason ∈ {planned, cue-advance, cue-abandon, policy-cut}
scene.transition-start fromSegment/toSegment, techniqueId, overlapWindowSeconds
scene.transition-end techniqueId + a continuityScorecard { fvd, flicker, colorJump, motionVector }
scene.live-direction-applied cueVerb, cueArgs, cueChannel ∈ {voice, tap, text}, target segment
scene.policy-intervention interventionKind ∈ {pse-strobe-cap, luminance-cap, motion-cap, tone-band-shift, persona-cap}, pre/post values, policyVersion
scene.crisis-frame crisisLabel (8 labels from safeself-harm-imminentcrisis-other), probability, enteredAtUnixMillis
scene.fallback-engaged fallbackKind ∈ {reduced-motion-render, still-image-only, transcript-only, audio-with-still, pre-rendered-substitute}, trigger ∈ {provider-degraded, policy-rejection, eval-gate-fail, shareability-restriction}

verifyEventStream(...) enforces a monotonic, gap-free sequence (each sequence must be exactly last + 1) and a single trace-id across the whole stream (a mid-stream trace-id change throws trace-id-missing), so audit replay can prove the feed is complete and un-interleaved.

Continuity-Eval Extensions for Named Techniques#

The base Continuity Eval suite (FVD, flicker, color-jump, motion-vector, narration-time) generalizes across all transitions. Named techniques supplement those with their own catalog evalThresholds (the table in V1 Launch Catalog) — they never replace the base evals:

  • match-cut carries the tightest maxFvd (0.30) and maxMotionVectorDelta (0.30) of the cinematic cuts, reflecting its shape/motion-continuity demand.
  • l-cut / j-cut demand the highest narration alignment (0.94), because audio leads or lags the visual and captions must align to the audio boundary (their accessibilityNotes spell out which side captions follow).
  • whip-pan allows the loosest motion-vector delta (0.70) because the technique is high-magnitude motion; under reduced motion it falls back to fade-to-black. A too-gentle whip pan is, by intent, the wrong technique.
  • jump-cut allows the loosest FVD (0.60); it is restricted to cinematic / entertainment bands and forbidden in contemplative and pedagogical bands.
  • montage is the only technique whose reduced-motion fallback is still-frame, and its accessibilityNote requires audio description per visual change.
  • fade-to-black verifies the tightest flicker (0.03) and a high narration alignment (0.92), since it is the section-break / recovery transition.

Per-technique gates are enforced at composition-draft promotion and at runtime before the Blend Kernel executes; below-threshold transitions surface as warnings at customer tier or block promotion at AAA tier, and every failure is logged with the failing metric so Compose Assist can learn from it.

Tara Sub-Variants — A Worked Example#

The Tara Contemplative Arc template ships five sub-variants (TARA_SUBVARIANTS, template-catalog.ts:18-24), each with a concrete, deterministic BreathCycle (tara.ts) of { inhaleSeconds, holdInSeconds, exhaleSeconds, holdOutSeconds }:

Sub-variant Inhale Hold-in Exhale Hold-out Cycle total
loving-kindness 4 1 6 1 12 s
body-scan 4 0 8 0 12 s
breath-anchor 4 4 4 4 16 s (box breathing)
nature-immersion 5 0 7 0 12 s
gratitude 4 1 6 1 12 s

breathCycleSeconds(...) simply sums the four phases, and the Tara template constrains its allowed cue verbs to {linger, advance, save-moment, abandon, kill} with strictestToneBand: true and reducedMotionVariantRequired: true. This is why the composition surface for a Tara Score offers only the gentle technique set and locks tone-band swing to 0.

Eval Gates and Tests#

Every template is held to a fixture-based eval gate (TEMPLATE_EVAL_GATES, template-catalog.ts:147-199). All five require a minimumFixtures of 30, a crisisTrigger pass rate of 1.0 (no crisis trigger may ever be missed), and a localeParity floor of 0.90; the rest vary by template:

Template golden adversarialCue accessibilityParity groundingCorrectness
tara-contemplative-arc 0.95 0.98 0.95 — (none)
nyx-sky-briefing 0.95 0.97 0.95 0.92
veritas-grounded-explainer 0.97 0.99 0.97 0.97
metis-lesson-visualizer 0.95 0.97 0.97 0.95
arete-living-offering 0.95 0.99 0.95 — (none)

Veritas carries the strictest golden, adversarial, and grounding thresholds, reflecting its claim-grounding burden; Tara and Arete have no grounding gate (groundingCorrectness: null) because they are not source-pinned.

The test coverage backing this page (across the libraries above and the BFF):

  • Catalog round-trip and contract conformance across all twelve entries; the twelve provenanceTags are grep-confirmed.
  • Compatibility-scorer determinism (same pair → same scores), since it is a pure function.
  • Per-template allowlist enforcement at all three enforcement points; every disallowed technique is rejected by the Technique Picker, Compose Assist, and Score promotion.
  • Crisis-frame collapse to {hard-cut, dissolve, fade-to-black} within one frame.
  • AI Compose Assist gold-set evaluation (precision, recall, refusalRate, correctRefusals, falseRefusals) across V1 launch locales.
  • Hard-incompatible pair coverage (every documented pair detected and blocked).
  • Reduced-motion fallback substitution per the REDUCED_MOTION_TECHNIQUE_FALLBACKS table.
  • Scene-event stream verification: monotonic gap-free sequence + single trace-id.
  • The customer scene viewer and BFF: apps/oshun/bff/src/routes/living-scenes.ts is ~1,871 lines of real keep / share / idempotency logic, exercised by scene-viewer-deepening.spec.ts, living-scene-card.spec.ts, and public-scene-abuse-report.spec.ts (per the v1 triage walkthrough).
  • Determinism: a composed Score re-rendered under the same Envelope produces a pixel-equivalent video within Isis-defined tolerance — a release gate (§25.9).

Accuracy Notes (Real vs. Aspirational)#

Two points where the older prose overstated the implementation, corrected here so the page matches the code:

  • Style-anchor "distance" is exact-ID equality, not CLIP-embedding distance. The real styleScore (scorer.ts:75-77) returns 1 when styleAnchorId matches and 0.35 otherwise; motionScore is likewise 1 vs 0.5 exact equality. The "CLIP-region embedding similarity ≥ 0.78" and "motion-vector alignment ≥ 0.80" figures the prose attaches to match-cut/match-action are catalog eval thresholds the downstream renderer is checked against, not embedding distances computed in this pure module. The compatibility scorer is deliberately string-grounded so it stays deterministic and dependency-free.
  • Segment fields are not the 13-field prose list. The real SegmentSpec (score.ts:47-60) is { segmentId, kind, displayName, durationSeconds, tone, workflowClassId, parameters, inboundCarryState }. intent lives on the Score (ScoreIntentLayer, with private/public-redacted text and a redaction-category list), not the Segment. Transitions are not stored on Segments (they are decided at boundaries). Grounding, persona, and accessibility role are not Segment fields. See Scene Score Schema for the full authoritative schema.

The entire pixel/frame layer — actual latent video generation, optical-flow warps, FVD computation, GPU-deterministic rendering — is aspirational relative to these modules: it is modeled as score inputs the pure functions consume, and its implementation lives downstream of the contracts documented here. Honest "planned/gated downstream" is the accurate posture; the decision logic on this page is shipped and tested.