Skip to content

Core source-media policy module: availability, tri-state, duration, failure tiers (source-media issue 06) - #17

Merged
lenxism merged 2 commits into
mainfrom
feat/source-media-06-core-policy
Jul 14, 2026
Merged

Core source-media policy module: availability, tri-state, duration, failure tiers (source-media issue 06)#17
lenxism merged 2 commits into
mainfrom
feat/source-media-06-core-policy

Conversation

@lenxism

@lenxism lenxism commented Jul 14, 2026

Copy link
Copy Markdown
Owner

What & why

Implements source-media issue 06 (.scratch/source-media/issues/06-core-source-media-policy.md): a pure core/ policy module (src/core/source-media.ts) owning every source-media decision a formula could get wrong, so the scene/ui layers hand it plain facts and obey. The mediabunny / canDecode() plumbing stays in scene/ui; this module only consumes their results as plain data.

It decides:

  • Video-export availabilityresolveVideoExportAvailability(document, facts): available when the document has an Animation OR the bound Source Media is a decodable video (supersedes "requires an Animation"). Unavailability carries a reason (nothing-to-export vs undecodable-video) so issue 08 can render the disabled state vs the persistent codec notice. Deliberate ambiguity resolution (recorded in the PRD + ticket): a bound playable-but-undecodable video blocks video export even alongside an Animation — the deterministic export loop cannot decode its frames.
  • Tri-state import classificationclassifySourceVideoImport: decodable / preview-only / rejected from the probe's playable/decodable facts.
  • Export-duration resolutionresolveVideoExportDuration: Animation duration when one exists (video truncates); else the video duration clamped to VIDEO_EXPORT_DURATION_CAP (derived from ANIMATION_DURATION_LIMIT.max), guarding non-finite durations to the cap and non-positive to 0.
  • Failure-tier mappingresolveSourceMediaFailureTier: reject-at-import / preview-only-notice / abort-export.

Unblocks issues 07 (deterministic video export) and 08 (availability + no-Animation export).

Checklist

  • pnpm typecheck && pnpm lint && pnpm test && pnpm build green locally
  • New core/ behavior covered by behavior-level Vitest tests (24 tests, red→green: availability truth table, tri-state, 30 s clamp + frame-count consequences, failure tiers)
  • scene/ / ui/ changes verified in the browser (screenshot below) — n/a, core-only slice
  • Uses CONTEXT.md vocabulary in names and types
  • core/ stays free of react/three imports (ESLint boundary)
  • If this PR bundles a device model — n/a

Evidence

Core-only, no visual change. src/core/source-media.test.ts: 24 passing behavior-level tests; full suite 467 green.


Note

Low Risk
Core-only pure functions and tests; no runtime or UI integration yet, so production behavior is unchanged until follow-up issues wire it in.

Overview
Adds a pure core/source-media policy layer so scene/UI can pass probe/facts and follow fixed rules for video export and import UX.

Video export availability (resolveVideoExportAvailability) now allows export when there is an Animation or a decodable bound video (replacing the old “requires an Animation” rule). Undecodable-but-playable video blocks export even with an Animation, with reason undecodable-video vs nothing-to-export for the export panel.

Import gets tri-state classifySourceVideoImport (decodable / preview-only / rejected) from playable+decodable probes; export length uses resolveVideoExportDuration (animation duration wins; otherwise video duration clamped to VIDEO_EXPORT_DURATION_CAP, tied to ANIMATION_DURATION_LIMIT.max). resolveSourceMediaFailureTier maps import/export failures to toast tiers (reject, preview-only notice, abort export).

New types and helpers are re-exported from core/index. Behavior is covered by source-media.test.ts (availability table, classification, duration edge cases, failure tiers).

Reviewed by Cursor Bugbot for commit 9cd3642. Bugbot is set up for automated code reviews on this repo. Configure here.

lenxism added 2 commits July 13, 2026 23:38
…ailure tiers (source-media issue 06)

Pure core module owning every source-media decision a formula could get
wrong; scene/ui hand it plain facts (the document + a SourceMediaFacts
projection of the ephemeral media record) and obey. Decides video-export
availability (Animation OR decodable video; an undecodable bound video
blocks with a codec reason even alongside an Animation), the decodable /
preview-only / rejected import tri-state, export duration (Animation
duration, else video duration clamped to the 30 s cap), and the
failure-tier mapping for the toast UX. Behavior-level tests red-to-green;
existing export math untouched.
Review follow-up: the 30 s cap and the Animation duration clamp are the
same ceiling and must not drift apart, so the constant now references the
limit instead of repeating the literal.
@vercel

vercel Bot commented Jul 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mockstudio Ready Ready Preview, Comment Jul 14, 2026 2:50am

@lenxism
lenxism merged commit 3a28876 into main Jul 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant