mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 01:35:36 +00:00
fix(ownership): update syncs when a same-date snapshot is rebuilt
A snapshot republished for the same as-of date (the TRUE ticker fix) kept the date, latest release, and release count, so sync saw nothing to do and existing installs kept the bad data without --force. The manifest gains an optional snapshot.replaces_sqlite_sha256 listing earlier builds for that date. Queries never write to a synced file, so a local database byte-identical to a listed build is replaced; one that matches nothing (local imports or edits) still needs --force. The publisher fills the list on a same-date rebuild. Older clients ignore the field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
cda12fe2db
commit
ec17a1bd05
5 changed files with 191 additions and 2 deletions
|
|
@ -396,6 +396,22 @@ if [[ "$old_asset" != "$new_asset" ]] && remote_asset_exists "$old_asset" && rem
|
|||
else
|
||||
fail "forced refresh keeps the previous content-addressed artifact (old=$old_asset new=$new_asset count=$(asset_count))"
|
||||
fi
|
||||
old_sha="${old_asset#ownership-snapshot-2026-08-31-}"
|
||||
old_sha="${old_sha%.sqlite}"
|
||||
if [[ "$(remote_manifest_field '.snapshot.replaces_sqlite_sha256 | join(",")')" == "$old_sha" ]]; then
|
||||
pass "same-date rebuild lists the build it replaces"
|
||||
else
|
||||
fail "same-date rebuild lists the build it replaces (got $(remote_manifest_field '.snapshot.replaces_sqlite_sha256'))"
|
||||
fi
|
||||
mid_sha="$(remote_manifest_field '.snapshot.sqlite_sha256')"
|
||||
export FAKE_BUILD_VARIANT="second-replacement"
|
||||
run_publisher --force
|
||||
unset FAKE_BUILD_VARIANT
|
||||
if [[ "$(remote_manifest_field '.snapshot.replaces_sqlite_sha256 | join(",")')" == "$old_sha,$mid_sha" ]]; then
|
||||
pass "a second rebuild carries earlier replaced builds forward"
|
||||
else
|
||||
fail "a second rebuild carries earlier replaced builds forward (got $(remote_manifest_field '.snapshot.replaces_sqlite_sha256'))"
|
||||
fi
|
||||
|
||||
# ===========================================================================
|
||||
# 5. a trustworthy-looking manifest with a missing asset forces a republish
|
||||
|
|
|
|||
|
|
@ -461,6 +461,25 @@ cp "$STAGED_MANIFEST_PATH" "$OUTPUT_DIR/ownership-snapshot-manifest.json"
|
|||
cp "$STAGED_SQLITE_PATH" "$OUTPUT_DIR/"
|
||||
|
||||
MANIFEST_PATH="$OUTPUT_DIR/ownership-snapshot-manifest.json"
|
||||
|
||||
# A rebuild for the published as-of date (e.g. after a parser fix) lists the
|
||||
# builds it replaces, so clients still holding one update without --force.
|
||||
if [[ "$BUILT_AS_OF" == "$PUBLISHED_AS_OF" && "$PUBLISHED_SHA256" =~ ^[0-9a-fA-F]{64}$ ]]; then
|
||||
replaces_tmp="$PUBLISH_WORKDIR/manifest-replaces.json"
|
||||
jq --arg published "$PUBLISHED_SHA256" \
|
||||
--argjson previous "$(jq -c '.snapshot.replaces_sqlite_sha256 // []' <<< "$PUBLISHED_MANIFEST" 2>/dev/null || echo '[]')" '
|
||||
.snapshot.sqlite_sha256 as $own
|
||||
| .snapshot.replaces_sqlite_sha256 =
|
||||
([$previous[], $published]
|
||||
| map(ascii_downcase) | map(select(. != ($own | ascii_downcase)))
|
||||
| reduce .[] as $sha ([]; if index([$sha]) then . else . + [$sha] end)
|
||||
| .[-20:])
|
||||
| if (.snapshot.replaces_sqlite_sha256 | length) == 0
|
||||
then del(.snapshot.replaces_sqlite_sha256) else . end
|
||||
' "$MANIFEST_PATH" > "$replaces_tmp"
|
||||
mv "$replaces_tmp" "$MANIFEST_PATH"
|
||||
fi
|
||||
|
||||
SQLITE_PATH="$OUTPUT_DIR/$(basename "$STAGED_SQLITE_PATH")"
|
||||
SQLITE_ASSET_NAME="$(basename "$STAGED_SQLITE_PATH")"
|
||||
LOCAL_SQLITE_BYTES="$(wc -c < "$SQLITE_PATH" | tr -d ' ')"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue