- AGENTS.md: a new §0 "Never crash" at the top of the rules (why, outranks feature work, the bans,
Result/? patterns, hostile input numbers, bounded recursion, lock poisoning, the last-resort
guard, a regression test per crash fix), linking craftrules/standards/never-crash.md. §3.1 now
points to it.
- CLAUDE.md non-negotiables, CONTRIBUTING.md and docs/contributing.md: short Never crash notes
pointing to AGENTS.md §0.
- clippy.toml: allow unwrap/expect/panic/indexing in tests, so crates can deny the panicking lints
in production code without touching their tests.
- [workspace.lints.rust] unsafe_code = "forbid" (no unsafe or allow(unsafe_code) in the workspace).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- LICENSE-MIT / LICENSE-APACHE from the Crafting Apps standard (copyright "ArtCraft Team and the
FilmCraft contributors"; Apache text in the canonical apache.org layout)
- NOTICE (new): license, brand carve-out, third-party list from ATTRIBUTION.md
- docs/brand/LICENSE-brand.txt (new): ArtCraft brand terms; brand sidecars, ATTRIBUTION.md and
AGENTS.md §1.8 point to it (owner "ArtCraft Team"; forks and modified versions remove the marks)
- README: "## License and credits" section per the standard (absorbs "Credits and clean room"),
badge anchor #license-and-credits, alt text "License: MIT OR Apache-2.0"
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Desktop/shared:
- Frame workers catch panics per job: a failing decode/render no longer kills the worker
or leaves its frame in flight forever (blank monitors). Counted as perf.stats failedJobs.
- UI pass catches panics and shows a "FilmCraft hit an error" window (Save Project /
Continue) instead of closing the app.
- Panic hook writes <data dir>/Logs/crash-<day>.log with thread, location and backtrace;
a window that can't start shows an error dialog instead of exiting silently.
- GPU compositor only on adapters that render/blend Rgba16Float with >= 4096 textures;
GPU validation errors and oversize frames switch to the CPU compositor instead of
wgpu's default panic.
- Dock layout and Media Browser splitter no longer panic on tiny panels/windows.
Web:
- Export mode / previews / voice-over / log reveal no longer call std::env::temp_dir
(panics on wasm32): new filmcraft_engine::temp_dir(); default export dir /exports.
- Fatal-error overlay with Reload; WebGPU device failure retries on WebGL2 (?webgl);
cache-busted wasm/glue URLs; webcodecs entries[0] guard.
Tests: robustness_ui (worker survives injected panics, UI panic recovery, tiny windows),
crash hook, dock split, GPU plan size, default export dir; web smoke test extended.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Lumetri grades PQ / HLG working spaces in their own signal normalised to
HDR White (Basic Correction) / HDR Range (Curves) in cd/m²
(filmcraft_color::GradeSpace): exposure in stops of light, highlights above
HDR White kept, HDR Specular scales them; Rec. 709 unchanged.
- HDR static metadata (mdcv/clli, Matroska MasteringMetadata/MaxCLL/MaxFALL)
on VideoStreamInfo::hdr; PQ media use MaxCLL / mastering peak as the
BT.2390 source peak; media.colorInfo reports it.
- HSL Secondary Refine: Denoise (median of the key) and Blur (Gaussian).
- Lumetri Presets (18 original looks in 4 folders) with thumbnails rendered by
our Lumetri on a procedural preview picture; Effects panel rows and a
thumbnail grid when wide; lumetri.presets / applyPreset / presetThumbnails.
- Color Match: Comparison View toggle; Apply Match uses its reference frame.
- Goldens lumetri_hdr_pq and lumetri_presets_grid; D-Log M stays unsupported
(no published formula).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
filmcraft-mxf gains a streaming writer (ST 377-1 partitions, primer, header
metadata, VBR index segments with temporal offsets, RIP; ST 378 OP1a
frame wrapping, ST 390 OP-Atom clip wrapping) for VC-3, ProRes, AVC byte
stream and PCM with start timecode and caller-supplied package UMIDs, plus
write_opatom_pcm. filmcraft-export adds mxf-op1a / mxf-opatom formats
(DNxHR, ProRes or H.264 + PCM; OP-Atom writes one mono file per channel),
presets, the engine mxfVideoCodec parameter and CLI .mxf inference.
Tests read our files back and check them against ffprobe / ffmpeg.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
List / Icon / Freeform views, Metadata Display, view presets, font size,
Preview Area, bin tabs and windows, hover-scrub In/Out; Media Browser tree,
Favorites, history, file types, thumbnails, Edit Columns, import and drag.
Engine: project_panel and media_browser modules, Services::list_entries.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Interleaved before/after bench (decode, playback incl. 1/4 and draft cases,
4K cold seeks) and decoder cycle counts in docs/performance.md; threading,
draft mode and 4K numbers in crates/h264/README.md; bench cases in
docs/testing.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The column pass and the add/clip of idct4/idct8 work on whole rows so they
vectorise (same integer steps in the spec's row-then-column order; checked
against the per-column formulation on random blocks). Docs: draft decoding in
architecture.md and perf.stats fields in control-protocol.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds ~115 keyboard-only commands from Premiere's default keyboard (engine:
filmcraft_engine::keyboard, UI: panels::keyboard): edit-point navigation on
targeted/any track, go to selected clip start/end, reveal nested sequence,
select clip at playhead/next/previous, extend previous/next edit to playhead,
nudge/slip/slide clip selection, target and source-patch toggles, clip volume
keys, audio scrubbing toggle, text size/leading/alignment, object nudge,
Export Frame, poster frames, frame maximize/full screen/panel cycling, monitor
zoom, track heights, Project and Text panel keyboard navigation, play to Out.
Existing commands that lacked their Premiere key are added to the table;
panel-scoped keys live in PREMIERE_PANEL. docs/keyboard.md lists the 39
skipped shortcuts with reasons. Tests: table integrity (no dangling ids, no
duplicate keys per scope, no conflicts), engine behaviour with undo, headless
key presses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.1 / multichannel:
- audio-dsp::channels: layouts (L R C LFE Ls Rs), ITU-R BS.775 up/downmix, 5.1 Mixdown Types,
equal-power 5.1 panner (puck, Center %, LFE).
- Mixer graph buses are 2 or 6 channels wide; 5.1 tracks/submixes/Mix; strips feeding a 5.1 bus
use the 5.1 panner (lanes pan51.x/y/center/lfe stored in MixerStrip::lanes, no schema change);
5.1 strips fold into stereo buses with BS.775; per-channel meters; clip effects on 6 channels.
- file.newSequence {mix, trackType}, sequence.settings {mix}; playback honours the 5.1 Mixdown
Type preference on stereo devices and plays 6 channels on 5.1 devices.
- Export Audio Channels 5.1: WAV WAVE_FORMAT_EXTENSIBLE (mask 0x3F), QuickTime PCM with a chan
atom, AAC channel configuration 6 (reordered to C L R Ls Rs LFE).
- Track Mixer: 5.1 panner puck with Center/LFE, N-channel meters, Show/Hide Tracks, Meter
Input(s) Only; transport record button runs voice-over.
Voice-over: engine AudioInput trait + SyntheticInput, cpal input in the app, audio.voiceover.*
commands (punch-in, pre/post-roll, countdown cues, WAV next to project / scratch disk, one undo
step), track header mic button and Voice-Over Record Settings dialog.
Remix: beat tracking + chroma/cepstra self-similarity planner in audio-dsp, hidden `remix` clip
effect holding the plan, render::remix playback with equal-power crossfades, clip.remix.*
commands, Remix tool and Remix Properties dialog.
Clip Mixer automation: per-track Latch/Touch/Write (clipMixer.setMode/touch/release) heard live
and written as thinned clip Volume/Panner keyframes at the end of the pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- HEVC inverse transform: sum basis rows of non-zero coefficients with a
const-generic size (bit-exact, tested against the direct product);
SAO edge offset gets a check-free interior loop. HEVC CPU/frame -60%.
- H.264/HEVC/VP9 planes are moved into VideoFrames, not copied.
- Catch-up decoding: frame jobs tell sources which frames are late
(filmcraft_media::cancel::with_catch_up); the GOP cache skips
non-reference samples of late frames (H.264 nal_ref_idc 0, HEVC
sub-layer non-reference pictures). Scrubs keep the last 2 s decoded.
- perf.stats: engine query + UI/control method (decode counters,
playback shown/dropped, frame-worker decode/render ms, cache use).
- Timeline waveform source peak cached; bench seek section and --only.
- docs/performance.md with before/after results.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- project: vtransition.rs registry. Animation, Dissolve, Grunge & Distort,
Immersive Video, Lights & Blurs, Slide, Smart Tools, Text, Transformers
and Wipe folders, plus Legacy > Video Transitions. Old ids are kept:
modern versions reuse push/slide/split/whip/clock_wipe/radial_wipe/
cross_zoom/page_peel, the old behaviour lives under *_legacy ids, and
removed transitions move to a hidden Obsolete folder. Parameters are
not animatable; find_transition looks up by kind (Mosaic/Mirror/
Directional Blur names are shared with video effects).
- render: transitions/ module with procedural CPU implementations, a
field-wipe engine (feather, border width/colour, anti-aliasing, centre),
a 3D card renderer (flips, cube, folds, spins), page curl, blur/light/
grunge families and flat VR approximations. Endpoints are exact,
pixel params scale with the render resolution, and Reverse now plays
B->A backwards. There is no GPU transition path, so the plan keeps
only the symmetric dissolves on the GPU.
- engine: applyVideoTransition takes params/reverse; new
sequence.setTransition; effects.list adds folder/kind filters,
badges and detail paramInfo; sequence.inspect shows transition params.
- ui: the Effects panel shows the Legacy top folder and all badges;
ui.set effectsSearch.
- tests: per-transition endpoint, continuity, midpoint, determinism,
NaN, parameter-wiring and direction properties; golden fingerprints;
tree counts; apply-every-transition via command; UI panel test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One Preferences window (app menu ▸ Settings ▸ <category>, Edit ▸ Preferences in-window, General =
Cmd+,): category list, schema-driven pages, Help / Reset… / Cancel / OK. Settings live in the
per-user preferences.json (version 2, v1 migrated, bad values repaired), reachable via
prefs.get/set/reset{category} and the new prefs.schema; app.settings.<category> opens a page;
every control has a settings.<key> automation id.
Wired: still/transition default durations, auto-scroll, snap playhead, return to beginning, play
after rendering, step many, selection-tool roll/ripple, theme/highlight/contrast, tooltips, at
startup + recent projects, label names/colours/defaults, indeterminate timebase, default media
scaling, media cache location/policy/clean, frame cache budget, cpal device/buffer/rate/output
mapping, transcription defaults + auto-transcribe on import, text smart quotes/ligatures/font.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>