fix(tests): redirect implementation tests to workflow files after extraction

After extracting debug.md and thread.md implementations to workflow files
and renaming extract_learnings.md, existing tests still referenced the
old locations:

- debug-session-management.test.cjs: commands/gsd/debug.md → workflows/debug.md
- thread-session-management.test.cjs: commands/gsd/thread.md → workflows/thread.md
- extract-learnings.test.cjs: extract_learnings.md → extract-learnings.md
- enh-2430-learnings-consumption.test.cjs: extract_learnings.md → extract-learnings.md

Also adds <available_agent_types> block and TEXT_MODE fallback note to
get-shit-done/workflows/debug.md to satisfy the spawn-type-consistency
(#1357) and AskUserQuestion text-mode fallback (#2012) contract tests
that scan all workflow files.
This commit is contained in:
Tom Boucher
2026-05-05 15:44:59 -04:00
parent ecf3510511
commit b752a9aae7
5 changed files with 29 additions and 23 deletions

View File

@@ -5,6 +5,12 @@ Invoked by `/gsd-debug` (`commands/gsd/debug.md`).
Systematic debugging using the scientific method with subagent isolation.
Orchestrates symptom gathering, session creation, and delegation to `gsd-debug-session-manager`.
<available_agent_types>
Valid GSD subagent types (use exact names — do not fall back to 'general-purpose'):
- gsd-debug-session-manager — manages debug checkpoint/continuation loop in isolated context
- gsd-debugger — investigates bugs using scientific method
</available_agent_types>
<process>
## 0. Initialize Context
@@ -139,7 +145,7 @@ If $ARGUMENTS provided OR user describes new issue:
## 2. Gather Symptoms (if new issue, SUBCMD=debug)
Use AskUserQuestion for each:
Use AskUserQuestion for each. **TEXT_MODE fallback:** when `workflow.text_mode` is true, replace AskUserQuestion calls with plain-text numbered prompts and wait for typed replies.
1. **Expected behavior** - What should happen?
2. **Actual behavior** - What happens instead?

View File

@@ -29,7 +29,7 @@ describe('debug session management implementation', () => {
test('debug command contains list subcommand logic', () => {
const content = fs.readFileSync(
path.join(process.cwd(), 'commands/gsd/debug.md'),
path.join(process.cwd(), 'get-shit-done/workflows/debug.md'),
'utf8'
);
assert.ok(
@@ -40,7 +40,7 @@ describe('debug session management implementation', () => {
test('debug command contains continue subcommand logic', () => {
const content = fs.readFileSync(
path.join(process.cwd(), 'commands/gsd/debug.md'),
path.join(process.cwd(), 'get-shit-done/workflows/debug.md'),
'utf8'
);
assert.ok(
@@ -51,7 +51,7 @@ describe('debug session management implementation', () => {
test('debug command contains status subcommand logic', () => {
const content = fs.readFileSync(
path.join(process.cwd(), 'commands/gsd/debug.md'),
path.join(process.cwd(), 'get-shit-done/workflows/debug.md'),
'utf8'
);
assert.ok(
@@ -62,7 +62,7 @@ describe('debug session management implementation', () => {
test('debug command contains TDD gate logic', () => {
const content = fs.readFileSync(
path.join(process.cwd(), 'commands/gsd/debug.md'),
path.join(process.cwd(), 'get-shit-done/workflows/debug.md'),
'utf8'
);
assert.ok(
@@ -73,7 +73,7 @@ describe('debug session management implementation', () => {
test('debug.md reads tdd_mode via workflow.tdd_mode key (not bare tdd_mode)', () => {
const content = fs.readFileSync(
path.join(process.cwd(), 'commands/gsd/debug.md'),
path.join(process.cwd(), 'get-shit-done/workflows/debug.md'),
'utf8'
);
assert.ok(
@@ -88,7 +88,7 @@ describe('debug session management implementation', () => {
test('debug command contains security hardening', () => {
const content = fs.readFileSync(
path.join(process.cwd(), 'commands/gsd/debug.md'),
path.join(process.cwd(), 'get-shit-done/workflows/debug.md'),
'utf8'
);
assert.ok(content.includes('DATA_START'), 'debug.md must contain DATA_START injection boundary marker');
@@ -96,7 +96,7 @@ describe('debug session management implementation', () => {
test('debug command surfaces next_action before spawn', () => {
const content = fs.readFileSync(
path.join(process.cwd(), 'commands/gsd/debug.md'),
path.join(process.cwd(), 'get-shit-done/workflows/debug.md'),
'utf8'
);
assert.ok(
@@ -148,13 +148,13 @@ describe('debug skill dispatch and sub-orchestrator (#2148, #2151)', () => {
});
test('debug.md orchestrator has specialist skill dispatch step', () => {
const content = fs.readFileSync(path.join(process.cwd(), 'commands', 'gsd', 'debug.md'), 'utf8');
const content = fs.readFileSync(path.join(process.cwd(), 'get-shit-done/workflows/debug.md'), 'utf8');
assert.ok(content.includes('specialist_hint'), 'debug.md missing specialist dispatch logic');
assert.ok(content.includes('typescript-expert'), 'debug.md missing skill dispatch mapping');
});
test('debug.md specialist dispatch prompt uses DATA_START/DATA_END boundaries', () => {
const content = fs.readFileSync(path.join(process.cwd(), 'commands', 'gsd', 'debug.md'), 'utf8');
const content = fs.readFileSync(path.join(process.cwd(), 'get-shit-done/workflows/debug.md'), 'utf8');
assert.ok(content.includes('DATA_START') && content.includes('DATA_END'),
'debug.md specialist dispatch prompt missing security boundaries');
});
@@ -182,7 +182,7 @@ describe('debug skill dispatch and sub-orchestrator (#2148, #2151)', () => {
});
test('debug.md delegates to gsd-debug-session-manager', () => {
const content = fs.readFileSync(path.join(process.cwd(), 'commands', 'gsd', 'debug.md'), 'utf8');
const content = fs.readFileSync(path.join(process.cwd(), 'get-shit-done/workflows/debug.md'), 'utf8');
assert.ok(content.includes('gsd-debug-session-manager'),
'debug.md does not delegate to session manager');
});

View File

@@ -200,20 +200,20 @@ describe('enh-2430 Part B — graduation.md helper workflow', () => {
});
});
describe('enh-2430 — extract_learnings.md graduated: field', () => {
test('extract_learnings.md documents optional graduated: annotation', () => {
const content = readWorkflow('extract_learnings.md');
describe('enh-2430 — extract-learnings.md graduated: field', () => {
test('extract-learnings.md documents optional graduated: annotation', () => {
const content = readWorkflow('extract-learnings.md');
assert.ok(
content.includes('graduated:') || content.includes('Graduated:'),
'extract_learnings.md must document optional graduated: field'
'extract-learnings.md must document optional graduated: field'
);
});
test('extract_learnings.md clarifies graduated: is written only by graduation workflow', () => {
const content = readWorkflow('extract_learnings.md');
test('extract-learnings.md clarifies graduated: is written only by graduation workflow', () => {
const content = readWorkflow('extract-learnings.md');
assert.ok(
content.includes('graduation workflow') || content.includes('graduation.md'),
'extract_learnings.md must clarify that graduated: is written only by graduation.md'
'extract-learnings.md must clarify that graduated: is written only by graduation.md'
);
});
});

View File

@@ -17,7 +17,7 @@ const fs = require('fs');
const path = require('path');
const COMMAND_PATH = path.join(__dirname, '..', 'commands', 'gsd', 'extract-learnings.md');
const WORKFLOW_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'extract_learnings.md');
const WORKFLOW_PATH = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'extract-learnings.md');
describe('extract-learnings command', () => {
test('command file exists', () => {
@@ -59,15 +59,15 @@ describe('extract-learnings command', () => {
test('command references the workflow via execution_context', () => {
const content = fs.readFileSync(COMMAND_PATH, 'utf-8');
assert.ok(
content.includes('workflows/extract_learnings.md'),
'Command must reference workflows/extract_learnings.md in execution_context'
content.includes('workflows/extract-learnings.md'),
'Command must reference workflows/extract-learnings.md in execution_context'
);
});
});
describe('extract-learnings workflow', () => {
test('workflow file exists', () => {
assert.ok(fs.existsSync(WORKFLOW_PATH), 'workflows/extract_learnings.md should exist');
assert.ok(fs.existsSync(WORKFLOW_PATH), 'workflows/extract-learnings.md should exist');
});
test('workflow has objective tag', () => {

View File

@@ -11,7 +11,7 @@ const path = require('path');
describe('thread session management (#2156)', () => {
const threadCmd = fs.readFileSync(
path.join(__dirname, '..', 'commands', 'gsd', 'thread.md'),
path.join(__dirname, '..', 'get-shit-done', 'workflows', 'thread.md'),
'utf8'
);