* fix(#373): replace unquoted $GSD_SDK with space-safe gsd_run launcher Workflow bash blocks resolved the runtime as GSD_SDK="node $GSD_TOOLS" and invoked it unquoted ($GSD_SDK query ...). On install paths containing spaces (e.g. /Volumes/Mini Me/...) the unquoted expansion word-split into `node /Volumes/Mini gsd-tools.cjs ...`, failing with "Cannot find module '/Volumes/Mini'" and getting masked by `2>/dev/null || echo "{}"` into a silent empty state. Replace the string variable with a single-line shell launcher that defines a gsd_run function, invokes the runtime with a fully-quoted path and "$@", and preserves the local-cjs / installed-gsd-tools-on-PATH fallback (#3668) plus the loud not-found error and install hint. The launcher uses _GSD_SHIM_NAME indirection so no workflow emits the /gsd-tools substring that the do.md dispatcher-parity scanner would misread, and is single-line to stay within the per-file progressive-disclosure line budgets (#2551). The canonical launcher lives in get-shit-done/workflows/_runtime-launcher.snippet.sh, is propagated once per file by scripts/sync-runtime-launcher.cjs, and is locked by tests/runtime-launcher-parity.test.cjs (fails CI on drift, on a reappearing $GSD_SDK token, or on a /gsd-tools substring). Dependent workflow-assertion tests are updated from $GSD_SDK to gsd_run, and the runtime launcher is registered in CONTEXT.md. Fixes #373 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci(#373): add changeset fragment and allow-test-rule for parity guard The runtime-launcher parity test is a structural drift guard that reads workflow markdown to assert the canonical launcher is present and the retired $GSD_SDK / /gsd-tools tokens are absent; annotate it with allow-test-rule per the no-source-grep lint escape hatch. Add the required .changeset fragment for this user-facing fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * test(#373): make parity PATH-fallback assertion cross-platform (Windows) Subtest (E) compared GSD_TOOLS against the Node-side absolute temp path, but the value originates from git-bash which reports the POSIX form, so the prefix comparison failed on windows-latest while the launcher itself worked (the installed stub was invoked). Assert the resolved binary by normalized suffix (/bin/gsd-tools, not .cjs) instead of the absolute prefix; the behavioral stub-invocation assertion is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
11 KiB
<required_reading> Read all files referenced by the invoking prompt's execution_context before starting. </required_reading>
``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GSD ► SPIKE WRAP-UP ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` ## Gather Spike Inventory- Read
.planning/spikes/MANIFEST.mdfor the overall idea context and requirements - Glob
.planning/spikes/*/README.mdand parse YAML frontmatter from each - Check if
./.claude/skills/spike-findings-*/SKILL.mdexists for this project- If yes: read its
processed_spikeslist from the metadata section and filter those out - If no: all spikes are candidates
- If yes: read its
If no unprocessed spikes exist:
No unprocessed spikes found in `.planning/spikes/`.
Run `/gsd:spike` first to create experiments.
Exit.
Check commit_docs config:
_GSD_SHIM_NAME="gsd-tools.cjs"; GSD_TOOLS="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/get-shit-done-redux@latest --claude --local" >&2; exit 1; fi
COMMIT_DOCS=$(gsd_run query config-get commit_docs 2>/dev/null || echo "true")
Include all unprocessed spikes automatically. Present a brief inventory showing what's being processed:
Processing N spikes:
001 — name (VALIDATED)
002 — name (PARTIAL)
003 — name (INVALIDATED)
Every spike carries forward:
- VALIDATED spikes provide proven patterns
- PARTIAL spikes provide constrained patterns
- INVALIDATED spikes provide landmines and dead ends
Group spikes by feature area based on tags, names, related fields, and content. Proceed directly into synthesis.
Each group becomes one reference file in the generated skill.
## Determine Output Skill NameDerive the skill name from the project directory:
- Get the project root directory name (e.g.,
solana-tracker) - The skill will be created at
./.claude/skills/spike-findings-[project-dir-name]/
If a skill already exists at that path (append mode), update in place.
## Copy Source FilesFor each included spike:
- Identify the core source files — the actual scripts, main files, and config that make the spike work. Exclude:
node_modules/,__pycache__/,.venv/, build artifacts- Lock files (
package-lock.json,yarn.lock, etc.) .git/,.DS_Store
- Copy the README.md and core source files into
sources/NNN-spike-name/inside the generated skill directory
For each feature-area group, write a reference file at references/[feature-area-name].md as an implementation blueprint — it should read like a recipe, not a research paper. A future build session should be able to follow this and build the feature correctly without re-spiking anything.
# [Feature Area Name]
## Requirements
[Non-negotiable design decisions from MANIFEST.md Requirements section that apply to this feature area. These MUST be honored in the real build. E.g., "Must use streaming JSON output", "Must support reconnection".]
## How to Build It
[Step-by-step: what to install, how to configure, what code pattern to use. Include key code snippets extracted from the spike source. This is the proven approach — not theory, but tested and working code.]
## What to Avoid
[Things that look right but aren't. Gotchas. Anti-patterns discovered during spiking. Dead ends that were tried and failed.]
## Constraints
[Hard facts: rate limits, library limitations, version requirements, incompatibilities]
## Origin
Synthesized from spikes: NNN, NNN, NNN
Source files available in: sources/NNN-spike-name/, sources/NNN-spike-name/
Create (or update) the generated skill's SKILL.md:
---
name: spike-findings-[project-dir-name]
description: Implementation blueprint from spike experiments. Requirements, proven patterns, and verified knowledge for building [project-dir-name]. Auto-loaded during implementation work.
---
<context>
## Project: [project-dir-name]
[One paragraph from MANIFEST.md describing the overall idea]
Spike sessions wrapped: [date(s)]
</context>
<requirements>
## Requirements
[Copied directly from MANIFEST.md Requirements section. These are non-negotiable design decisions that emerged from the user's choices during spiking. Every feature area reference must honor these.]
- [requirement 1]
- [requirement 2]
</requirements>
<findings_index>
## Feature Areas
| Area | Reference | Key Finding |
|------|-----------|-------------|
| [Name] | references/[name].md | [One-line summary] |
## Source Files
Original spike source files are preserved in `sources/` for complete reference.
</findings_index>
<metadata>
## Processed Spikes
[List of spike numbers wrapped up]
- 001-spike-name
- 002-spike-name
</metadata>
Write .planning/spikes/WRAP-UP-SUMMARY.md for project history:
# Spike Wrap-Up Summary
**Date:** [date]
**Spikes processed:** [count]
**Feature areas:** [list]
**Skill output:** `./.claude/skills/spike-findings-[project]/`
## Processed Spikes
| # | Name | Type | Verdict | Feature Area |
|---|------|------|---------|--------------|
## Key Findings
[consolidated findings summary]
Add an auto-load routing line to the project's CLAUDE.md (create the file if it doesn't exist):
- **Spike findings for [project]** (implementation patterns, constraints, gotchas) → `Skill("spike-findings-[project-dir-name]")`
If this routing line already exists (append mode), leave it as-is.
## Generate or Update CONVENTIONS.mdAnalyze all processed spikes for recurring patterns and write .planning/spikes/CONVENTIONS.md. This file tells future spike sessions how we spike — the stack, structure, and patterns that have been established.
-
Read all spike source code and READMEs looking for:
- Stack choices — What language/framework/runtime appears across multiple spikes?
- Structure patterns — Common file layouts, port numbers, naming schemes
- Recurring approaches — How auth is handled, how styling is done, how data is served
- Tools & libraries — Packages that showed up repeatedly with versions that worked
-
Write or update
.planning/spikes/CONVENTIONS.md:
# Spike Conventions
Patterns and stack choices established across spike sessions. New spikes follow these unless the question requires otherwise.
## Stack
[What we use for frontend, backend, scripts, and why — derived from what repeated across spikes]
## Structure
[Common file layouts, port assignments, naming patterns]
## Patterns
[Recurring approaches: how we handle auth, how we style, how we serve, etc.]
## Tools & Libraries
[Preferred packages with versions that worked, and any to avoid]
-
Only include patterns that appeared in 2+ spikes or were explicitly chosen by the user.
-
If
CONVENTIONS.mdalready exists (append mode), update sections with new patterns. Remove entries contradicted by newer spikes.
gsd_run query commit "docs(spike-wrap-up): package [N] spike findings into project skill" --files .planning/spikes/WRAP-UP-SUMMARY.md .planning/spikes/CONVENTIONS.md
Processed: {N} spikes
Feature areas: {list}
Skill: ./.claude/skills/spike-findings-[project]/
Conventions: .planning/spikes/CONVENTIONS.md
Summary: .planning/spikes/WRAP-UP-SUMMARY.md
CLAUDE.md: routing line added
The spike-findings skill will auto-load in future build conversations.
</step>
<step name="whats_next">
## What's Next
After the summary, present next-step options:
───────────────────────────────────────────────────────────────
## ▶ Next Up
**Explore frontier spikes** — see what else is worth spiking based on what we've learned
`/gsd:spike` (run with no argument — its frontier mode analyzes the spike landscape and proposes integration and frontier spikes)
───────────────────────────────────────────────────────────────
**Also available:**
- `/gsd:plan-phase` — start planning the real implementation
- `/gsd:spike [idea]` — spike a specific new idea
- `/gsd:explore` — continue exploring
- Other
───────────────────────────────────────────────────────────────
</step>
</process>
<success_criteria>
- [ ] All unprocessed spikes auto-included and processed
- [ ] Spikes grouped by feature area
- [ ] Spike-findings skill exists at `./.claude/skills/` with SKILL.md (including requirements), references/, sources/
- [ ] Reference files are implementation blueprints with Requirements, How to Build It, What to Avoid, Constraints
- [ ] `.planning/spikes/CONVENTIONS.md` created or updated with recurring stack/structure/pattern choices
- [ ] `.planning/spikes/WRAP-UP-SUMMARY.md` written for project history
- [ ] Project CLAUDE.md has auto-load routing line
- [ ] Summary presented
- [ ] Next-step options presented (including frontier spike exploration via `/gsd:spike`)
</success_criteria>