Context. surface mobile · domain atelier · route /compose · auth anon (paid-tier framed in copy; no gate enforced in code) · source apps/oshun/mobile/app/compose.tsx
Last walked. not yet walked
Purpose#
Compose is a Yemaya living-scenes composition surface: a segment library, an ordered timeline with per-segment transition-technique pickers and reorder controls, a scrub preview, a Compose Assist suggestion inserter, a reduced-motion technique summary, and an audit trail. It is a standalone stack screen (not a tab) and is purely in-memory — no persistence or network.
Entry points#
- Direct route
/compose(not declared in_layoutStack screens nor the tab bar; reachable byrouter.push('/compose')/ deep link). - No shell-nav tab or visible launcher found in the audited screens.
Layout regions#
- Header (in-screen): kicker "Studio", title "Compose", meta
(
mobile-compose-meta: "Paid tier · N Segments · Ns"). - Main (vertical
ScrollView,mobile-compose-surface): panels — Segment library (mobile-compose-segment-library), Timeline (mobile-compose-timeline), Scrub preview (mobile-compose-preview), Compose Assist (mobile-compose-assist), Reduced motion (mobile-compose-reduced-motion), Audit trail (mobile-compose-audit-log). - Footer / sticky bottom: none (no tab bar on this stack route).
States#
- Loading — N/A: synchronous in-memory state from
INITIAL_SEGMENTS. - Empty — not reachable: starts with 3 frozen segments; no delete control.
- Populated (short) — 3+ segments; Accept suggestion appends more.
- Populated (long) — appended
seg-assist-Nsegments grow the timeline. - Error — N/A: no async paths.
- Offline — fully functional offline (no network).
- Permissions-denied — N/A: no device permissions.
- Gated — copy says "Paid tier" but no entitlement check is enforced here.
- iOS vs Android — light theme (
#f6f8fb); no safe-area handling; this screen uses a light palette unlike the dark shell tabs.
Interactions#
- Library item (
mobile-compose-source-<segmentId>, Pressable)- Function:
setPreviewSegmentId(segment.segmentId). - Accessibility: role button, label "Preview
from ".
- Function:
- Timeline item (
mobile-compose-segment-<segmentId>, Pressable)- Function: tap → preview that segment; long-press → open the boundary Technique Picker + audit entry.
- Gesture/touch: tap (preview) AND long-press (picker).
- Accessibility: label "
, s, "; hint "Long press to open the boundary Technique Picker."
- Move up (
mobile-compose-move-up-<id>, Pressable)- Function:
moveSegment(index, -1)+ audit. Disabled whenindex === 0. - Accessibility: role button, label "Move
up". Touch target 44×40.
- Function:
- Move down (
mobile-compose-move-down-<id>, Pressable)- Function:
moveSegment(index, 1)+ audit. Disabled at last index. - Accessibility: label "Move
down".
- Function:
- Technique pill (
mobile-compose-technique-<id>-<techniqueId>, Pressable)- Function:
setTechnique(segmentId, techniqueId)(closes picker + audit). Options limited toALLOWED_TARA_TECHNIQUES(filterComposeAssistTechniqueSuggestionsfortara-contemplative-arc). - Accessibility: role button; label = technique label.
- Function:
- Accept suggestion (
mobile-compose-assist-accept, Pressable)- Function:
acceptSuggestion— appends amatch-actionCompose Assist bridge segment, previews it, audits. accessibilityLabel "Accept Compose Assist suggestion".
- Function:
Data & contracts#
- Reads:
@yemaya/living-scenes-runtime/compose-assist(V1_COMPOSITION_TECHNIQUE_IDS,filterComposeAssistTechniqueSuggestions,reducedMotionTechniqueFor,CompositionDraftSegment). - Writes: in-component state only (
segments,previewSegmentId,auditLog,activePickerSegmentId). No persistence. - Realtime: none.
- Telemetry: none wired.
- Auth/role check: none enforced (copy references paid tier only).
Cross-references#
- Tests:
apps/oshun/mobile/app/compose.test.tsx. - Runtime lib:
@yemaya/living-scenes-runtime/compose-assist. - Stack shell: not registered in
_layout.tsxStack screens (file-based route).
Open questions / known gaps#
- No entitlement gate despite "Paid tier" copy — confirm whether a paywall
should guard
/compose. - No visible launcher/entry point in the audited shell — confirm how users
reach
/compose. - No persistence/export of the composition — drafts are lost on unmount.