- add/update consolidated into ingest(isNew) — persist branch differs, error handling and cover path fully shared (Task 24) - zipIndex/cover use bookfile.OpenReaderAt instead of hand-rolled open+stat pairs - root containment check uses bookfile.Contains (local inside removed) - cover write goes through media.WriteAtomic (now exported, log-free — callers own context); media no longer logs inside the atomic helper