# XMP sidecars and interchange LightCraft keeps its catalog as the source of truth, and can also store each photo's metadata and develop settings in an XMP sidecar next to the original. Sidecars let edits travel with the files (backups, another LightCraft library, other tools), and let LightCraft pick up edits made elsewhere. ## Sidecar files | | | |---|---| | Name | `.xmp` by default (`IMG_0001.CR3` → `IMG_0001.xmp`); `.xmp` (`IMG_0001.CR3.xmp`) with `naming: "full"`. Reading accepts either (preferred first) and `.XMP`. With stem naming, files sharing a stem don't share a sidecar: see *Shared names* below. | | Write | `photo.saveMetadataToFile {ids?}` (Photo ▸ Save Metadata to File, ⌘S), or automatically after every change with `library.xmpPreferences {autoWrite: true}` (File ▸ Automatically Write Changes into XMP). Slider drags are written once, when the drag ends; undo/redo rewrite the sidecar. An existing sidecar is **merged into, never replaced** (see *Saving into an existing sidecar*). Written atomically (temp file, fsync, rename). The result lists `written`, `merged` and `backups`. | | Read | On import (`library.import`, the report counts `sidecars`), and `photo.readMetadataFromFile {ids?}` (one undo step). For raw/DNG files without a sidecar, the XMP embedded in the file is used. | | Preferences | `library.xmpPreferences {autoWrite?, naming?: stem\|full}`, stored in the library's `prefs.json`. | What we write (standard namespaces, so other tools can read the metadata): | Field | XMP property | |---|---| | Rating 0–5 | `xmp:Rating` | | Colour label | `xmp:Label` (`Red`, `Yellow`, `Green`, `Blue`, `Purple`) | | Title / caption / copyright / creator | `dc:title` / `dc:description` / `dc:rights` / `dc:creator` | | Copyright status | `xmpRights:Marked` (`True` copyrighted, `False` public domain, absent = unknown) | | Rights usage terms / copyright info URL | `xmpRights:UsageTerms` / `xmpRights:WebStatement` | | Keywords | `dc:subject` | | Capture time, GPS | `exif:DateTimeOriginal`, `photoshop:DateCreated`, `exif:GPSLatitude`/`GPSLongitude` | | Pick / reject flag | `lc:flag` (`pick`, `reject`, `none`) | | Location | `lc:location` | | Develop settings | `lc:settings` — our complete `DevelopSettings` as JSON (exact round trip, incl. masks, spots, crop and the rendering process; settings without `process` are V1, see [process-versions.md](process-versions.md)) | `lc:` is `http://ns.lightcraft.app/lc/1.0/`. Reading merges into the catalog with the **sidecar winning** for every field it states; fields it doesn't state are kept. The one exception is the **capture time**: a time embedded in the file (EXIF/IPTC) always wins; when the file has none, the sidecar's `exif:DateTimeOriginal`, else `photoshop:DateCreated`, else `xmp:CreateDate` (ISO 8601) is used — on import (it then also files a copied photo in its date folder) and by `photo.readMetadataFromFile` (undoable). `xmp:Rating="-1"` (the XMP convention for rejected) sets the reject flag. Develop settings come from `lc:settings` when present (exact); otherwise from the `crs:` fields below (approximate). ## Saving into an existing sidecar A sidecar may already hold another application's data — e.g. its `crs:` develop settings and `xmpMM:History` — often the only copy of those edits outside that application's catalog. Saving never drops it: - LightCraft **owns** the properties in the table above: `xmp:Rating`, `xmp:Label`, `dc:title`, `dc:description`, `dc:rights`, `dc:creator`, `dc:subject`, `Iptc4xmpCore:Location`, `Iptc4xmpCore:AltTextAccessibility`, `Iptc4xmpCore:ExtDescrAccessibility`, `photoshop:City`/`State`/`Country`, `xmpRights:Marked`/`UsageTerms`/ `WebStatement` and everything in `lc:`. They are replaced on every save, and removed when LightCraft has no value (clearing a title in LightCraft clears it in the file). All of them are read back on import, so the library starts from what the sidecar said. - The **capture time** (`exif:DateTimeOriginal`, `photoshop:DateCreated`) and **GPS** (`exif:GPSLatitude`, `exif:GPSLongitude`) are replaced only when LightCraft has a value; otherwise the file's stay. - **Everything else is kept byte for byte**: other namespaces (`crs:`, `xmpMM:`, `lr:hierarchicalSubject`, unknown ones), `xmp:CreatorTool`, comments, the packet wrapper and padding. LightCraft's properties go into one `rdf:Description` of their own; owned properties written by another application (in attribute or element form) are removed from its description, which otherwise stays as it was. - A sidecar that can't be read as XMP (not well-formed, not UTF-8, no `rdf:RDF`) is first copied to `.xmp.bak-