@ktpartners/dgs-platform 2.9.0 → 3.3.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.
- package/CHANGELOG.md +197 -0
- package/README.md +34 -2
- package/agents/dgs-executor.md +124 -3
- package/agents/dgs-idea-researcher.md +447 -0
- package/agents/dgs-plan-checker.md +61 -3
- package/agents/dgs-planner.md +51 -8
- package/bin/install.js +44 -0
- package/commands/dgs/abandon-quick.md +28 -0
- package/commands/dgs/add-tests.md +2 -2
- package/commands/dgs/audit-milestone.md +4 -3
- package/commands/dgs/capture-principle.md +11 -11
- package/commands/dgs/cleanup.md +2 -2
- package/commands/dgs/complete-milestone.md +11 -11
- package/commands/dgs/complete-quick.md +28 -0
- package/commands/dgs/create-milestone-job.md +2 -2
- package/commands/dgs/debug.md +3 -3
- package/commands/dgs/develop-idea.md +1 -1
- package/commands/dgs/diff-report.md +124 -0
- package/commands/dgs/fast.md +3 -1
- package/commands/dgs/health.md +1 -1
- package/commands/dgs/map-codebase.md +6 -6
- package/commands/dgs/new-milestone.md +5 -5
- package/commands/dgs/new-project.md +8 -21
- package/commands/dgs/package-scan.md +43 -0
- package/commands/dgs/plan-milestone-gaps.md +1 -1
- package/commands/dgs/progress.md +3 -3
- package/commands/dgs/quick-abandon.md +8 -0
- package/commands/dgs/quick-complete.md +8 -0
- package/commands/dgs/quick.md +10 -3
- package/commands/dgs/research-idea.md +3 -2
- package/commands/dgs/research-phase.md +3 -3
- package/commands/dgs/switch-project.md +14 -1
- package/commands/dgs/write-spec.md +3 -3
- package/deliver-great-systems/bin/dgs-tools.cjs +401 -32
- package/deliver-great-systems/bin/lib/audit-tolerance.cjs +77 -0
- package/deliver-great-systems/bin/lib/audit-tolerance.test.cjs +101 -0
- package/deliver-great-systems/bin/lib/commands.cjs +626 -46
- package/deliver-great-systems/bin/lib/commands.test.cjs +451 -0
- package/deliver-great-systems/bin/lib/commit-verify.test.cjs +236 -0
- package/deliver-great-systems/bin/lib/config.cjs +80 -6
- package/deliver-great-systems/bin/lib/config.test.cjs +309 -0
- package/deliver-great-systems/bin/lib/context.cjs +120 -0
- package/deliver-great-systems/bin/lib/core.cjs +35 -14
- package/deliver-great-systems/bin/lib/core.test.cjs +79 -1
- package/deliver-great-systems/bin/lib/execution.cjs +49 -17
- package/deliver-great-systems/bin/lib/fast-routing.cjs +199 -0
- package/deliver-great-systems/bin/lib/fast-routing.test.cjs +108 -0
- package/deliver-great-systems/bin/lib/final-commit-precondition.test.cjs +87 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/bundler-audit-gemfile.json +21 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/gate-parity-expected.md +186 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/gate-parity-runresult.json +235 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/govulncheck-import.json +3 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/npm-audit-v10.json +37 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/osv-clean.json +3 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/osv-vulns.json +77 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/pip-audit-requirements.json +28 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/snyk-lodash.json +30 -0
- package/deliver-great-systems/bin/lib/fixtures/package-scan/snyk-workspaces.json +55 -0
- package/deliver-great-systems/bin/lib/flat-migration.test.cjs +396 -0
- package/deliver-great-systems/bin/lib/frontmatter.cjs +1 -1
- package/deliver-great-systems/bin/lib/governance.cjs +211 -0
- package/deliver-great-systems/bin/lib/governance.test.cjs +339 -0
- package/deliver-great-systems/bin/lib/health-untracked-phase.test.cjs +269 -0
- package/deliver-great-systems/bin/lib/ideas.cjs +206 -91
- package/deliver-great-systems/bin/lib/ideas.test.cjs +244 -1
- package/deliver-great-systems/bin/lib/init.cjs +357 -61
- package/deliver-great-systems/bin/lib/init.test.cjs +625 -8
- package/deliver-great-systems/bin/lib/jobs.cjs +131 -25
- package/deliver-great-systems/bin/lib/jobs.test.cjs +193 -74
- package/deliver-great-systems/bin/lib/migration.cjs +409 -1
- package/deliver-great-systems/bin/lib/migration.test.cjs +158 -1
- package/deliver-great-systems/bin/lib/milestone.cjs +154 -31
- package/deliver-great-systems/bin/lib/milestone.test.cjs +203 -0
- package/deliver-great-systems/bin/lib/package-adapters.cjs +530 -0
- package/deliver-great-systems/bin/lib/package-adapters.test.cjs +618 -0
- package/deliver-great-systems/bin/lib/package-ecosystems.cjs +350 -0
- package/deliver-great-systems/bin/lib/package-ecosystems.test.cjs +348 -0
- package/deliver-great-systems/bin/lib/package-runner.cjs +199 -0
- package/deliver-great-systems/bin/lib/package-runner.test.cjs +198 -0
- package/deliver-great-systems/bin/lib/package-scan-provenance.cjs +56 -0
- package/deliver-great-systems/bin/lib/package-scan-provenance.test.cjs +103 -0
- package/deliver-great-systems/bin/lib/package-scan-report.cjs +1140 -0
- package/deliver-great-systems/bin/lib/package-scan-report.test.cjs +1963 -0
- package/deliver-great-systems/bin/lib/package-scan-skill.cjs +96 -0
- package/deliver-great-systems/bin/lib/package-scan-skill.test.cjs +136 -0
- package/deliver-great-systems/bin/lib/package-scan.cjs +919 -0
- package/deliver-great-systems/bin/lib/package-scan.test.cjs +2147 -0
- package/deliver-great-systems/bin/lib/phase.cjs +146 -3
- package/deliver-great-systems/bin/lib/phase.test.cjs +420 -0
- package/deliver-great-systems/bin/lib/plan-number-validity.test.cjs +48 -0
- package/deliver-great-systems/bin/lib/projects.cjs +65 -10
- package/deliver-great-systems/bin/lib/projects.test.cjs +198 -2
- package/deliver-great-systems/bin/lib/quick.cjs +739 -0
- package/deliver-great-systems/bin/lib/quick.test.cjs +730 -0
- package/deliver-great-systems/bin/lib/repos.cjs +37 -13
- package/deliver-great-systems/bin/lib/review.cjs +1821 -0
- package/deliver-great-systems/bin/lib/roadmap.cjs +34 -13
- package/deliver-great-systems/bin/lib/specs.cjs +3 -81
- package/deliver-great-systems/bin/lib/state-transition-gate.test.cjs +160 -0
- package/deliver-great-systems/bin/lib/state.cjs +147 -55
- package/deliver-great-systems/bin/lib/summary-frontmatter.cjs +54 -0
- package/deliver-great-systems/bin/lib/summary-frontmatter.test.cjs +78 -0
- package/deliver-great-systems/bin/lib/sweep-scope.test.cjs +263 -0
- package/deliver-great-systems/bin/lib/sync.cjs +75 -0
- package/deliver-great-systems/bin/lib/verify.cjs +198 -7
- package/deliver-great-systems/bin/lib/verify.test.cjs +82 -0
- package/deliver-great-systems/bin/lib/wave-0-template-rename.test.cjs +40 -0
- package/deliver-great-systems/bin/lib/worktrees.cjs +790 -0
- package/deliver-great-systems/bin/lib/worktrees.test.cjs +963 -0
- package/deliver-great-systems/references/agent-step-reliability.md +60 -0
- package/deliver-great-systems/references/conflict-resolution.md +4 -0
- package/deliver-great-systems/references/context-tiers.md +4 -0
- package/deliver-great-systems/references/package-scan-config.md +151 -0
- package/deliver-great-systems/references/questioning.md +0 -30
- package/deliver-great-systems/references/spec-review-loop.md +1 -2
- package/deliver-great-systems/references/workflow-conventions.md +29 -0
- package/deliver-great-systems/skills/dgs-tests/package-scan.md +44 -0
- package/deliver-great-systems/templates/REVIEW.md +35 -0
- package/deliver-great-systems/templates/VALIDATION.md +1 -1
- package/deliver-great-systems/templates/claude-md.md +27 -0
- package/deliver-great-systems/templates/package-scan-report.md +108 -0
- package/deliver-great-systems/templates/project.md +6 -170
- package/deliver-great-systems/templates/summary.md +3 -1
- package/deliver-great-systems/workflows/abandon-quick.md +89 -0
- package/deliver-great-systems/workflows/add-idea.md +3 -3
- package/deliver-great-systems/workflows/add-phase.md +5 -0
- package/deliver-great-systems/workflows/add-tests.md +14 -0
- package/deliver-great-systems/workflows/add-todo.md +1 -0
- package/deliver-great-systems/workflows/approve-spec.md +25 -4
- package/deliver-great-systems/workflows/audit-milestone.md +66 -10
- package/deliver-great-systems/workflows/audit-phase.md +15 -5
- package/deliver-great-systems/workflows/cancel-job.md +2 -2
- package/deliver-great-systems/workflows/check-todos.md +2 -3
- package/deliver-great-systems/workflows/codereview.md +103 -9
- package/deliver-great-systems/workflows/complete-milestone.md +218 -24
- package/deliver-great-systems/workflows/complete-quick.md +106 -0
- package/deliver-great-systems/workflows/consolidate-ideas.md +1 -1
- package/deliver-great-systems/workflows/create-milestone-job.md +4 -4
- package/deliver-great-systems/workflows/develop-idea.md +11 -11
- package/deliver-great-systems/workflows/diagnose-issues.md +14 -0
- package/deliver-great-systems/workflows/discuss-idea.md +1 -1
- package/deliver-great-systems/workflows/discuss-phase.md +3 -2
- package/deliver-great-systems/workflows/execute-phase.md +209 -33
- package/deliver-great-systems/workflows/execute-plan.md +22 -22
- package/deliver-great-systems/workflows/help.md +53 -20
- package/deliver-great-systems/workflows/import-spec.md +65 -7
- package/deliver-great-systems/workflows/init-product.md +45 -167
- package/deliver-great-systems/workflows/new-milestone.md +140 -33
- package/deliver-great-systems/workflows/new-project.md +60 -331
- package/deliver-great-systems/workflows/package-scan.md +59 -0
- package/deliver-great-systems/workflows/plan-phase.md +79 -1
- package/deliver-great-systems/workflows/progress-all.md +133 -0
- package/deliver-great-systems/workflows/quick-abandon.md +89 -0
- package/deliver-great-systems/workflows/quick-complete.md +106 -0
- package/deliver-great-systems/workflows/quick.md +328 -26
- package/deliver-great-systems/workflows/refine-spec.md +1 -1
- package/deliver-great-systems/workflows/research-idea.md +77 -139
- package/deliver-great-systems/workflows/resume-project.md +2 -2
- package/deliver-great-systems/workflows/run-job.md +29 -43
- package/deliver-great-systems/workflows/settings.md +13 -77
- package/deliver-great-systems/workflows/validate-phase.md +39 -1
- package/deliver-great-systems/workflows/verify-work.md +14 -0
- package/deliver-great-systems/workflows/write-spec.md +11 -13
- package/hooks/dist/dgs-enforce-discipline.js +196 -0
- package/package.json +1 -1
- package/scripts/build-hooks.js +1 -0
|
@@ -26,6 +26,8 @@ Parse `$ARGUMENTS` for:
|
|
|
26
26
|
- `--dry-run` flag → store as `$DRY_RUN` (true/false)
|
|
27
27
|
- `--full` flag → store as `$FULL_MODE` (true/false)
|
|
28
28
|
- `--discuss` flag → store as `$DISCUSS_MODE` (true/false)
|
|
29
|
+
- `--main` flag → store as `$FORCE_MAIN` (true/false)
|
|
30
|
+
- `--debug` flag → store as `$DEBUG_MODE` (true/false)
|
|
29
31
|
- Remaining text (after stripping all flags) → use as `$DESCRIPTION` if non-empty
|
|
30
32
|
|
|
31
33
|
If `$DESCRIPTION` is empty after parsing, prompt user interactively:
|
|
@@ -82,6 +84,108 @@ If `$FULL_MODE` only:
|
|
|
82
84
|
|
|
83
85
|
---
|
|
84
86
|
|
|
87
|
+
**Step 1.5: Detect quick mode and handle worktree lifecycle**
|
|
88
|
+
|
|
89
|
+
This step runs for BOTH fast and non-fast paths. For `$FAST_MODE`, it performs mode detection ONLY (no worktree creation) so the fast path can route commits correctly based on the active context.
|
|
90
|
+
|
|
91
|
+
Determine the effective mode flag:
|
|
92
|
+
- If `$DEBUG_MODE`: set `$QUICK_MODE_FLAG = 'debug'`
|
|
93
|
+
- If `$FULL_MODE`: set `$QUICK_MODE_FLAG = 'full'`
|
|
94
|
+
- Otherwise: set `$QUICK_MODE_FLAG = null`
|
|
95
|
+
|
|
96
|
+
Detect whether this is a product-level or milestone-context quick:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
QUICK_DETECT=$(node -e "
|
|
100
|
+
const q = require('$HOME/.claude/deliver-great-systems/bin/lib/quick.cjs');
|
|
101
|
+
const r = q.detectQuickMode(process.cwd(), ${FORCE_MAIN:-false});
|
|
102
|
+
process.stdout.write(JSON.stringify(r));
|
|
103
|
+
")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Parse `QUICK_DETECT` for `mode` field.
|
|
107
|
+
|
|
108
|
+
**If mode is 'product':**
|
|
109
|
+
|
|
110
|
+
**If NOT `$FAST_MODE`:**
|
|
111
|
+
|
|
112
|
+
Check the one-active-quick guard and create worktree:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
QUICK_START=$(node -e "
|
|
116
|
+
const q = require('$HOME/.claude/deliver-great-systems/bin/lib/quick.cjs');
|
|
117
|
+
const r = q.startProductQuick(process.cwd(), '${DESCRIPTION}', ${QUICK_MODE_FLAG ? \"'\" + QUICK_MODE_FLAG + \"'\" : 'null'});
|
|
118
|
+
process.stdout.write(JSON.stringify(r));
|
|
119
|
+
")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Parse `QUICK_START` result.
|
|
123
|
+
|
|
124
|
+
If `success` is false (guard triggered or creation failed):
|
|
125
|
+
```
|
|
126
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
127
|
+
║ ERROR ║
|
|
128
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
129
|
+
|
|
130
|
+
${error message from QUICK_START}
|
|
131
|
+
```
|
|
132
|
+
End workflow.
|
|
133
|
+
|
|
134
|
+
If `success` is true:
|
|
135
|
+
Set `$QUICK_CONTEXT = 'product'`
|
|
136
|
+
Set `$QUICK_SLUG` from result `slug`
|
|
137
|
+
Set `$QUICK_REPOS` from result `repos` (object mapping repoName -> worktreePath, may be empty `{}`)
|
|
138
|
+
Display: `Product-level quick created: ${QUICK_SLUG}`
|
|
139
|
+
|
|
140
|
+
**If `$FAST_MODE`:**
|
|
141
|
+
|
|
142
|
+
Skip worktree creation entirely. Fast in product mode commits directly to `base_branch` in the main checkout.
|
|
143
|
+
|
|
144
|
+
Set `$QUICK_CONTEXT = 'product'`
|
|
145
|
+
Set `$QUICK_REPO_CWD = null` (unset — git ops run in planning-root cwd)
|
|
146
|
+
Display: `Fast: product-level (no milestone) — committing to base_branch in main checkout.`
|
|
147
|
+
|
|
148
|
+
**If mode is 'milestone-context':**
|
|
149
|
+
|
|
150
|
+
Set `$QUICK_CONTEXT = 'milestone-context'`
|
|
151
|
+
Set `$MILESTONE_SLUG` from `activeMilestone` in detect result
|
|
152
|
+
|
|
153
|
+
**If `$FAST_MODE`:** Resolve the milestone worktree directory for the active repo so fast commits land on the milestone branch:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
QUICK_REPO_CWD=$(node -e "
|
|
157
|
+
const fs = require('fs');
|
|
158
|
+
const path = require('path');
|
|
159
|
+
const localPath = path.join(process.cwd(), 'config.local.json');
|
|
160
|
+
const local = JSON.parse(fs.readFileSync(localPath, 'utf-8'));
|
|
161
|
+
const { loadConfig } = require('$HOME/.claude/deliver-great-systems/bin/lib/core.cjs');
|
|
162
|
+
const cfg = loadConfig(process.cwd());
|
|
163
|
+
const proj = cfg.current_project;
|
|
164
|
+
const wt = (local.projects && local.projects[proj] && local.projects[proj].worktrees && local.projects[proj].worktrees['${MILESTONE_SLUG}']) || {};
|
|
165
|
+
const repos = Object.entries(wt.repos || {});
|
|
166
|
+
if (repos.length === 0) process.exit(1);
|
|
167
|
+
// Multi-repo: prefer the worktree with pending edits. Single-repo: the
|
|
168
|
+
// only entry. Fall back to the first entry if no diffs are detected.
|
|
169
|
+
const { execSync } = require('child_process');
|
|
170
|
+
let pick = repos[0][1];
|
|
171
|
+
for (const [name, dir] of repos) {
|
|
172
|
+
try {
|
|
173
|
+
const diff = execSync('git -C \"' + dir + '\" diff --stat', { encoding: 'utf-8' }).trim();
|
|
174
|
+
if (diff.length > 0) { pick = dir; break; }
|
|
175
|
+
} catch {}
|
|
176
|
+
}
|
|
177
|
+
process.stdout.write(pick);
|
|
178
|
+
")
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Display: `Fast: milestone-context (${MILESTONE_SLUG}) — committing to milestone branch in worktree ${QUICK_REPO_CWD}.`
|
|
182
|
+
|
|
183
|
+
**If NOT `$FAST_MODE`:** Leave `$QUICK_REPO_CWD` unset. Display: `Working in milestone context (${MILESTONE_SLUG}). Changes will be part of the milestone.`
|
|
184
|
+
|
|
185
|
+
No worktree creation. No guard check. Continue to Step 2.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
85
189
|
**Step 2: Initialize**
|
|
86
190
|
|
|
87
191
|
```bash
|
|
@@ -136,14 +240,138 @@ Switching to /dgs:quick...
|
|
|
136
240
|
```
|
|
137
241
|
Then continue from Step 3 as normal quick mode (skip the rest of the fast path).
|
|
138
242
|
|
|
243
|
+
**F1.5-pre. Pre-edit dirt check (REL-06; runs only when `$FAST_MODE` is true)**
|
|
244
|
+
|
|
245
|
+
Before any F2 edits, run a dirty-tree check across the planning root and all registered sub-repos. Pre-existing dirt that the user didn't initiate inside this fast-task would otherwise be swept into the F5 commit under a misleading message (the original idea-#27 footgun). Fail loudly with `pre-existing-dirt` exit-code label in non-interactive mode; ask to confirm in interactive mode.
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
DIRT_JSON=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" fast-route 2>/dev/null)
|
|
249
|
+
PRE_DIRTY=$(echo "$DIRT_JSON" | jq -r '
|
|
250
|
+
((.survey.planningRoot.dirty // false) as $pr |
|
|
251
|
+
([.survey.subRepos[]? | select(.dirty == true) | .path] | length) as $sr |
|
|
252
|
+
if ($pr or ($sr > 0)) then "true" else "false" end)
|
|
253
|
+
')
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
If `$PRE_DIRTY == "true"`:
|
|
257
|
+
|
|
258
|
+
- **Non-interactive mode (no TTY):** Print the dirty paths from `$DIRT_JSON` and exit non-zero with label `pre-existing-dirt`:
|
|
259
|
+
```
|
|
260
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
261
|
+
║ PRE-EXISTING DIRT DETECTED ║
|
|
262
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
263
|
+
|
|
264
|
+
/dgs:fast cannot proceed — the following repos have uncommitted changes
|
|
265
|
+
that pre-date this invocation:
|
|
266
|
+
- <planning root>: <paths>
|
|
267
|
+
- <sub-repo>: <paths>
|
|
268
|
+
|
|
269
|
+
Commit, stash, or `git restore` the listed paths and re-run, or use
|
|
270
|
+
/dgs:quick if these changes are part of the same intent.
|
|
271
|
+
|
|
272
|
+
exit-code label: pre-existing-dirt
|
|
273
|
+
```
|
|
274
|
+
End workflow. Do NOT proceed to F1.5.
|
|
275
|
+
|
|
276
|
+
- **Interactive mode:** Surface the dirty paths and prompt:
|
|
277
|
+
```
|
|
278
|
+
AskUserQuestion(
|
|
279
|
+
header: "Pre-existing dirt",
|
|
280
|
+
question: "The following repos are dirty before this fast invocation: <paths>. Proceed anyway, or stop?",
|
|
281
|
+
options: [
|
|
282
|
+
{ label: "Proceed", description: "Continue with /dgs:fast — dirty paths will NOT be included in this commit (only $FAST_EDITED_FILES will be staged)" },
|
|
283
|
+
{ label: "Stop", description: "Exit /dgs:fast — manually clean the working tree first" }
|
|
284
|
+
]
|
|
285
|
+
)
|
|
286
|
+
```
|
|
287
|
+
If "Stop": exit non-zero with label `pre-existing-dirt`. If "Proceed": continue to F1.5. Submodule warnings (per `decision.warnings`) are surfaced but do NOT block in either mode.
|
|
288
|
+
|
|
289
|
+
After F1.5-pre passes (clean state, OR user confirmed "Proceed"), continue to F1.5 cross-repo rejection guard.
|
|
290
|
+
|
|
291
|
+
**F1.5. Cross-repo rejection guard (product fast only)**
|
|
292
|
+
|
|
293
|
+
This guard is a pre-edit fail-fast check that prevents ambiguous multi-repo
|
|
294
|
+
fast invocations from reaching F2/F5. Since v23.2 / REL-05, F5 invokes
|
|
295
|
+
`dgs-tools fast-route` to pick the correct `--repo-cwd` post-edit, and F2
|
|
296
|
+
passes the tracked file list via the explicit `--files` argument so the
|
|
297
|
+
commit is scoped to the paths actually edited rather than a tree sweep.
|
|
298
|
+
That means a /dgs:fast edit confined to a single sibling repo (with
|
|
299
|
+
planning-root clean) is now safe and supported — F5 will route to that
|
|
300
|
+
repo via `--repo-cwd`. What's NOT safe is an edit that spans multiple
|
|
301
|
+
buckets: planning-root + a sibling, or two distinct siblings. Those would
|
|
302
|
+
fail at F5 with `multi-repo-dirt` anyway; F1.5 catches them earlier with
|
|
303
|
+
a clearer, edit-source-aware message before any disk writes happen.
|
|
304
|
+
|
|
305
|
+
**Activation condition:** this guard runs **only** when `$QUICK_CONTEXT == 'product'` AND `$FAST_MODE` is true. Skip it entirely (early return, no side effects) in any other combination:
|
|
306
|
+
- Milestone-context fast routes commits through `$QUICK_REPO_CWD` via `--repo-cwd`, which is already correct — guard not needed.
|
|
307
|
+
- Non-fast paths use worktrees and planner/executor discipline — guard not needed.
|
|
308
|
+
|
|
309
|
+
When the activation condition holds (`$QUICK_CONTEXT == 'product'` and `$FAST_MODE` is true), run the guard **before** any Read/Edit/Write in F2:
|
|
310
|
+
|
|
311
|
+
1. **Enumerate sibling repo roots** from both sources (deduplicate by absolute path):
|
|
312
|
+
|
|
313
|
+
a. `config.local.json` → `projects.${current_project}.worktrees.*.repos` is a map of `repoName -> absolute worktree path`. Every value in every worktree's `repos` map is a sibling repo root.
|
|
314
|
+
|
|
315
|
+
b. `REPOS.md` → the markdown table has a `Path` column (typically relative like `../repo-name`). For each entry, resolve the path relative to planning-root cwd to get the absolute sibling repo root.
|
|
316
|
+
|
|
317
|
+
2. **Determine the absolute path(s) you are about to edit.** Analyze `$DESCRIPTION` plus any codebase exploration needed to locate the target. For each intended edit, build the absolute path.
|
|
318
|
+
|
|
319
|
+
3. **Check each intended edit against the sibling roots.** Normalize paths (resolve symlinks, strip trailing slashes) and test whether the edit path starts with any sibling repo root. Edits whose absolute path lies under the planning-root cwd itself are always allowed — only flag paths that live under a *registered sibling* repo root.
|
|
320
|
+
|
|
321
|
+
4. **Partition intended edits into buckets.** For the set of intended-edit absolute paths from step 2:
|
|
322
|
+
- **planning-root bucket:** paths under the planning-root cwd that do NOT lie under any registered sibling root.
|
|
323
|
+
- **sibling-repo bucket(s):** paths whose absolute path starts with a sibling repo root (one bucket per matched sibling root, keyed by absolute root path).
|
|
324
|
+
|
|
325
|
+
Count the non-empty buckets:
|
|
326
|
+
|
|
327
|
+
- **0 non-empty buckets** (no edits inferred yet): proceed to F2; the guard re-checks via F5's post-edit `fast-route` if anything unexpected lands.
|
|
328
|
+
- **1 non-empty bucket** = planning-root only: ALLOWED. Continue to F2.
|
|
329
|
+
- **1 non-empty bucket** = exactly one sibling repo: ALLOWED. Continue to F2. F5's `fast-route` will route the commit through that sibling via `--repo-cwd`. Note in your edit plan which sibling you're targeting so RELATIVE_FILES computation in F5 uses the right STAGE_DIR.
|
|
330
|
+
- **2 or more non-empty buckets** (planning-root + sibling, OR sibling + sibling): BLOCKED. Fail fast with the error block below; do NOT proceed to F2.
|
|
331
|
+
|
|
332
|
+
```
|
|
333
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
334
|
+
║ AMBIGUOUS MULTI-REPO FAST ║
|
|
335
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
336
|
+
|
|
337
|
+
/dgs:quick --fast in product context supports edits confined to a single
|
|
338
|
+
bucket (planning-root only, OR exactly one sibling repo). The intended
|
|
339
|
+
edits span multiple buckets, which fast-mode cannot auto-route:
|
|
340
|
+
|
|
341
|
+
planning-root edits:
|
|
342
|
+
${planning_root_paths_or_"(none)"}
|
|
343
|
+
|
|
344
|
+
sibling-repo edits:
|
|
345
|
+
${for each non-empty sibling bucket: " - ${matched_sibling_root}: ${paths}"}
|
|
346
|
+
|
|
347
|
+
Options:
|
|
348
|
+
1. Split into separate /dgs:fast invocations, one per bucket. Run them
|
|
349
|
+
sequentially; each invocation auto-routes to the correct cwd.
|
|
350
|
+
2. If this multi-repo work is part of an active milestone, re-invoke
|
|
351
|
+
under milestone-context (the milestone worktree routes via
|
|
352
|
+
--repo-cwd against the registered repo).
|
|
353
|
+
3. Use /dgs:quick (full planner+executor) for genuinely cross-repo work
|
|
354
|
+
that must commit atomically across repos.
|
|
355
|
+
|
|
356
|
+
End workflow. Do not proceed to F2.
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
5. If exactly one bucket is non-empty (or none yet), continue to F2.
|
|
360
|
+
|
|
139
361
|
**F2. Make edits**
|
|
140
362
|
|
|
363
|
+
By the time F2 runs, the F1.5 cross-repo guard has already passed (in product-fast) or been skipped (in milestone-context fast / non-fast) — every path you touch below is guaranteed to land in the correct repo.
|
|
364
|
+
|
|
141
365
|
Read the relevant file(s) based on `$DESCRIPTION`, make the requested changes directly using Read/Edit/Write tools. No planner, no executor — the orchestrator acts as the implementer.
|
|
142
366
|
|
|
367
|
+
Track every file you edit in a shell array `$FAST_EDITED_FILES` (absolute paths as used with Read/Edit/Write). Initialize to empty before the first edit. Append each path exactly once (deduplicate before F5). This array is the authoritative file list for F5's commit — it replaces the default fallback behaviour of `cmdCommit` (which would otherwise stage `['.']` in `gitCwd` and sweep unrelated dirty state).
|
|
368
|
+
|
|
369
|
+
If `$QUICK_CONTEXT` is `'milestone-context'`, relevant files live under `$QUICK_REPO_CWD` (the milestone worktree). Prefix Read/Edit/Write absolute paths with that directory — the main-checkout paths will be on `base_branch` and miss in-progress milestone work.
|
|
370
|
+
|
|
143
371
|
If `$DRY_RUN`:
|
|
144
372
|
After making edits but BEFORE committing, show the diff:
|
|
145
373
|
```bash
|
|
146
|
-
git diff
|
|
374
|
+
git -C "${QUICK_REPO_CWD:-.}" diff
|
|
147
375
|
```
|
|
148
376
|
Then ask:
|
|
149
377
|
```
|
|
@@ -158,7 +386,7 @@ If `$DRY_RUN`:
|
|
|
158
386
|
```
|
|
159
387
|
If user chooses "No, discard":
|
|
160
388
|
```bash
|
|
161
|
-
git checkout -- .
|
|
389
|
+
git -C "${QUICK_REPO_CWD:-.}" checkout -- .
|
|
162
390
|
```
|
|
163
391
|
Display: "Changes discarded."
|
|
164
392
|
Skip to completion output with message: "Dry run complete — no changes applied."
|
|
@@ -166,9 +394,9 @@ If `$DRY_RUN`:
|
|
|
166
394
|
|
|
167
395
|
**F3. Post-edit scope check**
|
|
168
396
|
|
|
169
|
-
After edits are made, check actual scope:
|
|
397
|
+
After edits are made, check actual scope (run in the worktree when milestone-context):
|
|
170
398
|
```bash
|
|
171
|
-
git diff --stat
|
|
399
|
+
git -C "${QUICK_REPO_CWD:-.}" diff --stat
|
|
172
400
|
```
|
|
173
401
|
|
|
174
402
|
Parse the output to count:
|
|
@@ -205,15 +433,68 @@ Analyze the description and the actual changes (`git diff`) to infer a conventio
|
|
|
205
433
|
|
|
206
434
|
Commit message is NOT shown to user before committing — just commit silently.
|
|
207
435
|
|
|
208
|
-
**F5. Commit**
|
|
436
|
+
**F5. Commit (REL-05 routing-aware)**
|
|
437
|
+
|
|
438
|
+
When `$QUICK_REPO_CWD` is set (milestone-context), route git operations through the worktree via `--repo-cwd`. Config (commit_docs, sync_push, current_project, worktree map) is still loaded from the planning-root cwd.
|
|
439
|
+
|
|
440
|
+
For product-context fast (`$QUICK_CONTEXT == 'product'`, `$QUICK_REPO_CWD` empty), invoke the routing-decision helper to determine the correct `--repo-cwd`:
|
|
209
441
|
|
|
210
442
|
```bash
|
|
211
|
-
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs"
|
|
443
|
+
DIRT_JSON=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" fast-route 2>/dev/null)
|
|
444
|
+
ROUTE_ACTION=$(echo "$DIRT_JSON" | jq -r '.decision.action')
|
|
445
|
+
ROUTE_REPO=$(echo "$DIRT_JSON" | jq -r '.decision.repoCwd // empty')
|
|
446
|
+
ROUTE_EXIT=$(echo "$DIRT_JSON" | jq -r '.decision.exitCode // empty')
|
|
447
|
+
ROUTE_MSG=$(echo "$DIRT_JSON" | jq -r '.decision.message // empty')
|
|
212
448
|
```
|
|
213
449
|
|
|
214
|
-
|
|
450
|
+
Cases:
|
|
451
|
+
|
|
452
|
+
- `$ROUTE_ACTION == 'fail'` AND `$ROUTE_EXIT == 'multi-repo-dirt'`:
|
|
453
|
+
```
|
|
454
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
455
|
+
║ MULTI-REPO DIRT DETECTED ║
|
|
456
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
457
|
+
|
|
458
|
+
$ROUTE_MSG
|
|
459
|
+
|
|
460
|
+
exit-code label: multi-repo-dirt
|
|
461
|
+
```
|
|
462
|
+
End workflow with non-zero exit; do NOT commit.
|
|
463
|
+
|
|
464
|
+
- `$ROUTE_ACTION == 'route-to-sub-repo'`: commit with `--repo-cwd $ROUTE_REPO`.
|
|
465
|
+
- `$ROUTE_ACTION == 'route-to-planning-root'`: commit in planning-root cwd (existing behaviour).
|
|
466
|
+
|
|
467
|
+
Pass the tracked file list via `--files` so `cmdCommit` does not fall back to its `['.']` default (which would stage the entire `gitCwd` tree and sweep in unrelated dirty state — see the 260422-q7f incident). Surface any submodule warnings from `decision.warnings` to the user (display, do NOT block).
|
|
468
|
+
|
|
215
469
|
```bash
|
|
216
|
-
|
|
470
|
+
# Convert $FAST_EDITED_FILES (absolute paths) to paths relative to the
|
|
471
|
+
# routed staging directory. Paths outside the staging directory should not appear
|
|
472
|
+
# — the F1.5 cross-repo guard rejects them before F2.
|
|
473
|
+
if [ -n "$QUICK_REPO_CWD" ]; then
|
|
474
|
+
STAGE_DIR="$QUICK_REPO_CWD"
|
|
475
|
+
elif [ "$ROUTE_ACTION" = "route-to-sub-repo" ]; then
|
|
476
|
+
STAGE_DIR="$ROUTE_REPO"
|
|
477
|
+
else
|
|
478
|
+
STAGE_DIR="$(pwd)"
|
|
479
|
+
fi
|
|
480
|
+
RELATIVE_FILES=()
|
|
481
|
+
for f in "${FAST_EDITED_FILES[@]}"; do
|
|
482
|
+
# Strip STAGE_DIR prefix + leading slash to get the repo-relative path
|
|
483
|
+
RELATIVE_FILES+=( "${f#${STAGE_DIR}/}" )
|
|
484
|
+
done
|
|
485
|
+
|
|
486
|
+
if [ -n "$QUICK_REPO_CWD" ]; then
|
|
487
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "${commit_message}" --push --repo-cwd "$QUICK_REPO_CWD" --files "${RELATIVE_FILES[@]}"
|
|
488
|
+
elif [ "$ROUTE_ACTION" = "route-to-sub-repo" ]; then
|
|
489
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "${commit_message}" --push --repo-cwd "$ROUTE_REPO" --files "${RELATIVE_FILES[@]}"
|
|
490
|
+
else
|
|
491
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "${commit_message}" --push --files "${RELATIVE_FILES[@]}"
|
|
492
|
+
fi
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Get the short hash (from the routed staging directory):
|
|
496
|
+
```bash
|
|
497
|
+
git -C "${STAGE_DIR}" rev-parse --short HEAD
|
|
217
498
|
```
|
|
218
499
|
|
|
219
500
|
Store as `$COMMIT_HASH`.
|
|
@@ -260,17 +541,26 @@ If archival occurred (result contains `"archived": true`), `quick/HISTORY.md` wa
|
|
|
260
541
|
|
|
261
542
|
**F6c. Commit tracking (fast path only)**
|
|
262
543
|
|
|
263
|
-
Commit STATE.md and HISTORY.md together so archival data is persisted:
|
|
544
|
+
Commit STATE.md and HISTORY.md together so archival data is persisted. Uses `dgs-tools quick finalize --fast` — a single CLI call that stages both files (HISTORY.md optional) and commits with message `docs(quick-${quick_id}): track fast task`.
|
|
264
545
|
|
|
265
546
|
```bash
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
547
|
+
if [ -n "$QUICK_REPO_CWD" ]; then
|
|
548
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick finalize ${quick_id} \
|
|
549
|
+
--quick-dir "${quick_dir}" \
|
|
550
|
+
--state-path "${state_path}" \
|
|
551
|
+
--fast \
|
|
552
|
+
--push \
|
|
553
|
+
--repo-cwd "$QUICK_REPO_CWD" 2>/dev/null || true
|
|
554
|
+
else
|
|
555
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick finalize ${quick_id} \
|
|
556
|
+
--quick-dir "${quick_dir}" \
|
|
557
|
+
--state-path "${state_path}" \
|
|
558
|
+
--fast \
|
|
559
|
+
--push 2>/dev/null || true
|
|
269
560
|
fi
|
|
270
|
-
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "docs(quick-${quick_id}): track fast task" --push --files ${FILE_LIST} 2>/dev/null || true
|
|
271
561
|
```
|
|
272
562
|
|
|
273
|
-
The `|| true` handles the case where nothing changed (e.g., STATE.md wasn't modified).
|
|
563
|
+
The `|| true` handles the case where nothing changed (e.g., STATE.md wasn't modified) — `quick finalize` returns `commit_reason: 'nothing_to_commit'` cleanly in that scenario.
|
|
274
564
|
|
|
275
565
|
**F7. Output**
|
|
276
566
|
|
|
@@ -301,10 +591,10 @@ mkdir -p "${task_dir}"
|
|
|
301
591
|
|
|
302
592
|
**Step 4: Create quick task directory**
|
|
303
593
|
|
|
304
|
-
|
|
594
|
+
Use `task_dir` from init output — do NOT build the path manually:
|
|
305
595
|
|
|
306
596
|
```bash
|
|
307
|
-
QUICK_DIR="${
|
|
597
|
+
QUICK_DIR="${task_dir}"
|
|
308
598
|
mkdir -p "$QUICK_DIR"
|
|
309
599
|
```
|
|
310
600
|
|
|
@@ -616,6 +906,12 @@ Task(
|
|
|
616
906
|
prompt="
|
|
617
907
|
Execute quick task ${quick_id}.
|
|
618
908
|
|
|
909
|
+
${QUICK_CONTEXT === 'product' && QUICK_REPOS && Object.keys(QUICK_REPOS).length > 0 ? `
|
|
910
|
+
<worktree_context>
|
|
911
|
+
This quick task is executing in a git worktree. Work in these directories — do NOT use the main checkout paths:
|
|
912
|
+
${Object.entries(QUICK_REPOS).map(([name, dir]) => '- ' + name + ': ' + dir).join('\n')}
|
|
913
|
+
</worktree_context>
|
|
914
|
+
` : ''}
|
|
619
915
|
<files_to_read>
|
|
620
916
|
- ${QUICK_DIR}/${quick_id}-PLAN.md (Plan)
|
|
621
917
|
- ${state_path} (Project state)
|
|
@@ -751,6 +1047,10 @@ node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" state archive-quick
|
|
|
751
1047
|
|
|
752
1048
|
If archival occurred, `quick/HISTORY.md` was created or updated. Include it in Step 8's commit file list.
|
|
753
1049
|
|
|
1050
|
+
**7c3. Milestone-context quick tracking**
|
|
1051
|
+
|
|
1052
|
+
If `$QUICK_CONTEXT` is 'milestone-context', note this in the Directory column of the table row. Instead of a directory link, use: `milestone (${MILESTONE_SLUG})`.
|
|
1053
|
+
|
|
754
1054
|
**7d. Update "Last activity" line:**
|
|
755
1055
|
|
|
756
1056
|
Use `date` from init:
|
|
@@ -764,20 +1064,18 @@ Use Edit tool to make these changes atomically
|
|
|
764
1064
|
|
|
765
1065
|
**Step 8: Final commit and completion**
|
|
766
1066
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
Build file list:
|
|
770
|
-
- `${QUICK_DIR}/${quick_id}-PLAN.md`
|
|
771
|
-
- `${QUICK_DIR}/${quick_id}-SUMMARY.md`
|
|
772
|
-
- `${state_path}`
|
|
773
|
-
- `${project_root}/quick/HISTORY.md` (if it exists — may have been created by archival)
|
|
774
|
-
- If `$DISCUSS_MODE` and context file exists: `${QUICK_DIR}/${quick_id}-CONTEXT.md`
|
|
775
|
-
- If `$FULL_MODE` and verification file exists: `${QUICK_DIR}/${quick_id}-VERIFICATION.md`
|
|
1067
|
+
Commit all quick task artifacts atomically via `dgs-tools quick finalize`. This single CLI call stages and commits PLAN, SUMMARY, STATE, and any optional artifacts present on disk (CONTEXT, VERIFICATION, HISTORY) in one commit — no file-list assembly needed.
|
|
776
1068
|
|
|
777
1069
|
```bash
|
|
778
|
-
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs"
|
|
1070
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick finalize ${quick_id} \
|
|
1071
|
+
--quick-dir "${quick_dir}" \
|
|
1072
|
+
--state-path "${state_path}" \
|
|
1073
|
+
--description "${DESCRIPTION}" \
|
|
1074
|
+
--push
|
|
779
1075
|
```
|
|
780
1076
|
|
|
1077
|
+
Missing optional artifacts are skipped gracefully (no error if CONTEXT.md, VERIFICATION.md, or HISTORY.md do not exist).
|
|
1078
|
+
|
|
781
1079
|
Get final commit hash:
|
|
782
1080
|
```bash
|
|
783
1081
|
commit_hash=$(git rev-parse --short HEAD)
|
|
@@ -841,4 +1139,8 @@ Ready for next task: /dgs:quick
|
|
|
841
1139
|
- [ ] (--fast) Scope warning shown when >3 files or >30 lines affected
|
|
842
1140
|
- [ ] (--fast) (--dry-run) Changes shown as diff, user asked to apply or discard
|
|
843
1141
|
- [ ] (--fast) Minimal output: "Done: {message} [{hash}]"
|
|
1142
|
+
- [ ] (--fast) F5 commit passes `--files` with the exact list of paths edited during F2 (no fallback to `cmdCommit`'s `['.']` default)
|
|
1143
|
+
- [ ] (--fast) Product-context fast rejects edits targeting sibling repos registered in `config.local.json` worktrees or `REPOS.md`, with an actionable error before F2 begins
|
|
1144
|
+
- [ ] (--fast) F1.5-pre pre-edit dirt check runs BEFORE F1.5; pre-existing dirt fails with `pre-existing-dirt` exit-code label in non-interactive mode (REL-06)
|
|
1145
|
+
- [ ] (--fast) F5 commit routes via fast-route decision: single-sub-repo dirty → `--repo-cwd <sub>`; multi-dirty → fails with `multi-repo-dirt` exit-code label; submodule warnings surface but don't block (REL-05)
|
|
844
1146
|
</success_criteria>
|
|
@@ -125,7 +125,7 @@ Context is used to inform the conversation -- for example, when discussing imple
|
|
|
125
125
|
|
|
126
126
|
3. Load source idea docs:
|
|
127
127
|
Read the spec's frontmatter to find `source_ideas` (array of idea filenames). For each source idea:
|
|
128
|
-
a. Derive the idea docs path
|
|
128
|
+
a. Derive the idea docs path: strip prefix/suffix for slug, check `${project_root}/docs/ideas/{slug}/`
|
|
129
129
|
b. If docs/ directory exists, read all files using the same pattern above
|
|
130
130
|
c. Idea docs are loaded first (source material), then spec docs (refinements). If too many, cap spec docs.
|
|
131
131
|
|