@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.
- package/CHANGELOG.md +115 -0
- package/README.md +8 -1
- package/agents/dgs-executor.md +124 -3
- package/agents/dgs-idea-researcher.md +447 -0
- package/agents/dgs-plan-checker.md +32 -0
- package/agents/dgs-planner.md +41 -8
- package/bin/install.js +44 -0
- package/commands/dgs/audit-milestone.md +2 -1
- package/commands/dgs/diff-report.md +124 -0
- package/commands/dgs/new-project.md +8 -21
- package/commands/dgs/package-scan.md +43 -0
- package/commands/dgs/research-idea.md +1 -0
- package/commands/dgs/switch-project.md +13 -0
- package/deliver-great-systems/bin/dgs-tools.cjs +120 -5
- 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 +311 -16
- package/deliver-great-systems/bin/lib/commands.test.cjs +115 -0
- package/deliver-great-systems/bin/lib/commit-verify.test.cjs +236 -0
- package/deliver-great-systems/bin/lib/config.cjs +41 -0
- package/deliver-great-systems/bin/lib/config.test.cjs +309 -0
- package/deliver-great-systems/bin/lib/core.cjs +7 -3
- package/deliver-great-systems/bin/lib/core.test.cjs +79 -1
- 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/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/init.cjs +56 -27
- package/deliver-great-systems/bin/lib/init.test.cjs +212 -5
- package/deliver-great-systems/bin/lib/jobs.cjs +7 -4
- package/deliver-great-systems/bin/lib/milestone.cjs +101 -3
- 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 +18 -1
- package/deliver-great-systems/bin/lib/plan-number-validity.test.cjs +48 -0
- package/deliver-great-systems/bin/lib/projects.cjs +38 -3
- package/deliver-great-systems/bin/lib/projects.test.cjs +112 -2
- package/deliver-great-systems/bin/lib/quick.cjs +178 -23
- package/deliver-great-systems/bin/lib/quick.test.cjs +138 -4
- package/deliver-great-systems/bin/lib/repos.cjs +12 -12
- package/deliver-great-systems/bin/lib/review.cjs +1821 -0
- package/deliver-great-systems/bin/lib/state.cjs +7 -3
- 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/verify.cjs +118 -6
- 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 +27 -1
- package/deliver-great-systems/bin/lib/worktrees.test.cjs +76 -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 +11 -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/add-phase.md +5 -0
- package/deliver-great-systems/workflows/audit-milestone.md +66 -10
- package/deliver-great-systems/workflows/cancel-job.md +1 -1
- package/deliver-great-systems/workflows/codereview.md +103 -9
- package/deliver-great-systems/workflows/complete-milestone.md +26 -7
- package/deliver-great-systems/workflows/complete-quick.md +40 -2
- package/deliver-great-systems/workflows/discuss-phase.md +3 -2
- package/deliver-great-systems/workflows/execute-phase.md +89 -2
- package/deliver-great-systems/workflows/execute-plan.md +10 -1
- package/deliver-great-systems/workflows/help.md +51 -18
- package/deliver-great-systems/workflows/import-spec.md +65 -7
- package/deliver-great-systems/workflows/init-product.md +46 -152
- package/deliver-great-systems/workflows/new-milestone.md +115 -14
- 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/quick-complete.md +40 -2
- package/deliver-great-systems/workflows/quick.md +183 -10
- package/deliver-great-systems/workflows/research-idea.md +80 -142
- package/deliver-great-systems/workflows/run-job.md +21 -35
- package/deliver-great-systems/workflows/settings.md +13 -77
- package/deliver-great-systems/workflows/write-spec.md +9 -11
- package/hooks/dist/dgs-enforce-discipline.js +196 -0
- package/package.json +1 -1
- package/scripts/build-hooks.js +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<purpose>
|
|
2
|
-
Execute a milestone build job end-to-end. Reads the job file, loops through pending steps, spawns an isolated subagent per step, updates the job file in real-time, handles failures with immediate halt, manages dynamic gap-fix cycles at both milestone level (GapFixCycle, max 3) and phase level (PhaseFixCycle, max 2), and
|
|
2
|
+
Execute a milestone build job end-to-end. Reads the job file, loops through pending steps, spawns an isolated subagent per step, updates the job file in real-time, handles failures with immediate halt, manages dynamic gap-fix cycles at both milestone level (GapFixCycle, max 3) and phase level (PhaseFixCycle, max 2), and marks completed jobs with status: completed. Supports --dry-run mode for step preview without execution. Auto-generates job summaries on completion and failure.
|
|
3
3
|
|
|
4
4
|
The orchestrator stays lean: it reads only the job file and MILESTONE-AUDIT.md (plus phase UAT status via CLI for phase-level audits). All actual work is delegated to subagents via Task tool. Each subagent gets a fresh context window with no shared state beyond what is on disk.
|
|
5
5
|
</purpose>
|
|
@@ -106,7 +106,7 @@ Parse the JSON result.
|
|
|
106
106
|
Error: No job found for version {VERSION}. Create one with /dgs:create-milestone-job {VERSION}
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
**If found
|
|
109
|
+
**If found.status is 'completed':**
|
|
110
110
|
```
|
|
111
111
|
Error: Job {VERSION} is already completed.
|
|
112
112
|
```
|
|
@@ -117,21 +117,14 @@ Store `JOB_PATH` from the result for all subsequent operations.
|
|
|
117
117
|
<step name="move_to_in_progress">
|
|
118
118
|
Transition the job to in-progress state if needed.
|
|
119
119
|
|
|
120
|
-
**If
|
|
120
|
+
**If found.status is 'pending':**
|
|
121
121
|
|
|
122
|
-
1.
|
|
122
|
+
1. Set the job status to in-progress (updates both frontmatter and header):
|
|
123
123
|
```bash
|
|
124
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs jobs
|
|
124
|
+
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs jobs set-status "$VERSION" --status in-progress
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
3. Update the header Status field (using the updated `$JOB_PATH`):
|
|
130
|
-
```bash
|
|
131
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs jobs update-header "$JOB_PATH" Status in-progress
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**If already in `in-progress/`:** Skip the move. The job is being resumed.
|
|
127
|
+
**If found.status is already 'in-progress':** Skip. The job is being resumed.
|
|
135
128
|
|
|
136
129
|
**Record starting commit SHAs:**
|
|
137
130
|
|
|
@@ -332,13 +325,13 @@ Loop through steps starting from `nextStepIndex`.
|
|
|
332
325
|
```bash
|
|
333
326
|
SUMMARY=$(node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs jobs generate-summary "$VERSION")
|
|
334
327
|
```
|
|
335
|
-
Parse the result. If `found: true`, write the `content` field to `${jobs_root}/
|
|
336
|
-
Display: `Job summary written to ${jobs_root}/
|
|
328
|
+
Parse the result. If `found: true`, write the `content` field to `${jobs_root}/job-{version}-SUMMARY.md` using the Write tool (job stays in place on failure -- status is tracked in frontmatter).
|
|
329
|
+
Display: `Job summary written to ${jobs_root}/job-{version}-SUMMARY.md`
|
|
337
330
|
|
|
338
331
|
**Commit and push failure summary:**
|
|
339
332
|
|
|
340
333
|
```bash
|
|
341
|
-
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "docs(job): ${VERSION} failure summary" --files "${jobs_root}/
|
|
334
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "docs(job): ${VERSION} failure summary" --files "${jobs_root}/job-${VERSION}-SUMMARY.md" --push
|
|
342
335
|
```
|
|
343
336
|
|
|
344
337
|
**HALT immediately.** Do not proceed to the next step.
|
|
@@ -536,39 +529,32 @@ After an `audit-phase` step completes successfully, check the phase audit outcom
|
|
|
536
529
|
<step name="complete_job">
|
|
537
530
|
When all steps are completed (`nextStepIndex` is null after the loop):
|
|
538
531
|
|
|
539
|
-
1. **
|
|
532
|
+
1. **Set job status to `completed`** (updates both frontmatter and header):
|
|
540
533
|
```bash
|
|
541
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs jobs
|
|
534
|
+
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs jobs set-status "$VERSION" --status completed
|
|
542
535
|
```
|
|
543
536
|
|
|
544
|
-
2. **Move job to `completed/`:**
|
|
545
|
-
```bash
|
|
546
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs jobs move "$JOB_PATH" "${jobs_root}/completed"
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
Update `JOB_PATH` to reflect the new location under `completed/`.
|
|
550
|
-
|
|
551
537
|
**Commit and push job status:**
|
|
552
538
|
|
|
553
539
|
```bash
|
|
554
|
-
git add -A "$(dirname "$JOB_PATH")
|
|
540
|
+
git add -A "$(dirname "$JOB_PATH")/"
|
|
555
541
|
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "docs(job): ${VERSION} completed" --push
|
|
556
542
|
```
|
|
557
543
|
|
|
558
|
-
|
|
544
|
+
2. **Generate job summary:**
|
|
559
545
|
```bash
|
|
560
546
|
SUMMARY=$(node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs jobs generate-summary "$VERSION")
|
|
561
547
|
```
|
|
562
|
-
Parse the result. If `found: true`, write the `content` field to `${jobs_root}/
|
|
563
|
-
Display: `Job summary written to ${jobs_root}/
|
|
548
|
+
Parse the result. If `found: true`, write the `content` field to `${jobs_root}/job-{version}-SUMMARY.md` using the Write tool.
|
|
549
|
+
Display: `Job summary written to ${jobs_root}/job-{version}-SUMMARY.md`
|
|
564
550
|
|
|
565
551
|
**Commit and push completion summary:**
|
|
566
552
|
|
|
567
553
|
```bash
|
|
568
|
-
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "docs(job): ${VERSION} completion summary" --files "${jobs_root}/
|
|
554
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "docs(job): ${VERSION} completion summary" --files "${jobs_root}/job-${VERSION}-SUMMARY.md" --push
|
|
569
555
|
```
|
|
570
556
|
|
|
571
|
-
|
|
557
|
+
3. **Post-workflow push (sync_after):**
|
|
572
558
|
|
|
573
559
|
Follow the sync-hooks post-workflow push pattern with `WORKFLOW_NAME = "run-job"`:
|
|
574
560
|
|
|
@@ -582,7 +568,7 @@ When all steps are completed (`nextStepIndex` is null after the loop):
|
|
|
582
568
|
|
|
583
569
|
Display aggregated push summary including any accumulated `SYNC_WARNINGS` from mid-workflow pushes.
|
|
584
570
|
|
|
585
|
-
|
|
571
|
+
4. **Display completion banner:**
|
|
586
572
|
|
|
587
573
|
If `AUTO_RESOLVE_COUNT` is 0:
|
|
588
574
|
```
|
|
@@ -617,11 +603,11 @@ The orchestrator MUST stay lean per EXEC-07:
|
|
|
617
603
|
- [ ] Milestone audit gap-fix cycle auto-approved with 3-cycle safety limit
|
|
618
604
|
- [ ] Phase audit gap-fix cycle auto-approved with 2-cycle safety limit
|
|
619
605
|
- [ ] PhaseFixCycle counter resets on plan-phase/map-codebase steps
|
|
620
|
-
- [ ] Completed jobs
|
|
606
|
+
- [ ] Completed jobs marked with status: completed with banner
|
|
621
607
|
- [ ] Orchestrator reads only job file and MILESTONE-AUDIT.md (phase UAT via CLI)
|
|
622
608
|
- [ ] --dry-run flag displays step preview without executing
|
|
623
|
-
- [ ] Job summary auto-generated on completion (written to
|
|
624
|
-
- [ ] Job summary auto-generated on failure (written to
|
|
609
|
+
- [ ] Job summary auto-generated on completion (written to ${jobs_root}/)
|
|
610
|
+
- [ ] Job summary auto-generated on failure (written to ${jobs_root}/)
|
|
625
611
|
- [ ] Pre-workflow pull executed before job steps start (sync_before)
|
|
626
612
|
- [ ] Mid-workflow push after phase-completing steps (silent, no prompt)
|
|
627
613
|
- [ ] Post-workflow push after job completion (sync_after)
|
|
@@ -45,8 +45,8 @@ Parse current values (default to `true` if not present):
|
|
|
45
45
|
- `workflow.verifier` — spawn verifier during execute-phase
|
|
46
46
|
- `workflow.nyquist_validation` — validation architecture research during plan-phase (default: true if absent)
|
|
47
47
|
- `workflow.codereview` — spawn code reviewer after plan execution (default: false if absent)
|
|
48
|
+
- `workflow.four_eyes` — four-eyes completion governance mode (default: "off" if absent)
|
|
48
49
|
- `model_profile` — which model each agent uses (default: `balanced`)
|
|
49
|
-
- `git.branching_strategy` — branching approach (default: `"none"`)
|
|
50
50
|
- `git.base_branch` — integration target branch for code repos (default: `"main"`)
|
|
51
51
|
- `git.sync_push` — remote sync push mode (default: "off" if absent for existing installs)
|
|
52
52
|
- `git.sync_pull` — remote sync pull mode (default: "off" if absent for existing installs)
|
|
@@ -59,62 +59,6 @@ CLAUDE_MD_HAS_DGS=$(grep -l 'DGS:BEGIN' ./CLAUDE.md 2>/dev/null && echo "true" |
|
|
|
59
59
|
```
|
|
60
60
|
</step>
|
|
61
61
|
|
|
62
|
-
<step name="detect_old_templates">
|
|
63
|
-
After loading current config, check if the branch templates use old defaults without `{project}`:
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
CURRENT_PHASE_TPL=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" config-get git.phase_branch_template --raw 2>/dev/null)
|
|
67
|
-
CURRENT_MILESTONE_TPL=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" config-get git.milestone_branch_template --raw 2>/dev/null)
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
If either template is set AND does not contain `{project}`, and `branching_strategy` is not `"none"`, show migration hint before the settings questions:
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
74
|
-
DGS ► BRANCH TEMPLATE UPDATE AVAILABLE
|
|
75
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
76
|
-
|
|
77
|
-
Your branch templates don't include the project name, which can cause
|
|
78
|
-
collisions in multi-project setups.
|
|
79
|
-
|
|
80
|
-
Current: {current_phase_tpl}
|
|
81
|
-
Suggested: dgs/{project}/phase-{phase}-{slug}
|
|
82
|
-
|
|
83
|
-
Current: {current_milestone_tpl}
|
|
84
|
-
Suggested: dgs/{project}/{milestone}-{slug}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Use AskUserQuestion:
|
|
88
|
-
```
|
|
89
|
-
AskUserQuestion([{
|
|
90
|
-
question: "Update branch templates to include project name?",
|
|
91
|
-
header: "Templates",
|
|
92
|
-
multiSelect: false,
|
|
93
|
-
options: [
|
|
94
|
-
{ label: "Yes (Recommended)", description: "Updates templates to include {project} for multi-project safety" },
|
|
95
|
-
{ label: "No", description: "Keep current templates" }
|
|
96
|
-
]
|
|
97
|
-
}])
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
If "Yes": write updated templates to config.json using config-set:
|
|
101
|
-
```bash
|
|
102
|
-
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" config-set git.phase_branch_template "dgs/{project}/phase-{phase}-{slug}"
|
|
103
|
-
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" config-set git.milestone_branch_template "dgs/{project}/{milestone}-{slug}"
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
Show confirmation:
|
|
107
|
-
```
|
|
108
|
-
Updated branch templates to include {project}.
|
|
109
|
-
Branch names will now look like: dgs/your-project/phase-03-auth
|
|
110
|
-
|
|
111
|
-
Note: Existing branches using the old format will NOT be renamed.
|
|
112
|
-
Only new branches will use the updated format.
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
If templates already contain `{project}` or branching_strategy is "none": skip this step silently.
|
|
116
|
-
</step>
|
|
117
|
-
|
|
118
62
|
<step name="present_settings">
|
|
119
63
|
Use AskUserQuestion with current values pre-selected:
|
|
120
64
|
|
|
@@ -185,21 +129,14 @@ AskUserQuestion([
|
|
|
185
129
|
]
|
|
186
130
|
},
|
|
187
131
|
{
|
|
188
|
-
question: "
|
|
189
|
-
header: "
|
|
132
|
+
question: "Four-eyes completion governance? (requires a second contributor for milestone/quick completion)",
|
|
133
|
+
header: "Four-Eyes",
|
|
190
134
|
multiSelect: false,
|
|
191
135
|
options: [
|
|
192
|
-
{ label: "
|
|
193
|
-
{ label: "
|
|
194
|
-
{ label: "
|
|
136
|
+
{ label: "Off", description: "No contributor check at completion gates" },
|
|
137
|
+
{ label: "Warn", description: "Warn if only one contributor, but allow completion" },
|
|
138
|
+
{ label: "Enforce", description: "Block completion unless a second contributor is detected (bypass with --force)" }
|
|
195
139
|
]
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
question: "Base branch for code repos? (integration target for branching operations)",
|
|
199
|
-
header: "Git",
|
|
200
|
-
multiSelect: false,
|
|
201
|
-
freeform: true,
|
|
202
|
-
placeholder: currentConfig.base_branch || "main"
|
|
203
140
|
}
|
|
204
141
|
])
|
|
205
142
|
```
|
|
@@ -450,11 +387,11 @@ Merge new settings into existing config:
|
|
|
450
387
|
"auto_advance": true/false,
|
|
451
388
|
"nyquist_validation": true/false,
|
|
452
389
|
"codereview": true/false,
|
|
453
|
-
"discipline": true/false
|
|
390
|
+
"discipline": true/false,
|
|
391
|
+
"four_eyes": "off" | "warn" | "enforce"
|
|
454
392
|
},
|
|
455
393
|
"git": {
|
|
456
|
-
"
|
|
457
|
-
"base_branch": "main" | user_answer,
|
|
394
|
+
"base_branch": "main",
|
|
458
395
|
"sync_push": "off" | "prompt" | "auto",
|
|
459
396
|
"sync_pull": "off" | "prompt" | "auto"
|
|
460
397
|
}
|
|
@@ -495,7 +432,6 @@ Write `~/.dgs/defaults.json` with:
|
|
|
495
432
|
"model_profile": <current>,
|
|
496
433
|
"commit_docs": <current>,
|
|
497
434
|
"parallelization": <current>,
|
|
498
|
-
"branching_strategy": <current>,
|
|
499
435
|
"workflow": {
|
|
500
436
|
"research": <current>,
|
|
501
437
|
"plan_check": <current>,
|
|
@@ -503,7 +439,8 @@ Write `~/.dgs/defaults.json` with:
|
|
|
503
439
|
"auto_advance": <current>,
|
|
504
440
|
"nyquist_validation": <current>,
|
|
505
441
|
"codereview": <current>,
|
|
506
|
-
"discipline": <current
|
|
442
|
+
"discipline": <current>,
|
|
443
|
+
"four_eyes": <current>
|
|
507
444
|
},
|
|
508
445
|
"git": {
|
|
509
446
|
"sync_push": <current>,
|
|
@@ -544,8 +481,7 @@ Display:
|
|
|
544
481
|
| Auto-Advance | {On/Off} |
|
|
545
482
|
| Nyquist Validation | {On/Off} |
|
|
546
483
|
| Code Reviewer | {On/Off} |
|
|
547
|
-
|
|
|
548
|
-
| Base Branch | {main/develop/etc.} |
|
|
484
|
+
| Four-Eyes Governance | {Off/Warn/Enforce} |
|
|
549
485
|
| Workflow Discipline | {On/Off} |
|
|
550
486
|
| Git Sync Push | {Off/Prompt/Auto} |
|
|
551
487
|
| Git Sync Pull | {Off/Prompt/Auto} |
|
|
@@ -567,7 +503,7 @@ Quick commands:
|
|
|
567
503
|
|
|
568
504
|
<success_criteria>
|
|
569
505
|
- [ ] Current config read
|
|
570
|
-
- [ ] User presented with
|
|
506
|
+
- [ ] User presented with 8 workflow settings (profile + 6 workflow toggles + four-eyes governance)
|
|
571
507
|
- [ ] User shown review key status (read-only)
|
|
572
508
|
- [ ] Config updated with model_profile, workflow, and git sections
|
|
573
509
|
- [ ] User offered to save as global defaults (~/.dgs/defaults.json)
|
|
@@ -222,7 +222,7 @@ node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs specs add-log-entry --id
|
|
|
222
222
|
|
|
223
223
|
Commit the draft:
|
|
224
224
|
```bash
|
|
225
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: draft $id from ideas $idea_ids" --push --files
|
|
225
|
+
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: draft $id from ideas $idea_ids" --push --files specs/$filename
|
|
226
226
|
```
|
|
227
227
|
|
|
228
228
|
Store `SPEC_ID` and `FILENAME` for subsequent steps.
|
|
@@ -289,7 +289,7 @@ Use AskUserQuestion: "Review the draft spec above. Type **approve** to send to r
|
|
|
289
289
|
|
|
290
290
|
After approval, commit any changes:
|
|
291
291
|
```bash
|
|
292
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: revise draft $SPEC_ID" --push --files
|
|
292
|
+
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: revise draft $SPEC_ID" --push --files specs/$FILENAME
|
|
293
293
|
```
|
|
294
294
|
</step>
|
|
295
295
|
|
|
@@ -350,7 +350,7 @@ Estimated cost: ~$X.XX
|
|
|
350
350
|
**6. Commit updated spec:**
|
|
351
351
|
|
|
352
352
|
```bash
|
|
353
|
-
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: review $SPEC_ID (N rounds)" --push --files
|
|
353
|
+
node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs commit "specs: review $SPEC_ID (N rounds)" --push --files specs/$FILENAME
|
|
354
354
|
```
|
|
355
355
|
</step>
|
|
356
356
|
|
|
@@ -394,18 +394,16 @@ Source ideas moved to done: $IDEAS_MOVED
|
|
|
394
394
|
Research documents moved to done: $RESEARCH_DOCS_MOVED (if any)
|
|
395
395
|
|
|
396
396
|
What would you like to do next?
|
|
397
|
-
1.
|
|
398
|
-
2.
|
|
399
|
-
3. Nothing for now -- the spec is saved and ready when you are
|
|
397
|
+
1. Start a milestone from this spec -> /dgs:new-milestone --auto $SPEC_ID
|
|
398
|
+
2. Nothing for now -- the spec is saved and ready when you are
|
|
400
399
|
```
|
|
401
400
|
|
|
402
|
-
In interactive mode, use AskUserQuestion: "Choose 1
|
|
401
|
+
In interactive mode, use AskUserQuestion: "Choose 1 or 2 (or just press enter to defer):"
|
|
403
402
|
|
|
404
|
-
- If **1**: Tell user "Run `/dgs:new-
|
|
405
|
-
- If **2
|
|
406
|
-
- If **3** or empty/enter: Output "Spec saved. You can find it at `${project_root}/specs/$FILENAME`."
|
|
403
|
+
- If **1**: Tell user "Run `/dgs:new-milestone --auto $SPEC_ID` to start a milestone from this spec. If no project exists yet, run `/dgs:new-project` first to create the project holder, then `/dgs:new-milestone --auto $SPEC_ID`."
|
|
404
|
+
- If **2** or empty/enter: Output "Spec saved. You can find it at `specs/$FILENAME` (planning root)."
|
|
407
405
|
|
|
408
|
-
In `--auto` mode: skip the routing question, just output the summary with the
|
|
406
|
+
In `--auto` mode: skip the routing question, just output the summary with the two options listed for reference.
|
|
409
407
|
</step>
|
|
410
408
|
|
|
411
409
|
</process>
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// DGS Workflow Discipline Enforcement - PreToolUse + PostToolUse hook
|
|
3
|
+
//
|
|
4
|
+
// Ensures Edit/Write tool calls only happen inside /dgs:* commands.
|
|
5
|
+
// Works via a marker file that tracks active DGS command state:
|
|
6
|
+
//
|
|
7
|
+
// 1. When tool_name is "Skill" and the skill name starts with "dgs:":
|
|
8
|
+
// - PreToolUse: Write a marker file to /tmp/dgs-active-{session_id}.json
|
|
9
|
+
// - PostToolUse: Delete the marker, then check for uncommitted DGS files
|
|
10
|
+
//
|
|
11
|
+
// 2. When tool_name is "Edit" or "Write":
|
|
12
|
+
// - Check for marker file — if present, allow
|
|
13
|
+
// - Check if target path is in the allowlist — if so, allow
|
|
14
|
+
// - Check if cwd is a DGS planning folder — if not, allow (non-DGS project)
|
|
15
|
+
// - Otherwise, deny with explanation
|
|
16
|
+
//
|
|
17
|
+
// Safety net: After every /dgs:* command completes, checks for uncommitted
|
|
18
|
+
// DGS-managed files and auto-commits them. Logs a warning so the upstream
|
|
19
|
+
// workflow bug can be identified and fixed.
|
|
20
|
+
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const os = require('os');
|
|
23
|
+
const path = require('path');
|
|
24
|
+
const { execSync } = require('child_process');
|
|
25
|
+
|
|
26
|
+
// Paths where Edit/Write is allowed without a DGS command
|
|
27
|
+
const ALLOWED_PATH_PATTERNS = [
|
|
28
|
+
/\.claude\/projects\/.*\/memory\//, // Auto-memory system
|
|
29
|
+
/\.claude\/.*\/memory\//, // Memory in any .claude subfolder
|
|
30
|
+
/\/tmp\//, // Temp files
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
// DGS-managed paths that should be committed (relative to planning root)
|
|
34
|
+
// Used by the safety net to detect orphaned writes after a command completes
|
|
35
|
+
const DGS_MANAGED_PATTERNS = [
|
|
36
|
+
/^STATE\.md$/,
|
|
37
|
+
/^PROJECTS\.md$/,
|
|
38
|
+
/^MILESTONES\.md$/,
|
|
39
|
+
/^RETROSPECTIVE\.md$/,
|
|
40
|
+
/^CLAUDE\.md$/,
|
|
41
|
+
/^config\.json$/,
|
|
42
|
+
/^projects\/[^/]+\/STATE\.md$/,
|
|
43
|
+
/^projects\/[^/]+\/ROADMAP\.md$/,
|
|
44
|
+
/^projects\/[^/]+\/REQUIREMENTS\.md$/,
|
|
45
|
+
/^projects\/[^/]+\/PROJECT\.md$/,
|
|
46
|
+
/^projects\/[^/]+\/phases\//,
|
|
47
|
+
/^projects\/[^/]+\/milestones\//,
|
|
48
|
+
/^specs\//,
|
|
49
|
+
/^ideas\//,
|
|
50
|
+
/^todos\//,
|
|
51
|
+
/^jobs\//,
|
|
52
|
+
/^quick\//,
|
|
53
|
+
/^milestones\//,
|
|
54
|
+
/^codebase\//,
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
function getMarkerPath(sessionId) {
|
|
58
|
+
return path.join(os.tmpdir(), `dgs-active-${sessionId}.json`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isDgsProject(cwd) {
|
|
62
|
+
try {
|
|
63
|
+
const configPath = path.join(cwd, 'config.json');
|
|
64
|
+
if (!fs.existsSync(configPath)) return false;
|
|
65
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
66
|
+
return content.includes('"product_name"');
|
|
67
|
+
} catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isAllowedPath(filePath) {
|
|
73
|
+
if (!filePath) return false;
|
|
74
|
+
return ALLOWED_PATH_PATTERNS.some(pattern => pattern.test(filePath));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getTargetPath(toolName, toolInput) {
|
|
78
|
+
if (!toolInput) return null;
|
|
79
|
+
// Edit and Write both use file_path
|
|
80
|
+
return toolInput.file_path || null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let input = '';
|
|
84
|
+
const stdinTimeout = setTimeout(() => process.exit(0), 3000);
|
|
85
|
+
process.stdin.setEncoding('utf8');
|
|
86
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
87
|
+
process.stdin.on('end', () => {
|
|
88
|
+
clearTimeout(stdinTimeout);
|
|
89
|
+
try {
|
|
90
|
+
const data = JSON.parse(input);
|
|
91
|
+
const sessionId = data.session_id;
|
|
92
|
+
const hookEvent = data.hook_event_name;
|
|
93
|
+
const toolName = data.tool_name;
|
|
94
|
+
const toolInput = data.tool_input || {};
|
|
95
|
+
const cwd = data.cwd || process.cwd();
|
|
96
|
+
|
|
97
|
+
// ── PostToolUse: Clean up marker + safety net when Skill completes ──
|
|
98
|
+
if (hookEvent === 'PostToolUse') {
|
|
99
|
+
if (toolName === 'Skill') {
|
|
100
|
+
const skillName = toolInput.skill || toolInput.name || '';
|
|
101
|
+
if (skillName.startsWith('dgs:')) {
|
|
102
|
+
// Delete the active marker
|
|
103
|
+
const markerPath = getMarkerPath(sessionId);
|
|
104
|
+
try { fs.unlinkSync(markerPath); } catch { /* already gone */ }
|
|
105
|
+
|
|
106
|
+
// Safety net: check for uncommitted DGS-managed files
|
|
107
|
+
if (isDgsProject(cwd)) {
|
|
108
|
+
try {
|
|
109
|
+
const status = execSync('git status --porcelain', { cwd, encoding: 'utf-8', timeout: 5000 });
|
|
110
|
+
if (status.trim()) {
|
|
111
|
+
const lines = status.trim().split('\n');
|
|
112
|
+
const dirty = lines
|
|
113
|
+
.map(l => l.slice(3).trim()) // strip status prefix (e.g., " M ", "?? ")
|
|
114
|
+
.filter(f => DGS_MANAGED_PATTERNS.some(p => p.test(f)));
|
|
115
|
+
|
|
116
|
+
if (dirty.length > 0) {
|
|
117
|
+
// Stage and commit orphaned DGS files
|
|
118
|
+
for (const f of dirty) {
|
|
119
|
+
execSync(`git add "${f}"`, { cwd, stdio: 'pipe', timeout: 5000 });
|
|
120
|
+
}
|
|
121
|
+
const msg = `chore: auto-commit ${dirty.length} uncommitted DGS file(s) after ${skillName}`;
|
|
122
|
+
execSync(`git commit -m "${msg}"`, { cwd, stdio: 'pipe', timeout: 10000 });
|
|
123
|
+
|
|
124
|
+
// Warn via additionalContext so Claude sees it
|
|
125
|
+
const result = {
|
|
126
|
+
continue: true,
|
|
127
|
+
suppressOutput: false,
|
|
128
|
+
hookSpecificOutput: {
|
|
129
|
+
hookEventName: 'PostToolUse',
|
|
130
|
+
additionalContext: `[DGS safety net] Auto-committed ${dirty.length} orphaned file(s) after ${skillName}: ${dirty.join(', ')}. This indicates a missing commit in the ${skillName} workflow — consider fixing upstream.`,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
process.stdout.write(JSON.stringify(result));
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch { /* git not available or commit failed — don't block */ }
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ── PreToolUse: Skill → write marker ──
|
|
145
|
+
if (hookEvent === 'PreToolUse' && toolName === 'Skill') {
|
|
146
|
+
const skillName = toolInput.skill || toolInput.name || '';
|
|
147
|
+
if (skillName.startsWith('dgs:')) {
|
|
148
|
+
const markerPath = getMarkerPath(sessionId);
|
|
149
|
+
const marker = {
|
|
150
|
+
command: skillName,
|
|
151
|
+
started: new Date().toISOString(),
|
|
152
|
+
session_id: sessionId,
|
|
153
|
+
};
|
|
154
|
+
fs.writeFileSync(markerPath, JSON.stringify(marker));
|
|
155
|
+
}
|
|
156
|
+
process.exit(0);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ── PreToolUse: Edit/Write → check marker ──
|
|
160
|
+
if (hookEvent === 'PreToolUse' && (toolName === 'Edit' || toolName === 'Write')) {
|
|
161
|
+
// Not a DGS project? Allow everything.
|
|
162
|
+
if (!isDgsProject(cwd)) {
|
|
163
|
+
process.exit(0);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Target path in allowlist? Allow.
|
|
167
|
+
const targetPath = getTargetPath(toolName, toolInput);
|
|
168
|
+
if (isAllowedPath(targetPath)) {
|
|
169
|
+
process.exit(0);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// DGS command active? Allow.
|
|
173
|
+
const markerPath = getMarkerPath(sessionId);
|
|
174
|
+
if (fs.existsSync(markerPath)) {
|
|
175
|
+
process.exit(0);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// No DGS command active in a DGS project — deny.
|
|
179
|
+
const result = {
|
|
180
|
+
hookSpecificOutput: {
|
|
181
|
+
hookEventName: 'PreToolUse',
|
|
182
|
+
permissionDecision: 'deny',
|
|
183
|
+
permissionDecisionReason: 'DGS workflow discipline: Edit/Write requires an active /dgs:* command. Use /dgs:fast (trivial), /dgs:quick (small), or /dgs:execute-phase (feature). Say "skip DGS" to bypass.',
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
process.stdout.write(JSON.stringify(result));
|
|
187
|
+
process.exit(0);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Any other tool/event — allow
|
|
191
|
+
process.exit(0);
|
|
192
|
+
} catch {
|
|
193
|
+
// Parse error or unexpected input — don't block
|
|
194
|
+
process.exit(0);
|
|
195
|
+
}
|
|
196
|
+
});
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"bugs": {
|
|
9
9
|
"url": "https://github.com/KT-Partners-Ltd/dgs-platform-docs/issues"
|
|
10
10
|
},
|
|
11
|
-
"version": "3.0
|
|
11
|
+
"version": "3.3.0",
|
|
12
12
|
"description": "Deliver Great Systems Platform — A meta-prompting, context engineering and spec-driven development system for Claude Code and Gemini by KT Partners.",
|
|
13
13
|
"bin": {
|
|
14
14
|
"dgs": "bin/install.js"
|