# FilmCraft — rules for agents and contributors These rules apply to every human and AI contributor. `CLAUDE.md` holds the working instructions; this file holds the rules that must never be broken. When the two disagree, this file wins. ## 1. Assets: no Adobe artwork, every asset licensed and attributed This rule is absolute. Breaking it is the most serious mistake a contributor can make on this project. **What counts as an asset:** any image, icon, cursor, logo, illustration, screenshot, font, colour LUT, preset, template, sound, music, video, 3D model, or other non-code media. This covers files in the repository, bytes embedded in code (`include_bytes!`, base64, data URIs), and data hard-coded to reproduce an image (for example, point lists traced from someone else's icon). 1. **Never use Adobe iconography, images or other Adobe assets**, in any form: - no icons, cursors, logos, splash screens, UI artwork or screenshots from any Adobe product; - no Adobe fonts, LUTs, presets, templates, sound effects, stock media or sample projects; - no traced, redrawn, recoloured or "inspired-by" copies of Adobe icons. Our icons may follow generic conventions (a play triangle, a razor blade, a stopwatch), but each must be drawn from scratch without reference to Adobe's artwork. 2. **Every asset must be open**: open-source licensed (MIT, Apache-2.0, BSD, ISC, zlib, SIL OFL…), public domain / CC0, or Creative Commons (CC BY or CC BY-SA; no NC/ND licences), **or** created by a contributor who owns it and licenses it to the project under the project licence (MIT OR Apache-2.0). If the licence is unknown or unclear, the asset does not go in. 3. **Every asset needs an attribution sidecar.** Next to each asset file `X`, add `X.attribution` with: ```text asset: title: author: source: license: license-file: added: by notes: ``` Also add one line for the asset to [`ATTRIBUTION.md`](ATTRIBUTION.md). `cargo xtask assets` (part of `cargo xtask ci`) fails if any asset lacks a sidecar or index entry. 4. **Screenshots** in the repo may show only FilmCraft (or other open projects), with media we generated or media that is itself openly licensed. Never commit screenshots of Adobe products. 5. **Local reference material stays local.** Premiere reference screenshots and notes live only in `plan/premiere/` (gitignored). They must never be committed, bundled, embedded, traced or shipped. 6. **Code-drawn assets** (icons in `crates/ui-egui/src/icons.rs`, procedural demo footage in `crates/media`, procedural looks in `crates/render`) are original work under the project licence and are listed in `ATTRIBUTION.md`. 7. **When in doubt, leave it out** and draw or generate it yourself. 8. **The one exception: first-party ArtCraft brand marks.** The ArtCraft name and logos in `docs/brand/` are trademarks of the ArtCraft Team, not open source, usable only unmodified and only in the context of FilmCraft under `docs/brand/LICENSE-brand.txt`; forks and modified versions must remove them. They still need a sidecar and an `ATTRIBUTION.md` row (licence `LicenseRef-ArtCraft-Trademark`). No other non-open asset is allowed, and this exception never covers third-party marks (Adobe, Discord, GitHub and other logos stay out; draw a generic icon instead). ## 2. Clean-room code - Never read, disassemble or copy anything inside Adobe application bundles; file names and listings only. Observe behaviour by using the app; never capture its Home screen, recent projects, account info or file browsers. - Never copy GPL/LGPL/AGPL code (FFmpeg, x264, x265, MLT, Kdenlive, Shotcut, Olive, LAME…). - Implement codecs and formats from public specifications (ITU-T/ISO/IEC standards, IETF RFCs, the VP9 and AV1 bitstream specs, SMPTE documents, published container specs). Do not read the source of reference or third-party decoders/encoders while implementing a format, even permissively licensed ones (libvpx, libopus, libaom, dav1d, openh264…); spec text and conformance vectors only. Record the spec edition used in the crate README. - ffmpeg/ffprobe may be used only as external test oracles and fixture generators. They are never linked, bundled or shipped. - Dependencies must use permissive licences: MIT/Apache-2.0/BSD/ISC/Zlib/Unicode/CC0/BSL-1.0, or MPL-2.0 used unmodified. ## 3. Engineering rules ### 3.1 Never panic: fail with `Result` FilmCraft must not crash. A user losing unsaved work, or an agent's session dying, because of a bad file or an unexpected input is a bug as serious as wrong output. 1. **No panics in production code.** Don't use `unwrap()`, `expect()`, `panic!`, `unreachable!`, `todo!` or `unimplemented!` outside tests. Return `Result` with the crate's error type and propagate with `?`; in the UI, report the error (status bar, error dialog) and carry on. 2. **Avoid implicit panics too.** Index and slice with `get()` (or validate the bounds once, up front, where a hot loop needs plain indexing); use `checked_*` / `saturating_*` arithmetic where values come from outside; never divide by a value that can be zero (frame rates, timescales, sample rates, sizes); don't call `clamp` with bounds that can cross; bound recursion and loop counts. 3. **All input is untrusted:** media files, project and interchange files, presets, fonts, command parameters from the CLI / MCP / control channel, and UI state. A malformed or hostile input must give an error, never a panic, a hang, or an allocation sized by the input without a sane limit. 4. **Background work catches panics.** Every thread or job (export, previews, proxies, decoding workers…) runs its body under `catch_unwind` and reports a failure as an error: a dead worker leaves monitors blank or jobs "running" forever. 5. **Lock poisoning is not fatal:** use `lock().unwrap_or_else(|e| e.into_inner())`. 6. **Enforced:** crates deny `clippy::unwrap_used`, `clippy::expect_used`, `clippy::panic` and `clippy::unreachable` outside tests. Where an invariant truly cannot be violated and restructuring is unreasonable, a single-item `#[allow(...)]` with a one-line justification comment is acceptable; keep these rare and reviewable. 7. **Test the failure paths:** parsers and decoders get mutation-fuzz tests (truncation, bit flips, corrupt sizes) run under `catch_unwind`; new commands get hostile-parameter tests. Fix every panic a fuzzer finds and keep its reproducer as a test. ### 3.2 The rest See `CLAUDE.md`: pure Rust, dependency layering (`cargo xtask layers`), exact `Tick` time, everything is a command, everything is agent-drivable, and the quality gates (`cargo xtask ci`) before every commit. ## See also - [CONTRIBUTING.md](CONTRIBUTING.md) and [docs/contributing.md](docs/contributing.md): setup, gates, commits, how to add things - [docs/architecture.md](docs/architecture.md): layers, data model, commands, pipeline - [docs/testing.md](docs/testing.md): oracle tests, criteria, benchmarks - [docs/agents.md](docs/agents.md): driving FilmCraft over MCP / the control channel, and the agent work loop - [docs/control-protocol.md](docs/control-protocol.md): control-channel method reference - [ATTRIBUTION.md](ATTRIBUTION.md): asset index