readRemoteManifest treats a 404 on .geode/manifest.json as "no sync has ever happened" and pushes local files only. If the manifest is deleted while objects remain (a bucket lifecycle/expiry rule, manual cleanup, partial bucket restore), every existing remote object becomes invisible: absent from the new manifest, never pulled, orphaned forever. The first sync path never checks whether the bucket actually contains objects before assuming it is empty; listObjects exists and is unused by sync. Related to the stale state hazards in #89.
readRemoteManifest treats a 404 on .geode/manifest.json as "no sync has ever happened" and pushes local files only. If the manifest is deleted while objects remain (a bucket lifecycle/expiry rule, manual cleanup, partial bucket restore), every existing remote object becomes invisible: absent from the new manifest, never pulled, orphaned forever. The first sync path never checks whether the bucket actually contains objects before assuming it is empty; listObjects exists and is unused by sync. Related to the stale state hazards in #89.