* 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>
92 lines
3.1 KiB
Markdown
92 lines
3.1 KiB
Markdown
# Add Backlog Item Workflow
|
|
|
|
Invoked by `/gsd:capture --backlog` (`commands/gsd/capture.md`).
|
|
|
|
Adds an idea to the ROADMAP.md backlog parking lot using 999.x numbering. Backlog items
|
|
are unsequenced ideas that aren't ready for active planning — they live outside the normal
|
|
phase sequence and accumulate context over time.
|
|
|
|
<process>
|
|
|
|
## Step 1: Read ROADMAP.md
|
|
|
|
Check for existing backlog entries:
|
|
|
|
```bash
|
|
cat .planning/ROADMAP.md
|
|
```
|
|
|
|
## Step 2: Find next backlog number
|
|
|
|
```bash
|
|
_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
|
|
NEXT=$(gsd_run query phase.next-decimal 999 --raw)
|
|
```
|
|
|
|
If no 999.x phases exist yet, `phase.next-decimal` returns `999.1`. Sparse numbering
|
|
is fine (e.g. 999.1, 999.3) — always use `phase.next-decimal`, never guess.
|
|
|
|
## Step 3: Write ROADMAP entry
|
|
|
|
**Write the ROADMAP entry BEFORE creating the directory.** Directory existence is a
|
|
reliable indicator that the phase is already registered, which prevents false duplicate
|
|
detection in any hook that checks for existing 999.x directories (#2280).
|
|
|
|
Add under a `## Backlog` section. If the section doesn't exist, create it at the end
|
|
of ROADMAP.md:
|
|
|
|
```markdown
|
|
## Backlog
|
|
|
|
### Phase {NEXT}: {description} (BACKLOG)
|
|
|
|
**Goal:** [Captured for future planning]
|
|
**Requirements:** TBD
|
|
**Plans:** 0 plans
|
|
|
|
Plans:
|
|
- [ ] TBD (promote with /gsd:review-backlog when ready)
|
|
```
|
|
|
|
## Step 4: Create the phase directory
|
|
|
|
Apply the `project_code` prefix (if set in `.planning/config.json`) so the backlog directory name is consistent with all other phase-creation paths:
|
|
|
|
```bash
|
|
SLUG=$(gsd_run query generate-slug "$ARGUMENTS" --raw)
|
|
PROJECT_CODE=$(gsd_run query config-get project_code --raw 2>/dev/null || echo "")
|
|
PREFIX=$([ -n "$PROJECT_CODE" ] && echo "${PROJECT_CODE}-" || echo "")
|
|
PHASE_DIR=".planning/phases/${PREFIX}${NEXT}-${SLUG}"
|
|
mkdir -p "${PHASE_DIR}"
|
|
touch "${PHASE_DIR}/.gitkeep"
|
|
```
|
|
|
|
## Step 5: Commit
|
|
|
|
```bash
|
|
gsd_run query commit "docs: add backlog item ${NEXT} — ${ARGUMENTS}" --files .planning/ROADMAP.md "${PHASE_DIR}/.gitkeep"
|
|
```
|
|
|
|
## Step 6: Report
|
|
|
|
```
|
|
## 📋 Backlog Item Added
|
|
|
|
Phase {NEXT}: {description}
|
|
Directory: {PHASE_DIR}/
|
|
|
|
This item lives in the backlog parking lot.
|
|
Use /gsd:discuss-phase {NEXT} to explore it further.
|
|
Use /gsd:review-backlog to promote items to active milestone.
|
|
```
|
|
|
|
</process>
|
|
|
|
<notes>
|
|
- 999.x numbering keeps backlog items out of the active phase sequence
|
|
- Phase directories are created immediately so /gsd:discuss-phase and /gsd:plan-phase work on them
|
|
- No `Depends on:` field — backlog items are unsequenced by definition
|
|
- Sparse numbering is fine (999.1, 999.3) — always uses next-decimal
|
|
- Promote backlog items to the active milestone with /gsd:review-backlog
|
|
</notes>
|