Import Media
Queue cloud-sync handover batches and monitor worker runs.
About this section: Import MediaQueue cloud-sync handover bundles; the worker imports them in the background.
Purpose
Consume the upstream cloud-sync handover bundles from /mnt/ubuntu-nas/node2/assets/sync/ into the global library (asset, asset_gallery, asset_collection) per Decision 639. The CGI never imports inline; it queues batches into import_job for the background worker (Decision 640).
Flow
- Scan: walks the mount for
.readysentinels and records newingest_batchrows. - Pre-flight: validates the manifest shape, sentinel pair, and per-item decisions; no library writes.
- Queue: auto-preflights if needed, then inserts an
import_jobrow. Live progress shows on Import Tasks. - Bulk queue: select multiple batches and queue them in one click; the worker drains the queue in priority + FIFO order.
Example
Scan finds 37e428d2-a4f6-4a31-bacf-0c835fb24084.ready. Tick its checkbox (or several at once), click Queue selected. The worker claims the next queued job within seconds and writes job_* events as it progresses.
Consequences
- The library is site-agnostic. Sites surface library content via
asset_site_membership, gallery/collection membership, content allowlists, and access packages. - VIDEO-SIMPLE syncs import as stable
asset_type=videorows withasset_subtype=video_simple, duration, HLS, transcript, cloud-package, and library-cover deliverables. - Cancel is allowed only while a job is queued; once running, only
systemctl stop gpu-admin-panel-import-workerstops it. - Action
removeonly soft-deletes rows viadeleted_at; nothing is hard-deleted. - Frosted, blurred, and vivid_blurred derivatives are intentionally not persisted.
Deeper dive
Sourced from gpu-floor/MIGRATION-INTRO.md and the queued-worker decision in DECISION_LOG.md.
Worker contract
A long-running import-worker.pl daemon claims queued jobs using SELECT ... FOR UPDATE SKIP LOCKED (MariaDB 10.6+). It updates heartbeat_at every few items; if a worker dies, its running jobs are reset to queued after the configured stale threshold (default 15 minutes).
Sentinel protocol
A bundle is consumable only when both <sync_id>.json and <sync_id>.ready exist and the JSON has status = completed and verification.passed = true. The importer recomputes manifest_sha256 at consumption time so audit history records what we actually ingested.
Source-of-truth mapping
source/source.json->asset_source(cold provenance).source/data/photo.manifest.json+photo.analysis.json+photo.meaning.json+photo.family.json->asset_ai_runrows with explicitanalysis_kind; unknown filenames are captured withsource_data:<file>.- Bundled
cover_hash->asset_coverlinked to the parent asset. - Containers of type
gallery->asset_gallery+asset_gallery_itemjunctions.
Idempotency + integrity
Every multi-row write is wrapped in AdminDB::transaction. Hash-based UNIQUE keys make re-running the same batch a no-op. Per-item failures isolate to ingest_batch_item.decision = failed with last_error; the batch becomes partial when any siblings still succeeded.
Read-only mount + ledger boundary
The /mnt/ubuntu-nas/node2/assets tree is read-only for admin consumers. The importer never writes to upstream or deletes .ready sentinels; all consumer state lives in ingest_batch / ingest_batch_item / ingest_event / import_job in admin_panel.
Batch 8fccb37c-0689-4caa-857e-1e8f284fe2f6
Status: imported; action: import
Type
asset
Action
import
Status
imported
Items
25
Bytes
3.33 GB
Source host
orbit-2
Manifest sha256
89eaa0bc7638aed3...
Started
2026-06-27 18:00:11
Completed
2026-06-27 18:01:13
Manifest summary
- created_at: 2026-06-27T17:53:06Z
- completed_at: 2026-06-27T17:53:06Z
- verification.passed: true
- verification.total_files: 6058
- prior_sync_id: none
Job history 1
Newest first. The active job (if any) is at the top.
| id | state | requested_by | queued | claimed | worker | progress | finished | last_error |
|---|---|---|---|---|---|---|---|---|
| 12 | done | agent-e2e | 2026-06-27 18:00:14 | 2026-06-27 18:00:19 | vultr/pid:3491928 | 25/25 | 2026-06-27 18:01:13 | - |
Items 25
Per-item decisions captured by preflight and updated by import. Re-running pre-flight is safe.
| asset_type | asset_hash | cover_hash | decision | target ids | last_error | updated_at |
|---|---|---|---|---|---|---|
| video | c5bf9ae549af4e5a... | 99e73e6e5d44439d... | created | asset:395 | - | 2026-06-27 18:00:26 |
| reel | 6d1bcfe18f7259dd... | f7dc88e84a154048... | created | asset:396 | - | 2026-06-27 18:00:30 |
| reel | c5c7c52ca57ac72e... | 42262bf545a045e6... | created | asset:397 | - | 2026-06-27 18:00:34 |
| photo | 9a966fe0a853d078... | 41f60183537f4ca8... | created | asset:398 | - | 2026-06-27 18:00:36 |
| photo | 6ce31d467aa96b95... | abc517177eb84823... | created | asset:399 | - | 2026-06-27 18:00:37 |
| photo | 4f36f836a6f1af42... | a2453b3b69c949a4... | created | asset:400 | - | 2026-06-27 18:00:39 |
| photo | ffad87374ff59e3c... | 99722bb78bf44189... | created | asset:401 | - | 2026-06-27 18:00:40 |
| photo | e689f77f61e03bb8... | a8de705ca30748bd... | created | asset:402 | - | 2026-06-27 18:00:42 |
| photo | bd553eb27e99c3ed... | 278ece8bd9754956... | created | asset:403 | - | 2026-06-27 18:00:44 |
| photo | ae6467d076263013... | ef0174589013486f... | created | asset:404 | - | 2026-06-27 18:00:45 |
| photo | d71384e8e5dca817... | 8e586fd79b7447df... | created | asset:405 | - | 2026-06-27 18:00:47 |
| photo | 79f1ad91a30d0a4f... | 9e43f8b7770949e7... | created | asset:406 | - | 2026-06-27 18:00:49 |
| photo | 2e1b5a3f7186cfcc... | 2345e6ebe42f4417... | created | asset:407 | - | 2026-06-27 18:00:51 |
| photo | 683eb48ab82afa0a... | 8189b2824a8c48f0... | created | asset:408 | - | 2026-06-27 18:00:53 |
| photo | 1845945ba1e41f4c... | d22bcb779c13469d... | created | asset:409 | - | 2026-06-27 18:00:55 |
| photo | 61b1eada37171ac8... | aa531a83b5ea4e83... | created | asset:410 | - | 2026-06-27 18:00:57 |
| photo | e0d4eef7b27149d0... | 4a8c7f33978f4cf2... | created | asset:411 | - | 2026-06-27 18:00:58 |
| photo | b3a3b0af0b8cfd25... | d08f760786474ca7... | created | asset:412 | - | 2026-06-27 18:01:00 |
| photo | 9be4b682329e1170... | c0ff2d29f0e84f65... | created | asset:413 | - | 2026-06-27 18:01:02 |
| photo | a5e6389b1d0eb33b... | a9293f8070254482... | created | asset:414 | - | 2026-06-27 18:01:04 |
| photo | 33c637de4b615355... | ab4e794dad5b4610... | created | asset:415 | - | 2026-06-27 18:01:06 |
| photo | a13c13d88ea6d956... | f4e5346287e14a3a... | created | asset:416 | - | 2026-06-27 18:01:08 |
| photo | 973316e7fe3021ce... | 15016c1cada04884... | created | asset:417 | - | 2026-06-27 18:01:10 |
| photo | e714c82bfd0daea9... | 90925f4828f54276... | created | asset:418 | - | 2026-06-27 18:01:12 |
| photo | 60b94cd6c318fe5e... | 63436afc26e9452d... | created | asset:419 | - | 2026-06-27 18:01:13 |
Recent events
Append-only audit ledger for this batch (latest 50).
| event_type | payload | created_at |
|---|---|---|
| job_finished | {"error":null,"job_id":"12","phase":"job_finish","summary":{"items_seen":25,"ok":1,"status":"imported","summary":{"ok":1,"remaining":0,"status":"imported","tally":{"created":25,"deferred":0,"failed":0... | 2026-06-27 18:01:13 |
| import_finished | {"phase":"import","remaining":0,"skipped_terminal":0,"status":"imported","tally":{"created":25,"deferred":0,"failed":0,"linked":0,"skipped":0,"updated":0}} | 2026-06-27 18:01:13 |
| item_updated | {"container":1,"expected_member_count":22,"gallery_hash":"31b958c8ab9b6fc851f77f685b93ab79","gallery_id":"7","linked_member_count":22,"missing_member_count":0,"phase":"container_link","title":"AAAAAAA... | 2026-06-27 18:01:13 |
| item_created | {"cover_hash":"63436afc26e9452d9bf436211779ef11","error":null,"hash":"60b94cd6c318fe5e56b15435bdf7111e","phase":"item_import","target_ids":{"asset_id":"419"},"type":"photo"} | 2026-06-27 18:01:13 |
| item_created | {"cover_hash":"90925f4828f54276a6f215996fc2c92e","error":null,"hash":"e714c82bfd0daea9097a8f8e32cc2cc6","phase":"item_import","target_ids":{"asset_id":"418"},"type":"photo"} | 2026-06-27 18:01:12 |
| item_created | {"cover_hash":"15016c1cada048849284963730a413a9","error":null,"hash":"973316e7fe3021cebd6b08b6693131b0","phase":"item_import","target_ids":{"asset_id":"417"},"type":"photo"} | 2026-06-27 18:01:10 |
| item_created | {"cover_hash":"f4e5346287e14a3a8f496dccb41ff9cb","error":null,"hash":"a13c13d88ea6d956a430cc3ca6f311b7","phase":"item_import","target_ids":{"asset_id":"416"},"type":"photo"} | 2026-06-27 18:01:08 |
| item_created | {"cover_hash":"ab4e794dad5b4610bf49ac86cd0c6c0a","error":null,"hash":"33c637de4b615355069af5f61f12ea95","phase":"item_import","target_ids":{"asset_id":"415"},"type":"photo"} | 2026-06-27 18:01:06 |
| item_created | {"cover_hash":"a9293f8070254482b8c8fb0e14db701c","error":null,"hash":"a5e6389b1d0eb33b97f52dfaabf6cfbb","phase":"item_import","target_ids":{"asset_id":"414"},"type":"photo"} | 2026-06-27 18:01:04 |
| item_created | {"cover_hash":"c0ff2d29f0e84f659222f828c0b6869c","error":null,"hash":"9be4b682329e11707fbebc4791d14eb2","phase":"item_import","target_ids":{"asset_id":"413"},"type":"photo"} | 2026-06-27 18:01:02 |
| item_created | {"cover_hash":"d08f760786474ca7ae7862d57ac1f6a5","error":null,"hash":"b3a3b0af0b8cfd250823fa312ade6692","phase":"item_import","target_ids":{"asset_id":"412"},"type":"photo"} | 2026-06-27 18:01:00 |
| item_created | {"cover_hash":"4a8c7f33978f4cf28b5b6dd3d53a28c6","error":null,"hash":"e0d4eef7b27149d00f651aec0571070b","phase":"item_import","target_ids":{"asset_id":"411"},"type":"photo"} | 2026-06-27 18:00:58 |
| item_created | {"cover_hash":"aa531a83b5ea4e838d679b97ca45f917","error":null,"hash":"61b1eada37171ac83693b4fdcaa29f45","phase":"item_import","target_ids":{"asset_id":"410"},"type":"photo"} | 2026-06-27 18:00:57 |
| item_created | {"cover_hash":"d22bcb779c13469d97add0071c4989c0","error":null,"hash":"1845945ba1e41f4c44a2c2461ebf9511","phase":"item_import","target_ids":{"asset_id":"409"},"type":"photo"} | 2026-06-27 18:00:55 |
| item_created | {"cover_hash":"8189b2824a8c48f08b2ee8e93ea108f5","error":null,"hash":"683eb48ab82afa0a968700aa769bb1d3","phase":"item_import","target_ids":{"asset_id":"408"},"type":"photo"} | 2026-06-27 18:00:53 |
| item_created | {"cover_hash":"2345e6ebe42f44179ff4571fbc6e9b37","error":null,"hash":"2e1b5a3f7186cfcc1783383c0664bed0","phase":"item_import","target_ids":{"asset_id":"407"},"type":"photo"} | 2026-06-27 18:00:51 |
| item_created | {"cover_hash":"9e43f8b7770949e78f83daa7bfe50b3f","error":null,"hash":"79f1ad91a30d0a4fd2fa6737233ad045","phase":"item_import","target_ids":{"asset_id":"406"},"type":"photo"} | 2026-06-27 18:00:49 |
| item_created | {"cover_hash":"8e586fd79b7447dfa9e8fb5119f2b288","error":null,"hash":"d71384e8e5dca8174bb2548a569c28ab","phase":"item_import","target_ids":{"asset_id":"405"},"type":"photo"} | 2026-06-27 18:00:47 |
| item_created | {"cover_hash":"ef0174589013486fab8857438f3b264d","error":null,"hash":"ae6467d0762630136a419e71a01fa13a","phase":"item_import","target_ids":{"asset_id":"404"},"type":"photo"} | 2026-06-27 18:00:45 |
| item_created | {"cover_hash":"278ece8bd97549568dbb1abab03b9bcc","error":null,"hash":"bd553eb27e99c3ed4632d85ffb821c9b","phase":"item_import","target_ids":{"asset_id":"403"},"type":"photo"} | 2026-06-27 18:00:44 |
| item_created | {"cover_hash":"a8de705ca30748bd93e81d470f51bbea","error":null,"hash":"e689f77f61e03bb861c04a532a8175d8","phase":"item_import","target_ids":{"asset_id":"402"},"type":"photo"} | 2026-06-27 18:00:42 |
| item_created | {"cover_hash":"99722bb78bf44189b326124897bd2aaa","error":null,"hash":"ffad87374ff59e3cd8a7b77870132d75","phase":"item_import","target_ids":{"asset_id":"401"},"type":"photo"} | 2026-06-27 18:00:40 |
| item_created | {"cover_hash":"a2453b3b69c949a49e59db396de5b42a","error":null,"hash":"4f36f836a6f1af42b23c39ff57146fa6","phase":"item_import","target_ids":{"asset_id":"400"},"type":"photo"} | 2026-06-27 18:00:39 |
| item_created | {"cover_hash":"abc517177eb84823b9b9d53fa8c14029","error":null,"hash":"6ce31d467aa96b955a9893e8e74e0eb0","phase":"item_import","target_ids":{"asset_id":"399"},"type":"photo"} | 2026-06-27 18:00:37 |
| item_created | {"cover_hash":"41f60183537f4ca8afe8b2a4d423c524","error":null,"hash":"9a966fe0a853d078ce971626cfcfed8b","phase":"item_import","target_ids":{"asset_id":"398"},"type":"photo"} | 2026-06-27 18:00:36 |
| item_created | {"cover_hash":"42262bf545a045e6ac97b598af1d7dcd","error":null,"hash":"c5c7c52ca57ac72e2686e84a2e24a886","phase":"item_import","target_ids":{"asset_id":"397"},"type":"reel"} | 2026-06-27 18:00:34 |
| item_created | {"cover_hash":"f7dc88e84a15404890f0ce82972b35c2","error":null,"hash":"6d1bcfe18f7259dd338db8b141886ebc","phase":"item_import","target_ids":{"asset_id":"396"},"type":"reel"} | 2026-06-27 18:00:30 |
| item_created | {"cover_hash":"99e73e6e5d44439da9036d8e68b44f09","error":null,"hash":"c5bf9ae549af4e5a36fed5c94fd0a9d4","phase":"item_import","target_ids":{"asset_id":"395"},"type":"video"} | 2026-06-27 18:00:26 |
| import_started | {"action":"import","already_terminal_count":0,"container_count":2,"item_count":25,"manifest_sha256":"89eaa0bc7638aed3804308d1ab6fa5fdb69b4003557ba94618c8e1b1bc44b6c7","max_items":0,"phase":"import"} | 2026-06-27 18:00:19 |
| job_claimed | {"job_id":"12","phase":"job_claim","priority":100,"worker_id":"vultr/pid:3491928"} | 2026-06-27 18:00:19 |
| job_queued | {"job_id": "12", "requested_by": "agent-e2e", "items_total": "25"} | 2026-06-27 18:00:14 |
| preflight_finished | {"counts":{"will_create":25,"will_fail":0,"will_link":0,"will_skip":0,"will_update":0},"failure_samples":[],"item_count":25,"item_type_counts":{"photo":22,"reel":2,"video":1},"ok":1,"phase":"preflight... | 2026-06-27 18:00:14 |
| preflight_started | {"action":"import","container_count":2,"item_count":25,"item_type_counts":{"photo":22,"reel":2,"video":1},"manifest_sha256":"89eaa0bc7638aed3804308d1ab6fa5fdb69b4003557ba94618c8e1b1bc44b6c7","phase":"... | 2026-06-27 18:00:11 |
| scan | {"source": "agent-harness", "manifest_sha256": "89eaa0bc7638aed3804308d1ab6fa5fdb69b4003557ba94618c8e1b1bc44b6c7", "sync_type": "asset", "action": "import", "item_count": "25"} | 2026-06-27 18:00:11 |