# Art DAG Recipes Declarative media composition using content-addressed primitives and effects. ## Recipes | Recipe | Description | Inputs | Status | |--------|-------------|--------|--------| | [identity-cat](recipes/identity-cat/) | Apply identity effect to cat | fixed | ✅ Working | | [identity-then-dog](recipes/identity-then-dog/) | Chain identity → dog effects | fixed | ✅ Working | | [dog-concat](recipes/dog-concat/) | Dog video + user video concatenated | fixed + variable | ✅ Working | | [beat-cuts](recipes/beat-cuts/) | Cut between videos on beats | variable | 🔮 Future | | [energy-reactive](recipes/energy-reactive/) | Effects pulse with music energy | variable | 🔮 Future | | [tempo-match](recipes/tempo-match/) | Speed-match videos to music tempo | variable | 🔮 Future | ## Quick Start ```bash # Upload a recipe artdag upload-recipe recipes/dog-concat/recipe.yaml # Upload your video artdag upload /path/to/my-video.mp4 # → returns content_hash # Run with variable input artdag run-recipe -i source_second: ``` ## Recipe Structure ``` recipes/ ├── identity-cat/ │ ├── recipe.yaml # DAG definition │ └── README.md # Documentation ├── dog-concat/ │ └── recipe.yaml └── beat-cuts/ # Future: audio-reactive └── recipe.yaml ``` ## Recipe Schema ```yaml name: recipe-name version: "1.0" description: "What this recipe does" # Content-addressed references registry: assets: cat: hash: "33268b6e..." url: "https://..." effects: dog: hash: "d048fe31..." # DAG definition dag: nodes: - id: source_cat type: SOURCE config: asset: cat # Fixed: from registry - id: user_video type: SOURCE config: input: true # Variable: supplied at runtime name: "User Video" description: "Your video file" - id: result type: SEQUENCE inputs: - source_cat - user_video output: result owner: "@giles@artdag.rose-ash.com" ``` ## Primitives ### Implemented | Primitive | Description | Example | |-----------|-------------|---------| | `SOURCE` | Load media file | `config: { asset: cat }` or `{ input: true }` | | `SEGMENT` | Extract time range | `config: { offset: 0, duration: 5.0 }` | | `RESIZE` | Scale/crop/pad | `config: { width: 1920, height: 1080, mode: fit }` | | `TRANSFORM` | Visual effects | `config: { effects: { saturation: 1.5 } }` | | `SEQUENCE` | Concatenate in time | `config: { transition: { type: cut } }` | | `LAYER` | Stack spatially | `config: { inputs: [{}, {opacity: 0.5}] }` | | `MUX` | Combine video + audio | `config: { shortest: true }` | | `BLEND` | Blend two inputs | `config: { mode: overlay, opacity: 0.5 }` | | `EFFECT` | Apply registered effect | `config: { effect: dog }` | ### Future (Audio-Reactive) | Primitive | Description | Example | |-----------|-------------|---------| | `ANALYZE` | Extract audio features | `config: { feature: beats }` | | `BIND` | Map data → parameters | `config: { source: energy, target: saturation }` | | `MAP` | Apply op to each item | `config: { operation: RANDOM_SLICE }` | | `TRANSFORM_DYNAMIC` | Time-varying effects | Effects driven by BIND output | | `SOURCE_LIST` | Multiple inputs as list | `config: { input: true, min_items: 2 }` | | `GROUP` | Chunk data | `config: { size: 4, output: segments }` | | `COMPUTE` | Arithmetic on data | `config: { expression: "tempo / 120" }` | See [PRIMITIVES.md](PRIMITIVES.md) for full design documentation. ## Input Types ### Fixed Inputs Referenced by content hash from registry. Always the same. ```yaml config: asset: cat # Resolved from registry.assets.cat.hash ``` ### Variable Inputs Supplied at runtime by the user. ```yaml config: input: true name: "My Video" description: "Video to process" ``` ## DAG Patterns ### Chain Effects ``` SOURCE → EFFECT → EFFECT → output ``` ### Concatenate ``` SOURCE ──┐ ├→ SEQUENCE → output SOURCE ──┘ ``` ### Mux Audio + Video ``` video SOURCE ──┐ ├→ MUX → output audio SOURCE ──┘ ``` ### Audio-Reactive (Future) ``` audio → ANALYZE → BIND ──┐ ├→ TRANSFORM_DYNAMIC → MUX → output video ───────────────────┘ ``` ## Content Addressing Everything is identified by SHA3-256 hash: - **Assets**: `33268b6e167deaf018cc538de12dbe562612b33e89a749391cef855b320a269b` - **Effects**: `d048fe313433eb4e38f0e24194ffae91b896ca3e6eed3e50b2cc37b7be495555` - **Nodes**: `hash(type + config + inputs)` - automatic deduplication - **Recipes**: Hash of YAML file Same inputs + same recipe = same output. Always. ## Ownership Recipes are signed by ActivityPub actors (e.g., `@giles@artdag.rose-ash.com`). Ownership enables: - Provenance tracking - Revenue distribution down the creation chain - Federated sharing across L2 servers ## Registry References - **Assets**: https://git.rose-ash.com/art-dag/registry - **Effects**: https://git.rose-ash.com/art-dag/effects - **Art Source**: https://git.rose-ash.com/art-dag/art-source