From 18397fb7f5f30714856922ae77da2e8232d8f46b Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 15 May 2026 12:47:54 -0400 Subject: [PATCH 1/3] fix(3561): gate ultraplan runtime on Claude Code markers --- get-shit-done/workflows/ultraplan-phase.md | 11 ++++++++++- tests/ultraplan-phase.test.cjs | 7 +++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/get-shit-done/workflows/ultraplan-phase.md b/get-shit-done/workflows/ultraplan-phase.md index a6a448c50..503b6f898 100644 --- a/get-shit-done/workflows/ultraplan-phase.md +++ b/get-shit-done/workflows/ultraplan-phase.md @@ -29,7 +29,16 @@ Use /gsd:plan-phase for stable local planning. Check that the session is running inside Claude Code: ```bash -echo "$CLAUDE_CODE_VERSION" +if [ "$CLAUDECODE" = "1" ] || [ -n "$CLAUDE_CODE_ENTRYPOINT" ]; then + CC_VERSION="$(claude --version 2>/dev/null | awk '{print $1}')" + if [ -n "$CC_VERSION" ] && [ "$(printf '%s\n' "2.1.91" "$CC_VERSION" | sort -V | head -n1)" != "2.1.91" ]; then + echo "" + else + echo "claude-code:${CC_VERSION:-unknown}" + fi +else + echo "" +fi ``` If the output is empty or unset, display the following error and exit: diff --git a/tests/ultraplan-phase.test.cjs b/tests/ultraplan-phase.test.cjs index bcb799742..91211712c 100644 --- a/tests/ultraplan-phase.test.cjs +++ b/tests/ultraplan-phase.test.cjs @@ -86,8 +86,11 @@ describe('ultraplan-phase workflow beta marker', () => { describe('ultraplan-phase workflow runtime gate', () => { const content = fs.readFileSync(WF_PATH, 'utf-8'); - test('checks CLAUDE_CODE_VERSION to detect Claude Code runtime', () => { - assert.ok(content.includes('CLAUDE_CODE_VERSION'), 'workflow must gate on CLAUDE_CODE_VERSION env var'); + test('checks Claude Code runtime markers instead of version env var', () => { + assert.ok( + content.includes('CLAUDECODE') || content.includes('CLAUDE_CODE_ENTRYPOINT'), + 'workflow must gate on Claude Code runtime marker env vars' + ); }); test('error message references /gsd-plan-phase as local alternative', () => { From fbfa4e30f3f00714c826d62e85d995ebed3c6a08 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 15 May 2026 12:48:45 -0400 Subject: [PATCH 2/3] chore(changeset): add fragment for #3561 --- .changeset/silly-finches-travel.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/silly-finches-travel.md diff --git a/.changeset/silly-finches-travel.md b/.changeset/silly-finches-travel.md new file mode 100644 index 000000000..635103460 --- /dev/null +++ b/.changeset/silly-finches-travel.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 3563 +--- +**Ultraplan runtime gate now detects Claude Code correctly** - runtime gating no longer relies on `CLAUDE_CODE_VERSION`; it uses Claude Code marker env vars and preserves the minimum supported version floor. Fixes #3561. From f0975986893b8d4aebd374ba539773e0ae4e4ed3 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 15 May 2026 12:59:18 -0400 Subject: [PATCH 3/3] fix(3561): fail closed when Claude version is unavailable --- get-shit-done/workflows/ultraplan-phase.md | 8 ++++---- tests/ultraplan-phase.test.cjs | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/get-shit-done/workflows/ultraplan-phase.md b/get-shit-done/workflows/ultraplan-phase.md index 503b6f898..d8c12db79 100644 --- a/get-shit-done/workflows/ultraplan-phase.md +++ b/get-shit-done/workflows/ultraplan-phase.md @@ -30,11 +30,11 @@ Check that the session is running inside Claude Code: ```bash if [ "$CLAUDECODE" = "1" ] || [ -n "$CLAUDE_CODE_ENTRYPOINT" ]; then - CC_VERSION="$(claude --version 2>/dev/null | awk '{print $1}')" - if [ -n "$CC_VERSION" ] && [ "$(printf '%s\n' "2.1.91" "$CC_VERSION" | sort -V | head -n1)" != "2.1.91" ]; then - echo "" + CC_VERSION="$(claude --version 2>/dev/null | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)" + if [ -n "$CC_VERSION" ] && [ "$(printf '%s\n' "2.1.91" "$CC_VERSION" | sort -V | head -n1)" = "2.1.91" ]; then + echo "claude-code:${CC_VERSION}" else - echo "claude-code:${CC_VERSION:-unknown}" + echo "" fi else echo "" diff --git a/tests/ultraplan-phase.test.cjs b/tests/ultraplan-phase.test.cjs index 91211712c..2ea6ec310 100644 --- a/tests/ultraplan-phase.test.cjs +++ b/tests/ultraplan-phase.test.cjs @@ -91,6 +91,10 @@ describe('ultraplan-phase workflow runtime gate', () => { content.includes('CLAUDECODE') || content.includes('CLAUDE_CODE_ENTRYPOINT'), 'workflow must gate on Claude Code runtime marker env vars' ); + assert.ok( + !content.includes('CLAUDE_CODE_VERSION'), + 'workflow must not gate on CLAUDE_CODE_VERSION' + ); }); test('error message references /gsd-plan-phase as local alternative', () => {