Title: gstack-slug inherits outer-repo slug when project is a subdirectory; poisoned cache is unrecoverable
Summary
bin/gstack-slug derives the project slug from git remote get-url origin. When the current working directory is a subdirectory of a larger git repo (e.g., a standalone project living inside a shared workspace repo), git walks up and returns the outer repo's remote. The resulting slug belongs to the outer repo, not the actual project. That slug is then cached at ~/.gstack/slug-cache/{pwd-encoded} with no TTL, no invalidation path, and no override — so once it's wrong, it stays wrong across every future session for that path.
Repro
- Have a git repo at
/Users/me/workspace with remote origin pointing to me/workspace.
- Create a new project dir at
/Users/me/workspace/IoTopia/ (no .git of its own).
cd /Users/me/workspace/IoTopia && gstack-slug
Expected
Slug reflects the IoTopia project — either prompt the user, or fall back to basename since this dir is not the repo root.
Actual
The outer repo's slug. ~/.gstack/projects/me-workspace/ now collects artifacts for an unrelated project, and ~/.gstack/slug-cache/_Users_me_workspace_IoTopia locks that mistake in.
Root cause
bin/gstack-slug lines ~22–28:
REMOTE_URL=$(git remote get-url origin 2>/dev/null) || REMOTE_URL=""
if [[ -n "$REMOTE_URL" ]]; then
RAW_SLUG=$(printf '%s' "$REMOTE_URL" | sed '...')
SLUG=$(printf '%s' "$RAW_SLUG" | tr -cd 'a-zA-Z0-9._-')
fi
There is no check for whether $PWD is actually the repo's top-level. Any subdirectory inherits the parent repo's identity.
Impact
Downstream skills (office-hours, plan-ceo-review, plan-eng-review, autoplan, design-consultation, etc.) read/write under ~/.gstack/projects/{slug}/. When slug is wrong, artifacts land in the wrong project's folder and cross-contaminate unrelated work. Users only notice after the fact, and manual cleanup of both ~/.gstack/projects/ and ~/.gstack/slug-cache/ is needed.
Suggested fixes (in order of increasing ambition)
- Subdir guard. Before trusting the remote URL, check
git rev-parse --show-toplevel against $PWD. If they differ, don't inherit the outer slug — fall through to basename, or prompt.
- Per-project override. If a
.gstack-slug file exists in $PWD, use its contents verbatim and skip all inference. Cheap, user-controllable, survives gstack-upgrade.
- Cache management. Add
gstack-slug --reset to clear the cache entry for $PWD, and gstack-slug --set <slug> to write one explicitly. Also consider a TTL or a staleness warning when the cached slug doesn't match what the resolver would compute today.
- Interactive first-run. For a new path that has no cache entry and ambiguous inference (subdir of another repo, no
.git, etc.), prompt once and persist the choice to .gstack-slug.
Environment
- gstack version: 1.5.1.0
- OS: macOS (Darwin 25.3.0)
- Shell: zsh
Title:
gstack-sluginherits outer-repo slug when project is a subdirectory; poisoned cache is unrecoverableSummary
bin/gstack-slugderives the project slug fromgit remote get-url origin. When the current working directory is a subdirectory of a larger git repo (e.g., a standalone project living inside a shared workspace repo), git walks up and returns the outer repo's remote. The resulting slug belongs to the outer repo, not the actual project. That slug is then cached at~/.gstack/slug-cache/{pwd-encoded}with no TTL, no invalidation path, and no override — so once it's wrong, it stays wrong across every future session for that path.Repro
/Users/me/workspacewith remoteoriginpointing tome/workspace./Users/me/workspace/IoTopia/(no.gitof its own).cd /Users/me/workspace/IoTopia && gstack-slugExpected
Slug reflects the IoTopia project — either prompt the user, or fall back to basename since this dir is not the repo root.
Actual
The outer repo's slug.
~/.gstack/projects/me-workspace/now collects artifacts for an unrelated project, and~/.gstack/slug-cache/_Users_me_workspace_IoTopialocks that mistake in.Root cause
bin/gstack-sluglines ~22–28:There is no check for whether
$PWDis actually the repo's top-level. Any subdirectory inherits the parent repo's identity.Impact
Downstream skills (office-hours, plan-ceo-review, plan-eng-review, autoplan, design-consultation, etc.) read/write under
~/.gstack/projects/{slug}/. When slug is wrong, artifacts land in the wrong project's folder and cross-contaminate unrelated work. Users only notice after the fact, and manual cleanup of both~/.gstack/projects/and~/.gstack/slug-cache/is needed.Suggested fixes (in order of increasing ambition)
git rev-parse --show-toplevelagainst$PWD. If they differ, don't inherit the outer slug — fall through to basename, or prompt..gstack-slugfile exists in$PWD, use its contents verbatim and skip all inference. Cheap, user-controllable, survivesgstack-upgrade.gstack-slug --resetto clear the cache entry for$PWD, andgstack-slug --set <slug>to write one explicitly. Also consider a TTL or a staleness warning when the cached slug doesn't match what the resolver would compute today..git, etc.), prompt once and persist the choice to.gstack-slug.Environment