XMP Sync And Writeback Policy¶
This page defines the bounded public policy for generated portable XMP during metadata transfer.
It covers:
generated EXIF-to-XMP properties
generated IPTC-to-XMP properties
source embedded XMP decoded from the source metadata
destination embedded XMP loaded from the target file
destination sidecar XMP loaded from a sibling
.xmp
This is not a full arbitrary metadata synchronization engine. It is the writer-side contract used by the transfer helpers so hosts can predict preserve, merge, and writeback behavior.
For target-specific embedded carrier replacement and unmanaged-data preservation rules, see Writer Target Contract.
Default Contract¶
The default transfer behavior is conservative:
Option |
Default |
Effect |
|---|---|---|
|
|
Generate portable XMP properties from EXIF/TIFF/GPS fields. |
|
|
Generate portable XMP properties from IPTC-IIM fields. |
|
|
Include existing XMP already decoded into the source |
|
|
Emit generated EXIF properties, then existing XMP, then generated IPTC properties. |
|
|
Do not merge a destination sidecar unless explicitly requested. |
|
|
Do not merge destination embedded XMP unless explicitly requested. |
|
|
Keep generated XMP in the managed embedded carrier. |
|
|
Preserve existing embedded XMP when sidecar-only writeback suppresses generated embedded XMP. |
|
|
Preserve an existing sibling |
Native EXIF and IPTC carrier emission is independent from XMP projection.
Turning off xmp_project_exif or xmp_project_iptc suppresses only the
generated XMP projection, not native EXIF/IPTC transfer.
Existing XMP Carrier Precedence¶
OpenMeta first builds one decoded transfer store. Optional destination XMP carriers are merged into that store before or after the source entries according to explicit precedence options.
For duplicate existing XMP properties, earlier merged entries win during portable XMP output.
Conflict |
Option |
Default order |
Alternate order |
|---|---|---|---|
destination sidecar vs source embedded XMP |
|
sidecar before source ( |
source before sidecar ( |
destination embedded XMP vs source embedded XMP |
|
destination before source ( |
source before destination ( |
destination sidecar vs destination embedded XMP |
|
sidecar before embedded ( |
embedded before sidecar ( |
The destination sidecar is loaded only when
xmp_existing_sidecar_mode == MergeIfPresent. The destination embedded
packet is loaded only when
xmp_existing_destination_embedded_mode == MergeIfPresent.
If both destination sidecar and destination embedded XMP are merged on the
same side of the source entries,
xmp_existing_destination_carrier_precedence decides which destination
carrier wins. If they are placed on opposite sides of the source entries, the
two source-precedence options define the effective order.
Failed or missing optional destination carriers do not silently change the source metadata. The result reports a status and message for the attempted sidecar or destination-embedded load.
Generated EXIF/IPTC Versus Existing XMP¶
After the transfer store is assembled, xmp_conflict_policy decides the
relative precedence between generated portable XMP and the existing XMP set.
The existing XMP set includes source embedded XMP plus any destination XMP
carriers that were explicitly merged.
Policy |
Pass order |
Practical effect |
|---|---|---|
|
EXIF-derived, existing XMP, IPTC-derived |
EXIF projection wins over existing XMP; existing XMP wins over IPTC projection. |
|
existing XMP, EXIF-derived, IPTC-derived |
Existing XMP wins over generated EXIF/IPTC projection. |
|
EXIF-derived, IPTC-derived, existing XMP |
Generated EXIF/IPTC projection wins over existing XMP. |
When generated EXIF and generated IPTC projection both claim the same portable property, EXIF-derived output is emitted first and wins.
xmp_existing_standard_namespace_policy applies inside the existing-XMP
pass:
PreserveAllkeeps existing standard portable namespace entries subject to the conflict order above.CanonicalizeManageddrops OpenMeta-managed standard portable properties from existing XMP when a generated replacement exists.
xmp_existing_namespace_policy controls breadth:
KnownPortableOnlykeeps only standard portable namespaces known to OpenMeta.PreserveCustomalso preserves safe simple or indexed properties from custom namespaces.
Writeback Modes¶
Writeback mode controls where the generated XMP packet goes after transfer execution.
Mode |
Edited file |
Sibling |
Cleanup behavior |
|---|---|---|---|
|
Generated XMP stays in the managed embedded carrier. |
No generated sidecar output. |
Existing sidecar is preserved unless
|
|
Generated embedded XMP blocks are suppressed. |
Generated XMP is returned as sidecar output. |
Existing embedded XMP is preserved unless
|
|
Generated XMP stays in the managed embedded carrier. |
The same generated XMP is returned as sidecar output. |
No destination sidecar cleanup is requested. |
Destination sidecar cleanup is supported only for embedded writeback. If
xmp_destination_sidecar_mode == StripExisting, OpenMeta returns a cleanup
request for the sibling .xmp;
persist_prepared_transfer_file_result(...) performs the removal when
remove_destination_xmp_sidecar is true.
Destination embedded-XMP stripping is supported for sidecar-only writeback on
the current managed writer targets: JPEG, TIFF/DNG, PNG, WebP, JP2, JXL, and
bounded BMFF targets (HEIF, AVIF, CR3). Other combinations report
an unsupported policy result instead of guessing.
Sidecar output and cleanup paths are derived from xmp_sidecar_base_path
when provided, otherwise from the edit/output target path. Hosts that do not
have a filesystem path can set xmp_existing_destination_sidecar_state
explicitly so OpenMeta can return deterministic cleanup guidance without
probing the filesystem.
The persistence helper writes generated sidecars only when sidecar output is
requested. It does not overwrite an existing sidecar unless
overwrite_xmp_sidecar is true.
Non-Goals¶
This bounded policy intentionally does not claim:
full MWG-style EXIF/IPTC/XMP reconciliation
arbitrary XMP graph editing
raw packet passthrough or byte-for-byte XMP preservation
semantic conflict resolution beyond the documented portable property order
full sidecar and embedded synchronization for every possible namespace
Those remain broader parity work. The current contract is meant to be stable enough for predictable transfer and export workflows.