Philosophy
Core design principles for Cambium.
Cambium is a Pipeline Orchestrator
Founding use case: Game asset conversion - textures, meshes, audio, configs all need processing through diverse tools with inconsistent interfaces.
Core job: Unification. One vocabulary, one interface, many backends.
The Agent Knowledge Gap
The deeper motivation: agents suck at toolchains.
When an AI agent (like moss) needs to convert data, it faces:
- "Do I run blender? gltf-pipeline? meshoptimizer?"
- "What flags? Is it installed? Which version?"
- Hallucinated flags, wrong CLI versions, failed optimizations
Cambium solves this by being a route planner, not a task runner.
# Task runner (make/just): agent must know the recipe
blender --background --python export.py -- input.blend output.glb
gltf-pipeline -i output.glb -o optimized.glb --draco.compressionLevel 7
# Cambium: agent only knows source and destination
cambium convert model.blend optimized.glb --optimizeThe agent says "I have X, I need Y" - cambium finds the path through the graph.
Why not existing tools?
| Tool | Approach | Gap |
|---|---|---|
| Make | File-based, mtime-driven | You write the recipes |
| Just | Task runner | You write the recipes manually |
| Nix | Content-addressed, reproducible | Heavyweight, config-heavy |
| Cambium | Type-driven route planning | Agent just declares intent |
Scope test: If the transformation is "agent shouldn't need to know the toolchain," it's in scope. If it requires business logic or architectural decisions, it's out.
Plan → Execute (Agent-Friendly Interface)
Conversions are two-phase:
Phase 1: Plan - Find path, surface required decisions.
cambium plan --from sprites/*.png --to spritesheet.png
# Output:
# Suggested path: glob → regex-extract → spritesheet-pack
# Required:
# regex-extract.pattern: string (regex with named groups)
# Optional:
# spritesheet-pack.quality: 0-100 (default: 80)
# spritesheet-pack.padding: int (default: 2)
# Presets: --preset lossless | balanced | crush
# Tools: all available ✓Phase 2: Execute - Provide options, run the path.
cambium convert sprites/*.png spritesheet.png \
--pattern "sprite_(?<id>\d+)_(?<frame>\d+)" \
--preset balancedIncomplete plans = suggestions. No separate suggest command.
# Incomplete: only source and sink
cambium plan --from input.png --to output.webp
# Cambium suggests pipeline + shows what options are available
# Complete: shows exact execution plan
cambium plan workflow.yamlNormalized Options
Users learn ONE vocabulary. Cambium maps to tool-specific flags:
# Same --quality flag everywhere
cambium convert image.png image.webp --quality 80 # → cwebp -q 80
cambium convert video.mp4 video.webm --quality 80 # → ffmpeg -crf 23
cambium convert model.glb model.glb --quality 80 # → draco level 7Agent doesn't need to know that quality=80 means different flags for different tools.
Presets
Declarative option bundles for common scenarios:
# presets.toml
[lossless]
quality = 100
compression = "lossless"
[balanced]
quality = 80
compression = "lossy"
[crush]
quality = 60
strip_metadata = truecambium convert image.png image.webp --preset crush
cambium convert image.png image.webp --preset balanced --quality 90 # overrideProperty Bags, Not Types
See ADR-0003
Data is described by property bags, not hierarchical types:
{format: "png", width: 1024, height: 768, colorspace: "srgb"}Conversion = property transformation. Format is just another property.
{format: "png", width: 4096} → {format: "webp", width: 1024}Same model handles format change, resize, transcode, etc.
Property naming: Flat by default, namespace only when semantics differ.
width,height,format- universalimage.compressionvsarchive.compression- different meanings
Workflows
Workflows are serializable pipelines:
# workflow.yaml
preset: balanced
source:
glob: "sprites/*.png"
steps:
- converter: regex-extract
options:
pattern: "sprite_(?<id>\\d+)_(?<frame>\\d+)"
- converter: spritesheet-pack
options:
quality: 90
sink:
path: "output/sprites.png"Format-agnostic: YAML, TOML, JSON - cambium eats its own dogfood.
cambium convert workflow.json workflow.yaml # convert workflow files tooAgents can build workflows programmatically:
Workflow::new()
.preset("balanced")
.source("sprites/*.png")
.pipe("regex-extract", [("pattern", r"sprite_(?<id>\d+)_(?<frame>\d+)")])
.pipe("spritesheet-pack", [("quality", 90)])
.sink("output/sprites.png")
.build()?N→M Cardinality
Not all conversions are 1→1:
| Pattern | Example |
|---|---|
| 1→1 | png → webp |
| 1→N | video → frames |
| N→1 | frames → video, files → manifest |
| N→M | batch tree conversion |
Converters declare their cardinality. Orchestration handles batching.
No special cases: sidecars, manifests, spritesheets are all just N→M conversions.
Pattern Extraction (Plugin)
Structured filename parsing is a plugin, not core. Uses regex:
cambium convert "sprites/*.png" spritesheet.png \
--pattern "sprite_(?<id>\d+)_(?<frame>\d+)"The regex-extract plugin parses filenames, enriches properties:
- Input:
{path: "sprite_001_002.png"} - Output:
{path: "sprite_001_002.png", id: "001", frame: "002"}
Why regex: agents know regex (even if imperfectly), no new DSL to learn.
Plugins, Not Monolith
Unlike pandoc/ffmpeg (which bundle everything), Cambium is:
- Core: property bags, graph traversal, workflow orchestration, CLI
- Plugins: converters, inspectors, pattern extractors
cambium plugin add cambium-images # png, jpg, webp, etc.
cambium plugin add cambium-ffmpeg # video/audio via ffmpeg
cambium plugin add cambium-regex # pattern extractionPlugins are C ABI dynamic libraries. See ADR-0001.
Library-First
Cambium is a library with a CLI wrapper, not vice versa.
use cambium::{Registry, Workflow};
let registry = Registry::with_default_plugins()?;
let plan = registry.plan(&from_props, &to_props)?;
let result = registry.execute(&plan, &input, &options)?;See ADR-0002.
No Special Cases
Design principle: if something feels like a special case, generalize it.
- "Sidecars" → just 1→N conversion
- "Manifests" → just N→1 conversion
- "Presets" → just option bundles
- "Pattern extraction" → just a property-enriching converter
- "Suggest" → just
planon incomplete workflow
One model, many uses.
Prior Art & Inspiration
Tools that informed Cambium's design:
| Tool | What It Does | What We Take |
|---|---|---|
| CyberChef | "Cyber Swiss Army Knife" - browser-based encoding, compression, hashing, data analysis | Recipe-based pipelines, comprehensive format coverage, "bake" metaphor |
| Pandoc | Universal document converter | Format graph traversal, intermediate representation idea |
| FFmpeg | Media transcoding | Filter graphs, format negotiation |
| ImageMagick | Image manipulation | Batch processing, format detection |
| jq | JSON processor | Streaming, composable transformations |
Key difference: These tools are format-specific or monolithic. Cambium is a unified orchestrator - one interface that routes to the right tool for each conversion.