Place prepared Takes on an independent Timeline with gaps and overlaps. Present picture, sound and captions through explicit Use rules while preserving source timing and project-authored styles.
Unify Companion bands, parameter ownership and source writeback in Studio. Migrate components, examples and authoring guidance, remove retired Speech/Semantic Track interfaces, and retain protocol identifiers at @1.
Validation: repository suite (786 tests; six sandbox-blocked tests passed on permitted rerun), 43 Studio tests after audit fixes, TypeScript, public declarations, four example-package builds, chat Source check and npm file inventory.
Speech publishes semantic timing and original audio. Media Performance and project components consume the prepared material, preserving source offsets across Takes while controlling their own framing and motion.
Add explicit renderer programs for coordinated HTML/CSS/JavaScript scenes, with typed media children, backdrop filtering and blending. Remove stand-in and estimated-take preview paths, migrate Sources and documentation, and demonstrate a Moment-driven video-to-diagram handoff.
Center image direction on decisive prompts and tested capture language, make generated-video craft model-neutral, and complete Script and Caption semantics with direct discovery from the Skill entrypoint.
Delete packages/reference-video-tools: the route/revision/variant state
machines, pending_observations, the check gates, layout_accept,
render_element (a Build outside Build), render_previews (posters are
designed, not rendered) and the per-video global cache tree. What an
agent needs outside a Build survives as dumb local commands in video-cli:
hypit media probe/cut/frames/tile/shots/fetch and hypit vocabulary.
Drop the four-word cue rule from @hypit/script; cue breaks are craft,
fit is the caption component's own knowledge. @hypit/yt-dlp writes to
the file the caller names. Prompts and measured parameters are kept
verbatim in .agents/development/observation-knowledge.md for the Skill.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The three example package locks conflicted: both sides had regenerated
them. Neither side's digests were still correct, since the merged tree
combines their source refactor with the license field added to every
manifest, so the locks were rebuilt from the merged bytes rather than
resolved by picking a side.
Every workspace manifest omitted a license field, so a scanner reading
the published repository would resolve all 90 of them as unknown. Both
Python services went further and declared plain Apache-2.0, which is
looser than the LICENSE they actually ship under.
Package bytes feed the example package locks, so adding the field
invalidated all three; refreshed them. Only closureDigest and artifacts
move — same 31 selected packages, nothing added or removed.
Also record what the READMEs never said: ffmpeg is a real prerequisite
for a Build and had zero mentions, and the media Lambda layer is a GPL
FFmpeg build. That build is deliberate — libx264 is GPL-only and the
encode path requires it — and it stays lawful only because the operator
builds and deploys it into their own account. Publishing a prebuilt
layer would break that, so the boundary is now written down.
Rename the author frontend around Markup, replace PromptKit with graph-native Text templates, and keep video typography in its own package. Wire ordinary Text through explicit graph edges into model and visible consumers, refresh examples, locks, tests, and architecture documentation.
A Script marker names one of the 2M+2N anchors the Script defines, and Token
cuts and Segment cuts are equal citizens there. Three consumers each recomputed
that from a token index instead, and two of them got it wrong: outward markers
took the whole neighbouring word rather than snapping to its far edge, and a
marker at the head of a Segment reached back into the previous Segment, whose
end may sit at a different time.
The parser now resolves each marker's affinity once, where the surrounding
structure is known, and records the anchor on the boundary. Locating is a
lookup, Segment cuts become reachable, and a Caption Selection's token range
stops depending on affinity, which never moved words in the first place.
Moment becomes consumable: it publishes a referenceable NarrativeMoment and
momentFrames locates one instant per occurrence, mirroring selectionFrameSpans.
The map keeps anchors, segments and tokens. groups, durationSec and
quantizationPolicy had no consumer; the alignment classification they carried is
now asserted directly against alignWordGroups, one layer closer to the code.
The umbrella video-contracts package collapsed eight unrelated
vocabularies into one release unit. Public video communication now
lives in small, independently versioned contract packages: narrative,
media, program-space, speech, speech-evidence, semantic-map, visual-ir
and composition. Speech implementation packages are renamed for what
they do (speech-spine, speech-basis, speech-alignment), realization
folds into run, and hyperframes-render becomes render-hyperframes with
a renderer-neutral Visual IR spec. Every model package gains a direct
activation entry, and shared video test fixtures move to test-support.
Example package locks are regenerated for the decomposed closure; the
graph-check, live, echo-pro-aroll and bootstrap sources all compile
against the new package set.
The package holds Narrative, Media, ProgramSpace, Speech, SemanticTime,
Track, Composition and HyperFrames Visual IR contracts — all video
domain vocabulary. A domain-neutral name overstated its scope and
collided with the repository's own naming discipline. Example locks are
regenerated for the new package identity.
Also removes three empty untracked directories left from earlier
package drafts (provider-kit, prelude-video, video-fragments).
Narratage (narration + montage) is the project, framework, npm scope
(@narratage/*) and CLI command. SVML remains the name of its markup
language, so file suffixes (.svml/.svs/.svrun), source Headers and
svml.* wire format ids are intentionally unchanged. Example locks are
regenerated because package manifests participate in artifact digests.
The exploratory root compiler never shipped, so version-numbered
narration only confused the current single implementation. Doc and spec
filenames drop their -v1 suffix, titles drop v1, prose describes the
present system, the v2-bootstrap example becomes bootstrap, and the CLI
usage/scripts are plain svml. Package locks are regenerated because
package README bytes participate in artifact digests.
Script Surface's own v1 target statements remain: that spec genuinely
defines its first public version.