@ktpartners/dgs-platform 2.6.3 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -136,13 +136,23 @@ function createTempProject(options) {
136
136
  var projectRoot;
137
137
 
138
138
  if (layout === 'root') {
139
- // Root layout: planning files live at repo root, dgs.config.json at root
139
+ // Root layout: planning files live at repo root
140
140
  planningDir = cwd;
141
141
  projectRoot = '.';
142
142
 
143
- // Write dgs.config.json at repo root with planningRoot: '.'
144
- var rootConfigData = Object.assign({ planningRoot: '.' }, withConfig);
145
- writeFile(cwd, 'dgs.config.json', JSON.stringify(rootConfigData));
143
+ // Split withConfig into shared and local keys
144
+ var rootLocalKeys = { planningRoot: '.' };
145
+ var rootSharedKeys = {};
146
+ var LOCAL_KEY_SET = new Set(['current_project', 'planningRoot', 'v2_hint_shown', 'sync_hint_shown']);
147
+ for (var k in withConfig) {
148
+ if (LOCAL_KEY_SET.has(k)) {
149
+ rootLocalKeys[k] = withConfig[k];
150
+ } else {
151
+ rootSharedKeys[k] = withConfig[k];
152
+ }
153
+ }
154
+ writeFile(cwd, 'config.local.json', JSON.stringify(rootLocalKeys));
155
+ writeFile(cwd, 'config.json', JSON.stringify(rootSharedKeys));
146
156
 
147
157
  // Project files at root
148
158
  writeFile(cwd, 'PROJECT.md', '# Project: ' + projectName + '\n');
@@ -176,9 +186,19 @@ function createTempProject(options) {
176
186
  projectRoot = path.join('.planning', PROJECTS_DIR, project);
177
187
  var absProjectRoot = path.join(cwd, '.planning', PROJECTS_DIR, project);
178
188
 
179
- // Product-level config
180
- var configData = Object.assign({ current_project: project }, withConfig);
181
- writeFile(cwd, '.planning/config.json', JSON.stringify(configData));
189
+ // Product-level config: split into shared and local
190
+ var v2LocalKeys = { current_project: project };
191
+ var v2SharedKeys = {};
192
+ var LOCAL_KEY_SET_V2 = new Set(['current_project', 'planningRoot', 'v2_hint_shown', 'sync_hint_shown']);
193
+ for (var ck in withConfig) {
194
+ if (LOCAL_KEY_SET_V2.has(ck)) {
195
+ v2LocalKeys[ck] = withConfig[ck];
196
+ } else {
197
+ v2SharedKeys[ck] = withConfig[ck];
198
+ }
199
+ }
200
+ writeFile(cwd, '.planning/config.json', JSON.stringify(v2SharedKeys));
201
+ writeFile(cwd, '.planning/config.local.json', JSON.stringify(v2LocalKeys));
182
202
 
183
203
  // v2 markers
184
204
  var projectsMd = '# Projects\n\n## Active\n\n';
@@ -221,9 +241,21 @@ function createTempProject(options) {
221
241
  planningDir = path.join(cwd, '.planning');
222
242
  projectRoot = '.planning';
223
243
 
224
- // config.json
225
- var v1ConfigData = Object.assign({}, withConfig);
226
- writeFile(cwd, '.planning/config.json', JSON.stringify(v1ConfigData));
244
+ // Split withConfig into shared and local
245
+ var v1SharedKeys = {};
246
+ var v1LocalKeys = {};
247
+ var LOCAL_KEY_SET_V1 = new Set(['current_project', 'planningRoot', 'v2_hint_shown', 'sync_hint_shown']);
248
+ for (var vk in withConfig) {
249
+ if (LOCAL_KEY_SET_V1.has(vk)) {
250
+ v1LocalKeys[vk] = withConfig[vk];
251
+ } else {
252
+ v1SharedKeys[vk] = withConfig[vk];
253
+ }
254
+ }
255
+ writeFile(cwd, '.planning/config.json', JSON.stringify(v1SharedKeys));
256
+ if (Object.keys(v1LocalKeys).length > 0) {
257
+ writeFile(cwd, '.planning/config.local.json', JSON.stringify(v1LocalKeys));
258
+ }
227
259
 
228
260
  // Project files
229
261
  writeFile(cwd, '.planning/PROJECT.md', '# Project: ' + projectName + '\n');
@@ -248,3 +248,84 @@ Each plan produces 2-4 commits (tasks + metadata). Clear, granular, bisectable.
248
248
  - "Commit noise" irrelevant when consumer is Claude, not humans
249
249
 
250
250
  </commit_strategy_rationale>
251
+
252
+ <remote_sync>
253
+
254
+ ## Remote Synchronisation
255
+
256
+ DGS can automatically pull from and push to remotes for all registered repos. Behaviour is controlled by two config keys (`git.sync_push` and `git.sync_pull`) and a per-workflow cadence table.
257
+
258
+ ### Sync Modes
259
+
260
+ | Mode | Pull behaviour | Push behaviour | Best for |
261
+ |------|---------------|----------------|----------|
262
+ | `off` | No pull, no prompt | No push, no prompt | Solo developers, no remote, or manual git users |
263
+ | `prompt` | Asks before pulling (Y default) | Asks before pushing (Y default) | Teams learning DGS, cautious users |
264
+ | `auto` | Pulls silently before work | Pushes silently after work | Established teams, CI/CD pipelines, job execution |
265
+
266
+ Fresh installs default to `prompt`. Existing users upgrading get `off` (zero behaviour change).
267
+
268
+ ### Per-Workflow Cadence
269
+
270
+ Not every workflow needs sync. A cadence table in `sync.cjs` classifies each workflow:
271
+
272
+ | Pattern | Count | Examples |
273
+ |---------|-------|---------|
274
+ | Pull + Push | 35 | execute-phase, plan-phase, write-spec, run-job |
275
+ | Push only | 17 | pause-work, add-idea, import-spec, map-codebase |
276
+ | Pull only | 4 | resume-work, progress, find-related-ideas |
277
+ | No sync | 14 | help, list-ideas, search, debug |
278
+
279
+ A workflow syncs only when BOTH conditions are true: the cadence table says it should AND the user's config mode is not `off`.
280
+
281
+ Full per-workflow detail: see `references/sync-cadence.md`.
282
+
283
+ ### Failure Handling
284
+
285
+ **Pull failure:**
286
+ - Aborts the workflow BEFORE any DGS state is modified
287
+ - Reports which repo failed and why (dirty state, non-fast-forward, auth error, network timeout)
288
+ - In `prompt` mode, offers to continue without pulling
289
+ - Uses `--ff-only` -- non-fast-forward situations require manual resolution
290
+
291
+ **Push failure:**
292
+ - Does NOT abort -- work is already committed locally
293
+ - Reports a warning with the failing repo name and error
294
+ - Mid-workflow pushes (execute-phase after each plan) retry: 1 retry in prompt mode, 3 in auto mode
295
+
296
+ **Pre-flight checks (block sync if detected):**
297
+ - Dirty working tree (uncommitted changes)
298
+ - Mid-merge, mid-rebase, or mid-cherry-pick state
299
+ - Detached HEAD
300
+ - Each check names the affected repo with an actionable fix
301
+
302
+ ### Workflow Integration
303
+
304
+ Workflows use sync hooks at their boundaries:
305
+
306
+ 1. **Before work:** Check cadence + mode, pull if applicable, abort on failure
307
+ 2. **After work:** Check cadence + mode, push if applicable, warn on failure
308
+ 3. **Mid-workflow:** `execute-phase` pushes after each plan; `run-job` pushes after each phase (silent, no prompt)
309
+
310
+ **Prompt fatigue mitigation:** In `prompt` mode, a "Yes" answer suppresses re-prompting for 5 minutes across all workflows. Suppression uses temp files for cross-process persistence.
311
+
312
+ **Stale-state warning:** In `off` mode, if the planning repo's remote is ahead, a one-liner warning is displayed before continuing.
313
+
314
+ **First-run hint:** When a remote exists but sync is `off`, a one-time hint suggests enabling sync via `/dgs:settings`.
315
+
316
+ ### Configuration
317
+
318
+ ```bash
319
+ # Set both directions at once
320
+ dgs-tools config-set git.sync prompt
321
+
322
+ # Set independently
323
+ dgs-tools config-set git.sync_push auto
324
+ dgs-tools config-set git.sync_pull prompt
325
+
326
+ # Or use /dgs:settings for interactive toggle
327
+ ```
328
+
329
+ Valid values: `off`, `prompt`, `auto`.
330
+
331
+ </remote_sync>
@@ -2,39 +2,110 @@
2
2
 
3
3
  Configuration options for planning directory behavior.
4
4
 
5
- > **v2 Multi-Project:** Config file (`dgs.config.json`) is always product-level not project-scoped. In v2 setups, project-specific paths (STATE.md, ROADMAP.md, phases/) resolve to `<project-slug>/` within the planning root via init commands, but config stays at the product root.
5
+ > **v2 Multi-Project:** Config file (`config.json`) is always product-level -- not project-scoped. In v2 setups, project-specific paths (STATE.md, ROADMAP.md, phases/) resolve to `<project-slug>/` within the planning root via init commands, but config stays at the product root.
6
+
7
+ ## Two-File Config Layout
8
+
9
+ DGS splits configuration across two files, both resolved via `getPlanningRoot()`:
10
+
11
+ | File | Tracked | Purpose | Keys |
12
+ |------|---------|---------|------|
13
+ | `config.json` | Yes (shared) | Team settings: model profile, workflow flags, git config, sync config, parallelization | All `VALID_CONFIG_KEYS` |
14
+ | `config.local.json` | No (gitignored) | Per-machine state: which project is active, where planning lives | `current_project`, `planningRoot`, `v2_hint_shown`, `sync_hint_shown` |
15
+
16
+ `loadConfig()` in `core.cjs` merges both files -- local overrides shared. `writeConfigField()` in `config.cjs` routes writes to the correct file based on `isLocalKey()`.
17
+
18
+ **Migration:** On first read, if only `dgs.config.json` exists, `_migrateLegacyConfig()` splits it into the two-file layout automatically.
6
19
 
7
20
  <config_schema>
21
+
22
+ ## Config Schema
23
+
24
+ Complete JSON example with all sections (fresh-install defaults):
25
+
8
26
  ```json
9
- "workflow": {
10
- "research": true,
11
- "plan_check": true,
12
- "verifier": true,
13
- "auto_advance": false,
14
- "nyquist_validation": true,
15
- "codereview": false
16
- },
17
- "planning": {
27
+ {
28
+ "model_profile": "balanced",
18
29
  "commit_docs": true,
19
- "search_gitignored": false
20
- },
21
- "git": {
22
- "base_branch": "main",
23
- "branching_strategy": "none",
24
- "phase_branch_template": "dgs/{project}/phase-{phase}-{slug}",
25
- "milestone_branch_template": "dgs/{project}/{milestone}-{slug}"
30
+ "search_gitignored": false,
31
+ "parallelization": true,
32
+ "brave_search": false,
33
+ "granularity": "standard",
34
+ "workflow": {
35
+ "research": true,
36
+ "plan_check": true,
37
+ "verifier": true,
38
+ "nyquist_validation": true,
39
+ "discipline": true
40
+ },
41
+ "git": {
42
+ "base_branch": "main",
43
+ "branching_strategy": "none",
44
+ "phase_branch_template": "dgs/{project}/phase-{phase}-{slug}",
45
+ "milestone_branch_template": "dgs/{project}/{milestone}-{slug}",
46
+ "sync_push": "prompt",
47
+ "sync_pull": "prompt"
48
+ }
26
49
  }
27
50
  ```
28
51
 
29
- | Option | Default | Description |
30
- |--------|---------|-------------|
31
- | `workflow.codereview` | `false` | Spawn 3-pass multi-agent code reviewer after plan execution. Auto-fixes low-risk issues in separate commit. |
32
- | `commit_docs` | `true` | Whether to commit planning artifacts to git |
33
- | `search_gitignored` | `false` | Add `--no-ignore` to broad rg searches |
34
- | `git.base_branch` | `"main"` | Integration target branch for code repo branching operations (branch creation and merge) |
35
- | `git.branching_strategy` | `"none"` | Git branching approach: `"none"`, `"phase"`, or `"milestone"` |
36
- | `git.phase_branch_template` | `"dgs/{project}/phase-{phase}-{slug}"` | Branch template for phase strategy |
37
- | `git.milestone_branch_template` | `"dgs/{project}/{milestone}-{slug}"` | Branch template for milestone strategy |
52
+ ## Config Schema Table
53
+
54
+ ### Top-Level Keys
55
+
56
+ | Key | Default (fresh) | Default (upgrade) | Values | Description |
57
+ |-----|-----------------|-------------------|--------|-------------|
58
+ | `mode` | -- | -- | `interactive`, `non-interactive` | Execution mode; set by orchestration workflows, not user-facing |
59
+ | `model_profile` | `"balanced"` | `"balanced"` | `"speed"`, `"balanced"`, `"quality"` | Selects model tier for planning/execution agents |
60
+ | `commit_docs` | `true` | `true` | `true`, `false` | Whether to commit planning artifacts to git |
61
+ | `search_gitignored` | `false` | `false` | `true`, `false` | Add `--no-ignore` to broad rg searches |
62
+ | `parallelization` | `true` | `true` | `true`, `false` | Enable parallel plan execution within a phase |
63
+ | `brave_search` | auto-detected | `false` | `true`, `false` | Whether Brave Search API is available (auto-detected from `$BRAVE_API_KEY` or `~/.dgs/brave_api_key`) |
64
+ | `granularity` | `"standard"` | `"standard"` | `"coarse"`, `"standard"`, `"fine"` | Planning granularity level (maps from deprecated `depth`) |
65
+
66
+ ### Workflow Keys (`workflow.*`)
67
+
68
+ | Key | Default (fresh) | Default (upgrade) | Values | Description |
69
+ |-----|-----------------|-------------------|--------|-------------|
70
+ | `workflow.research` | `true` | `true` | `true`, `false` | Run research phase before planning |
71
+ | `workflow.plan_check` | `true` | `true` | `true`, `false` | Run plan-check validation after planning |
72
+ | `workflow.verifier` | `true` | `true` | `true`, `false` | Run auto-verifier after plan execution |
73
+ | `workflow.nyquist_validation` | `true` | `true` | `true`, `false` | Validate plan coverage meets Nyquist sampling threshold |
74
+ | `workflow.discipline` | `true` | `true` | `true`, `false` | Enforce `/dgs:` command routing discipline |
75
+ | `workflow.ui_phase` | -- | -- | `true`, `false` | Enable UI-specific phase handling |
76
+ | `workflow.ui_safety_gate` | -- | -- | `true`, `false` | Enable safety gate before UI changes |
77
+ | `workflow._auto_chain_active` | -- | -- | `true`, `false` | Internal: tracks whether auto-chain execution is in progress |
78
+
79
+ ### Git Keys (`git.*`)
80
+
81
+ | Key | Default (fresh) | Default (upgrade) | Values | Description |
82
+ |-----|-----------------|-------------------|--------|-------------|
83
+ | `git.base_branch` | `"main"` | `"main"` | any branch name | Integration target branch for code repo branching operations |
84
+ | `git.branching_strategy` | `"none"` | `"none"` | `"none"`, `"phase"`, `"milestone"` | Git branching approach for code repos |
85
+ | `git.phase_branch_template` | `"dgs/{project}/phase-{phase}-{slug}"` | `"dgs/{project}/phase-{phase}-{slug}"` | template string | Branch name template for phase strategy |
86
+ | `git.milestone_branch_template` | `"dgs/{project}/{milestone}-{slug}"` | `"dgs/{project}/{milestone}-{slug}"` | template string | Branch name template for milestone strategy |
87
+ | `git.sync_push` | `"prompt"` | `"off"` | `"off"`, `"prompt"`, `"auto"` | Remote push mode -- controls whether and how DGS pushes after workflows |
88
+ | `git.sync_pull` | `"prompt"` | `"off"` | `"off"`, `"prompt"`, `"auto"` | Remote pull mode -- controls whether and how DGS pulls before workflows |
89
+ | `git.sync` | -- (virtual) | -- (virtual) | `"off"`, `"prompt"`, `"auto"` | Virtual shorthand -- writes both `sync_push` and `sync_pull` simultaneously; never stored in config |
90
+
91
+ ### Alias Keys (`planning.*`)
92
+
93
+ | Key | Alias for | Description |
94
+ |-----|-----------|-------------|
95
+ | `planning.commit_docs` | `commit_docs` | Alias for the top-level `commit_docs` key |
96
+ | `planning.search_gitignored` | `search_gitignored` | Alias for the top-level `search_gitignored` key |
97
+
98
+ ### Local Keys (`config.local.json`)
99
+
100
+ These keys are stored in `config.local.json` (gitignored, per-machine):
101
+
102
+ | Key | Default | Description |
103
+ |-----|---------|-------------|
104
+ | `current_project` | -- | Active project slug for multi-project setups |
105
+ | `planningRoot` | -- | Absolute path to planning root (when non-standard) |
106
+ | `v2_hint_shown` | -- | Whether the v2 migration hint has been shown |
107
+ | `sync_hint_shown` | -- | Whether the sync first-run hint has been shown |
108
+
38
109
  </config_schema>
39
110
 
40
111
  <commit_docs_behavior>
@@ -74,7 +145,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
74
145
  node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "docs: update state" --files ${state_path}
75
146
  ```
76
147
 
77
- The CLI checks `commit_docs` config and gitignore status internally no manual conditionals needed.
148
+ The CLI checks `commit_docs` config and gitignore status internally -- no manual conditionals needed.
78
149
 
79
150
  </commit_docs_behavior>
80
151
 
@@ -132,7 +203,7 @@ To use uncommitted mode:
132
203
 
133
204
  **Base Branch:**
134
205
 
135
- All branching operations on code repos (branch creation in `execute-phase`, merge in `complete-milestone`) use `git.base_branch` as the starting point instead of hardcoded `main`. Default is `main`. Set during `/dgs:init-product` or change via `/dgs:settings`. The product folder repo always uses `main` only sibling code repos registered in REPOS.md use the configured base branch.
206
+ All branching operations on code repos (branch creation in `execute-phase`, merge in `complete-milestone`) use `git.base_branch` as the starting point instead of hardcoded `main`. Default is `main`. Set during `/dgs:init-product` or change via `/dgs:settings`. The product folder repo always uses `main` -- only sibling code repos registered in REPOS.md use the configured base branch.
136
207
 
137
208
  **When `git.branching_strategy: "none"` (default):**
138
209
  - All work commits to current branch
@@ -179,7 +250,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
179
250
  **Branch creation:**
180
251
 
181
252
  ```bash
182
- # For phase strategy (code repos product folder always uses main)
253
+ # For phase strategy (code repos -- product folder always uses main)
183
254
  if [ "$BRANCHING_STRATEGY" = "phase" ]; then
184
255
  PHASE_SLUG=$(echo "$PHASE_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
185
256
  BRANCH_NAME=$(echo "$PHASE_BRANCH_TEMPLATE" | sed "s/{project}/$PROJECT_SLUG/g" | sed "s/{phase}/$PADDED_PHASE/g" | sed "s/{slug}/$PHASE_SLUG/g")
@@ -189,7 +260,7 @@ if [ "$BRANCHING_STRATEGY" = "phase" ]; then
189
260
  git checkout -b "$BRANCH_NAME" 2>/dev/null || git checkout "$BRANCH_NAME"
190
261
  fi
191
262
 
192
- # For milestone strategy (code repos product folder always uses main)
263
+ # For milestone strategy (code repos -- product folder always uses main)
193
264
  if [ "$BRANCHING_STRATEGY" = "milestone" ]; then
194
265
  MILESTONE_SLUG=$(echo "$MILESTONE_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
195
266
  BRANCH_NAME=$(echo "$MILESTONE_BRANCH_TEMPLATE" | sed "s/{project}/$PROJECT_SLUG/g" | sed "s/{milestone}/$MILESTONE_VERSION/g" | sed "s/{slug}/$MILESTONE_SLUG/g")
@@ -209,7 +280,7 @@ fi
209
280
  | Delete without merging | `git branch -D` | Discard branch work |
210
281
  | Keep branches | (none) | Manual handling later |
211
282
 
212
- Squash merge is recommended keeps main branch history clean while preserving the full development history in the branch (until deleted).
283
+ Squash merge is recommended -- keeps main branch history clean while preserving the full development history in the branch (until deleted).
213
284
 
214
285
  **Use cases:**
215
286
 
@@ -221,4 +292,56 @@ Squash merge is recommended — keeps main branch history clean while preserving
221
292
 
222
293
  </branching_strategy_behavior>
223
294
 
295
+ <sync_behavior>
296
+
297
+ ## Remote Synchronisation Config
298
+
299
+ DGS can automatically pull from and push to remotes for all registered repos. Behaviour is controlled by two config keys: `git.sync_push` and `git.sync_pull`.
300
+
301
+ ### Three Modes
302
+
303
+ | Mode | Pull behaviour | Push behaviour | Best for |
304
+ |------|---------------|----------------|----------|
305
+ | `off` | No pull, no prompt | No push, no prompt | Solo developers, no remote, or manual git users |
306
+ | `prompt` | Asks before pulling (Y default) | Asks before pushing (Y default) | Teams learning DGS, cautious users |
307
+ | `auto` | Pulls silently before work | Pushes silently after work | Established teams, CI/CD pipelines, job execution |
308
+
309
+ ### Default Behaviour
310
+
311
+ - **Fresh installs** default to `prompt` -- the recommended mode for teams. New users get sync out of the box with a confirmation step.
312
+ - **Existing users upgrading** default to `off` -- zero behaviour change. The `loadConfig()` defaults in `core.cjs` ensure that users who upgrade from pre-v17.0 never see unexpected sync activity.
313
+
314
+ ### Virtual Shorthand: `git.sync`
315
+
316
+ `git.sync` is a convenience shorthand that writes both `sync_push` and `sync_pull` simultaneously:
317
+
318
+ ```bash
319
+ dgs-tools config-set git.sync auto # sets both sync_push AND sync_pull to "auto"
320
+ ```
321
+
322
+ The `git.sync` key is never stored in `config.json` -- it expands at write time only. Reading config always returns `sync_push` and `sync_pull` individually.
323
+
324
+ ### Per-Workflow Cadence
325
+
326
+ Not every workflow pulls and pushes. A cadence table in `sync.cjs` classifies each workflow by whether it should pull, push, both, or neither. A workflow syncs only when both conditions are true: the cadence table says it should AND the user's config mode is not `off`.
327
+
328
+ Full per-workflow detail: see `references/sync-cadence.md`.
329
+
330
+ ### Configuration
331
+
332
+ ```bash
333
+ # Set both directions at once
334
+ dgs-tools config-set git.sync prompt
335
+
336
+ # Set independently
337
+ dgs-tools config-set git.sync_push auto
338
+ dgs-tools config-set git.sync_pull prompt
339
+
340
+ # Or use /dgs:settings for interactive toggle
341
+ ```
342
+
343
+ Valid values: `off`, `prompt`, `auto`. Invalid values are rejected at `config-set` time.
344
+
345
+ </sync_behavior>
346
+
224
347
  </planning_config>
@@ -0,0 +1,191 @@
1
+ # Sync Cadence Table
2
+
3
+ When each DGS workflow should pull from and push to remotes.
4
+
5
+ **Source of truth:** The authoritative cadence classification lives in the `CADENCE_TABLE` constant in `bin/lib/sync.cjs`. This document explains the reasoning behind each classification and provides quick-reference views -- it is documentation only. `sync.cjs` does not parse this file.
6
+
7
+ ## Flag Semantics
8
+
9
+ Each workflow has two boolean flags:
10
+
11
+ - **`cadence_pull`** -- Whether the workflow *should* pull before starting. Ensures the agent works on the latest shared state.
12
+ - **`cadence_push`** -- Whether the workflow *should* push after completing. Shares new artifacts with other team members.
13
+
14
+ These flags express **intent** ("this workflow benefits from syncing"). The user's configuration determines **behavior**:
15
+
16
+ - `git.sync_pull` and `git.sync_push` are mode strings: `off`, `prompt`, or `auto`.
17
+ - A workflow syncs only when both conditions are true: the cadence flag says "should sync" AND the user config is not `off`.
18
+ - Resolution: `if (cadence_pull && sync_pull !== 'off') { /* perform pull */ }`
19
+
20
+ ---
21
+
22
+ ## Primary Table: By Workflow Category
23
+
24
+ ### Phase Lifecycle
25
+
26
+ | Command | Pull | Push | Reason |
27
+ |---------|------|------|--------|
28
+ | execute-phase | Yes | Yes | Reads ROADMAP/STATE/REQUIREMENTS; writes PLAN execution artifacts, SUMMARY, STATE |
29
+ | plan-phase | Yes | Yes | Reads ROADMAP/CONTEXT/prior SUMMARYs; writes PLAN files |
30
+ | discuss-phase | Yes | Yes | Reads phase context; writes CONTEXT.md with decisions |
31
+ | research-phase | Yes | Yes | Reads phase scope; writes RESEARCH.md |
32
+ | pause-work | No | Yes | Records pause state in STATE.md; does not need latest state to pause |
33
+ | resume-work | Yes | No | Reads STATE.md to restore context; does not produce new artifacts |
34
+
35
+ ### Job Orchestration
36
+
37
+ | Command | Pull | Push | Reason |
38
+ |---------|------|------|--------|
39
+ | run-job | Yes | Yes | Reads job definitions; writes execution results |
40
+ | create-milestone-job | Yes | Yes | Reads milestone/roadmap state; writes job definition |
41
+ | cancel-job | Yes | Yes | Reads job state; writes cancellation status |
42
+ | rollback-job | Yes | Yes | Reads job state; writes rollback artifacts |
43
+
44
+ ### Milestone Lifecycle
45
+
46
+ | Command | Pull | Push | Reason |
47
+ |---------|------|------|--------|
48
+ | new-milestone | Yes | Yes | Reads current state; writes new ROADMAP/milestone structure |
49
+ | complete-milestone | Yes | Yes | Reads milestone state; writes completion status and audit |
50
+ | audit-milestone | Yes | Yes | Reads planning state for audit; produces MILESTONE-AUDIT.md which captures the audit outcome for the team. Even clean audits produce artifacts useful to other team members. |
51
+ | plan-milestone-gaps | Yes | Yes | Reads audit results; writes gap-filling phase plans |
52
+ | cleanup | Yes | Yes | Reads completed state; writes archive/cleanup artifacts |
53
+
54
+ ### Ideas Pipeline
55
+
56
+ | Command | Pull | Push | Reason |
57
+ |---------|------|------|--------|
58
+ | add-idea | No | Yes | Creates new idea file; does not need latest state to capture an idea |
59
+ | discuss-idea | Yes | Yes | Reads idea and related context; writes discussion notes |
60
+ | develop-idea | Yes | Yes | Reads idea context; writes developed idea with detail |
61
+ | research-idea | Yes | Yes | Reads idea for research direction; writes research findings |
62
+ | find-related-ideas | Yes | No | Reads all ideas for comparison; produces display output only |
63
+ | consolidate-ideas | Yes | Yes | Reads multiple ideas; writes consolidated idea |
64
+ | undo-consolidation | Yes | Yes | Reads consolidation state; writes restoration |
65
+ | reject-idea | No | Yes | Writes rejection status; does not need latest state |
66
+ | restore-idea | No | Yes | Writes restoration status; does not need latest state |
67
+ | update-idea | No | Yes | Writes idea updates; single-idea operation does not need full sync |
68
+
69
+ ### Specs Pipeline
70
+
71
+ | Command | Pull | Push | Reason |
72
+ |---------|------|------|--------|
73
+ | write-spec | Yes | Yes | Reads requirements/ideas for spec context; writes spec document |
74
+ | refine-spec | Yes | Yes | Reads spec and review feedback; writes refined spec |
75
+ | approve-spec | Yes | Yes | Reads spec for approval; writes approval status |
76
+ | import-spec | No | Yes | Creates spec from external input; does not need latest state |
77
+
78
+ ### Quick/Fast Tasks
79
+
80
+ | Command | Pull | Push | Reason |
81
+ |---------|------|------|--------|
82
+ | quick | Yes | Yes | Reads project state for context; writes task artifacts and STATE updates |
83
+ | fast | Yes | Yes | Reads project state for context; writes task artifacts |
84
+ | add-todo | Yes | Yes | Reads existing todos; writes new todo file |
85
+ | check-todos | Yes | Yes | Reads todo state; writes completion status updates |
86
+
87
+ ### Project Management
88
+
89
+ | Command | Pull | Push | Reason |
90
+ |---------|------|------|--------|
91
+ | new-project | Yes | Yes | Reads existing projects; writes new project structure |
92
+ | init-product | Yes | Yes | Reads config; writes initial product scaffold |
93
+ | complete-project | No | Yes | Writes completion status; single-project operation |
94
+ | reactivate-project | No | Yes | Writes reactivation status; single-project operation |
95
+ | switch-project | No | Yes | Writes project switch state; local operation |
96
+
97
+ ### Roadmap Structure
98
+
99
+ | Command | Pull | Push | Reason |
100
+ |---------|------|------|--------|
101
+ | add-phase | Yes | Yes | Reads ROADMAP for placement; writes new phase entry |
102
+ | insert-phase | Yes | Yes | Reads ROADMAP for insertion point; writes phase and renumbers |
103
+ | remove-phase | Yes | Yes | Reads ROADMAP for target; writes removal and renumbers |
104
+
105
+ ### Verification and Testing
106
+
107
+ | Command | Pull | Push | Reason |
108
+ |---------|------|------|--------|
109
+ | audit-phase | Yes | Yes | Reads phase artifacts for audit; produces UAT verification artifacts. Even clean audits (no gaps found) generate UAT records that are useful to other team members for tracking verification history. |
110
+ | validate-phase | Yes | Yes | Reads phase for validation; writes validation results |
111
+ | verify-work | Yes | Yes | Reads work artifacts; writes verification results |
112
+ | add-tests | Yes | Yes | Reads code for test targets; writes test files |
113
+
114
+ ### Configuration
115
+
116
+ | Command | Pull | Push | Reason |
117
+ |---------|------|------|--------|
118
+ | settings | Yes | Yes | Reads current config; writes updated config |
119
+ | set-profile | No | Yes | Writes profile change; local preference |
120
+ | add-repo | No | Yes | Writes REPOS.md entry; local operation |
121
+ | remove-repo | No | Yes | Writes REPOS.md removal; local operation |
122
+ | add-doc | No | Yes | Writes DOCS.md entry; local operation |
123
+ | remove-doc | No | Yes | Writes DOCS.md removal; local operation |
124
+ | capture-principle | No | Yes | Writes principle to CLAUDE.md; local capture |
125
+ | map-codebase | No | Yes | Writes codebase map; does not need remote state |
126
+ | reapply-patches | No | Yes | Writes patched files; local operation |
127
+
128
+ ### Progress and Display
129
+
130
+ | Command | Pull | Push | Reason |
131
+ |---------|------|------|--------|
132
+ | progress | Yes | No | Reads STATE.md for display; does not write durable artifacts. Stale progress data is misleading, so pulling ensures the displayed metrics reflect actual team state. |
133
+ | list-phase-assumptions | Yes | No | Reads phase context for display; does not write artifacts |
134
+
135
+ ### No Sync
136
+
137
+ | Command | Pull | Push | Reason |
138
+ |---------|------|------|--------|
139
+ | help | No | No | Pure display; reads no project state |
140
+ | join-discord | No | No | Opens external URL; no project interaction |
141
+ | list-ideas | No | No | Shows local idea state for instant response. Users can pull manually before listing if freshness matters. |
142
+ | list-specs | No | No | Shows local spec state for instant response |
143
+ | list-docs | No | No | Shows local doc state for instant response |
144
+ | list-jobs | No | No | Shows local job state for instant response |
145
+ | list-projects | No | No | Shows local project state for instant response |
146
+ | search | No | No | Searches local content; read-only |
147
+ | overlap-check | No | No | Analyzes local content; read-only |
148
+ | health | No | No | Checks local installation health; read-only |
149
+ | update | No | No | Updates DGS package; not a project operation |
150
+ | debug | No | No | Diagnostic/exploratory in unknown or broken state. Pulling in a broken context could worsen the situation by introducing merge conflicts or overwriting local diagnostic changes. Users can manually push after a successful debug resolution. |
151
+ | node-repair | No | No | Repairs Node.js installation; not a project operation |
152
+ | sync-upstream | No | No | Manages DGS package updates; separate from project sync |
153
+
154
+ ---
155
+
156
+ ## Summary: By Sync Pattern
157
+
158
+ ### Pull + Push (35 commands)
159
+
160
+ Workflows that read shared state AND produce artifacts worth sharing.
161
+
162
+ add-phase, add-tests, add-todo, approve-spec, audit-milestone, audit-phase, cancel-job, check-todos, cleanup, complete-milestone, consolidate-ideas, create-milestone-job, develop-idea, discuss-idea, discuss-phase, execute-phase, fast, init-product, insert-phase, new-milestone, new-project, plan-milestone-gaps, plan-phase, quick, refine-spec, remove-phase, research-idea, research-phase, rollback-job, run-job, settings, undo-consolidation, validate-phase, verify-work, write-spec
163
+
164
+ ### Push Only (17 commands)
165
+
166
+ Workflows that produce artifacts but do not need the latest remote state to operate correctly.
167
+
168
+ add-doc, add-idea, add-repo, capture-principle, complete-project, import-spec, map-codebase, pause-work, reactivate-project, reapply-patches, reject-idea, remove-doc, remove-repo, restore-idea, set-profile, switch-project, update-idea
169
+
170
+ ### Pull Only (4 commands)
171
+
172
+ Workflows that read shared state for display or analysis but do not produce durable artifacts.
173
+
174
+ find-related-ideas, list-phase-assumptions, progress, resume-work
175
+
176
+ ### No Sync (14 commands)
177
+
178
+ Informational, diagnostic, or infrastructure workflows with no project sync benefit.
179
+
180
+ debug, health, help, join-discord, list-docs, list-ideas, list-jobs, list-projects, list-specs, node-repair, overlap-check, search, sync-upstream, update
181
+
182
+ ---
183
+
184
+ ## Maintenance
185
+
186
+ When adding a new DGS workflow, update two places:
187
+
188
+ 1. **`CADENCE_TABLE` in `bin/lib/sync.cjs`** -- Add one line with `{ pull: boolean, push: boolean }`.
189
+ 2. **This document** -- Add the workflow to the appropriate category table (with reasoning) and to the correct summary group (alphabetically).
190
+
191
+ The cadence table in `sync.cjs` is the machine-readable source of truth. This document is the human-readable companion that explains the "why" behind each classification.