v1.34.1.0 fix: gstack-update-check resists stale GitHub raw CDN + adds semver-order guard#1475
Merged
Merged
Conversation
Replace branch-raw fetch with git ls-remote + SHA-pinned raw URL. Add semver-order guard via sort -V so REMOTE < LOCAL stays silent instead of emitting a backwards UPGRADE_AVAILABLE line. Fence git ls-remote with GIT_TERMINAL_PROMPT=0 + 5s low-speed timeout. Honor explicit GSTACK_REMOTE_URL overrides for test fixtures and private mirrors. 3 new tests cover stale-CDN regression, multi-segment 1.9 vs 1.10 both directions. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
E2E Evals: ✅ PASS0/0 tests passed | $0 total cost | 12 parallel runners
12x ubicloud-standard-2 (Docker: pre-baked toolchain + deps) | wall clock ≈ slowest suite |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two bugs in
bin/gstack-update-checksurfaced when running/gstack-upgraderight after v1.34.0.0 landed:raw.githubusercontent.com/.../main/VERSION) was serving stale1.33.2.0for several minutes after the merge.--forcecleared the local cache but happily wroteUP_TO_DATE 1.33.2.0from the stale upstream and exited silently.UPGRADE_AVAILABLE 1.34.0.0 1.33.2.0, telling the user to "upgrade" to an older version. No semver-order check existed.This PR ships both fixes in one focused diff.
Fix 1: SHA-pinned VERSION fetch.
bin/gstack-update-checknow runsgit ls-remote https://github.com/garrytan/gstack.git refs/heads/mainto get the live HEAD SHA, then curlsraw.githubusercontent.com/garrytan/gstack/<SHA>/VERSION. SHA-pinned raw URLs are immediately consistent — no branch-raw CDN lag. Branch-pinned URL kept as a fallback for offline / no-git / mirror cases. NewGSTACK_REMOTE_REPOenv var lets tests and private mirrors override the git URL.Fix 2: Semver-order guard. After fetching REMOTE, the script runs
printf '%s\n%s\n' "$LOCAL" "$REMOTE" | sort -V | tail -1to confirm REMOTE > LOCAL. When LOCAL is at or ahead of REMOTE, it cachesUP_TO_DATEand exits silently. This protects against transient stale-CDN responses AND dev installs running ahead of main.Hardening:
git ls-remoteis fenced withGIT_TERMINAL_PROMPT=0+GIT_HTTP_LOW_SPEED_LIMIT=1000+GIT_HTTP_LOW_SPEED_TIME=5so a flaky network or captive portal can't hang every skill preamble.Test surface preservation: Existing tests use
GSTACK_REMOTE_URL=file://...fixtures. The script now skips the ls-remote SHA path whenGSTACK_REMOTE_URLis explicitly set, so all 35 existing tests pass unchanged.Test Coverage
browse/test/gstack-update-check.test.ts— 35 existing tests + 3 new semver-guard tests.New tests cover:
remote older than local (stale CDN) → silent, cache UP_TO_DATEmulti-segment sort: 1.9.0.0 < 1.10.0.0 → UPGRADE_AVAILABLEmulti-segment reverse sort: 1.10.0.0 > 1.9.0.0 → no rewindTests: 35 → 38 (+3 new). All green in 1.65s.
Pre-Landing Review
Pre-Landing Review: No issues found.
Manual adversarial pass on my own diff caught one real concern before commit:
git ls-remotehas no built-in timeout. WithoutGIT_HTTP_LOW_SPEED_*, a flaky network would hang every skill preamble. Fixed by fencing the call with the timeout env vars. Verified the test suite still passes after the addition.Surfaces reviewed:
_REMOTE_SHAvalidated against^[0-9a-f]{40}$before any URL interpolation. SHA cannot inject path traversal or query params.GSTACK_REMOTE_REPOandGSTACK_REMOTE_URLare user-controlled but only used asgit ls-remoteandcurltargets.GIT_TERMINAL_PROMPT=0prevents credential prompts on malicious URLs.sort -Vis available on both GNU and BSD coreutils, handles 4-segment versions consistently.Design Review
No frontend files changed — design review skipped.
Eval Results
No prompt-related files changed — evals skipped.
Plan Completion
No plan file detected — this was a focused hotfix discovered live during
/gstack-upgradeimmediately after v1.34.0.0 merged.TODOS
No TODO items completed in this PR.
Verification Results
End-to-end verified against real GitHub state:
After applying the patch to the global install at
~/.claude/skills/gstack/,gstack-update-check --forcecorrectly reportsUP_TO_DATE(LOCAL and REMOTE both at the live HEAD). Test suite reproduces every failure mode againstfile://fixtures without touching the network.Documentation
Documentation is current. No README / CLAUDE.md / ARCHITECTURE / CONTRIBUTING references to
gstack-update-checkinternals, and the newGSTACK_REMOTE_REPOenv var is documented in-script.Test plan
bun test browse/test/gstack-update-check.test.ts— 38 pass, 0 failgstack-update-check --forceagainst real GitHub returnsUP_TO_DATEraw.githubusercontent.com/<owner>/<repo>/<SHA>/VERSIONreturns the live VERSIONUPGRADE_AVAILABLElines🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmithwith what you need.