diff --git a/agents/gsd-debugger.md b/agents/gsd-debugger.md
index e22b61f64..226e99b9a 100644
--- a/agents/gsd-debugger.md
+++ b/agents/gsd-debugger.md
@@ -979,7 +979,16 @@ mkdir -p .planning/debug/resolved
mv .planning/debug/{slug}.md .planning/debug/resolved/
```
-Commit:
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**Commit the fix:**
+
+If `COMMIT_PLANNING_DOCS=true` (default):
```bash
git add -A
git commit -m "fix: {brief description}
@@ -988,6 +997,16 @@ Root cause: {root_cause}
Debug session: .planning/debug/resolved/{slug}.md"
```
+If `COMMIT_PLANNING_DOCS=false`:
+```bash
+# Only commit code changes, exclude .planning/
+git add -A
+git reset .planning/
+git commit -m "fix: {brief description}
+
+Root cause: {root_cause}"
+```
+
Report completion and offer next steps.
diff --git a/agents/gsd-executor.md b/agents/gsd-executor.md
index bc9ed3fe9..e3cb542fd 100644
--- a/agents/gsd-executor.md
+++ b/agents/gsd-executor.md
@@ -39,6 +39,17 @@ Options:
```
**If .planning/ doesn't exist:** Error - project not initialized.
+
+**Load planning config:**
+
+```bash
+# Check if planning docs should be committed (default: true)
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+# Auto-detect gitignored (overrides config)
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+Store `COMMIT_PLANNING_DOCS` for use in git operations.
@@ -692,6 +703,10 @@ Resume file: [path to .continue-here if exists, else "None"]
After SUMMARY.md and STATE.md updates:
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations for planning files, log "Skipping planning docs commit (commit_docs: false)"
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
**1. Stage execution artifacts:**
```bash
diff --git a/agents/gsd-phase-researcher.md b/agents/gsd-phase-researcher.md
index 07e95c72c..4b30b7292 100644
--- a/agents/gsd-phase-researcher.md
+++ b/agents/gsd-phase-researcher.md
@@ -450,6 +450,11 @@ PHASE_DIR=$(ls -d .planning/phases/${PADDED_PHASE}-* .planning/phases/${PHASE}-*
# Read CONTEXT.md if exists (from /gsd:discuss-phase)
cat "${PHASE_DIR}"/*-CONTEXT.md 2>/dev/null
+
+# Check if planning docs should be committed (default: true)
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+# Auto-detect gitignored (overrides config)
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
```
**If CONTEXT.md exists**, it contains user decisions that MUST constrain your research:
@@ -526,6 +531,10 @@ Where `PHASE_DIR` is the full path (e.g., `.planning/phases/01-foundation`)
## Step 6: Commit Research
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations, log "Skipping planning docs commit (commit_docs: false)"
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add "${PHASE_DIR}/${PADDED_PHASE}-RESEARCH.md"
git commit -m "docs(${PHASE}): research phase domain
diff --git a/agents/gsd-planner.md b/agents/gsd-planner.md
index fdf9af177..1266897ba 100644
--- a/agents/gsd-planner.md
+++ b/agents/gsd-planner.md
@@ -953,6 +953,10 @@ After making edits, self-check:
### Step 6: Commit Revised Plans
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations, log "Skipping planning docs commit (commit_docs: false)"
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/phases/${PHASE}-*/${PHASE}-*-PLAN.md
git commit -m "fix(${PHASE}): revise plans based on checker feedback"
@@ -998,6 +1002,17 @@ Read `.planning/STATE.md` and parse:
- Blockers/concerns (things this phase may address)
If STATE.md missing but .planning/ exists, offer to reconstruct or continue without.
+
+**Load planning config:**
+
+```bash
+# Check if planning docs should be committed (default: true)
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+# Auto-detect gitignored (overrides config)
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+Store `COMMIT_PLANNING_DOCS` for use in git operations.
@@ -1209,6 +1224,10 @@ Update ROADMAP.md to finalize phase placeholders created by add-phase or insert-
Commit phase plan(s) and updated roadmap:
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations, log "Skipping planning docs commit (commit_docs: false)"
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/phases/${PHASE}-*/${PHASE}-*-PLAN.md .planning/ROADMAP.md
git commit -m "docs(${PHASE}): create phase plan
diff --git a/agents/gsd-research-synthesizer.md b/agents/gsd-research-synthesizer.md
index a31c33cb8..df9e7a0fe 100644
--- a/agents/gsd-research-synthesizer.md
+++ b/agents/gsd-research-synthesizer.md
@@ -48,6 +48,11 @@ cat .planning/research/STACK.md
cat .planning/research/FEATURES.md
cat .planning/research/ARCHITECTURE.md
cat .planning/research/PITFALLS.md
+
+# Check if planning docs should be committed (default: true)
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+# Auto-detect gitignored (overrides config)
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
```
Parse each file to extract:
@@ -125,6 +130,10 @@ Write to `.planning/research/SUMMARY.md`
The 4 parallel researcher agents write files but do NOT commit. You commit everything together.
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations, log "Skipping planning docs commit (commit_docs: false)"
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/research/
git commit -m "docs: complete project research
diff --git a/commands/gsd/add-todo.md b/commands/gsd/add-todo.md
index 6dfef9031..a7bab1be4 100644
--- a/commands/gsd/add-todo.md
+++ b/commands/gsd/add-todo.md
@@ -126,6 +126,17 @@ If `.planning/STATE.md` exists:
Commit the todo and any updated state:
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations, log "Todo saved (not committed - commit_docs: false)"
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/todos/pending/[filename]
[ -f .planning/STATE.md ] && git add .planning/STATE.md
diff --git a/commands/gsd/check-todos.md b/commands/gsd/check-todos.md
index c89b93a1f..ccb09f4c9 100644
--- a/commands/gsd/check-todos.md
+++ b/commands/gsd/check-todos.md
@@ -177,6 +177,17 @@ Update STATE.md "### Pending Todos" section if exists.
If todo was moved to done/, commit the change:
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations, log "Todo moved (not committed - commit_docs: false)"
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/todos/done/[filename]
git rm --cached .planning/todos/pending/[filename] 2>/dev/null || true
diff --git a/commands/gsd/execute-phase.md b/commands/gsd/execute-phase.md
index 9b8c5a0e0..a95dfd0bf 100644
--- a/commands/gsd/execute-phase.md
+++ b/commands/gsd/execute-phase.md
@@ -99,7 +99,9 @@ Phase: $ARGUMENTS
- Skip if: REQUIREMENTS.md doesn't exist, or phase has no Requirements line
10. **Commit phase completion**
- Bundle all phase metadata updates in one commit:
+ Check `COMMIT_PLANNING_DOCS` from config.json (default: true).
+ If false: Skip git operations for .planning/ files.
+ If true: Bundle all phase metadata updates in one commit:
- Stage: `git add .planning/ROADMAP.md .planning/STATE.md`
- Stage REQUIREMENTS.md if updated: `git add .planning/REQUIREMENTS.md`
- Commit: `docs({phase}): complete {phase-name} phase`
diff --git a/commands/gsd/help.md b/commands/gsd/help.md
index 3ed8b4b4b..c941290b3 100644
--- a/commands/gsd/help.md
+++ b/commands/gsd/help.md
@@ -337,6 +337,33 @@ Set during `/gsd:new-project`:
Change anytime by editing `.planning/config.json`
+## Planning Configuration
+
+Configure how planning artifacts are managed in `.planning/config.json`:
+
+**`planning.commit_docs`** (default: `true`)
+- `true`: Planning artifacts committed to git (standard workflow)
+- `false`: Planning artifacts kept local-only, not committed
+
+When `commit_docs: false`:
+- Add `.planning/` to your `.gitignore`
+- Useful for OSS contributions, client projects, or keeping planning private
+- All planning files still work normally, just not tracked in git
+
+**`planning.search_gitignored`** (default: `false`)
+- `true`: Add `--no-ignore` to broad ripgrep searches
+- Only needed when `.planning/` is gitignored and you want project-wide searches to include it
+
+Example config:
+```json
+{
+ "planning": {
+ "commit_docs": false,
+ "search_gitignored": true
+ }
+}
+```
+
## Common Workflows
**Starting a new project:**
diff --git a/commands/gsd/new-milestone.md b/commands/gsd/new-milestone.md
index 81ed4ee5c..46ae4825b 100644
--- a/commands/gsd/new-milestone.md
+++ b/commands/gsd/new-milestone.md
@@ -8,37 +8,31 @@ allowed-tools:
- Bash
- Task
- AskUserQuestion
- - Glob
---
-
Start a new milestone through unified flow: questioning → research (optional) → requirements → roadmap.
-This is the brownfield equivalent of new-project. The project exists, PROJECT.md has history. This command gathers "what's next" and takes you through the full cycle.
+This is the brownfield equivalent of new-project. The project exists, PROJECT.md has history. This command gathers "what's next", updates PROJECT.md, then continues through the full requirements → roadmap cycle.
**Creates/Updates:**
- `.planning/PROJECT.md` — updated with new milestone goals
-- `.planning/research/` — domain research (optional)
-- `.planning/REQUIREMENTS.md` — scoped requirements
-- `.planning/ROADMAP.md` — phase structure
-- `.planning/STATE.md` — updated project memory
+- `.planning/research/` — domain research (optional, focuses on NEW features)
+- `.planning/REQUIREMENTS.md` — scoped requirements for this milestone
+- `.planning/ROADMAP.md` — phase structure (continues numbering)
+- `.planning/STATE.md` — reset for new milestone
**After this command:** Run `/gsd:plan-phase [N]` to start execution.
-
-
@~/.claude/get-shit-done/references/questioning.md
@~/.claude/get-shit-done/references/ui-brand.md
@~/.claude/get-shit-done/templates/project.md
@~/.claude/get-shit-done/templates/requirements.md
-
-
Milestone name: $ARGUMENTS (optional - will prompt if not provided)
**Load project context:**
@@ -47,133 +41,40 @@ Milestone name: $ARGUMENTS (optional - will prompt if not provided)
@.planning/MILESTONES.md
@.planning/config.json
+**Load milestone context (if exists, from /gsd:discuss-milestone):**
+@.planning/MILESTONE-CONTEXT.md
-## Phase 1: Validate
+## Phase 1: Load Context
-**MANDATORY FIRST STEP — Execute these checks before ANY user interaction:**
+- Read PROJECT.md (existing project, Validated requirements, decisions)
+- Read MILESTONES.md (what shipped previously)
+- Read STATE.md (pending todos, blockers)
+- Check for MILESTONE-CONTEXT.md (from /gsd:discuss-milestone)
-1. **Verify project exists:**
- ```bash
- [ -f .planning/PROJECT.md ] || { echo "ERROR: No PROJECT.md. Run /gsd:new-project first."; exit 1; }
- ```
+## Phase 2: Gather Milestone Goals
-2. **Check for active milestone (ROADMAP.md exists):**
- ```bash
- [ -f .planning/ROADMAP.md ] && echo "ACTIVE_MILESTONE" || echo "READY_FOR_NEW"
- ```
+**If MILESTONE-CONTEXT.md exists:**
+- Use features and scope from discuss-milestone
+- Present summary for confirmation
- **If ACTIVE_MILESTONE:**
- Use AskUserQuestion:
- - header: "Active Milestone"
- - question: "A milestone is in progress. What would you like to do?"
- - options:
- - "Complete current first" — Run /gsd:complete-milestone
- - "Continue anyway" — Start new milestone (will archive current)
+**If no context file:**
+- Present what shipped in last milestone
+- Ask: "What do you want to build next?"
+- Use AskUserQuestion to explore features
+- Probe for priorities, constraints, scope
- If "Complete current first": Exit with routing to `/gsd:complete-milestone`
- If "Continue anyway": Continue to Phase 2
+## Phase 3: Determine Milestone Version
-3. **Load previous milestone context:**
- ```bash
- cat .planning/MILESTONES.md 2>/dev/null || echo "NO_MILESTONES"
- cat .planning/STATE.md
- ```
+- Parse last version from MILESTONES.md
+- Suggest next version (v1.0 → v1.1, or v2.0 for major)
+- Confirm with user
-## Phase 2: Present Context
+## Phase 4: Update PROJECT.md
-**Display stage banner:**
-
-```
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- GSD ► NEW MILESTONE
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-```
-
-**Present what shipped:**
-
-```
-Last milestone: v[X.Y] [Name] (shipped [DATE])
-
-Key accomplishments:
-- [From MILESTONES.md]
-- [From MILESTONES.md]
-- [From MILESTONES.md]
-
-Validated requirements:
-- [From PROJECT.md Validated section]
-
-Pending todos:
-- [From STATE.md if any]
-```
-
-## Phase 3: Deep Questioning
-
-**Display stage banner:**
-
-```
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- GSD ► QUESTIONING
-━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-```
-
-**Open the conversation:**
-
-Ask inline (freeform, NOT AskUserQuestion):
-
-"What do you want to build next?"
-
-Wait for their response. This gives you the context needed to ask intelligent follow-up questions.
-
-**Follow the thread:**
-
-Based on what they said, ask follow-up questions that dig into their response. Use AskUserQuestion with options that probe what they mentioned — interpretations, clarifications, concrete examples.
-
-Keep following threads. Each answer opens new threads to explore. Ask about:
-- What excited them
-- What problem sparked this
-- What they mean by vague terms
-- What it would actually look like
-- What's already decided
-
-Consult `questioning.md` for techniques:
-- Challenge vagueness
-- Make abstract concrete
-- Surface assumptions
-- Find edges
-- Reveal motivation
-
-**Decision gate:**
-
-When you could update PROJECT.md with clear new goals, use AskUserQuestion:
-
-- header: "Ready?"
-- question: "I think I understand what you're after. Ready to update PROJECT.md?"
-- options:
- - "Update PROJECT.md" — Let's move forward
- - "Keep exploring" — I want to share more / ask me more
-
-If "Keep exploring" — ask what they want to add, or identify gaps and probe naturally.
-
-Loop until "Update PROJECT.md" selected.
-
-## Phase 4: Determine Milestone Version
-
-Parse last version from MILESTONES.md and suggest next:
-
-Use AskUserQuestion:
-- header: "Version"
-- question: "What version is this milestone?"
-- options:
- - "v[X.Y+0.1] (patch)" — Minor update: [suggested name]
- - "v[X+1].0 (major)" — Major release
- - "Custom" — I'll specify
-
-## Phase 5: Update PROJECT.md
-
-Update `.planning/PROJECT.md` with new milestone section:
+Add/update these sections:
```markdown
## Current Milestone: v[X.Y] [Name]
@@ -186,30 +87,49 @@ Update `.planning/PROJECT.md` with new milestone section:
- [Feature 3]
```
-Update Active requirements section with new goals (keep Validated section intact).
+Update Active requirements section with new goals.
Update "Last updated" footer.
-**Commit PROJECT.md:**
+## Phase 5: Update STATE.md
-```bash
-git add .planning/PROJECT.md
-git commit -m "$(cat <<'EOF'
-docs: start milestone v[X.Y] [Name]
+```markdown
+## Current Position
-[One-liner describing milestone focus]
-EOF
-)"
+Phase: Not started (defining requirements)
+Plan: —
+Status: Defining requirements
+Last activity: [today] — Milestone v[X.Y] started
```
-## Phase 6: Research Decision
+Keep Accumulated Context section (decisions, blockers) from previous milestone.
+
+## Phase 6: Cleanup and Commit
+
+Delete MILESTONE-CONTEXT.md if exists (consumed).
+
+Check planning config:
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+If `COMMIT_PLANNING_DOCS=false`: Skip git operations
+
+If `COMMIT_PLANNING_DOCS=true` (default):
+```bash
+git add .planning/PROJECT.md .planning/STATE.md
+git commit -m "docs: start milestone v[X.Y] [Name]"
+```
+
+## Phase 7: Research Decision
Use AskUserQuestion:
- header: "Research"
-- question: "Research the domain ecosystem before defining requirements?"
+- question: "Research the domain ecosystem for new features before defining requirements?"
- options:
- - "Research first (Recommended)" — Discover patterns, expected features, architecture
- - "Skip research" — I know this domain well, go straight to requirements
+ - "Research first (Recommended)" — Discover patterns, expected features, architecture for NEW capabilities
+ - "Skip research" — I know what I need, go straight to requirements
**If "Research first":**
@@ -219,7 +139,7 @@ Display stage banner:
GSD ► RESEARCHING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-Researching [domain] ecosystem...
+Researching [new features] ecosystem...
```
Create research directory:
@@ -227,46 +147,53 @@ Create research directory:
mkdir -p .planning/research
```
-**Milestone context is "subsequent"** — Research focuses on new features, not re-researching validated requirements.
-
Display spawning indicator:
```
◆ Spawning 4 researchers in parallel...
- → Stack research
+ → Stack research (for new features)
→ Features research
- → Architecture research
+ → Architecture research (integration)
→ Pitfalls research
```
-Spawn 4 parallel gsd-project-researcher agents with context:
+Spawn 4 parallel gsd-project-researcher agents with milestone-aware context:
```
Task(prompt="
-Project Research — Stack dimension for [domain].
+Project Research — Stack dimension for [new features].
-Subsequent milestone (v[X.Y]).
+SUBSEQUENT MILESTONE — Adding [target features] to existing app.
-Research what's needed to add [target features] to an existing [domain] app. Don't re-research the existing system.
+Existing validated capabilities (DO NOT re-research):
+[List from PROJECT.md Validated requirements]
+
+Focus ONLY on what's needed for the NEW features.
-What's needed to add [target features] to [domain]?
+What stack additions/changes are needed for [new features]?
-[PROJECT.md summary - core value, validated requirements, new goals]
+[PROJECT.md summary - current state, new milestone goals]
Your STACK.md feeds into roadmap creation. Be prescriptive:
-- Specific libraries with versions
-- Clear rationale for each choice
-- What NOT to use and why
+- Specific libraries with versions for NEW capabilities
+- Integration points with existing stack
+- What NOT to add and why
+
+- [ ] Versions are current (verify with Context7/official docs, not training data)
+- [ ] Rationale explains WHY, not just WHAT
+- [ ] Integration with existing stack considered
+
+
-
-
-- `.planning/PROJECT.md` (updated)
-- `.planning/research/` (if research selected)
- - `STACK.md`
- - `FEATURES.md`
- - `ARCHITECTURE.md`
- - `PITFALLS.md`
- - `SUMMARY.md`
-- `.planning/REQUIREMENTS.md`
-- `.planning/ROADMAP.md`
-- `.planning/STATE.md`
-
-
-
-
-- [ ] Project validated (PROJECT.md exists)
-- [ ] Previous milestone context presented
-- [ ] Deep questioning completed (threads followed)
-- [ ] Milestone version determined
-- [ ] PROJECT.md updated with new milestone goals → **committed**
-- [ ] Research completed (if selected) → **committed**
-- [ ] Requirements gathered and scoped
-- [ ] REQUIREMENTS.md created with REQ-IDs → **committed**
-- [ ] gsd-roadmapper spawned with context
-- [ ] Roadmap files written immediately
+- [ ] PROJECT.md updated with Current Milestone section
+- [ ] STATE.md reset for new milestone
+- [ ] MILESTONE-CONTEXT.md consumed and deleted (if existed)
+- [ ] Research completed (if selected) — 4 parallel agents spawned, milestone-aware
+- [ ] Requirements gathered (from research or conversation)
+- [ ] User scoped each category
+- [ ] REQUIREMENTS.md created with REQ-IDs
+- [ ] gsd-roadmapper spawned with phase numbering context
+- [ ] Roadmap files written immediately (not draft)
- [ ] User feedback incorporated (if any)
-- [ ] ROADMAP.md, STATE.md → **committed**
-- [ ] User knows next step is `/gsd:plan-phase [N]`
+- [ ] ROADMAP.md created with phases continuing from previous milestone
+- [ ] All commits made (if planning docs committed)
+- [ ] User knows next step is `/gsd:discuss-phase [N]`
+**Atomic commits:** Each phase commits its artifacts immediately. If context is lost, artifacts persist.
diff --git a/commands/gsd/pause-work.md b/commands/gsd/pause-work.md
index 63fa4c877..d607e155c 100644
--- a/commands/gsd/pause-work.md
+++ b/commands/gsd/pause-work.md
@@ -90,6 +90,17 @@ Be specific enough for a fresh Claude to understand immediately.
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/phases/*/.continue-here.md
git commit -m "wip: [phase-name] paused at task [X]/[Y]"
diff --git a/commands/gsd/plan-milestone-gaps.md b/commands/gsd/plan-milestone-gaps.md
index 70bed3460..6d1494f3f 100644
--- a/commands/gsd/plan-milestone-gaps.md
+++ b/commands/gsd/plan-milestone-gaps.md
@@ -158,6 +158,17 @@ mkdir -p ".planning/phases/{NN}-{name}"
## 8. Commit Roadmap Update
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/ROADMAP.md
git commit -m "docs(roadmap): add gap closure phases {N}-{M}"
diff --git a/commands/gsd/progress.md b/commands/gsd/progress.md
index 3b8e2597f..f12ba075f 100644
--- a/commands/gsd/progress.md
+++ b/commands/gsd/progress.md
@@ -21,6 +21,12 @@ Provides situational awareness before continuing work.
**Verify planning structure exists:**
+Use Bash (not Glob) to check—Glob respects .gitignore but .planning/ is often gitignored:
+
+```bash
+test -d .planning && echo "exists" || echo "missing"
+```
+
If no `.planning/` directory:
```
diff --git a/commands/gsd/remove-phase.md b/commands/gsd/remove-phase.md
index f59d3d6ea..a7ff59b62 100644
--- a/commands/gsd/remove-phase.md
+++ b/commands/gsd/remove-phase.md
@@ -252,6 +252,17 @@ Update any internal references to reflect new numbering.
Stage and commit the removal:
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/
git commit -m "chore: remove phase {target} ({original-phase-name})"
diff --git a/get-shit-done/references/planning-config.md b/get-shit-done/references/planning-config.md
new file mode 100644
index 000000000..f55995b98
--- /dev/null
+++ b/get-shit-done/references/planning-config.md
@@ -0,0 +1,94 @@
+
+
+Configuration options for `.planning/` directory behavior.
+
+
+```json
+"planning": {
+ "commit_docs": true,
+ "search_gitignored": false
+}
+```
+
+| Option | Default | Description |
+|--------|---------|-------------|
+| `commit_docs` | `true` | Whether to commit planning artifacts to git |
+| `search_gitignored` | `false` | Add `--no-ignore` to broad rg searches |
+
+
+
+
+**When `commit_docs: true` (default):**
+- Planning files committed normally
+- SUMMARY.md, STATE.md, ROADMAP.md tracked in git
+- Full history of planning decisions preserved
+
+**When `commit_docs: false`:**
+- Skip all `git add`/`git commit` for `.planning/` files
+- User must add `.planning/` to `.gitignore`
+- Useful for: OSS contributions, client projects, keeping planning private
+
+**Checking the config:**
+
+```bash
+# Check config.json first
+COMMIT_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+
+# Auto-detect gitignored (overrides config)
+git check-ignore -q .planning 2>/dev/null && COMMIT_DOCS=false
+```
+
+**Auto-detection:** If `.planning/` is gitignored, `commit_docs` is automatically `false` regardless of config.json. This prevents git errors when users have `.planning/` in `.gitignore`.
+
+**Conditional git operations:**
+
+```bash
+if [ "$COMMIT_DOCS" = "true" ]; then
+ git add .planning/STATE.md
+ git commit -m "docs: update state"
+fi
+```
+
+
+
+
+
+**When `search_gitignored: false` (default):**
+- Standard rg behavior (respects .gitignore)
+- Direct path searches work: `rg "pattern" .planning/` finds files
+- Broad searches skip gitignored: `rg "pattern"` skips `.planning/`
+
+**When `search_gitignored: true`:**
+- Add `--no-ignore` to broad rg searches that should include `.planning/`
+- Only needed when searching entire repo and expecting `.planning/` matches
+
+**Note:** Most GSD operations use direct file reads or explicit paths, which work regardless of gitignore status.
+
+
+
+
+
+To use uncommitted mode:
+
+1. **Set config:**
+ ```json
+ "planning": {
+ "commit_docs": false,
+ "search_gitignored": true
+ }
+ ```
+
+2. **Add to .gitignore:**
+ ```
+ .planning/
+ ```
+
+3. **Existing tracked files:** If `.planning/` was previously tracked:
+ ```bash
+ git rm -r --cached .planning/
+ git commit -m "chore: stop tracking planning docs"
+ ```
+
+
+
+
diff --git a/get-shit-done/templates/config.json b/get-shit-done/templates/config.json
index 644e57f50..536e6e046 100644
--- a/get-shit-done/templates/config.json
+++ b/get-shit-done/templates/config.json
@@ -1,6 +1,10 @@
{
"mode": "interactive",
"depth": "standard",
+ "planning": {
+ "commit_docs": true,
+ "search_gitignored": false
+ },
"parallelization": {
"enabled": true,
"plan_level": true,
diff --git a/get-shit-done/workflows/complete-milestone.md b/get-shit-done/workflows/complete-milestone.md
index 2c40f3251..cd90a2fb6 100644
--- a/get-shit-done/workflows/complete-milestone.md
+++ b/get-shit-done/workflows/complete-milestone.md
@@ -620,6 +620,17 @@ git push origin v[X.Y]
Commit milestone completion including archive files and deletions.
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
# Stage archive files (new)
git add .planning/milestones/v[X.Y]-ROADMAP.md
diff --git a/get-shit-done/workflows/diagnose-issues.md b/get-shit-done/workflows/diagnose-issues.md
index 92778cffb..ce28df4ab 100644
--- a/get-shit-done/workflows/diagnose-issues.md
+++ b/get-shit-done/workflows/diagnose-issues.md
@@ -156,6 +156,17 @@ For each gap in the Gaps section, add artifacts and missing fields:
Update status in frontmatter to "diagnosed".
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
Commit the updated UAT.md:
```bash
git add ".planning/phases/XX-name/{phase}-UAT.md"
diff --git a/get-shit-done/workflows/discuss-phase.md b/get-shit-done/workflows/discuss-phase.md
index e24f985b8..f12619a26 100644
--- a/get-shit-done/workflows/discuss-phase.md
+++ b/get-shit-done/workflows/discuss-phase.md
@@ -393,6 +393,17 @@ Created: .planning/phases/${PADDED_PHASE}-${SLUG}/${PADDED_PHASE}-CONTEXT.md
Commit phase context:
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add "${PHASE_DIR}/${PADDED_PHASE}-CONTEXT.md"
git commit -m "$(cat <<'EOF'
diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md
index 22f99ea57..d2bdf1bcd 100644
--- a/get-shit-done/workflows/execute-phase.md
+++ b/get-shit-done/workflows/execute-phase.md
@@ -8,6 +8,7 @@ The orchestrator's job is coordination, not execution. Each subagent loads the f
Read STATE.md before any operation to load project context.
+Read config.json for planning behavior settings.
@@ -33,6 +34,17 @@ Options:
```
**If .planning/ doesn't exist:** Error - project not initialized.
+
+**Load planning config:**
+
+```bash
+# Check if planning docs should be committed (default: true)
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+# Auto-detect gitignored (overrides config)
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+Store `COMMIT_PLANNING_DOCS` for use in git operations.
@@ -456,6 +468,17 @@ Update ROADMAP.md to reflect phase completion:
# Update status
```
+**Check planning config:**
+
+If `COMMIT_PLANNING_DOCS=false` (set in load_project_state):
+- Skip all git operations for .planning/ files
+- Planning docs exist locally but are gitignored
+- Log: "Skipping planning docs commit (commit_docs: false)"
+- Proceed to offer_next step
+
+If `COMMIT_PLANNING_DOCS=true` (default):
+- Continue with git operations below
+
Commit phase completion (roadmap, state, verification):
```bash
git add .planning/ROADMAP.md .planning/STATE.md .planning/phases/{phase_dir}/*-VERIFICATION.md
diff --git a/get-shit-done/workflows/execute-plan.md b/get-shit-done/workflows/execute-plan.md
index a90592674..de551857f 100644
--- a/get-shit-done/workflows/execute-plan.md
+++ b/get-shit-done/workflows/execute-plan.md
@@ -4,6 +4,7 @@ Execute a phase prompt (PLAN.md) and create the outcome summary (SUMMARY.md).
Read STATE.md before any operation to load project context.
+Read config.json for planning behavior settings.
@~/.claude/get-shit-done/references/git-integration.md
@@ -36,6 +37,17 @@ Options:
**If .planning/ doesn't exist:** Error - project not initialized.
This ensures every execution has full project context.
+
+**Load planning config:**
+
+```bash
+# Check if planning docs should be committed (default: true)
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+# Auto-detect gitignored (overrides config)
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+Store `COMMIT_PLANNING_DOCS` for use in git operations.
@@ -1513,6 +1525,17 @@ Commit execution metadata (SUMMARY + STATE + ROADMAP):
**Note:** All task code has already been committed during execution (one commit per task).
PLAN.md was already committed during plan-phase. This final commit captures execution results only.
+**Check planning config:**
+
+If `COMMIT_PLANNING_DOCS=false` (set in load_project_state):
+- Skip all git operations for .planning/ files
+- Planning docs exist locally but are gitignored
+- Log: "Skipping planning docs commit (commit_docs: false)"
+- Proceed to next step
+
+If `COMMIT_PLANNING_DOCS=true` (default):
+- Continue with git operations below
+
**1. Stage execution artifacts:**
```bash
diff --git a/get-shit-done/workflows/map-codebase.md b/get-shit-done/workflows/map-codebase.md
index 0a32f0a5e..48fdf7e20 100644
--- a/get-shit-done/workflows/map-codebase.md
+++ b/get-shit-done/workflows/map-codebase.md
@@ -211,6 +211,17 @@ Continue to commit_codebase_map.
Commit the codebase map:
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
```bash
git add .planning/codebase/*.md
git commit -m "$(cat <<'EOF'
diff --git a/get-shit-done/workflows/verify-work.md b/get-shit-done/workflows/verify-work.md
index f22a439ca..c1534f42d 100644
--- a/get-shit-done/workflows/verify-work.md
+++ b/get-shit-done/workflows/verify-work.md
@@ -285,6 +285,17 @@ Clear Current Test section:
[testing complete]
```
+**Check planning config:**
+
+```bash
+COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
+git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=false
+```
+
+**If `COMMIT_PLANNING_DOCS=false`:** Skip git operations
+
+**If `COMMIT_PLANNING_DOCS=true` (default):**
+
Commit the UAT file:
```bash
git add ".planning/phases/XX-name/{phase}-UAT.md"