From c866dd7a65b33c4c1e6845eb7f7aa5ff9bd0aeba Mon Sep 17 00:00:00 2001 From: hermes Date: Thu, 24 Sep 2026 21:12:34 +0000 Subject: [PATCH] fix(ownership): harden --history parsing per review Addresses review on #27: canonicalize --history ("08" no longer hits bash octal parsing), run the history jq in a plain command substitution so a jq failure aborts under set -e, and restore the schedule-guidance paragraph in OWNERSHIP_SELF_HOSTED.md. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017a5Cv5Z1NzdYKgKnTiAF4E --- docs/OWNERSHIP_SELF_HOSTED.md | 4 ++-- scripts/build-latest-ownership-snapshot.sh | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/OWNERSHIP_SELF_HOSTED.md b/docs/OWNERSHIP_SELF_HOSTED.md index 57be012..b51962a 100644 --- a/docs/OWNERSHIP_SELF_HOSTED.md +++ b/docs/OWNERSHIP_SELF_HOSTED.md @@ -71,11 +71,11 @@ That is intentionally conservative. The ownership source is monthly, but the exact publish day can drift. Observed XLSX upload times (HTTP Last-Modified): 2026-06-03, 2026-07-02 03:55Z, 2026-08-02 01:50Z, 2026-09-02 03:51Z, so a run on the 2nd can occasionally land before the file exists; the 3rd is safer. +Start with an early-month schedule and adjust after observing a few real runs. Pass `--history ` (for example via `services.idxOwnershipPublish.extraArgs = [ "--history" "5" ];` in `clan-private`) to include earlier months so -`idx ownership changes` works straight from the synced snapshot. Start with an early-month schedule and adjust after -observing a few real runs. +`idx ownership changes` works straight from the synced snapshot. ## Clan Integration Later diff --git a/scripts/build-latest-ownership-snapshot.sh b/scripts/build-latest-ownership-snapshot.sh index 72da16d..9b787b4 100755 --- a/scripts/build-latest-ownership-snapshot.sh +++ b/scripts/build-latest-ownership-snapshot.sh @@ -86,6 +86,8 @@ if ! [[ "$HISTORY" =~ ^[0-9]+$ ]]; then echo "--history must be a non-negative integer" >&2 exit 2 fi +# Canonicalize so "08" is 8, not an invalid octal literal in (( )). +HISTORY=$((10#$HISTORY)) if [[ -z "$BASE_URL" ]]; then BASE_URL="https://github.com/${REPO_FULL_NAME}/releases/download/${RELEASE_TAG}" @@ -167,7 +169,9 @@ DISCOVERED_ORIGINAL_FILENAME="${discovery_fields[6]:-}" if (( HISTORY > 0 )); then # Earlier supported XLSX months, one per as-of date, newest first; import oldest first. - mapfile -t history_urls < <( + # Run jq in a plain command substitution (not <(...)) so a jq failure + # stops the script under set -e instead of looking like zero months. + history_payload="$( jq -r --arg latest "$DISCOVERED_PDF_URL" --argjson n "$HISTORY" ' (map(select(.pdf_url == $latest)) | .[0].as_of_date // "") as $latest_as_of | [ .[] @@ -178,7 +182,11 @@ if (( HISTORY > 0 )); then | .[:$n] | reverse | .[].pdf_url ' "$DISCOVERY_JSON" - ) + )" + history_urls=() + if [[ -n "$history_payload" ]]; then + mapfile -t history_urls <<< "$history_payload" + fi printf 'Importing %d earlier monthly report(s) for history...\n' "${#history_urls[@]}" for url in "${history_urls[@]}"; do "$IDX_BIN" ownership import --url "$url"