@ktpartners/dgs-platform 2.6.3 → 2.7.1
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.
- package/agents/dgs-executor.md +51 -0
- package/commands/dgs/sync.md +70 -0
- package/deliver-great-systems/bin/dgs-tools.cjs +290 -4
- package/deliver-great-systems/bin/lib/config.cjs +259 -67
- package/deliver-great-systems/bin/lib/core.cjs +49 -8
- package/deliver-great-systems/bin/lib/core.test.cjs +35 -14
- package/deliver-great-systems/bin/lib/init.cjs +61 -6
- package/deliver-great-systems/bin/lib/init.test.cjs +9 -9
- package/deliver-great-systems/bin/lib/migration.cjs +1 -1
- package/deliver-great-systems/bin/lib/migration.test.cjs +7 -9
- package/deliver-great-systems/bin/lib/path-audit.test.cjs +1 -1
- package/deliver-great-systems/bin/lib/paths.cjs +32 -22
- package/deliver-great-systems/bin/lib/paths.test.cjs +16 -6
- package/deliver-great-systems/bin/lib/projects.cjs +1 -1
- package/deliver-great-systems/bin/lib/projects.test.cjs +1 -1
- package/deliver-great-systems/bin/lib/repos.cjs +29 -10
- package/deliver-great-systems/bin/lib/state.cjs +2 -2
- package/deliver-great-systems/bin/lib/sync.cjs +878 -0
- package/deliver-great-systems/bin/lib/test-helpers.cjs +44 -12
- package/deliver-great-systems/references/git-integration.md +81 -0
- package/deliver-great-systems/references/planning-config.md +154 -31
- package/deliver-great-systems/references/sync-cadence.md +191 -0
- package/deliver-great-systems/references/sync-hooks.md +96 -0
- package/deliver-great-systems/test/cadence.test.cjs +160 -0
- package/deliver-great-systems/test/sync-workflow.test.cjs +562 -0
- package/deliver-great-systems/workflows/execute-phase.md +111 -4
- package/deliver-great-systems/workflows/init-product.md +6 -2
- package/deliver-great-systems/workflows/run-job.md +77 -2
- package/deliver-great-systems/workflows/settings.md +82 -1
- package/package.json +1 -1
|
@@ -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
|
|
139
|
+
// Root layout: planning files live at repo root
|
|
140
140
|
planningDir = cwd;
|
|
141
141
|
projectRoot = '.';
|
|
142
142
|
|
|
143
|
-
//
|
|
144
|
-
var
|
|
145
|
-
|
|
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
|
|
181
|
-
|
|
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';
|
|
@@ -208,8 +228,8 @@ function createTempProject(options) {
|
|
|
208
228
|
}
|
|
209
229
|
|
|
210
230
|
if (withTodos) {
|
|
211
|
-
fs.mkdirSync(path.join(cwd, '.planning',
|
|
212
|
-
fs.mkdirSync(path.join(cwd, '.planning',
|
|
231
|
+
fs.mkdirSync(path.join(cwd, '.planning', 'todos', 'pending'), { recursive: true });
|
|
232
|
+
fs.mkdirSync(path.join(cwd, '.planning', 'todos', 'completed'), { recursive: true });
|
|
213
233
|
}
|
|
214
234
|
|
|
215
235
|
if (withResearch) {
|
|
@@ -221,9 +241,21 @@ function createTempProject(options) {
|
|
|
221
241
|
planningDir = path.join(cwd, '.planning');
|
|
222
242
|
projectRoot = '.planning';
|
|
223
243
|
|
|
224
|
-
//
|
|
225
|
-
var
|
|
226
|
-
|
|
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 (`
|
|
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
|
-
|
|
10
|
-
"
|
|
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
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
|
34
|
-
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
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
|
|
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`
|
|
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
|
|
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
|
|
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
|
|
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.
|