diff --git a/get-shit-done/references/planning-config.md b/get-shit-done/references/planning-config.md
index df8f54b98..db9c2964f 100644
--- a/get-shit-done/references/planning-config.md
+++ b/get-shit-done/references/planning-config.md
@@ -214,4 +214,219 @@ Squash merge is recommended — keeps main branch history clean while preserving
+
+
+## Complete Field Reference
+
+Generated from `CONFIG_DEFAULTS` (core.cjs) and `VALID_CONFIG_KEYS` (config.cjs).
+
+### Core Fields
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `model_profile` | string | `"balanced"` | `"quality"`, `"balanced"`, `"budget"`, `"inherit"` | Model selection preset for subagents |
+| `mode` | string | (none) | `"code-first"`, `"plan-first"`, `"hybrid"` | Per-phase workflow mode controlling discuss/plan/execute flow |
+| `granularity` | string | (none) | `"coarse"`, `"standard"`, `"fine"` | Planning depth for phase plans (migrated from deprecated `depth`) |
+| `commit_docs` | boolean | `true` | `true`, `false` | Commit .planning/ artifacts to git (auto-false if .planning/ is gitignored) |
+| `search_gitignored` | boolean | `false` | `true`, `false` | Include gitignored paths in broad rg searches via `--no-ignore` |
+| `phase_naming` | string | `"sequential"` | `"sequential"`, `"custom"` | Phase numbering: auto-increment or arbitrary string IDs |
+| `project_code` | string\|null | `null` | Any short string | Prefix for phase dirs (e.g., `"CK"` produces `CK-01-foundation`) |
+| `response_language` | string\|null | `null` | Any language name | Language for user-facing prompts (e.g., `"Portuguese"`, `"Japanese"`) |
+| `context_window` | number | `200000` | `200000`, `1000000` | Context window size; set `1000000` for 1M-context models |
+| `resolve_model_ids` | boolean\|string | `false` | `false`, `true`, `"omit"` | Map model aliases to full Claude IDs; `"omit"` returns empty string |
+
+### Workflow Fields
+
+Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research": true }`).
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `workflow.research` | boolean | `true` | `true`, `false` | Run research agent before planning |
+| `workflow.plan_check` | boolean | `true` | `true`, `false` | Run plan-checker agent to validate plans. _Alias:_ `plan_checker` is the flat-key form used in `CONFIG_DEFAULTS`; `workflow.plan_check` is the canonical namespaced form. |
+| `workflow.verifier` | boolean | `true` | `true`, `false` | Run verifier agent after execution |
+| `workflow.nyquist_validation` | boolean | `true` | `true`, `false` | Enable Nyquist-inspired validation gates |
+| `workflow.auto_advance` | boolean | `false` | `true`, `false` | Auto-advance to next phase after completion |
+| `workflow.node_repair` | boolean | `true` | `true`, `false` | Attempt automatic repair of failed plan nodes |
+| `workflow.node_repair_budget` | number | `2` | Any positive integer | Max repair retries per failed node |
+| `workflow.ui_phase` | boolean | `true` | `true`, `false` | Generate UI-SPEC.md for frontend phases |
+| `workflow.ui_safety_gate` | boolean | `true` | `true`, `false` | Require safety gate approval for UI changes |
+| `workflow.text_mode` | boolean | `false` | `true`, `false` | Use plain-text numbered lists instead of AskUserQuestion menus |
+| `workflow.research_before_questions` | boolean | `false` | `true`, `false` | Run research before interactive questions in discuss phase |
+| `workflow.discuss_mode` | string | `"discuss"` | `"discuss"`, `"auto"`, `"analyze"` | Default mode for discuss-phase agent |
+| `workflow.skip_discuss` | boolean | `false` | `true`, `false` | Skip discuss phase entirely |
+| `workflow.use_worktrees` | boolean | `true` | `true`, `false` | Run executor agents in isolated git worktrees |
+| `workflow.subagent_timeout` | number | `300000` | Any positive integer (ms) | Timeout for parallel subagent tasks (default: 5 minutes) |
+| `workflow._auto_chain_active` | boolean | `false` | `true`, `false` | Internal: tracks whether autonomous chaining is active |
+
+### Git Fields
+
+Set via `git.*` namespace (e.g., `"git": { "branching_strategy": "phase" }`).
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `git.branching_strategy` | string | `"none"` | `"none"`, `"phase"`, `"milestone"` | Git branching approach for phase/milestone isolation |
+| `git.base_branch` | string\|null | `null` (auto-detect) | Any branch name | Target branch for PRs and merges; auto-detects from `origin/HEAD` when `null` |
+| `git.phase_branch_template` | string | `"gsd/phase-{phase}-{slug}"` | Template with `{phase}`, `{slug}` | Branch naming template for `phase` strategy |
+| `git.milestone_branch_template` | string | `"gsd/{milestone}-{slug}"` | Template with `{milestone}`, `{slug}` | Branch naming template for `milestone` strategy |
+| `git.quick_branch_template` | string\|null | `null` | Template with `{slug}` | Optional branch template for quick-task runs |
+
+### Search & API Fields
+
+These toggle external search integrations. Auto-detected at project creation when API keys are present.
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `brave_search` | boolean | `false` | `true`, `false` | Enable Brave web search for research agent (requires `BRAVE_API_KEY`) |
+| `firecrawl` | boolean | `false` | `true`, `false` | Enable Firecrawl page scraping (requires `FIRECRAWL_API_KEY`) |
+| `exa_search` | boolean | `false` | `true`, `false` | Enable Exa semantic search (requires `EXA_API_KEY`) |
+
+### Features Fields
+
+Set via `features.*` namespace (e.g., `"features": { "thinking_partner": true }`).
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `features.thinking_partner` | boolean | `false` | `true`, `false` | Enable conditional extended thinking at workflow decision points (used by discuss-phase and plan-phase for architectural tradeoff analysis) |
+
+### Hook Fields
+
+Set via `hooks.*` namespace (e.g., `"hooks": { "context_warnings": true }`).
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `hooks.context_warnings` | boolean | `true` | `true`, `false` | Show warnings when context budget is exceeded |
+
+### Manager Fields
+
+Set via `manager.*` namespace (e.g., `"manager": { "flags": { "discuss": "--auto" } }`).
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `manager.flags.discuss` | string | `""` | Any CLI flags string | Flags passed to `/gsd-discuss-phase` from manager (e.g., `"--auto --analyze"`) |
+| `manager.flags.plan` | string | `""` | Any CLI flags string | Flags passed to plan workflow from manager |
+| `manager.flags.execute` | string | `""` | Any CLI flags string | Flags passed to execute workflow from manager |
+
+### Advanced Fields
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `parallelization` | boolean\|object | `true` | `true`, `false`, `{ "enabled": true }` | Enable parallel wave execution; object form allows additional sub-keys |
+| `model_overrides` | object\|null | `null` | `{ "": "" }` | Override model selection per agent type |
+| `agent_skills` | object | `{}` | `{ "": "" }` | Assign skill sets to specific agent types |
+| `sub_repos` | array | `[]` | Array of relative path strings | Child directories with independent `.git` repos (auto-detected) |
+
+### Planning Fields
+
+These can be set at top level or nested under `planning.*` (e.g., `"planning": { "commit_docs": false }`). Both forms are equivalent; top-level takes precedence if both exist.
+
+| Key | Type | Default | Allowed Values | Description |
+|-----|------|---------|----------------|-------------|
+| `planning.commit_docs` | boolean | `true` | `true`, `false` | Alias for top-level `commit_docs` |
+| `planning.search_gitignored` | boolean | `false` | `true`, `false` | Alias for top-level `search_gitignored` |
+
+---
+
+## Field Interactions
+
+Several config fields affect each other or trigger special behavior:
+
+1. **`commit_docs` auto-detection** -- When no explicit value is set in config.json and `.planning/` is in `.gitignore`, `commit_docs` automatically resolves to `false`. An explicit `true` or `false` in config always overrides auto-detection.
+
+2. **`branching_strategy` controls branch templates** -- The `phase_branch_template` and `milestone_branch_template` fields are only used when `branching_strategy` is set to `"phase"` or `"milestone"` respectively. When `branching_strategy` is `"none"`, all template fields are ignored.
+
+3. **`context_window` threshold triggers** -- When `context_window >= 500000`, workflows enable adaptive context enrichment: full-body reads of prior phase SUMMARYs, cross-phase context injection in plan-phase, and deeper read depth for anti-pattern references. Below 500000, only frontmatter and summaries are read.
+
+4. **`parallelization` polymorphism** -- Accepts both a simple boolean and an object with an `enabled` field. `loadConfig()` normalizes either form to a boolean. `{ "enabled": true }` is equivalent to `true`.
+
+5. **Search API keys and flags** -- `brave_search`, `firecrawl`, and `exa_search` are auto-set to `true` during project creation if the corresponding API key is detected (environment variable or `~/.gsd/_api_key` file). Setting them to `true` without the API key has no effect.
+
+6. **`planning.*` and top-level equivalence** -- `planning.commit_docs` and `commit_docs` are equivalent; `planning.search_gitignored` and `search_gitignored` are equivalent. If both are set, the top-level value takes precedence.
+
+7. **`depth` to `granularity` migration** -- The deprecated `depth` key (`quick`/`standard`/`comprehensive`) is automatically migrated to `granularity` (`coarse`/`standard`/`fine`) on config load and persisted back to disk.
+
+8. **`sub_repos` auto-sync** -- On every config load, GSD scans for child directories with `.git` and updates the `sub_repos` array if the filesystem has changed. Legacy `multiRepo: true` is automatically migrated to a detected `sub_repos` array.
+
+---
+
+## Example Configurations
+
+### Minimal -- Solo Developer
+
+```json
+{
+ "model_profile": "balanced",
+ "commit_docs": true,
+ "workflow": {
+ "research": true,
+ "plan_check": true,
+ "verifier": true,
+ "use_worktrees": false
+ }
+}
+```
+
+### Team Project with Branching
+
+```json
+{
+ "model_profile": "quality",
+ "commit_docs": true,
+ "project_code": "APP",
+ "git": {
+ "branching_strategy": "phase",
+ "base_branch": "develop",
+ "phase_branch_template": "gsd/phase-{phase}-{slug}"
+ },
+ "workflow": {
+ "research": true,
+ "plan_check": true,
+ "verifier": true,
+ "nyquist_validation": true,
+ "use_worktrees": true,
+ "discuss_mode": "discuss"
+ },
+ "manager": {
+ "flags": {
+ "discuss": "",
+ "plan": "",
+ "execute": ""
+ }
+ },
+ "response_language": "English"
+}
+```
+
+### Large Codebase -- 1M Context with Extended Timeouts
+
+```json
+{
+ "model_profile": "quality",
+ "context_window": 1000000,
+ "commit_docs": true,
+ "project_code": "MEGA",
+ "phase_naming": "sequential",
+ "git": {
+ "branching_strategy": "milestone",
+ "milestone_branch_template": "gsd/{milestone}-{slug}"
+ },
+ "workflow": {
+ "research": true,
+ "plan_check": true,
+ "verifier": true,
+ "nyquist_validation": true,
+ "subagent_timeout": 600000,
+ "use_worktrees": true,
+ "node_repair": true,
+ "node_repair_budget": 3,
+ "auto_advance": true
+ },
+ "brave_search": true,
+ "hooks": {
+ "context_warnings": true
+ }
+}
+```
+
+
+
diff --git a/tests/config-field-docs.test.cjs b/tests/config-field-docs.test.cjs
new file mode 100644
index 000000000..bbe765d09
--- /dev/null
+++ b/tests/config-field-docs.test.cjs
@@ -0,0 +1,179 @@
+/**
+ * Verify planning-config.md documents all config fields from source code.
+ */
+
+const { describe, test, before } = require('node:test');
+const assert = require('node:assert/strict');
+const fs = require('fs');
+const path = require('path');
+
+const REFERENCE_PATH = path.join(__dirname, '..', 'get-shit-done', 'references', 'planning-config.md');
+const CORE_PATH = path.join(__dirname, '..', 'get-shit-done', 'bin', 'lib', 'core.cjs');
+
+describe('config-field-docs', () => {
+ let content;
+
+ before(() => {
+ content = fs.readFileSync(REFERENCE_PATH, 'utf-8');
+ });
+
+ test('contains Complete Field Reference section', () => {
+ assert.ok(
+ content.includes('## Complete Field Reference'),
+ 'planning-config.md must contain a "Complete Field Reference" heading'
+ );
+ });
+
+ test('documents at least 15 config fields in tables', () => {
+ // Count table rows that start with | `` (field rows, not header/separator)
+ const fieldRows = content.match(/^\| `[a-z_][a-z0-9_.]*` \|/gm);
+ assert.ok(fieldRows, 'Expected markdown table rows with backtick-quoted keys');
+ assert.ok(
+ fieldRows.length >= 15,
+ `Expected at least 15 documented fields, found ${fieldRows.length}`
+ );
+ });
+
+ test('contains example configurations', () => {
+ assert.ok(
+ content.includes('## Example Configurations'),
+ 'planning-config.md must contain an "Example Configurations" section'
+ );
+ // Verify at least one JSON code block with a model_profile key
+ assert.ok(
+ content.includes('"model_profile"'),
+ 'Example configurations must include model_profile'
+ );
+ });
+
+ test('contains field interactions section', () => {
+ assert.ok(
+ content.includes('## Field Interactions'),
+ 'planning-config.md must contain a "Field Interactions" section'
+ );
+ });
+
+ test('every CONFIG_DEFAULTS key appears in the doc', () => {
+ // Extract CONFIG_DEFAULTS keys from core.cjs source
+ const coreSource = fs.readFileSync(CORE_PATH, 'utf-8');
+ const defaultsMatch = coreSource.match(
+ /const CONFIG_DEFAULTS\s*=\s*\{([\s\S]*?)\n\};/
+ );
+ assert.ok(defaultsMatch, 'Could not find CONFIG_DEFAULTS in core.cjs');
+
+ const body = defaultsMatch[1];
+ // Match property keys (word characters before the colon)
+ const keys = [...body.matchAll(/^\s*(\w+)\s*:/gm)].map(m => m[1]);
+ assert.ok(keys.length > 0, 'Could not extract any keys from CONFIG_DEFAULTS');
+
+ // CONFIG_DEFAULTS uses flat keys; the doc may use namespaced equivalents.
+ // Map flat keys to the namespace forms used in config.json and the doc.
+ const NAMESPACE_MAP = {
+ research: 'workflow.research',
+ plan_checker: 'workflow.plan_check',
+ verifier: 'workflow.verifier',
+ nyquist_validation: 'workflow.nyquist_validation',
+ text_mode: 'workflow.text_mode',
+ subagent_timeout: 'workflow.subagent_timeout',
+ branching_strategy: 'git.branching_strategy',
+ phase_branch_template: 'git.phase_branch_template',
+ milestone_branch_template: 'git.milestone_branch_template',
+ quick_branch_template: 'git.quick_branch_template',
+ };
+
+ const missing = keys.filter(k => {
+ // Check both bare key and namespaced form
+ if (content.includes(`\`${k}\``)) return false;
+ const ns = NAMESPACE_MAP[k];
+ if (ns && content.includes(`\`${ns}\``)) return false;
+ return true;
+ });
+ assert.deepStrictEqual(
+ missing,
+ [],
+ `CONFIG_DEFAULTS keys missing from planning-config.md: ${missing.join(', ')}`
+ );
+ });
+
+ test('documents workflow namespace fields', () => {
+ const workflowFields = [
+ 'workflow.research',
+ 'workflow.plan_check',
+ 'workflow.verifier',
+ 'workflow.nyquist_validation',
+ 'workflow.use_worktrees',
+ 'workflow.subagent_timeout',
+ 'workflow.text_mode',
+ ];
+ const missing = workflowFields.filter(f => !content.includes(`\`${f}\``));
+ assert.deepStrictEqual(
+ missing,
+ [],
+ `Workflow fields missing from planning-config.md: ${missing.join(', ')}`
+ );
+ });
+
+ test('documents git namespace fields', () => {
+ const gitFields = [
+ 'git.branching_strategy',
+ 'git.base_branch',
+ 'git.phase_branch_template',
+ 'git.milestone_branch_template',
+ ];
+ const missing = gitFields.filter(f => !content.includes(`\`${f}\``));
+ assert.deepStrictEqual(
+ missing,
+ [],
+ `Git fields missing from planning-config.md: ${missing.join(', ')}`
+ );
+ });
+
+ test('documents KNOWN_TOP_LEVEL internal fields not in CONFIG_DEFAULTS', () => {
+ // These fields are in KNOWN_TOP_LEVEL (core.cjs) and read by loadConfig()
+ // but not in CONFIG_DEFAULTS, so the CONFIG_DEFAULTS test doesn't cover them.
+ const internalFields = [
+ 'model_overrides',
+ 'agent_skills',
+ ];
+ const missing = internalFields.filter(f => !content.includes(`\`${f}\``));
+ assert.deepStrictEqual(
+ missing,
+ [],
+ `KNOWN_TOP_LEVEL internal fields missing from planning-config.md: ${missing.join(', ')}`
+ );
+ });
+
+ test('documents sub_repos field (CONFIG_DEFAULTS, no namespace form)', () => {
+ // sub_repos is in CONFIG_DEFAULTS but has no NAMESPACE_MAP entry
+ // (it uses a planning.sub_repos nested lookup but is documented as a
+ // top-level field). Verify it explicitly since the NAMESPACE_MAP path
+ // would silently skip it.
+ assert.ok(
+ content.includes('`sub_repos`'),
+ 'planning-config.md must document the sub_repos field'
+ );
+ });
+
+ test('documents features.thinking_partner field', () => {
+ // features.thinking_partner is in VALID_CONFIG_KEYS (config.cjs) and
+ // used by discuss-phase.md and plan-phase.md for conditional extended
+ // thinking at workflow decision points.
+ assert.ok(
+ content.includes('`features.thinking_partner`'),
+ 'planning-config.md must document the features.thinking_partner field'
+ );
+ });
+
+ test('documents plan_checker alias for workflow.plan_check', () => {
+ // plan_checker is the flat-key form in CONFIG_DEFAULTS; workflow.plan_check
+ // is the canonical namespaced form. The doc should mention the alias.
+ assert.ok(
+ content.includes('`workflow.plan_check`'),
+ 'planning-config.md must document workflow.plan_check'
+ );
+ assert.ok(
+ content.includes('plan_checker'),
+ 'planning-config.md must mention the plan_checker flat-key alias'
+ );
+ });
+});