Post-run reconciliation
Use the streamed event contract to make completed writes visible in the library.
UI events can make plugin writes part of the library immediately. When a streamed result event has status equal to matched or success, Oruva associates its asset_path with a context asset and inspects the file_written events from that same runId.
file_written.kind | What Oruva does |
|---|---|
replace | Calls POST /api/assets/<asset_id>/reconcile-file. Oruva re-hashes and re-stats the asset, re-extracts width, height, palette, and thumbnail, clears byte-sensitive AI data, and marks it for the next Make It Smart pass. The grid receives the refreshed thumbnail URL. |
extra | Calls POST /api/plugins/reconcile-extras with the reported paths. Each supported thumbnailable sibling enters the normal import or index pipeline and inherits the source asset's organizational folders. |
To participate:
- Write a replacement in place with the exact original path and filename, then emit
file_writtenwith that absolute path andkind:'replace'. - Write extras beside the original file, never elsewhere, and emit one
file_writtenevent withkind:'extra'and the absolute path for each. - After all writes, emit a
resultfor the same asset path and run withstatus:'matched'orstatus:'success'.
The exact-name and sibling rules are real validation boundaries. Without an explicit asset_path on a file_written payload, the host associates a replacement only when its reported path equals the result asset path, and an extra only when its parent equals the source parent. The backend repeats the sibling check, rejects the source itself as an extra, requires a supported thumbnailable asset, and rejects a sibling symlink that escapes the directory.
For a managed/imported library, extras pass through the copy pipeline and the temporary sibling is removed after its managed copy exists. For an indexed library, the sibling remains in place and is indexed. Existing matching extras are refreshed if their bytes changed. In all cases, Oruva copies the source asset's organizational-folder memberships to the imported extra.
Reconciliation is driven by the streamed events, not by scanning stdout text or the files_written array inside result. If a plugin writes files but omits the individual events, uses a non-success result status, or exits without a result, the files are not reconciled automatically.