Skip to content

fix(gstack-slug): resolve slug from git remote, not a stale cache#2010

Open
steven1370 wants to merge 1 commit into
garrytan:mainfrom
steven1370:fix/gstack-slug-remote-first
Open

fix(gstack-slug): resolve slug from git remote, not a stale cache#2010
steven1370 wants to merge 1 commit into
garrytan:mainfrom
steven1370:fix/gstack-slug-remote-first

Conversation

@steven1370

Copy link
Copy Markdown

Problem

bin/gstack-slug resolves a project's slug cache-first (~/.gstack/slug-cache/<encoded-path>) and never re-validates it against the git remote once cached. If the slug is first computed while a repo's origin is temporarily wrong — most commonly a project scaffolded by copying another repo before its remote is repointed — the wrong slug gets cached and then shadows the corrected remote forever. Every consumer (ship metrics, /retro, artifacts, project state) then files under the wrong project slug indefinitely.

Root cause

Lines 16-19 trust a present cache file verbatim, and the remote is only consulted on a cache miss (line 23). There is no invalidation path, so a stale entry is permanent.

Fix

Flip resolution to remote-first:

  1. Derive the slug from git remote get-url origin on every run.
  2. Fall back to the cached slug (then basename) only when there is no remote.
  3. Always refresh the cache to match the resolved slug.

A stale or poisoned cache now self-heals on the next run. For a remote-less repo or a non-repo dir, behavior is unchanged: the cache still provides cross-session stability and is still sanitized on read.

Invariants preserved: [a-zA-Z0-9._-] sanitization on every path, atomic cache write via mktemp + mv, and pipefail-safe remote read.

Verification

  • bash -n clean.
  • Correct resolution for repos with a remote, no-remote dirs (basename fallback), and a repo whose slug had previously been mis-cached.
  • Self-heal: writing a wrong value into the cache file, then running once, returns and re-caches the correct remote-derived slug.
  • Injection safety: a malicious cached value (only reachable on a no-remote dir) is sanitized to [a-zA-Z0-9._-], not executed.

🤖 Generated with Claude Code

gstack-slug cached a project's slug permanently and never re-validated it
against the git remote. A slug cached while a repo's remote was temporarily
wrong — e.g. a project scaffolded by copying another before its remote was
repointed — stuck forever, so that project filed its gstack/retro artifacts
under the wrong slug indefinitely (observed: a repo resolving to an unrelated
sibling project's slug).

Flip resolution to remote-first: derive the slug from `git remote get-url
origin` on every run and overwrite the cache. Fall back to the cache (then
basename) only when there is no remote. A stale or poisoned cache now
self-heals on the next run instead of being pinned forever.

The [a-zA-Z0-9._-] sanitization and atomic cache write are preserved; the
cache-read path is still sanitized (now reachable only on no-remote dirs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Jun 15, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant