* fix(#614): resolve gsd-tools via runtime shim in discuss-phase mode routing The discuss-phase mode-routing snippet and the codebase-drift gate called the bare `gsd-tools` binary. On a shim-only install (gsd-tools.cjs present but `gsd-tools` not on PATH) the call exits 127, `2>/dev/null` hides it, and `|| echo` silently substitutes a default — so `workflow.discuss_mode: assumptions` was ignored and routing always fell back to standard discuss mode. Both sites now resolve the binary through the canonical `_GSD_SHIM_NAME` probe and call `gsd_run`. Discuss-phase fails loudly on a genuinely missing shim (interactive — wrong mode is worse than an error); the non-blocking drift gate uses a soft `return 127` fallback so it still skips gracefully when nothing is resolvable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#614): set changeset pr to 618 * fix(#614): scope to discuss-phase mode routing; revert drift-gate change The runtime-launcher-parity invariant requires exactly one canonical (byte-equal) gsd_run preamble per workflow .md before the first gsd_run call. codebase-drift-gate.md has two independent gsd_run bash blocks; hardening its first block cleanly conflicts with that invariant and risks the auto-remap block's separate execution scope. Descope the drift-gate hardening to a follow-up and keep this PR focused on the titled bug: the discuss-phase mode-routing snippet now resolves gsd-tools via the runtime shim (gsd_run) instead of the bare PATH command, so shim-only installs no longer silently fall back to standard discuss mode. Drift-gate file reverted to its next state; its test assertion removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
5
.changeset/614-discuss-phase-shim-resolution.md
Normal file
5
.changeset/614-discuss-phase-shim-resolution.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 618
|
||||
---
|
||||
**`/gsd-discuss-phase` now honors `workflow.discuss_mode: assumptions` on shim-only installs** — mode routing resolves `gsd-tools` via the runtime shim instead of the bare PATH command, so a missing PATH binary no longer silently falls back to standard discuss mode.
|
||||
@@ -47,7 +47,8 @@ Context files are resolved in-workflow using `init phase-op` and roadmap/state t
|
||||
<process>
|
||||
**Mode routing:**
|
||||
```bash
|
||||
DISCUSS_MODE=$(gsd-tools query config-get workflow.discuss_mode 2>/dev/null || echo "discuss")
|
||||
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; 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" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
|
||||
DISCUSS_MODE=$(gsd_run query config-get workflow.discuss_mode 2>/dev/null || echo "discuss")
|
||||
```
|
||||
|
||||
If `--assumptions` is in $ARGUMENTS:
|
||||
|
||||
@@ -164,4 +164,25 @@ describe('workflow.discuss_mode config', () => {
|
||||
assert.ok(doc.includes('discuss'), 'doc should mention discuss');
|
||||
assert.ok(doc.includes('config-set'), 'doc should show how to configure');
|
||||
});
|
||||
|
||||
test('discuss-phase command mode-routing uses gsd_run (shim-safe) not bare gsd-tools', () => {
|
||||
const command = fs.readFileSync(
|
||||
path.join(__dirname, '..', 'commands', 'gsd', 'discuss-phase.md'), 'utf8'
|
||||
);
|
||||
// Must contain the canonical shim probe marker
|
||||
assert.ok(
|
||||
command.includes('_GSD_SHIM_NAME'),
|
||||
'discuss-phase.md must define _GSD_SHIM_NAME shim probe before mode routing'
|
||||
);
|
||||
// Must use gsd_run for the config lookup
|
||||
assert.ok(
|
||||
command.includes('gsd_run query config-get workflow.discuss_mode'),
|
||||
'discuss-phase.md must use gsd_run (not bare gsd-tools) for discuss_mode lookup'
|
||||
);
|
||||
// Must NOT contain the bare footgun pattern: gsd-tools immediately before the silent default
|
||||
assert.ok(
|
||||
!command.includes('gsd-tools query config-get workflow.discuss_mode 2>/dev/null || echo'),
|
||||
'discuss-phase.md must NOT use bare gsd-tools binary for discuss_mode lookup (shim-only install footgun)'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user