@ktpartners/dgs-platform 3.0.4 → 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.
Files changed (115) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +8 -1
  3. package/agents/dgs-executor.md +124 -3
  4. package/agents/dgs-idea-researcher.md +447 -0
  5. package/agents/dgs-plan-checker.md +32 -0
  6. package/agents/dgs-planner.md +41 -8
  7. package/bin/install.js +44 -0
  8. package/commands/dgs/audit-milestone.md +2 -1
  9. package/commands/dgs/diff-report.md +124 -0
  10. package/commands/dgs/new-project.md +8 -21
  11. package/commands/dgs/package-scan.md +43 -0
  12. package/commands/dgs/research-idea.md +1 -0
  13. package/commands/dgs/switch-project.md +13 -0
  14. package/deliver-great-systems/bin/dgs-tools.cjs +120 -5
  15. package/deliver-great-systems/bin/lib/audit-tolerance.cjs +77 -0
  16. package/deliver-great-systems/bin/lib/audit-tolerance.test.cjs +101 -0
  17. package/deliver-great-systems/bin/lib/commands.cjs +311 -16
  18. package/deliver-great-systems/bin/lib/commands.test.cjs +115 -0
  19. package/deliver-great-systems/bin/lib/commit-verify.test.cjs +236 -0
  20. package/deliver-great-systems/bin/lib/config.cjs +41 -0
  21. package/deliver-great-systems/bin/lib/config.test.cjs +309 -0
  22. package/deliver-great-systems/bin/lib/core.cjs +7 -3
  23. package/deliver-great-systems/bin/lib/core.test.cjs +79 -1
  24. package/deliver-great-systems/bin/lib/fast-routing.cjs +199 -0
  25. package/deliver-great-systems/bin/lib/fast-routing.test.cjs +108 -0
  26. package/deliver-great-systems/bin/lib/final-commit-precondition.test.cjs +87 -0
  27. package/deliver-great-systems/bin/lib/fixtures/package-scan/bundler-audit-gemfile.json +21 -0
  28. package/deliver-great-systems/bin/lib/fixtures/package-scan/gate-parity-expected.md +186 -0
  29. package/deliver-great-systems/bin/lib/fixtures/package-scan/gate-parity-runresult.json +235 -0
  30. package/deliver-great-systems/bin/lib/fixtures/package-scan/govulncheck-import.json +3 -0
  31. package/deliver-great-systems/bin/lib/fixtures/package-scan/npm-audit-v10.json +37 -0
  32. package/deliver-great-systems/bin/lib/fixtures/package-scan/osv-clean.json +3 -0
  33. package/deliver-great-systems/bin/lib/fixtures/package-scan/osv-vulns.json +77 -0
  34. package/deliver-great-systems/bin/lib/fixtures/package-scan/pip-audit-requirements.json +28 -0
  35. package/deliver-great-systems/bin/lib/fixtures/package-scan/snyk-lodash.json +30 -0
  36. package/deliver-great-systems/bin/lib/fixtures/package-scan/snyk-workspaces.json +55 -0
  37. package/deliver-great-systems/bin/lib/frontmatter.cjs +1 -1
  38. package/deliver-great-systems/bin/lib/governance.cjs +211 -0
  39. package/deliver-great-systems/bin/lib/governance.test.cjs +339 -0
  40. package/deliver-great-systems/bin/lib/health-untracked-phase.test.cjs +269 -0
  41. package/deliver-great-systems/bin/lib/init.cjs +56 -27
  42. package/deliver-great-systems/bin/lib/init.test.cjs +212 -5
  43. package/deliver-great-systems/bin/lib/jobs.cjs +7 -4
  44. package/deliver-great-systems/bin/lib/milestone.cjs +101 -3
  45. package/deliver-great-systems/bin/lib/milestone.test.cjs +203 -0
  46. package/deliver-great-systems/bin/lib/package-adapters.cjs +530 -0
  47. package/deliver-great-systems/bin/lib/package-adapters.test.cjs +618 -0
  48. package/deliver-great-systems/bin/lib/package-ecosystems.cjs +350 -0
  49. package/deliver-great-systems/bin/lib/package-ecosystems.test.cjs +348 -0
  50. package/deliver-great-systems/bin/lib/package-runner.cjs +199 -0
  51. package/deliver-great-systems/bin/lib/package-runner.test.cjs +198 -0
  52. package/deliver-great-systems/bin/lib/package-scan-provenance.cjs +56 -0
  53. package/deliver-great-systems/bin/lib/package-scan-provenance.test.cjs +103 -0
  54. package/deliver-great-systems/bin/lib/package-scan-report.cjs +1140 -0
  55. package/deliver-great-systems/bin/lib/package-scan-report.test.cjs +1963 -0
  56. package/deliver-great-systems/bin/lib/package-scan-skill.cjs +96 -0
  57. package/deliver-great-systems/bin/lib/package-scan-skill.test.cjs +136 -0
  58. package/deliver-great-systems/bin/lib/package-scan.cjs +919 -0
  59. package/deliver-great-systems/bin/lib/package-scan.test.cjs +2147 -0
  60. package/deliver-great-systems/bin/lib/phase.cjs +18 -1
  61. package/deliver-great-systems/bin/lib/plan-number-validity.test.cjs +48 -0
  62. package/deliver-great-systems/bin/lib/projects.cjs +38 -3
  63. package/deliver-great-systems/bin/lib/projects.test.cjs +112 -2
  64. package/deliver-great-systems/bin/lib/quick.cjs +178 -23
  65. package/deliver-great-systems/bin/lib/quick.test.cjs +138 -4
  66. package/deliver-great-systems/bin/lib/repos.cjs +12 -12
  67. package/deliver-great-systems/bin/lib/review.cjs +1821 -0
  68. package/deliver-great-systems/bin/lib/state.cjs +7 -3
  69. package/deliver-great-systems/bin/lib/summary-frontmatter.cjs +54 -0
  70. package/deliver-great-systems/bin/lib/summary-frontmatter.test.cjs +78 -0
  71. package/deliver-great-systems/bin/lib/sweep-scope.test.cjs +263 -0
  72. package/deliver-great-systems/bin/lib/verify.cjs +118 -6
  73. package/deliver-great-systems/bin/lib/verify.test.cjs +82 -0
  74. package/deliver-great-systems/bin/lib/wave-0-template-rename.test.cjs +40 -0
  75. package/deliver-great-systems/bin/lib/worktrees.cjs +27 -1
  76. package/deliver-great-systems/bin/lib/worktrees.test.cjs +76 -0
  77. package/deliver-great-systems/references/agent-step-reliability.md +60 -0
  78. package/deliver-great-systems/references/conflict-resolution.md +4 -0
  79. package/deliver-great-systems/references/context-tiers.md +4 -0
  80. package/deliver-great-systems/references/package-scan-config.md +151 -0
  81. package/deliver-great-systems/references/questioning.md +0 -30
  82. package/deliver-great-systems/references/spec-review-loop.md +1 -2
  83. package/deliver-great-systems/references/workflow-conventions.md +29 -0
  84. package/deliver-great-systems/skills/dgs-tests/package-scan.md +44 -0
  85. package/deliver-great-systems/templates/REVIEW.md +35 -0
  86. package/deliver-great-systems/templates/VALIDATION.md +1 -1
  87. package/deliver-great-systems/templates/claude-md.md +11 -0
  88. package/deliver-great-systems/templates/package-scan-report.md +108 -0
  89. package/deliver-great-systems/templates/project.md +6 -170
  90. package/deliver-great-systems/templates/summary.md +3 -1
  91. package/deliver-great-systems/workflows/add-phase.md +5 -0
  92. package/deliver-great-systems/workflows/audit-milestone.md +66 -10
  93. package/deliver-great-systems/workflows/cancel-job.md +1 -1
  94. package/deliver-great-systems/workflows/codereview.md +103 -9
  95. package/deliver-great-systems/workflows/complete-milestone.md +26 -7
  96. package/deliver-great-systems/workflows/complete-quick.md +40 -2
  97. package/deliver-great-systems/workflows/discuss-phase.md +3 -2
  98. package/deliver-great-systems/workflows/execute-phase.md +89 -2
  99. package/deliver-great-systems/workflows/execute-plan.md +10 -1
  100. package/deliver-great-systems/workflows/help.md +51 -18
  101. package/deliver-great-systems/workflows/import-spec.md +65 -7
  102. package/deliver-great-systems/workflows/init-product.md +46 -152
  103. package/deliver-great-systems/workflows/new-milestone.md +115 -14
  104. package/deliver-great-systems/workflows/new-project.md +60 -331
  105. package/deliver-great-systems/workflows/package-scan.md +59 -0
  106. package/deliver-great-systems/workflows/plan-phase.md +79 -1
  107. package/deliver-great-systems/workflows/quick-complete.md +40 -2
  108. package/deliver-great-systems/workflows/quick.md +183 -10
  109. package/deliver-great-systems/workflows/research-idea.md +80 -142
  110. package/deliver-great-systems/workflows/run-job.md +21 -35
  111. package/deliver-great-systems/workflows/settings.md +13 -77
  112. package/deliver-great-systems/workflows/write-spec.md +9 -11
  113. package/hooks/dist/dgs-enforce-discipline.js +196 -0
  114. package/package.json +1 -1
  115. package/scripts/build-hooks.js +1 -0
@@ -8,7 +8,44 @@ This workflow is only valid for product-level quicks. If the user is working in
8
8
 
9
9
  <process>
10
10
 
11
- **Step 1: Validate and execute quick-complete**
11
+ **Step 1: Generate inline review summary**
12
+
13
+ Before rebase-and-merge, generate a review report while the quick branch still exists with original commits.
14
+
15
+ ```bash
16
+ REVIEW_RESULT=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick generate-review --raw 2>&1)
17
+ REVIEW_EXIT=$?
18
+ ```
19
+
20
+ **If generation succeeds** (`REVIEW_EXIT` is 0):
21
+
22
+ Parse JSON output for the summary:
23
+ ```bash
24
+ REVIEW_PATH=$(echo "$REVIEW_RESULT" | jq -r '.relativePath // empty')
25
+ REVIEW_COMMITS=$(echo "$REVIEW_RESULT" | jq -r '.stats.commits // 0')
26
+ REVIEW_FILES=$(echo "$REVIEW_RESULT" | jq -r '.stats.filesChanged // 0')
27
+ REVIEW_RISKS=$(echo "$REVIEW_RESULT" | jq -r '.stats.riskFlags // 0')
28
+ ```
29
+
30
+ Display the stats banner:
31
+ ```
32
+ Review: ${REVIEW_PATH} (${REVIEW_COMMITS} commits, ${REVIEW_FILES} files${REVIEW_RISKS > 0 ? ", ${REVIEW_RISKS} risk flags" : ""})
33
+ ```
34
+
35
+ **If fast-forward detected** (output contains `"fastForward": true`):
36
+
37
+ Display: `No code changes detected -- review not generated.`
38
+
39
+ **If generation fails** (`REVIEW_EXIT` is non-zero):
40
+
41
+ Log warning and continue -- do NOT block task completion:
42
+ ```
43
+ Warning: Review generation failed. Continuing with completion.
44
+ ```
45
+
46
+ Review generation failure is non-fatal. The quick task will still complete normally.
47
+
48
+ **Step 2: Validate and execute quick-complete**
12
49
 
13
50
  Call the quick-complete CLI command which validates the active quick and executes the full flow:
14
51
 
@@ -43,7 +80,7 @@ After resolving conflicts manually, re-run:
43
80
  ```
44
81
  End workflow.
45
82
 
46
- **Step 2: Display success**
83
+ **Step 3: Display success**
47
84
 
48
85
  Parse JSON result from RESULT.
49
86
 
@@ -59,6 +96,7 @@ Worktree cleaned up. Pushed to origin.
59
96
  </process>
60
97
 
61
98
  <success_criteria>
99
+ - [ ] Review summary generated before rebase-and-merge (or warning logged on failure)
62
100
  - [ ] Active product-level quick validated
63
101
  - [ ] Rebase-before-merge flow executed via rebaseAndMerge()
64
102
  - [ ] Worktree and branch cleaned up
@@ -240,10 +240,132 @@ Switching to /dgs:quick...
240
240
  ```
241
241
  Then continue from Step 3 as normal quick mode (skip the rest of the fast path).
242
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
+
243
361
  **F2. Make edits**
244
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
+
245
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.
246
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
+
247
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.
248
370
 
249
371
  If `$DRY_RUN`:
@@ -311,21 +433,68 @@ Analyze the description and the actual changes (`git diff`) to infer a conventio
311
433
 
312
434
  Commit message is NOT shown to user before committing — just commit silently.
313
435
 
314
- **F5. Commit**
436
+ **F5. Commit (REL-05 routing-aware)**
315
437
 
316
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.
317
439
 
440
+ For product-context fast (`$QUICK_CONTEXT == 'product'`, `$QUICK_REPO_CWD` empty), invoke the routing-decision helper to determine the correct `--repo-cwd`:
441
+
318
442
  ```bash
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')
448
+ ```
449
+
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
+
469
+ ```bash
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
+
319
486
  if [ -n "$QUICK_REPO_CWD" ]; then
320
- node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "${commit_message}" --push --repo-cwd "$QUICK_REPO_CWD"
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[@]}"
321
490
  else
322
- node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "${commit_message}" --push
491
+ node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "${commit_message}" --push --files "${RELATIVE_FILES[@]}"
323
492
  fi
324
493
  ```
325
494
 
326
- Get the short hash (from the same directory the commit landed in):
495
+ Get the short hash (from the routed staging directory):
327
496
  ```bash
328
- git -C "${QUICK_REPO_CWD:-.}" rev-parse --short HEAD
497
+ git -C "${STAGE_DIR}" rev-parse --short HEAD
329
498
  ```
330
499
 
331
500
  Store as `$COMMIT_HASH`.
@@ -377,14 +546,14 @@ Commit STATE.md and HISTORY.md together so archival data is persisted. Uses `dgs
377
546
  ```bash
378
547
  if [ -n "$QUICK_REPO_CWD" ]; then
379
548
  node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick finalize ${quick_id} \
380
- --quick-dir "${project_root}/quick" \
549
+ --quick-dir "${quick_dir}" \
381
550
  --state-path "${state_path}" \
382
551
  --fast \
383
552
  --push \
384
553
  --repo-cwd "$QUICK_REPO_CWD" 2>/dev/null || true
385
554
  else
386
555
  node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick finalize ${quick_id} \
387
- --quick-dir "${project_root}/quick" \
556
+ --quick-dir "${quick_dir}" \
388
557
  --state-path "${state_path}" \
389
558
  --fast \
390
559
  --push 2>/dev/null || true
@@ -422,10 +591,10 @@ mkdir -p "${task_dir}"
422
591
 
423
592
  **Step 4: Create quick task directory**
424
593
 
425
- Create the directory for this quick task:
594
+ Use `task_dir` from init output do NOT build the path manually:
426
595
 
427
596
  ```bash
428
- QUICK_DIR="${project_root}/quick/${quick_id}-${slug}"
597
+ QUICK_DIR="${task_dir}"
429
598
  mkdir -p "$QUICK_DIR"
430
599
  ```
431
600
 
@@ -899,7 +1068,7 @@ Commit all quick task artifacts atomically via `dgs-tools quick finalize`. This
899
1068
 
900
1069
  ```bash
901
1070
  node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick finalize ${quick_id} \
902
- --quick-dir "${project_root}/quick" \
1071
+ --quick-dir "${quick_dir}" \
903
1072
  --state-path "${state_path}" \
904
1073
  --description "${DESCRIPTION}" \
905
1074
  --push
@@ -970,4 +1139,8 @@ Ready for next task: /dgs:quick
970
1139
  - [ ] (--fast) Scope warning shown when >3 files or >30 lines affected
971
1140
  - [ ] (--fast) (--dry-run) Changes shown as diff, user asked to apply or discard
972
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)
973
1146
  </success_criteria>
@@ -1,9 +1,9 @@
1
1
  <purpose>
2
- Subagent-driven research workflow that investigates an idea's feasibility and technical landscape across five adaptive dimensions. Claude acts as an analyst -- purposeful and efficient, adapting depth to what the idea actually needs rather than running a checklist.
2
+ Subagent-driven research workflow that investigates an idea's feasibility and technical landscape. The orchestrator parses arguments, loads idea context (body, discussion log, prior research, supporting docs, REPOS.md), spawns a dedicated `dgs-idea-researcher` subagent for the five adaptive research dimensions, then handles the Research Log entry, git commit, and next-step suggestion. The orchestrator keeps its own context clean dimension prose and retrieved web/codebase content stay inside the subagent.
3
3
 
4
- Produces a structured research document at `${project_root}/docs/ideas/{slug}-research.md` and appends a Research Log entry to the idea file. Commits both files together and suggests the next step based on findings.
4
+ Produces a structured research document at `${project_root}/docs/ideas/pending/{slug}-research.md` and appends a Research Log entry to the idea file. Commits both files together and suggests the next step based on findings.
5
5
 
6
- When re-researching a previously-researched idea, the document is overwritten with a "Changes from Prior Research" section highlighting what shifted. Each re-research appends a fresh Research Log entry.
6
+ When re-researching a previously-researched idea, the subagent overwrites the document and emits a "Changes from Prior Research" section only when meaningful differences exist. Each re-research appends a fresh Research Log entry.
7
7
  </purpose>
8
8
 
9
9
  <context_tier>planning</context_tier>
@@ -84,9 +84,9 @@ Also check for prior research document:
84
84
  ```bash
85
85
  # Derive slug from filename (strip id prefix and .md suffix)
86
86
  SLUG=$(echo "${filename}" | sed 's/^[0-9]*-//' | sed 's/\.md$//')
87
- RESEARCH_DOC="${project_root}/docs/ideas/${SLUG}-research.md"
87
+ RESEARCH_DOC="${project_root}/docs/ideas/pending/${SLUG}-research.md"
88
88
  ```
89
- If the research document file exists, read it for prior research context.
89
+ If the research document file exists, note its path so the subagent can read it for re-research diffing.
90
90
 
91
91
  **Load idea supporting documents:**
92
92
 
@@ -126,161 +126,99 @@ cat ${project_root}/REPOS.md 2>/dev/null
126
126
  If REPOS.md exists and has entries, this is a multi-repo project -- research should be partitioned by repo where relevant.
127
127
  </step>
128
128
 
129
- <step name="research_context">
130
- Assess the idea and decide research strategy:
129
+ <step name="spawn_researcher">
130
+ Resolve the model for the idea-researcher subagent. The `resolve-model` CLI subcommand on `dgs-tools.cjs` emits JSON (`{"model": "...", "profile": "..."}`) — pipe through `jq -r .model` to extract the bare model string:
131
131
 
132
- 1. **Announce focus**: Print one line explaining which dimensions matter most for this idea and why. E.g.: "Focusing on landscape survey and codebase analysis -- this idea involves integrating with existing patterns."
133
-
134
- 2. **Read Discussion Log** if present -- use discussion insights (refined problem, approach, open questions) to guide research focus areas.
135
-
136
- 3. **Read prior research** if present -- note what was found before. On re-research, Claude will overwrite the document but should note what changed.
137
-
138
- 4. **Read supporting documents** if `ideaDocs` is not empty -- review loaded text files, diagrams, and other supporting materials. These may reveal additional context about the idea's scope, architecture requirements, or prior art that inform the research focus areas.
139
-
140
- 5. **Determine repo scope**: If REPOS.md exists, identify which repos are relevant to this idea. If no REPOS.md, treat as single-repo research.
141
- </step>
142
-
143
- <step name="web_search">
144
- **Dimension 1: Web Search**
145
-
146
- Announce: "Searching web for prior art and technical landscape..."
147
-
148
- Use WebSearch and WebFetch to investigate:
149
- - How others have solved similar problems
150
- - Existing libraries, tools, or frameworks relevant to the idea
151
- - Common patterns and anti-patterns
152
- - Recent discussions or blog posts
153
-
154
- Adapt depth to what the idea needs -- a well-understood problem gets a quick scan, a novel idea gets broader exploration. If web search yields little, note the gap and move on.
155
-
156
- Web search is best-effort -- search what's findable, note gaps, move on. Don't burn time on thin topics.
157
- </step>
158
-
159
- <step name="codebase_analysis">
160
- **Dimension 2: Codebase Analysis**
161
-
162
- Announce: "Analyzing codebase for related implementations..."
163
-
164
- Use Grep and Glob to examine:
165
- - Existing code that relates to the idea's domain
166
- - Patterns already established that would apply
167
- - Potential conflicts or integration points
168
- - Code that would need to change
169
-
170
- For multi-repo projects: analyze each relevant repo separately, noting repo-specific patterns and concerns.
171
- </step>
172
-
173
- <step name="landscape_survey">
174
- **Dimension 3: Landscape Survey**
175
-
176
- Announce: "Surveying technical landscape..."
177
-
178
- Build comparison information for relevant tools/libraries/approaches:
179
- - For obvious choices (one clear winner): brief verdict with reasoning
180
- - For genuine tradeoffs: table with pros, cons, license, maintenance status, compatibility
181
- - Per repo stack for multi-repo projects
182
-
183
- Recommend when clear -- strong recommendation when one option is clearly better, present options neutrally when it's genuinely a toss-up.
184
- </step>
185
-
186
- <step name="approaches">
187
- **Dimension 4: Approaches & Patterns**
188
-
189
- Announce: "Identifying approaches and patterns..."
190
-
191
- Identify how similar problems have been solved:
192
- - Architectural patterns that apply
193
- - Implementation strategies
194
- - Sequencing (what to build first)
195
- - What to avoid and why
196
- </step>
197
-
198
- <step name="feasibility">
199
- **Dimension 5: Feasibility Assessment**
200
-
201
- Announce: "Assessing feasibility..."
202
-
203
- Assess:
204
- - **Stack fit**: How well does this fit the existing technology stack?
205
- - **Effort estimate**: T-shirt size (S/M/L/XL) + approximate phase count
206
- - **Key risks**: What could go wrong? What are the unknowns?
207
- - **New dependencies**: Any new libraries, services, or external integrations needed?
208
- - **Recommendation**: Overall go/no-go/conditional assessment
209
- </step>
210
-
211
- <step name="write_document">
212
- Create (or overwrite) the research document.
213
-
214
- Ensure directory exists:
215
132
  ```bash
216
- mkdir -p ${project_root}/docs/ideas
133
+ IDEA_RESEARCHER_MODEL=$(node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs resolve-model dgs-idea-researcher | jq -r .model)
217
134
  ```
218
135
 
219
- Write the research document to `${project_root}/docs/ideas/${SLUG}-research.md` using the Write tool.
220
-
221
- **Document structure:**
222
- ```markdown
223
- ---
224
- type: research
225
- idea_id: {id}
226
- idea_title: "{title}"
227
- date: "{YYYY-MM-DD}"
228
- repos_analysed: ["{repo1}", "{repo2}"]
229
- ---
230
-
231
- # Research: {title}
232
-
233
- {If re-research and meaningful changes exist:}
234
- ## Changes from Prior Research
235
-
236
- {Bullet list of what's new, updated, or contradicted vs prior findings. Include when there are meaningful differences from prior research, skip when findings are similar.}
136
+ The MODEL_PROFILES entry resolves to `inherit` (quality profile), `sonnet` (balanced), or `haiku` (budget) based on the project's `model_profile` config. (Note: wiring `idea_researcher_model` directly into init.cjs — so the orchestrator could read it from init JSON, mirroring `researcher_model` in plan-phase — is a follow-up. The CLI invocation above is the canonical resolution path here.)
237
137
 
238
- ## Web Search Findings
138
+ Build the research prompt with all loaded context. Inline the idea content; pass paths for files the subagent should Read itself:
239
139
 
240
- {Findings from Dimension 1}
241
-
242
- ## Codebase Analysis
243
-
244
- {Findings from Dimension 2. For multi-repo: subsections per repo.}
245
-
246
- ## Landscape Survey
247
-
248
- {Findings from Dimension 3. Comparison tables where applicable.}
249
-
250
- ## Approaches & Patterns
251
-
252
- {Findings from Dimension 4}
253
-
254
- ## Feasibility Assessment
140
+ ```markdown
141
+ <objective>
142
+ Research idea #${id}: ${title}
143
+ Answer: "Is this idea feasible? What's the technical landscape and recommended approach?"
144
+ </objective>
145
+
146
+ <files_to_read>
147
+ {If prior research exists:} ${RESEARCH_DOC}
148
+ {If discussion log file exists separately, pass its path; otherwise the discussion log is inlined in <idea_content> below.}
149
+ {For each ideaDoc loaded: pass its path}
150
+ {If REPOS.md exists:} ${project_root}/REPOS.md
151
+ </files_to_read>
152
+
153
+ <idea_content>
154
+ **Title:** ${title}
155
+ **Tags:** ${tags}
156
+ **Body:**
157
+ ${body}
158
+
159
+ {If notes:} **Notes:** ${notes}
160
+
161
+ {If discussionLog:} **Discussion Log:**
162
+ ${discussionLog}
163
+ </idea_content>
164
+
165
+ <prior_research>
166
+ {If prior research doc exists:}
167
+ Prior research at `${RESEARCH_DOC}` — read it before researching, then include a `## Changes from Prior Research` section in the new doc ONLY when meaningful differences exist. Omit the section when findings are substantially the same.
168
+ {Otherwise:}
169
+ No prior research.
170
+ </prior_research>
171
+
172
+ <supporting_docs>
173
+ {If ideaDocs non-empty:}
174
+ The following per-idea supporting documents were loaded by the orchestrator; their paths are listed in <files_to_read>. Brief summaries: {list path + 1-line summary per doc}.
175
+ {Otherwise:}
176
+ None
177
+ </supporting_docs>
178
+
179
+ <repos>
180
+ {If REPOS.md exists:}
181
+ Multi-repo project. Repos: {list repo names from REPOS.md}. Partition Codebase Analysis (Dimension 2) by repo, and provide per-repo stack recommendations in the Landscape Survey (Dimension 3) where relevant.
182
+ {Otherwise:}
183
+ Single-repo project — no partitioning needed.
184
+ </repos>
185
+
186
+ <output>
187
+ Write the research document to: ${project_root}/docs/ideas/pending/${SLUG}-research.md
188
+
189
+ `mkdir -p ${project_root}/docs/ideas/pending` first if the directory doesn't exist.
190
+
191
+ Return a `## RESEARCH COMPLETE` block with: key findings (3-5 bullets), recommendation, document path, outcome (one of: "Ready for spec" / "Needs more discussion" / "Not feasible" / "Other: {short label}").
192
+ </output>
193
+ ```
255
194
 
256
- **Stack Fit:** {assessment}
257
- **Effort:** {T-shirt size} -- {phase count estimate}
258
- **Key Risks:**
259
- {bullet list}
260
- **New Dependencies:**
261
- {bullet list or "None"}
262
- **Recommendation:** {go / no-go / conditional with conditions}
195
+ Spawn the subagent:
263
196
 
264
- ---
265
- *Researched: {YYYY-MM-DD}*
197
+ ```
198
+ Task(
199
+ prompt=research_prompt,
200
+ subagent_type="dgs-idea-researcher",
201
+ model="${IDEA_RESEARCHER_MODEL}",
202
+ description="Research idea #${id}"
203
+ )
266
204
  ```
267
205
 
268
- For multi-repo projects, the Codebase Analysis and Landscape Survey sections should have `### {repo-name}` subsections.
269
-
270
- If repos_analysed is empty (no REPOS.md), omit the field from frontmatter or use an empty array.
206
+ Handle the return:
207
+ - **`## RESEARCH COMPLETE`**: extract `keyFindings`, `recommendation`, `outcome`, and the document path from the structured return. These flow into `save_research_log` as the entry JSON fields.
208
+ - **`## RESEARCH BLOCKED`**: display the blocker to the user, offer the options the subagent surfaced (provide context / abort). Do NOT proceed to `save_research_log` or `git_commit` until the blocker is resolved.
271
209
  </step>
272
210
 
273
211
  <step name="save_research_log">
274
212
  Save the Research Log entry to the idea file via the CLI command.
275
213
 
276
- Build the entry JSON:
214
+ Build the entry JSON from the subagent's structured return:
277
215
  ```json
278
216
  {
279
217
  "date": "YYYY-MM-DD",
280
218
  "summary": "{Actionable summary paragraph -- findings, recommendation, key risks. Enough to act on without opening the full document.}",
281
219
  "keyFindings": "- {finding 1}\n- {finding 2}\n- {finding 3}",
282
220
  "recommendation": "{Strong recommendation or neutral options presentation}",
283
- "documentLink": "${project_root}/docs/ideas/${SLUG}-research.md",
221
+ "documentLink": "${project_root}/docs/ideas/pending/${SLUG}-research.md",
284
222
  "outcome": "{Recommended next step: 'Ready for spec', 'Needs more discussion', 'Not feasible', etc.}"
285
223
  }
286
224
  ```
@@ -296,7 +234,7 @@ Parse the JSON result to confirm success.
296
234
  <step name="git_commit">
297
235
  Commit both the research document and the updated idea file:
298
236
  ```bash
299
- node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "docs: research idea #${id} -- ${title}" --files ${project_root}/docs/ideas/${SLUG}-research.md ${project_root}/ideas/${filename}
237
+ node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "docs: research idea #${id} -- ${title}" --files ${project_root}/docs/ideas/pending/${SLUG}-research.md ${project_root}/ideas/${filename}
300
238
  ```
301
239
  </step>
302
240
 
@@ -317,8 +255,8 @@ Suggest next step based on outcome:
317
255
 
318
256
  <success_criteria>
319
257
  - [ ] Idea loaded with full context (body, tags, notes, discussion log, research log)
320
- - [ ] Research dimensions executed with progress announcements
321
- - [ ] Research document created at `${project_root}/docs/ideas/{slug}-research.md` with frontmatter
258
+ - [ ] `dgs-idea-researcher` subagent spawned with resolved model and a complete research prompt
259
+ - [ ] Research document created at `${project_root}/docs/ideas/pending/{slug}-research.md` with frontmatter
322
260
  - [ ] Research Log entry saved to idea file via research-save CLI
323
261
  - [ ] Both files committed together
324
262
  - [ ] Key finding + recommendation + next step displayed