garrytan / garrytan/gstack

design detector probes IMPECCABLE_SKILL: absent for every Claude Code plugin install of impeccable

Open
#2,838 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
133k
Forks
19.9k
Avg merge
18h 46m
Merged PRs (30d)
26

Description

`bin/gstack-design-detect.ts` looks for impeccable under `//skills/impeccable/`, but the normal way to get impeccable today is as a Claude Code plugin, which installs somewhere that pattern never reaches. Every plugin install therefore probes as `IMPECCABLE_SKILL: absent`, and the launcher and sibling-engine discovery in the same loop miss it too.

## Observed

gstack 1.84.1.0, Linux, impeccable plugin 4.3.1 installed via the Claude Code plugin marketplace.

```
$ bun ~/.claude/skills/gstack/bin/gstack-design-detect.ts probe
IMPECCABLE_READY: /home/dgrant/.impeccable/bin/0.1.5/impeccable
IMPECCABLE_SKILL: absent
IMPECCABLE_HOOK: absent
IMPECCABLE_IGNORED_RULES:
IMPECCABLE_IGNORED_FILES:
IMPECCABLE_IGNORED_VALUES:
IMPECCABLE_ENGINE_UNTESTED: 0.1.5
```

The skill is installed and its 23 `/impeccable ` commands are live in the session. `IMPECCABLE_SKILL: absent` is wrong.

## Why

`SKILL_ROOTS` (`bin/gstack-design-detect.ts:163`) is `['.claude', '.agents', '.cursor', '.gemini', '.github', '.opencode']`, and the loop at :311 tests `path.join(root, sub, 'skills', 'impeccable', 'SKILL.md')` for each of repoRoot, cwd and HOME. That resolves to `~/.claude/skills/impeccable/SKILL.md`.

A plugin install puts it at:

```
~/.claude/plugins/cache/impeccable/impeccable/4.3.1/skills/impeccable/SKILL.md
~/.claude/plugins/cache/impeccable/impeccable/4.3.1/skills/impeccable/scripts/impeccable # the launcher
```

`~/.claude/skills/impeccable/` does not exist and is not created by a plugin install — the manifest points Claude Code at `./skills/` inside the versioned plugin cache directory. The path segment `plugins/cache////` sits between the `SKILL_ROOTS` entry and the `skills/` the probe expects, so no amount of the existing pattern matches.

Three things in that one loop miss, not just the flag:

1. `p.skillPresent` stays false.
2. `p.launcher` stays null, so the `NOT_CACHED` state and its `DESIGN_DETECTOR_HINT` can never fire for a plugin user — the probe goes straight from "no engine" to `NOT_AVAILABLE` and the install offer, even though the user already has impeccable's own launcher on disk.
3. The sibling-engine candidate under `path.dirname(launcher)` is never considered.

## Consequence

Cosmetic but load-bearing for the interop story. The handoff lines are gated on `IMPECCABLE_SKILL: present`:

- `ship/sections/review-army.md:101` — "When the probe printed `IMPECCABLE_SKILL: present`, end each NEEDS INPUT detector row with the `handoff=` command"
- `design-review/SKILL.md:856` and `:1699` — same gate on deferred findings
- generated from `scripts/resolvers/design.ts:60` and `:892`, so `/review`, `/ship` and `/design-review` are all affected

So a plugin user gets the `FINDING-NNN [rule-id]` rows but never the `/impeccable typeset|layout|colorize|…` handoff that the v1.84.0.0 release notes describe as the point of the integration — and they have the skill installed and could act on it immediately. Detection itself is unaffected: scans run and findings are correct.

## Related: the engine was found by coincidence

On this machine `IMPECCABLE_READY` resolved even though gstack never installed anything — `design_detector_install_prompted=false` and `grep -c impeccable ~/.gstack/security/egress.jsonl` is 0. impeccable's own launcher had put the engine at `~/.impeccable/bin/0.1.5/impeccable`, which happens to be the exact cache layout gstack reserves for its own download, so the HOME-cache step matched by luck rather than through the plugin.

Two things follow from that. `IMPECCABLE_ENGINE_UNTESTED: 0.1.5` fires on every plugin user whose own launcher keeps the engine current, since gstack's fixtures pin 0.1.3. And a plugin user who says yes to the install offer gets a second, older engine written into the directory their launcher already manages.

## Reproduce

Install impeccable as a Claude Code plugin (`/plugin marketplace add pbakaus/impeccable` then install), with no `~/.claude/skills/impeccable/`, and run `gstack-design-detect probe`.

Contributor guide

Open the contributing guide

Research direction

Start in bin/gstack-design-detect.ts at SKILL_ROOTS and the detection loop around line 311, then reproduce with the probe command and a Claude Code plugin install. Trace how the plugin-cache path affects skillPresent, launcher, and sibling-engine discovery; done means plugin users report the skill and launcher correctly without being offered an unnecessary install, while the existing probe behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli, devtools, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.