* test(#2624): failing-first regression for stale .gsd-source marker read-before-write
Adds failing-first regression proving a Claude-global upgrade currently lets
staging read a stale prior-version .gsd-source marker before install() rewrites
it. Pre-seeds a stale marker pointing at a still-existing fake source, spies on
findInstallSourceRoot to capture which source staging resolves, and asserts
staging never resolves the stale path. Also covers fresh-install and ghost-marker
negative space.
* fix(#2624): write the .gsd-source marker before staging reads it
A Claude-global upgrade silently installed skill content from the PREVIOUS
version. findInstallSourceRoot prefers <configDir>/.gsd-source, and install()
used to rewrite that marker AFTER staging had already read it — so on an
upgrade the marker still pointed at the prior version's source (an npx cache
dir that still exists on disk) and every converted skill was generated from
the OLD commands/gsd, with generateManifest then recording the stale content's
hash as correct.
Extract the marker write into _writeGsdSourceMarker(runtime, targetDir, src,
isGlobal) and call it BEFORE the staging pass (before the _isSkillsRuntime
branch), preserving the original sourceMarkerFile && isGlobal guard, the
half-published-package existsSync guard, and the non-fatal write-failure warn.
This closes the read-before-write hole for every findInstallSourceRoot
consumer (skills, commands, /gsd-surface, capability-state) in one move.
Long-standing (marker write added in ee6f3b70c / #1477, already in v1.7.0);
triggers on any Claude-global upgrade where skill content changed and the
prior source path still exists (the common npx-persistent-cache case).
* test(#2624): use t.mock.method for process.exit/console per CONTRIBUTING rules
Address code-review finding: replace manual process.exit/console monkeypatch
and try/finally in the #2624 test helpers with t.mock.method (auto-restored),
matching CONTRIBUTING.md test conventions and the t.mock.method idiom used
elsewhere in the suite.
* docs(changeset): #2624 install-source-root-stale-marker
* docs(changeset): backfill #2624 PR number to 2811
510 B
510 B
type, pr
| type | pr |
|---|---|
| Fixed | 2811 |
Upgrading a Claude-global GSD install now uses the new version's skill content instead of the previous version's — the installer read a .gsd-source marker that still pointed at the prior install's source location before rewriting it, so on an upgrade every converted skill was generated from the old version's command definitions (while the file manifest faithfully recorded the stale content's hash as correct). The marker is now written before anything reads it. (#2624)