filmcraft · git:20261026.76415fe · 2026-10-26 · sha256 c7894901a48bc327

filmcraft git:20261026.76415feA

Immutable. This exact content never changes and is served at /api/v1/blob/c7894901a48bc327.

---
name: filmcraft
description: FilmCraft is an open-source, professional non-linear video editor (editing, multicam, colour, effects, titles, captions, audio mixing, export) written in pure Rust, mirroring Adobe Premiere Pro's workflow, for macOS/Windows/Linux and the web. Trigger this skill whenever the user mentions FilmCraft (or "fcproj"/".fcproj", "filmcraft-cli", the FilmCraft control channel or MCP server, "window.filmcraft"), asks what it can or cannot do, which formats it reads or writes, how to script or automate it, how to prepare or convert media for it, how to verify or repair its exports and project files, or troubleshoot it — and also when they never name the app but describe the job — "cut this footage", "make a rough cut", "export an H.264 MP4", "grade this clip", "add captions to this video", "hand an EDL/AAF to an editor", "drive a video editor from an agent". Prefer this skill over generic NLE knowledge for anything FilmCraft touches; do not assume Premiere-only capabilities (`.prproj` import, plug-ins, upload destinations) exist here.
---

# FilmCraft

**Audit basis:** this checkout is tag `v0.13.0`, commit `30536bc5d0ddf690f2181b7b97182db8658a6038` (detached shallow clone, release commit 2026-10-25). The installed `/Applications/FilmCraft.app` reports version `0.13.0`, its Info.plist records `FilmCraftBuildCommit` = the same commit, and `Contents/MacOS/FilmCraft --version` prints `filmcraft 0.13.0`, so the bundle matches this source. **Verify against your installed version** if the ArtCraft Launcher has auto-updated since. Deep detail lives in `references/cli-and-protocol.md` (CLI, control channel with its new token auth, MCP, command cheat sheet) and `references/formats.md` (import/export tables, `.fcproj`, interchange).

## Overview

FilmCraft is an open-source professional non-linear video editor written from scratch in Rust: its panels, workspaces, tools and shortcuts mirror Adobe Premiere Pro, and its codecs, containers and renderer are its own (README.md; clean-room rules in `AGENTS.md` §2 — ffmpeg is used only as an external test oracle). The parity target is Premiere Pro 2026 **26.5.2**, tracked in `docs/target-app-parity.md`, and the project calls itself **alpha** with an author-measured **~86 % feature breadth / ~56 % ready for real work** (README.md "Status"; `docs/target-app-parity.md:15,173` — measurements, not re-measured here). It runs natively on macOS, Windows (x64/arm64/x86), Linux (x86_64/aarch64/riscv64), as a FreeBSD 14 x86_64 tarball, and in the browser via WebAssembly (`README.md` Downloads; `apps/filmcraft-web`, `docs/web.md`). The engine is headless and command-driven: the egui UI, `filmcraft-cli`, a JSON-lines control channel and an MCP server dispatch the same command ids (`docs/architecture.md` §1; `crates/engine/src/commands.rs`). Source: GitHub `storytold/filmcraft`.

0.13.0 is a large release (+9 577/−10 972 lines over 521 files since v0.11.0): MP4/MOV, Matroska/WebM and bit-level I/O moved into the shared `craft-media` crate (craft-libs), the test tree was reorganised, and the visible editor gained a **work area bar**, **duplicate-frame markers**, caption razor/duplicate/copy-paste, History-panel pruning, animated WebP import, Fujifilm F-Log/F-Log2, and **mandatory control-channel authentication**.

## Capabilities (verified)

### Editing (implemented)

- Three-point editing: Source monitor In/Out → `source.insert` (`,`) / `source.overwrite` (`.`); `sequence.lift` (`;`) / `sequence.extract` (`'`). Trim tools and modes: ripple, roll, slip, slide, rate-stretch, razor (`timeline.razor`), Trim Monitor plus deterministic dynamic trimming (`trim.shuttle` / `trim.tick` / `trim.shuttleStop` / `trim.playAround`; `crates/engine/src/trim.rs`, `crates/ui-egui/src/panels/trim_monitor.rs`).
- Add Edit (⌘K), ripple delete/close gap, nesting, markers with colour/name/duration and `markers.exportCsv` (UTF-8 CSV; 100 000-marker and 16 MiB caps — `crates/engine/src/marker_export.rs:11-12`), scene edit detection, subclips, sync/merge clips, multicam source sequences with live angle switching (`crates/engine/src/multicam.rs`; `multicam.selectCamera1..9` generated by `camera_keys!`, `crates/engine/src/multicam.rs:53`).
- **Exact integer time**: 254 016 000 000 ticks per second (`crates/time/src/lib.rs:20`); commands accept `ticks`, `seconds`, `frame` or `timecode`.
- Undo is copy-on-write snapshots with a **200-step history limit** (`s.history.limit = 200`, `crates/engine/src/commands.rs:1187`, `:4525`); continuous gestures merge into one step. **New in 0.13.0**: History-panel pruning — `history.deleteRedoable` (deletes the redo stack; Backspace in the Premiere preset, and the panel asks OK first) and `history.clear` (`crates/engine/src/commands.rs:1671-1672`, `crates/engine/src/lib.rs:247-260`, `crates/ui-egui/src/panels/misc.rs`). Neither changes the project.
- **New in 0.13.0 — work area bar**, closing the v0.11 gap: `sequence.workAreaBar {show?}` (Timeline panel menu checkbox), `sequence.setWorkAreaIn` (Alt+[) / `sequence.setWorkAreaOut` (Alt+]) / `sequence.setWorkArea {start,end}` in ticks (`crates/engine/src/commands.rs:2334-2385`; UI bar and hit-testing `crates/ui-egui/src/panels/timeline.rs`, docs `docs/keyboard.md` "Work area" row, tests `crates/engine/src/work_area_tests.rs`, `crates/ui-egui/tests/it/timeline_work_area_ui.rs`).
- **New in 0.13.0 — duplicate-frame markers**: `sequence.showDuplicateFrameMarkers {on?}` and the query `sequence.duplicateFrames` (per clip: colour index, timeline ranges) computed by `duplicate_frames` (10 colours, 1 000 000-frame budget; `crates/engine/src/sequence_tools.rs:113-130,428`), drawn as coloured stripes with `timeline.duplicateFrames.<clip>.<n>` automation ids.
- Four shortcut presets (FilmCraft Default, Premiere Pro Compatible, Final Cut Pro Compatible, Avid Media Composer Compatible; `BUILTIN_PRESETS`, `crates/engine/src/shortcuts.rs:63`).
- **9 built-in workspace layouts** in `WORKSPACES` (`crates/ui-egui/src/dock.rs:180`): Editing, Assembly, Color, Effects, Audio, Captions and Graphics, Learning, Review, All Panels — 7 of them in the Window ▸ Workspaces menu (`crates/ui-egui/src/menus.rs:113-119`), Learning and Review keyboard-only at Alt+Shift+7/8 (`crates/ui-egui/src/panels/keyboard.rs:69-70`). **28 dockable panel kinds** (`PanelKind::ALL`, `crates/ui-egui/src/dock.rs:46-76`); docking/floating is scriptable (`window.dockPanel`, `window.floatPanel`, `window.dockAction`).

### Colour, effects, motion (implemented; some effects approximate)

- Lumetri-style colour: Basic Correction, Creative looks, RGB + hue/sat/luma curves, three-way wheels, HSL Secondary, Vignette; LUT import/export for `.cube` (1D/3D/shaper) and `.3dl` (`crates/engine/src/color.rs`, `crates/color/src/lut.rs`).
- **10 camera log curves** — S-Log3, V-Log, Canon Log 2/3, LogC3, LogC4, Apple Log, D-Log, and **new in 0.13.0** Fujifilm F-Log and F-Log2 (`LogCurve::ALL`, `crates/color/src/log.rs:52-63`).
- **93 video effects across 16 folders** (test `premiere_26_video_effects_catalogue`, `crates/project/src/effect/vfx.rs:1251-1263`); **53 audio effects** (`PREMIERE_AUDIO_EFFECTS`, `crates/project/src/effect/audio.rs:578`); **84 video transitions + 21 Legacy** in 10 folders (`crates/project/src/vtransition.rs:413-417`); **27 blend modes** (`BLEND_MODES`, `crates/project/src/effect.rs:144`; the README still says "26").
- Keyframes: linear, Bézier, auto/continuous Bézier, hold, ease in/out; value and velocity graphs; keyframable effect parameters, masks and graphic properties (`crates/project/src/keyframe.rs`, `crates/engine/src/masks.rs`, `docs/graphics.md`).
- **New in 0.13.0**: `effects.setParam` now refuses a value outside the parameter's published hard range instead of saving it (`crates/engine/src/commands.rs:3186-3193`), and the Export format list greys out formats this machine cannot encode with the reason instead of failing at export time (`crates/ui-egui/src/panels/export_mode.rs`, fn `unavailable_why`).
- Compositing: wgpu GPU compositor (Metal/Vulkan/DX12/WebGPU) with a CPU reference renderer (`crates/gpu`, `README.md` "Effects and motion"). **Approximate, not exact**: Warp Stabilizer is 2-D, Morph Cut has no face tracking (`docs/gaps.md` G18); AI effects (Object Mask, Generative Extend) do not exist (G12).

### Audio (implemented)

- Loudness meters to ITU-R BS.1770 / EBU R128 (momentary/short-term/integrated + true peak), matching ffmpeg's `ebur128` to 0.1 LU per the authors' measurement (README.md "Audio").
- Own DSP: EQ, filters, dynamics, true-peak limiter, delay, reverb, DeNoise, DeHummer, pitch shift; keyframable, latency-compensated (`crates/audio-dsp`).
- Audio Track Mixer / Clip Mixer with faders, pan, five insert slots per track, sends, submixes, and Read/Latch/Touch/Write automation (`crates/engine/src/mixer.rs`, `docs/control-protocol.md`). **New in 0.13.0**: the mixer's Show/Hide Tracks… and Meter Input(s) Only are commands — `mixer.showHideTracks` (Cmd+Alt+T) and `mixer.meterInputOnly` (Ctrl+Shift+I), UI-only ids (`crates/ui-egui/src/panels/mixer.rs:226-240`, `crates/engine/src/shortcut_presets.rs:356-357`).
- Essential Sound (Dialogue/Music/SFX/Ambience, loudness auto-match, ducking that writes keyframes) via `essentialSound.*` (`crates/engine/src/essential_sound.rs`).
- Audio-clock playback and voice-over recording with punch-in (`crates/engine/src/voiceover.rs`); a failed/lost audio output is reopened every 2 s while playing (`AUDIO_RETRY_S`, `crates/ui-egui/src/lib.rs`).

### Titles, graphics, captions, transcripts (implemented, with build gates)

- Text engine (OpenType shaping, kerning, ligatures, bidi), Type/Shape/Pen tools, graphic clips with text/shape layers, `.fcgt` graphics templates (`crates/text`, `crates/engine/src/graphics.rs`, `crates/engine/src/graphic_templates.rs`). `.mogrt` is refused by design (`docs/target-app-parity.md`).
- Caption tracks in Subtitle / CEA-608 / CEA-708 / Teletext (`crates/project/src/caption.rs`). Import and export **7 formats** — SRT, WebVTT, SCC, MCC, EBU STL, TTML, DFXP (`Format::ALL`, `crates/captions/src/lib.rs:49`) — plus burn-in and SRT/VTT sidecars (`burnCaptions`, `captionSidecar`; `crates/engine/src/export_tools.rs:277,315`).
- **New in 0.13.0 — caption editing**: the Razor tool cuts captions (Shift = every caption track), ⌥-drag duplicates them (`captions.duplicate`, copies on their own tracks overwriting what is there), and Edit ▸ Copy/Cut/Paste/Paste Insert carry captions when only captions are selected (`crates/engine/src/captions.rs:169-230`, `edit.copy`/`edit.cut` accept clips-or-captions, `crates/engine/src/commands.rs:1673-1697`); the Text panel caption list follows the playhead (`crates/ui-egui/src/panels/text.rs`, `docs/captions.md`).
- Text-based editing: `transcript.*` commands work, **but recognition needs a `whisper` build**; official releases pass no `--features`, so `transcript.generate` returns "speech-to-text is not available in this build" (`crates/engine/src/transcript.rs:59-61`; `packaging/macos/package.sh:61`). Import a transcript with `transcript.set`.
- Text-to-speech narration: `tts.*` with built-in Basic Female / Basic Male formant voices; Kokoro-82M neural voices need the `kokoro`/`neural-voices` feature (off in releases) plus a model download (`crates/tts/src/lib.rs:50`, `apps/filmcraft/Cargo.toml:18`).
- Interface localisation: English + 11 catalogues (de, es, fr, id, it, ja, ko, pt-BR, ru, uk, zh-CN; `crates/ui-egui/src/i18n/`). Missing translations show English and no longer fail a build (`cargo xtask i18n-report`; `docs/localization-parity.md`).

### Import and open (implemented — exact lists)

- Extension lists are code, not docs: `STILL_EXTENSIONS`, `AUDIO_EXTENSIONS`, `VIDEO_EXTENSIONS` (`crates/media/src/lib.rs:175-179`; unchanged from v0.11.0).
- Container openers, in order: MP4/MOV, Matroska/WebM, MXF, Ogg, MPEG-TS/PS + MPEG-1/2 ES, APV, AVI, Y4M, standalone audio (`crates/codecs/src/lib.rs:134-137`); plus a streaming `reader_openers` registry for platform sources (`:157-165`). Stills/WAV/animated images fall back in `crates/media`.
- **New in 0.13.0**: animated **WebP** joins animated GIF and APNG as importable movie clips with transparency (`crates/media/src/animated.rs:1-118`; README formats table).
- Video decoded: H.264 (8-bit 4:2:0 software; High 10/4:2:2 only through OS hardware), HEVC Main/Main 10, VP8, VP9, AV1, ProRes, DNxHD/HR, MPEG-2/1, MJPEG, APV, uncompressed; VP9/Opus/AV1 also from MP4 (`docs/codec-parity.md:18-24`).
- Audio decoded: AAC-LC, AC-3, **E-AC-3 (partial — plays the 5.1 core; no AHT, enhanced coupling or 7.1 dependent substreams, `docs/codec-parity.md:45`)**, Opus, Vorbis, MP1/MP2/MP3, FLAC, ALAC, PCM (`crates/ac3`, `crates/codecs/src/audio.rs`).
- Stills incl. EXR, DPX, Targa, DNG/CinemaDNG, Radiance HDR. Image sequences: `file.importImageSequence`, CLI `probe --image-sequence`.
- **Containers moved in 0.13.0**: `crates/isobmff`, `crates/matroska` and `crates/bitstream` are now thin re-exports of `craft-media` from craft-libs (pinned `rev = f0ad6c1e1d297908915f4be315b0fcfc9be7b5d4`, `Cargo.toml:76`). Container behaviour beyond the re-export surface is therefore *not* auditable in this repo — say "uncertain — see Cargo.toml pin" rather than guessing.

### Native project format and durability (implemented)

- `.fcproj` = UTF-8 JSON with `format: "filmcraft.project"` and an explicit `schema_version`, still **15** (14 migrations v1→v15; `MIGRATIONS`/`SCHEMA_VERSION`, `crates/format/src/lib.rs:62-66`; test asserts 15 at `:398`). Every version from 1 migrates on load; newer files are refused (`TooNew`). **Doc drift**: the example in `docs/project-files.md:11` still shows `schema_version: 13`.
- New load-time hardening in 0.13.0: embedded LUT text over 8 MiB is dropped (`MAX_LUT_TEXT_BYTES`, `crates/project/src/lib.rs:1327`), media frame sizes are validated, and `next_id` is raised past the largest id in use so a hand-edited file cannot hand out a live id (`crates/format/src/lib.rs:216-280`).
- Media referenced by path (never embedded), with size + first/last-MiB fingerprints for relinking (`docs/project-files.md`; stored-path policy in `crates/engine/src/doc_path.rs`).
- **Atomic saves** (temp file → fsync → rename → fsync dir) for projects, auto-saves, recovery snapshots and preferences; `atomic_write_new` publishes extracted audio without clobbering (`crates/format/src/atomic.rs`, `docs/project-files.md:88-99`).
- Auto-save ring (default every 5 min, 20 versions) with `<name>-YYYY-MM-DD_HH-MM-SS-<unix seconds>.fcproj` names, **plus** a crash-recovery journal written ~1 s after each edit (`crates/format/src/autosave.rs`, `docs/project-files.md:113-180`). 0.13.0: a failed discard keeps the recovery session for retry instead of losing it (`file.discardRecovery`, `crates/engine/src/commands.rs:1564-1595`).
- Offline media never blocks opening: missing files render a "MEDIA NOT FOUND" slate; repair with `media.findMissing` / `media.relink` / `media.autoRelink` / `media.search` / `media.status` (`crates/engine/src/relink.rs`). Growing files refresh with `media.refreshChanged`.
- Proxies (ProRes Proxy/LT or H.264 presets), ingest (copy/transcode/createProxies), Project Manager collect/consolidate — and in 0.13.0 proxy/Project-Manager file I/O only uses the media pool's policy-approved resolved path (`s.media.follow`), not stored strings (`crates/engine/src/proxies.rs`, `crates/engine/src/project_manager.rs`).

### Export (implemented)

- Export formats are the `Format` enum, **21 variants**: H.264, HEVC, AV1, ProRes, DNxHR, APV, MJPEG, PNG/TIFF/BMP/JPEG/Targa/DPX/EXR sequences, GIF, WAV, AIFF, AAC (`.m4a` or ADTS `.aac`), FLAC, MXF OP1a, MXF OP-Atom (`Format::ALL`, `crates/export/src/lib.rs:272-294`).
- Availability is machine-dependent and queryable: `export.formats` reports `available` per format (`crates/engine/src/export_tools.rs`). **AV1 registers no encoder on any platform**; **HEVC has no software encoder** (VideoToolbox on macOS, NVENC on Windows) (`crates/platform/src/lib.rs:70-100`, `crates/export/src/lib.rs` docs on `Hevc`).
- **39 built-in presets** ("Match Source – Adaptive High Bitrate" is the default; `builtin_presets`, `crates/export/src/presets.rs:95-190`, default at `:35`), plus user presets in `<data dir>/export-presets.json`.
- Export queue as background jobs with progress/ETA/cancel, Quick Export, render previews (`export.queue.*`, `export.quick`, `jobs.list`, `jobs.cancel`).
- Hardware encoding: H.264 via VideoToolbox (macOS) or NVENC (Windows/Linux, opt-in); HEVC export is hardware-only — NVENC writes Main 8-bit SDR and Main 10 HDR (PQ/HLG), VideoToolbox writes Main 8-bit SDR (`crates/platform/src/hardware_encode.rs`, `crates/platform/src/nvenc/export.rs:212-216`).
- Ranges: `entire|inOut|workArea|custom`. **workArea is usable in 0.13.0** now that the work area bar and its commands exist (`crates/engine/src/export_tools.rs:337-365`; previously it always failed). Options include `sdr` (tone-map an HDR sequence to SDR), `burnCaptions`, `captionSidecar`, `alpha`, `exrCompression`, `loudnessLufs`, `hardwareEncoding`, `gpuRendering` (`crates/engine/src/export_tools.rs:265-330`, `crates/engine/src/commands.rs:1655`).
- Offline media in an export is reported, not hidden: the result lists `offlineMedia`, stderr names each item, exit status 1 unless `--allow-offline` (`apps/filmcraft-cli/src/main.rs`, `docs/agents.md:105-132`).

### Interchange (implemented; partly unvalidated)

- Import **and** export: CMX 3600 EDL, Final Cut Pro 7 XML (`xmeml` v4/v5), FCPXML 1.9–1.11, OpenTimelineIO JSON, AAF (Edit Protocol, embedded/consolidated audio), OMF 2.0; Avid Log Exchange (ALE) export only; markers CSV export only (`crates/interchange/src/lib.rs:1-16`; formats unchanged from v0.11.0).
- Detection sniffs content before trusting the extension (AAF/OMF structured storage, `<xmeml`/`<fcpxml`, `"OTIO_SCHEMA"`, EDL headers). Every importer merges as one undoable step and returns a report of what could not be represented; imported sequence settings are now validated first (`crates/engine/src/interchange.rs:75-90`).
- Embedded AAF/OMF audio is written without overwriting: collisions get `name (2).wav`, `name (3).wav` … and path separators survive (`crates/engine/src/interchange.rs:27-56`).
- **Unvalidated in the wild**: AAF/OMF have never been opened in Media Composer/Pro Tools; FCP7 XML import of a Premiere sequence was measured at 97 s (`docs/gaps.md` G15).

### Automation surface (implemented)

- CLI `filmcraft-cli` with **12 subcommand words** = 11 functional subcommands (`exec`, `run`, `commands`, `describe`, `inspect`, `import`, `export`, `render`, `probe`, `bench-decode`, `mcp`) plus `help` (`-h`); `--version` in the subcommand position prints the version (`apps/filmcraft-cli/src/main.rs:63-145` `HELP`, dispatch `:317-520`). Unchanged from v0.11.0 — the previous skill counted the 11 functional ones.
- Control channel: `filmcraft --control <port>` or `FILMCRAFT_CONTROL_PORT` — JSON-lines on 127.0.0.1, **now authenticated**: the listener stays closed unless `FILMCRAFT_CONTROL_TOKEN` holds exactly 64 hex characters, and every request must carry the same top-level `token` (constant-time compare; missing/wrong token answers an error and closes the connection before dispatch) (`apps/filmcraft/src/control_server.rs:31-41,130-141`; `docs/control-protocol.md:4-24`). **23 methods** (`crates/ui-egui/src/control.rs`): engine.execute/ui.menu.invoke, engine.commands/ui.menu.list, ui.inspect, ui.elements, ui.set, ui.panel.show/close, ui.click/move, ui.drag, ui.scroll, ui.key/type, ui.timeline.hit/locate, ui.playback, ui.screenshot, ui.resize, app.quit, ui.focus, perf.stats.
- MCP server on stdio, headless or via `--bridge`: **17 tools** + **2 resources** (`filmcraft://document`, `filmcraft://commands`) — unchanged (`crates/automation/src/server.rs`, `:612-613`, `docs/agents.md:56-77`, `.mcp.json`).
- Web build exposes the same engine as JS promises: `window.filmcraft.{execute,request,commands,inspect,screenshot,importFiles,importUrl,openProject,files,readFile,info}` (`docs/web.md`, `apps/filmcraft-web/src/api.rs`).
- **Counts at v0.13.0** (all re-measured from code; the previous skill's v0.11.0 numbers in brackets): **662 statically registered engine command ids** [653 with the same script at v0.11.0] = 653 source literals + 9 generated by `camera_keys!`; **215 UI-only command ids** in `crates/ui-egui/src` [212]; 12 CLI subcommand words (11 functional + `help`) [same]; 17 MCP tools + 2 resources [17+2]; 23 control methods; 21 export formats [21]; 39 presets [39]; 7 caption formats [7]; 28 panels [28]; **9 built-in workspaces** — the previous skill said 7, which was the Window-menu subset, not the built-in list; 4 shortcut presets [4]; 12 UI languages [12]; schema 15 [15]; 93 video effects/16 folders, 53 audio effects, 84+21 transitions, 27 blend modes [same]; 10 camera log curves [8]. Engine ids **added** in 0.13.0: `captions.duplicate`, `history.clear`, `history.deleteRedoable`, `sequence.duplicateFrames`, `sequence.setWorkArea`, `sequence.setWorkAreaIn`, `sequence.setWorkAreaOut`, `sequence.showDuplicateFrameMarkers`, `sequence.workAreaBar`; **removed: none**. UI ids added: `mixer.meterInputOnly`, `mixer.showHideTracks`, `view.transparencyGrid`. The README's "more than 650 engine commands" (README.md "Built for agents") is now consistent with the static 662. Enumeration method and the exact script are in `evidence.md`; the runtime list (`filmcraft-cli commands`, MCP `command_list`) stays authoritative — it was not run here (no build).

## Known limitations and not-implemented

Do not assign these to FilmCraft; they are absent from the code or gated off in releases.

- **`.prproj` cannot be opened or written** (`grep -ri prproj crates apps` finds nothing; `docs/gaps.md` G2 — the stated beta blocker). Import Premiere work through FCP7 XML, AAF or OTIO.
- **No plug-in hosting**: no VST3/Audio Units, OpenFX, UXP or Adobe plug-in APIs (`docs/gaps.md` G11); Settings ▸ Plugins only offers a developer-mode toggle.
- **Delivery codecs**: H.264 is the only software delivery encoder (plus ProRes/DNxHR/APV/MJPEG). HEVC needs hardware (VideoToolbox on macOS, NVENC on Windows — not Linux); **AV1 has no encoder anywhere**; no MPEG-2/DVD/Blu-ray/DCP, no MP3 or WMV/FLV writes, no interlaced encoding (`docs/gaps.md` G13; `crates/export/src/lib.rs:272-294`; `crates/platform/src/lib.rs:70-100`).
- **Camera RAW is DNG only**: no R3D, ARRIRAW, Sony RAW/X-OCN, Canon RAW, BRAW, ProRes RAW, JPEG 2000/XS MXF (`docs/gaps.md` G10).
- **10-bit / 4:2:2 camera H.264 and HEVC decode only through OS hardware**; without a hardware decoder there is no software fallback (`docs/gaps.md` G3).
- **Stills that will not open**: PSD, HEIF/HEIC, AI/EPS, ICO; EXR only scan-line none/RLE/ZIPS/ZIP/PXR24 (no PIZ/B44/DWA/tiled/deep) (`docs/file-format-parity.md:55-65`: PSD, HEIF/HEIC, AI/EPS/ICO rows; EXR row).
- **No caption codecs embedded in the video stream** (CEA-608/708 in H.264 SEI or MXF) — burn-in and sidecar export only (`docs/file-format-parity.md`).
- **One project at a time.** `file.closeAllOtherProjects` exists only to report "only one project is open" (`crates/engine/src/project_tools.rs:90-92`). Sequences open in Timeline tabs; there are no Productions (docs/keyboard.md gaps table).
- **Speech to text is off in official builds** (`docs/gaps.md` G19); import a transcript with `transcript.set`. **Kokoro neural TTS voices are off in official builds**.
- **Export destinations beyond "Media File" do not exist.** The README screenshot alt text still advertises YouTube, Vimeo, TikTok, Instagram and FTP destinations; the code registers exactly one, `export.destination.mediaFile` (`crates/ui-egui/src/panels/export_mode.rs:204`). "YouTube 1080p Full HD" etc. are **presets**, not upload destinations.
- **AI features are minimal**: no Object Mask, Generative Extend, media-intelligence search, caption translation, model-based Enhance Speech or auto colour (`docs/gaps.md` G12).
- **UI/UX gaps**: remaining verified ones include Productions, the Search panel, effect-selection removal in Effect Controls, Effects-panel custom bins, inline caption/transcript segment editing and source transcripts (`docs/keyboard.md` gap table). **Do not repeat older gap lists blindly**: `docs/ui-parity.md` (last reviewed 2026-10-10) and `docs/gaps.md` G8 have repeatedly lagged the code — at this tag the work area bar, History-panel pruning, mixer Show/Hide Tracks + Meter Input(s) Only, on-monitor transform handles, Effect Controls divider/row lines, Project-panel marquee and continuous timeline thumbnails all exist (`docs/keyboard.md` gap table was trimmed accordingly; `crates/ui-egui/src/panels/transform_handles.rs`, `crates/ui-egui/src/panels/effect_controls.rs`, `crates/ui-egui/src/panels/project_views.rs`, `crates/ui-egui/src/panels/timeline.rs`).
- **Windows and Linux are far less tested than macOS** (`docs/gaps.md` G9); **the web app shell is incomplete** — file access, WebCodecs decode, browser audio differences (`docs/gaps.md` G20, `docs/web.md`).
- **Performance**: colour grading, keys and export rendering run on the CPU; GPU compositing is partial (README.md "Status"). Monitor Transparency Grid and Alpha display modes render on the CPU / live instead of previews, so playback is slower there (`docs/monitors.md`).
- **FreeBSD aarch64 is not in the release**: README lists a FreeBSD x86_64 tarball only.
- **Command total**: the README now says ">650", and static extraction finds 662 ids, so the claim is consistent — but a static count is not the registry. Enumerate with `filmcraft-cli commands` on a built binary before relying on a specific id.
- **Container behaviour is only partly auditable here**: MP4/MOV, Matroska/WebM and bit I/O come from `craft-media` (craft-libs) at the pinned rev; this repo holds only re-exports (`crates/isobmff/src/lib.rs`, `crates/matroska/src/lib.rs`, `crates/bitstream/src/lib.rs`). Questions about box/element-level support beyond `docs/file-format-parity.md` are "uncertain — see Cargo.toml pin".
- **Known doc drift (trust the code)**: file-format-parity AVI row still says "no demuxer (#598)" although `avi::opener` is wired (`crates/codecs/src/lib.rs:136`, `crates/avi/README.md`); project-files schema example (`docs/project-files.md:11`, says 13; code writes 15); README "26 blend modes" (code 27) and "around 30 transitions" (code 84+21); README "Not yet: … E-AC-3" (`docs/codec-parity.md:45` documents a 75 %-complete E-AC-3 decoder); `docs/target-app-parity.md:22` "45 crates" (workspace has 50 crates + 3 apps); `docs/roadmap.md` M6 says "24 built-in presets" (code 39); `docs/architecture.md` still lists `isobmff`/`matroska` as in-repo L0 crates (now craft-media re-exports).

## How to operate

**Launch (macOS).** `open -a FilmCraft` or `open -a FilmCraft cut.fcproj`. A `.fcproj` argument opens as a project (extension match case-insensitive); any other file is imported as media (`apps/filmcraft/src/args.rs:125`). Binary: `/Applications/FilmCraft.app/Contents/MacOS/FilmCraft` (the only executable in `Contents/MacOS`); app id `ai.storyteller.filmcraft`, documents UTI `ai.storyteller.filmcraft.project`, minimum macOS 11.0 (installed bundle Info.plist).

**Desktop flags** (from the `USAGE` string, `apps/filmcraft/src/args.rs:7-26`; an unknown option is an error, not a file name):

```
filmcraft [options] [project.fcproj | media files...]
  --control <port>      localhost JSON-lines control server   (FILMCRAFT_CONTROL_PORT;
                        also needs FILMCRAFT_CONTROL_TOKEN, 64 hex chars)
  --control-input-only  accept widget input only from the control server (needs --control)
  --demo | --empty      demo project or empty project
  --recover | --no-recover
  --data-dir <dir>      auto-save, crash recovery and logs    (FILMCRAFT_DATA_DIR)
  --graphics <mode>     default | dx12 (Windows) | software (Windows, Linux)
  --version             print version   -h/--help  print help
```

Started with `--control`, the app opens without stealing focus (`docs/control-protocol.md`). Cmd+Q routes through `app.quit` so unsaved changes prompt; `--control-input-only` ignores native menu/keyboard/pointer input except window close/quit and screenshots.

**Data directory (macOS):** `~/Library/Application Support/FilmCraft` — preferences.json, Auto-Save/, Recovery/, Logs/filmcraft.log (and crash-<day>.log), Media Cache/, workspaces.json, user export/effect presets (`crates/engine/src/autosave.rs`, `apps/filmcraft/src/logging.rs`).

**The CLI is not inside the .app.** On macOS `filmcraft-cli` ships as a separate release asset, `filmcraft-cli-<version>-macos-<arch>.zip` (default arch `universal`; `packaging/macos/package.sh:5,44`; `docs/agents.md` "From an installed release"), or build it: `cargo run --release -p filmcraft-cli -- commands`.

**Control channel with authentication (new in 0.13.0).** Both the desktop and any bridge/raw client must share one token in the environment; without it the desktop prints `control server disabled: FILMCRAFT_CONTROL_TOKEN must contain 64 random hex characters` and never listens:

```sh
export FILMCRAFT_CONTROL_TOKEN="$(python3 -c 'import secrets; print(secrets.token_hex(32))')"
filmcraft --control 9876 &
filmcraft-cli mcp --bridge 127.0.0.1:9876      # inherits the token; adds "token" to every line
python3 - <<'PY'
import json, os, socket
s = socket.create_connection(("127.0.0.1", 9876)); f = s.makefile("rw")
f.write(json.dumps({"id":1, "token": os.environ["FILMCRAFT_CONTROL_TOKEN"],
                    "method":"engine.execute", "params":{"command":"sequence.addEdit","params":{"seconds":3}}})+"\n"); f.flush()
print(f.readline())
PY
```

Do not put the token in arguments, logs, or a checked-in `.mcp.json` — the repo's `.mcp.json` relies on the inherited variable. Limits: 4 MiB per line, 16 concurrent connections, 120 s socket read/write timeout, 60 s wait for a UI reply; a non-request line gets one error and the connection closes (`apps/filmcraft/src/control_server.rs:22-28,130-141`; `docs/control-protocol.md`). `ui.click` takes `count` 0–10 (0 = no click) and `ui.drag` `steps` 0–1024 (0/1 → 2); out-of-range values are rejected before any input is queued (`crates/ui-egui/src/control.rs:28-45`).

**CLI shape** (full reference: `references/cli-and-protocol.md`):

```sh
filmcraft-cli commands razor                    # find command ids
filmcraft-cli describe timeline.razor           # one command: menu, shortcut, params, enabled now
filmcraft-cli --demo inspect sequence           # project/sequence as JSON, no window
filmcraft-cli --project cut.fcproj --save exec timeline.razor seconds=3.5
filmcraft-cli --project cut.fcproj --save import a.mov b.wav
filmcraft-cli --project cut.fcproj export out.mp4 --preset "YouTube 1080p Full HD" --start 0 --end 10
filmcraft-cli export --list-presets prores
filmcraft-cli --project cut.fcproj render --seconds 2.5 --out frame.png
filmcraft-cli --bridge 127.0.0.1:9876 exec window.workspace.color   # needs FILMCRAFT_CONTROL_TOKEN
filmcraft-cli mcp --demo                                            # MCP on stdio, headless
```

Values parse as JSON when they can (`3.5`, `true`, `[1,2]`), else strings; dotted keys nest (capped at 64 levels, `apps/filmcraft-cli/src/args.rs`). Exit status: 0 success, 1 a command failed or offline media was drawn without `--allow-offline`, 2 usage error.

**Document model.** One project per running app; sequences are the timelines and open in Timeline tabs. Panels dock/float; 28 panel kinds; 9 built-in workspaces plus your own saved layouts (Window ▸ Workspaces).

**Core workflow.** Import media (⌘I or `file.import`) → build a sequence (`file.newSequence` / `file.newSequenceFromClip`) → edit on the timeline → save `.fcproj` (⌘S; `file.save` / `file.saveAs` ⇧⌘S / `file.saveCopy` ⌥⌘S) → export (`File ▸ Export ▸ Media…`, `file.exportMedia`, or `export.quick`). Verified keys: `Cmd+Z`/`Cmd+Shift+Z` undo/redo, `Cmd+K` Add Edit, `Cmd+S` save, `Cmd+O` open, `Cmd+I` import, `Alt+Shift+1..8` workspaces (Learning/Review are 7/8; All Panels has no key), `Alt+[` / `Alt+]` work area In/Out (`crates/engine/src/shortcut_presets.rs:290-295`).

**Time.** Ticks everywhere: 254 016 000 000 per second (`crates/time/src/lib.rs:20`). Commands accept `ticks`, `seconds`, `frame` or `timecode`.

**Work area.** Show it with `sequence.workAreaBar` (Timeline panel menu ▸ Work Area Bar), set in/out with `sequence.setWorkAreaIn`/`Out` (positional args or the playhead) or both with `sequence.setWorkArea {start,end}` in ticks; `range: "workArea"` in an export then works. `export.resolve` errors with "the sequence has no work area" until one exists (`crates/engine/src/work_area_tests.rs:27-41`).

## Working with an AI agent

Legitimate and effective:

- **Headless round trips** with `filmcraft-cli` (no window, no GUI state): import → edit via `exec`/`run` → `export` → verify. `run script.jsonl` takes one `{"id","params"}` per line (`#` comments allowed) and stops at the first failure unless `--keep-going`.
- **Drive the live app** through a tokened `--control <port>` or `filmcraft-cli mcp --bridge 127.0.0.1:9876`: run commands, inspect `ui.elements` for automation ids, click/drag/type, screenshot the window or one panel, then `edit.undo` if wrong. Pass the token through the environment of both processes; never embed it in a script argument.
- **Enumerate before you guess**: never invent command ids, parameter names or shortcuts. `commands`, `describe <id>` and `command_list` are authoritative and return enablement state. Two gestures that are easy to get wrong: `effects.setParam` rejects out-of-range values instead of clamping, and captions are pasted by `edit.paste` only when captions (not clips) were the last copy.
- **Prepare and convert inputs**: generate test media with ffmpeg (allowed as an external oracle — never linked into the app, `AGENTS.md` §2); convert unsupported sources (`.prproj`, WMV, HEIC, PSD, R3D…) into what FilmCraft reads: FCP7 XML/AAF/OTIO for timelines, ProRes/H.264 MP4 or image sequences for media.
- **Interpret and repair project files**: `.fcproj` is documented JSON with a migration chain and atomic writes — read it, diff it, reason about it. Repair by relinking media through commands (`media.findMissing`, `media.relink`, `media.autoRelink`, `media.search`), not by editing paths while the app has the project open.
- **Verify exports outside the app**: `ffprobe`/`ffmpeg -i` for streams, duration, frame count, A/V sync; check exit status, the `offlineMedia` array, and the written path (the format may change the extension: `out.mp4` exported as APV becomes `out.mp4.mov` — `apps/filmcraft-cli/src/main.rs:536-550` `written_paths`, test at `:664` and `apps/filmcraft-cli/tests/it/cli.rs:234`). `sdr: true` tone-maps HDR to SDR; without it an HDR sequence goes out as Main 10 PQ/HLG only where the encoder supports it.
- **Follow background exports correctly**: local `file.exportMedia` calls block unless `wait:false`; with the bridge, without `wait`, use the returned `poll: "jobs.list"` / `cancel: "jobs.cancel"` hints. `export.queue.list` lists only the Export Queue, not direct exports. Do not pass `wait:false` to a one-shot local CLI process unless you keep it alive: it exits and the render is lost.
- **Batch production**: `export.queue.add … start=true wait=true` for several deliverables; `jobs.list` for progress/ETA; `jobs.cancel` to stop.
- **Import AAF/OMF repeatedly**: embedded audio is extracted next to the document without clobbering; the media item may point at `name (2).wav` (`crates/engine/src/interchange.rs:27-56`). Read the import result, do not assume the original name.
- **Find repeated frames before trimming**: `sequence.duplicateFrames` returns per-clip ranges that another clip also shows (used by Show Duplicate Frame Markers); it skips stills, generators, nests, graphics, adjustment layers, frame holds and keyframed Time Remapping (`crates/engine/src/sequence_tools.rs:428`), so an empty result is not proof that no frame repeats.

Must not attempt:

- Do not assume `.prproj`, Premiere projects, plug-ins, upload destinations, Whisper transcription or Kokoro voices exist in the installed build.
- Do not start the control server without a token, or reuse one token across machines/sessions in a shared file; the listener refuses to start otherwise and any unauthenticated line is rejected before dispatch.
- Do not drive the GUI blind: read `ui.elements`/`ui.inspect` before clicking by id, and screenshot to confirm. The window may stay behind other windows (by design).
- Do not leave the control port open when idle: it is loopback-only, authenticated, serves 16 connections at once, and a non-JSON line closes the connection.
- Do not hand-edit a `.fcproj` to look like a newer schema or copy a `schema_version` forward; older builds refuse newer files, and the loader now raises/refuses inconsistent `next_id` values.
- Do not expect the headless MCP server to be sandboxed: it can read and write wherever the user can; there are no confinement flags (`docs/agents.md:17-19`).
- Do not commit screenshots of Adobe products or use Adobe artwork when producing documentation assets (repo rule `AGENTS.md` §1).

## Verification protocol

FilmCraft is alpha and estimates itself "~56% ready for real work". Assume every step can silently produce a wrong-but-valid file:

1. **Throwaway round trip first.** New project → import one clip → place → export → `ffprobe` the output → reopen the project in a second process and check `inspect` matches. Only then touch real work.
2. **Never trust a silent export.** Check the exit status, the `offlineMedia` list and the message naming the written files. `filmcraft-cli export` exits 1 when it drew placeholder frames for offline media unless you passed `--allow-offline`.
3. **Read the result as media, not as a file.** Check duration, frame count, frame rate, audio channels and a couple of decoded frames; do not take codec correctness on faith for a deliverable.
4. **Version and back up per session.** Auto-save and the recovery journal are safety nets, not backups. `file.saveAs` / `file.saveCopy` before risky operations; the first save over an upgraded project keeps `<name> (schema vN backup).fcproj`.
5. **Mind the schema.** A project saved by a newer build cannot be opened by an older one (it is refused). Update apps only *between* projects.
6. **Do not trust parity docs or the README over the code.** They drift (AVI row, schema example, blend-mode/transition/preset counts, "45 crates", the architecture crate table — see Known limitations). When a doc and the code disagree, the code wins; when both are silent, write "uncertain" and test.
7. **Record the exact build** you tested (version + commit, e.g. 0.13.0 / `30536bc5…`) — bug reports with real footage and a build id are what the project asks for.

## Sources & evidence

- Repo: https://github.com/storytold/filmcraft — inspected at **tag `v0.13.0`, commit `30536bc5d0ddf690f2181b7b97182db8658a6038`** (`git rev-parse HEAD`, detached shallow clone, release commit 2026-10-25), **2026-10-26**. The installed app reports `filmcraft 0.13.0` and its Info.plist records the same build commit, so the bundle is this release; users on other builds may lag or lead this pin — verify against your installed version (`filmcraft --version`).
- Diff used for "what changed": `git diff --stat v0.11.0..v0.13.0` = **521 files, +9 577/−10 972** (v0.12.0 was a small ProRes-alpha follow-up, 7 files). Tag objects for v0.11.0 and v0.12.0 were fetched into the clone for this comparison.
- Files read: `README.md`, `ROADMAP.md`, `Cargo.toml`, `AGENTS.md`, `CLAUDE.md`, `.mcp.json`, `docs/{agents,control-protocol,architecture,project-files,keyboard,gaps,target-app-parity,roadmap,file-format-parity,codec-parity,captions,graphics,monitors,performance,localization-parity,web,releasing,testing,ui-parity}.md`, `apps/filmcraft/src/{args,control_server,logging,main}.rs`, `apps/filmcraft-cli/src/{args,main}.rs`, `packaging/macos/package.sh`, `crates/engine/src/{commands,captions,sequence_tools,lib,shortcuts,mixer,proxies,project_manager,project_tools,interchange,relink,export_tools,transcript,marker_export,settings,panels,paste_media,media_browser,keyframe_move}.rs`, `crates/engine/src/{work_area,history,captions,sequence_tools,panels}_tests.rs`, `crates/automation/src/{server,bridge,long_job}.rs`, `crates/ui-egui/src/{control,menus,dock,lib}.rs`, `crates/ui-egui/src/panels/{timeline,timeline_hit,timeline_captions,transition_controls,misc,mixer,export_mode,monitor_view,mod,text,keyboard}.rs`, `crates/ui-egui/tests/it/{timeline_work_area_ui,keyboard_ui,panels_ui,project_panel_ui}.rs`, `crates/export/src/{lib,presets,pipeline}.rs`, `crates/interchange/src/lib.rs`, `crates/media/src/{lib,animated}.rs`, `crates/codecs/src/lib.rs`, `crates/format/src/{lib,atomic,autosave}.rs`, `crates/project/src/{lib,effect.rs,effect/vfx.rs,effect/audio.rs,vtransition.rs,caption.rs}`, `crates/color/src/log.rs`, `crates/captions/src/lib.rs`, `crates/isobmff/src/lib.rs`, `crates/matroska/src/lib.rs`, `crates/bitstream/src/lib.rs`, `crates/platform/src/lib.rs`, `crates/time/src/lib.rs`.
- Shared libraries consulted only by pin: `craft-media` (`rev f0ad6c1e1d297908915f4be315b0fcfc9be7b5d4`) now owns MP4/MOV, Matroska/WebM and bit I/O; `craft-docpath` (`rev 82a24b0…`) backs stored-path policy; `craft-ui` (`rev 5c874d5…`) the docking widgets (`Cargo.toml:75-80`).
- See `evidence.md` in this directory for the claim → evidence table, the count re-measurement method, the corrections against the v0.11.0 skill, and how to re-verify.