diff --git a/get-shit-done/bin/lib/config.cjs b/get-shit-done/bin/lib/config.cjs
index 1570e29ae..252a6e446 100644
--- a/get-shit-done/bin/lib/config.cjs
+++ b/get-shit-done/bin/lib/config.cjs
@@ -20,6 +20,7 @@ const VALID_CONFIG_KEYS = new Set([
'workflow.text_mode',
'workflow.research_before_questions',
'workflow.discuss_mode',
+ 'workflow.skip_discuss',
'workflow._auto_chain_active',
'git.branching_strategy', 'git.phase_branch_template', 'git.milestone_branch_template', 'git.quick_branch_template',
'planning.commit_docs', 'planning.search_gitignored',
@@ -114,6 +115,7 @@ function buildNewProjectConfig(userChoices) {
text_mode: false,
research_before_questions: false,
discuss_mode: 'discuss',
+ skip_discuss: false,
},
hooks: {
context_warnings: true,
diff --git a/get-shit-done/workflows/autonomous.md b/get-shit-done/workflows/autonomous.md
index 4d4a96eb5..f293c8323 100644
--- a/get-shit-done/workflows/autonomous.md
+++ b/get-shit-done/workflows/autonomous.md
@@ -136,7 +136,79 @@ Phase ${PHASE_NUM}: Context exists — skipping discuss.
Proceed to 3b.
-**If has_context is false:** Execute the smart_discuss step for this phase.
+**If has_context is false:** Check if discuss is disabled via settings:
+
+```bash
+SKIP_DISCUSS=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" config-get workflow.skip_discuss 2>/dev/null || echo "false")
+```
+
+**If SKIP_DISCUSS is `true`:** Skip discuss entirely — the ROADMAP phase description is the spec. Display:
+
+```
+Phase ${PHASE_NUM}: Discuss skipped (workflow.skip_discuss=true) — using ROADMAP phase goal as spec.
+```
+
+Write a minimal CONTEXT.md so downstream plan-phase has valid input. Get phase details:
+
+```bash
+DETAIL=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" roadmap get-phase ${PHASE_NUM})
+```
+
+Extract `goal` and `requirements` from JSON. Write `${phase_dir}/${padded_phase}-CONTEXT.md` with:
+
+```markdown
+# Phase {PHASE_NUM}: {Phase Name} - Context
+
+**Gathered:** {date}
+**Status:** Ready for planning
+**Mode:** Auto-generated (discuss skipped via workflow.skip_discuss)
+
+
+## Phase Boundary
+
+{goal from ROADMAP phase description}
+
+
+
+
+## Implementation Decisions
+
+### Claude's Discretion
+All implementation choices are at Claude's discretion — discuss phase was skipped per user setting. Use ROADMAP phase goal, success criteria, and codebase conventions to guide decisions.
+
+
+
+
+## Existing Code Insights
+
+Codebase context will be gathered during plan-phase research.
+
+
+
+
+## Specific Ideas
+
+No specific requirements — discuss phase skipped. Refer to ROADMAP phase description and success criteria.
+
+
+
+
+## Deferred Ideas
+
+None — discuss phase skipped.
+
+
+```
+
+Commit the minimal context:
+
+```bash
+node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs(${PADDED_PHASE}): auto-generated context (discuss skipped)" --files "${phase_dir}/${padded_phase}-CONTEXT.md"
+```
+
+Proceed to 3b.
+
+**If SKIP_DISCUSS is `false` (or unset):** Execute the smart_discuss step for this phase.
After smart_discuss completes, verify context was written:
diff --git a/get-shit-done/workflows/settings.md b/get-shit-done/workflows/settings.md
index 0ddcaa1e1..17c1bd593 100644
--- a/get-shit-done/workflows/settings.md
+++ b/get-shit-done/workflows/settings.md
@@ -144,6 +144,15 @@ AskUserQuestion([
{ label: "No (Recommended)", description: "Ask questions directly. Faster, uses fewer tokens." },
{ label: "Yes", description: "Search web for best practices before each question group. More informed questions but uses more tokens." }
]
+ },
+ {
+ question: "Skip discuss-phase in autonomous mode? (use ROADMAP phase goals as spec)",
+ header: "Skip Discuss",
+ multiSelect: false,
+ options: [
+ { label: "No (Recommended)", description: "Run smart discuss before each phase — surfaces gray areas and captures decisions." },
+ { label: "Yes", description: "Skip discuss in /gsd:autonomous — chain directly to plan. Best for backend/pipeline work where phase descriptions are the spec." }
+ ]
}
])
```
@@ -166,7 +175,8 @@ Merge new settings into existing config.json:
"ui_safety_gate": true/false,
"text_mode": true/false,
"research_before_questions": true/false,
- "discuss_mode": "discuss" | "assumptions"
+ "discuss_mode": "discuss" | "assumptions",
+ "skip_discuss": true/false
},
"git": {
"branching_strategy": "none" | "phase" | "milestone",
@@ -222,7 +232,8 @@ Write `~/.gsd/defaults.json` with:
"auto_advance": ,
"nyquist_validation": ,
"ui_phase": ,
- "ui_safety_gate":
+ "ui_safety_gate": ,
+ "skip_discuss":
}
}
```
@@ -247,6 +258,7 @@ Display:
| UI Phase | {On/Off} |
| UI Safety Gate | {On/Off} |
| Git Branching | {None/Per Phase/Per Milestone} |
+| Skip Discuss | {On/Off} |
| Context Warnings | {On/Off} |
| Saved as Defaults | {Yes/No} |
@@ -264,7 +276,7 @@ Quick commands:
- [ ] Current config read
-- [ ] User presented with 9 settings (profile + 7 workflow toggles + git branching)
+- [ ] User presented with 10 settings (profile + 8 workflow toggles + git branching)
- [ ] Config updated with model_profile, workflow, and git sections
- [ ] User offered to save as global defaults (~/.gsd/defaults.json)
- [ ] Changes confirmed to user
diff --git a/tests/config.test.cjs b/tests/config.test.cjs
index 1a3255323..9671dbc0e 100644
--- a/tests/config.test.cjs
+++ b/tests/config.test.cjs
@@ -674,3 +674,78 @@ describe('config-set-model-profile command', () => {
}
});
});
+
+// ─── config-set (workflow.skip_discuss) ───────────────────────────────────────
+
+describe('config-set workflow.skip_discuss', () => {
+ let tmpDir;
+
+ beforeEach(() => {
+ tmpDir = createTempProject();
+ runGsdTools('config-ensure-section', tmpDir);
+ });
+
+ afterEach(() => {
+ cleanup(tmpDir);
+ });
+
+ test('workflow.skip_discuss is a valid config key', () => {
+ const result = runGsdTools('config-set workflow.skip_discuss true', tmpDir);
+ assert.ok(result.success, `Command failed: ${result.error}`);
+
+ const config = readConfig(tmpDir);
+ assert.strictEqual(config.workflow.skip_discuss, true);
+ });
+
+ test('skip_discuss defaults to false in new configs', () => {
+ const config = readConfig(tmpDir);
+ assert.strictEqual(config.workflow.skip_discuss, false);
+ });
+
+ test('skip_discuss can be toggled back to false', () => {
+ runGsdTools('config-set workflow.skip_discuss true', tmpDir);
+ const result = runGsdTools('config-set workflow.skip_discuss false', tmpDir);
+ assert.ok(result.success, `Command failed: ${result.error}`);
+
+ const config = readConfig(tmpDir);
+ assert.strictEqual(config.workflow.skip_discuss, false);
+ });
+
+ test('skip_discuss is present in config-new-project output', () => {
+ const emptyDir = createTempProject();
+ try {
+ const result = runGsdTools(['config-new-project', '{}'], emptyDir, { HOME: emptyDir, USERPROFILE: emptyDir });
+ assert.ok(result.success, `Command failed: ${result.error}`);
+
+ const config = readConfig(emptyDir);
+ assert.strictEqual(config.workflow.skip_discuss, false, 'skip_discuss should default to false');
+ } finally {
+ cleanup(emptyDir);
+ }
+ });
+
+ test('skip_discuss can be set via config-new-project choices', () => {
+ const emptyDir = createTempProject();
+ try {
+ const choices = JSON.stringify({
+ workflow: { skip_discuss: true },
+ });
+ const result = runGsdTools(['config-new-project', choices], emptyDir, { HOME: emptyDir, USERPROFILE: emptyDir });
+ assert.ok(result.success, `Command failed: ${result.error}`);
+
+ const config = readConfig(emptyDir);
+ assert.strictEqual(config.workflow.skip_discuss, true);
+ } finally {
+ cleanup(emptyDir);
+ }
+ });
+
+ test('config-get workflow.skip_discuss returns the set value', () => {
+ runGsdTools('config-set workflow.skip_discuss true', tmpDir);
+ const result = runGsdTools('config-get workflow.skip_discuss', tmpDir);
+ assert.ok(result.success, `Command failed: ${result.error}`);
+
+ const output = JSON.parse(result.output);
+ assert.strictEqual(output, true);
+ });
+});