Overview
A content-addressed, history-preserving, LLM-native successor to OpenRaster — and why this repo builds it.
FPD (working name — see Naming below) is a native document
format for layered image editing: content-addressed, branching-history,
worker-hosted, and built to make an AI-assisted edit ("same mask, three
models, three results") a first-class, losslessly-storable fact rather than
something every tool reinvents. faceless-photolib — the headless,
color-managed, GPU-accelerated engine documented in /docs — is the
format's reference implementation: it already ships a reference renderer
(CPU golden backend + WebGPU, with conformance
gates), which is exactly what a new format needs to
avoid the fate described below.
Why a new format
OpenRaster (ORA) is the closest prior art — an open, layered, zip-based interchange format — and it stalled at v0.0.6 with no steward. Research into why (see Positioning) converged on one lesson: ORA tried to be a universal layered-image file with no dominant reference renderer, so no two apps agreed on how a document should actually look. PSD stayed relevant not because it is elegant but because apps depended on it. Meanwhile, nobody ships an open, layered format that also stores generative provenance — the prompt, the mask, the model, and a branching history of results — even though every AI image tool (ComfyUI, Firefly, Krita AI Diffusion) now generates exactly that payload with nowhere durable to put it.
Positioning
This section's content is a direct build-out of the llm-native-media-format
research (OMEG) and the in-repo native-file-format change built on it. The
research's own framing:
Not "PSD but open." The sharpest v0 is "a content-addressed, GPU-ready, history-preserving media document for AI-assisted image creation" — an immutable object graph with a mutable head pointer, not a giant editable ZIP.
Concretely, that means:
- Reference-first, not file-first. A document is a small manifest plus a
graph of typed refs into a content-addressed blob store — see
Package anatomy. Directory-on-disk and single-file
.fpdare two envelopes around the identical logical package, not two formats. - History is a persistent, branching DAG, not linear undo. The same parent state can produce three sibling results (three different models given the same mask) without duplicating anything they share — see History-DAG model.
- A format without a reference renderer loses.
faceless-photolibships the renderer, golden images, and conformance gates before the format's spec was even frozen — the format is downstream of a working engine, not the other way around.
Ten invariants (research summary)
The full research fanned out ten parallel investigation streams plus two
independently-produced from-scratch designs (the user's prior "OMEG" and an
independent "Luma" design) that converged on the same architecture. The
invariants that shape every decision in this /format section:
| # | Invariant |
|---|---|
| 1 | Reference-first: manifest + graph of refs into content-addressed blobs, not "one big file." |
| 2 | Manifest-prefix + content-addressed blobs: identify the file and locate the preview from the first few KB. |
| 3 | Extensibility is a mechanism (skippable, versioned, preserve-unknown), not a wishlist — ORA died from unratified proposals. |
| 4 | Master ≠ GPU cache ≠ preview: multiple representations per resource, never conflated. |
| 5 | History = a persistent content-addressed DAG, not linear undo. Branches are sibling nodes sharing a parent. |
| 6 | Store intent and result: the prompt/mask is scope, the rendered pixels are the source of truth. |
| 7 | Filters: one declarative representation runs on CPU and GPU; WASM is an escape hatch, never canonical. |
| 8 | Provenance: embed C2PA rather than reinvent it (schema envelope reserved; emission is out of v0). |
| 9 | Wide gamut done right: linear-light, premultiplied, Rec.2020/ACEScg compositing — matches this engine's existing pipeline. |
| 10 | A format without a reference renderer loses. Ship the renderer + golden images + validator first. |
What ships in v0 — and what's explicitly deferred
The native-file-format change builds the format core; migration
importers and this documentation are sibling changes. In scope for v0:
- Canonical JSON + BLAKE3 content hashing with versioned ref strings (Ref grammar).
- The package layout, validator, and golden fixtures (Package anatomy).
- The branching history DAG with named heads, intent envelopes, and publish-time redaction (History-DAG model).
- All format I/O (open/save/validate/preview) in a Web Worker behind a typed protocol (Worker API), with a standalone CLI validator (Validator usage).
DocV2: image-layer sources become a discriminated union that can carry a typed content ref, with a realDocV1 → DocV2migration.
Explicitly out of v0 (per the research's own second-pass review and two
external consultant passes): KTX2 tiled GPU pyramids, a custom binary
container (the .fpd zip envelope is a placeholder — blobs stay
byte-addressable so it can be re-enveloped later without rewriting them),
C2PA emission (the intent envelope reserves the shape), full
generative-provenance workflow round-tripping, and CRDT/multi-writer editing.
PSD/ORA/Krita/flat-image import is the sibling format-migration-importers
change — see the migration guides for the policy
those importers ship under.
Planned: video layers
Video/animation functionality (video-layers, video-timeline in the corpus
feature registry) is registered ahead of the engine implementation. The
samples block below states that status explicitly — corpus samples tagged
with a planned feature run as typed planned-feature checks in the
Test Lab, never a silent skip, and
become enforcing the moment the feature ships (its registry status flips,
nothing else changes).
planned-feature checks, never a silent skip.Preparing sample list…
Naming
The working extension is .fpd ("Faceless Photo Document"). The research's
own working name, OMEG, collides with the unrelated
OME-Zarr bioimaging community, so this
repo does not use it; final naming is an open question in the
native-file-format change's design doc.
Where to go next
- Package anatomy — the directory/
.fpdtree, manifest and index fields, the mandatory flat-preview contract. - Ref grammar + canonical hashing — the
v1:b3:<hex>ref string, the JCS canonicalization profile, and the unknown-fields rule. - History-DAG model — nodes, named heads, branching, undo-as-a-view, publish-time redaction.
- Worker API reference and validator usage — how a browser app or a CI job talks to a package.
- Migration guides: OpenRaster, Krita, Photoshop, flat images.