@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
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dgs:diff-report
|
|
3
|
+
description: Generate a diff report (REVIEW.md) on demand for any milestone or quick task
|
|
4
|
+
argument-hint: "[version|--quick slug] [--detailed]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# /dgs:diff-report -- On-Demand Diff Report
|
|
11
|
+
|
|
12
|
+
Generate a REVIEW.md on demand without requiring audit-milestone or complete-quick.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
/dgs:diff-report -- Auto-detect: active quick task or current milestone
|
|
18
|
+
/dgs:diff-report v21.0 -- Generate for a specific milestone version
|
|
19
|
+
/dgs:diff-report --quick slug -- Generate for a specific quick task
|
|
20
|
+
/dgs:diff-report --detailed -- Use LLM-powered detailed analysis mode
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
<step name="parse_arguments">
|
|
26
|
+
Parse $ARGUMENTS for:
|
|
27
|
+
- A version string (e.g., `v21.0`, `v22.0`) — milestone target
|
|
28
|
+
- `--quick <slug>` — quick task target with explicit slug
|
|
29
|
+
- `--detailed` — pass through to underlying CLI command
|
|
30
|
+
- No arguments — auto-detect mode
|
|
31
|
+
|
|
32
|
+
Store as `TARGET_TYPE` (one of: `milestone`, `quick`, `auto`), `TARGET_VALUE` (version or slug, may be empty), and `DETAILED` (boolean).
|
|
33
|
+
</step>
|
|
34
|
+
|
|
35
|
+
<step name="detect_context">
|
|
36
|
+
**If TARGET_TYPE is `auto`** (no version or --quick specified):
|
|
37
|
+
|
|
38
|
+
Check for an active quick task first:
|
|
39
|
+
```bash
|
|
40
|
+
ACTIVE_QUICK=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick generate-review --raw 2>&1)
|
|
41
|
+
QUICK_EXIT=$?
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If `QUICK_EXIT` is 0 and the output contains `"generated": true` or `"fastForward": true`:
|
|
45
|
+
- Set `TARGET_TYPE = quick` (auto-detected)
|
|
46
|
+
- The command already ran and produced the review
|
|
47
|
+
|
|
48
|
+
If `QUICK_EXIT` is non-zero (no active quick task):
|
|
49
|
+
- Set `TARGET_TYPE = milestone` (fall back to current milestone)
|
|
50
|
+
|
|
51
|
+
**If TARGET_TYPE is `milestone`:**
|
|
52
|
+
Use the version argument if provided. Otherwise auto-detection happens inside the CLI command.
|
|
53
|
+
|
|
54
|
+
**If TARGET_TYPE is `quick`:**
|
|
55
|
+
Use the slug argument if provided. Otherwise auto-detection happens inside the CLI command.
|
|
56
|
+
</step>
|
|
57
|
+
|
|
58
|
+
<step name="show_context">
|
|
59
|
+
Display what will be generated before proceeding:
|
|
60
|
+
|
|
61
|
+
**If auto-detected quick task:**
|
|
62
|
+
```
|
|
63
|
+
Generating review for quick task...
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**If milestone (with version):**
|
|
67
|
+
```
|
|
68
|
+
Generating review for milestone {version}...
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**If milestone (auto-detect):**
|
|
72
|
+
```
|
|
73
|
+
Generating review for current milestone...
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**If explicit quick task:**
|
|
77
|
+
```
|
|
78
|
+
Generating review for quick task {slug}...
|
|
79
|
+
```
|
|
80
|
+
</step>
|
|
81
|
+
|
|
82
|
+
<step name="generate">
|
|
83
|
+
Run the appropriate CLI command:
|
|
84
|
+
|
|
85
|
+
**For milestone reports:**
|
|
86
|
+
```bash
|
|
87
|
+
RESULT=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" jobs generate-review ${TARGET_VALUE} ${DETAILED_FLAG} 2>&1)
|
|
88
|
+
EXIT_CODE=$?
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Where `${TARGET_VALUE}` is the version (e.g., `v21.0`) or empty for auto-detect, and `${DETAILED_FLAG}` is `--detailed` if requested or empty.
|
|
92
|
+
|
|
93
|
+
**For quick task reports:**
|
|
94
|
+
```bash
|
|
95
|
+
RESULT=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" quick generate-review ${TARGET_VALUE} ${DETAILED_FLAG} 2>&1)
|
|
96
|
+
EXIT_CODE=$?
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Where `${TARGET_VALUE}` is the slug or empty for auto-detect.
|
|
100
|
+
|
|
101
|
+
Note: If auto-detect already ran the quick command in step 2 and succeeded, skip re-running — use the result from step 2.
|
|
102
|
+
</step>
|
|
103
|
+
|
|
104
|
+
<step name="report">
|
|
105
|
+
**If EXIT_CODE is 0:**
|
|
106
|
+
|
|
107
|
+
Display the result from the CLI command (it includes file path and stats).
|
|
108
|
+
|
|
109
|
+
**If EXIT_CODE is non-zero:**
|
|
110
|
+
|
|
111
|
+
Display the error from the CLI command. The underlying commands already produce actionable error messages:
|
|
112
|
+
- `No version specified and no active job found` — no milestone to generate for
|
|
113
|
+
- `No active quick task found` — no quick task to generate for
|
|
114
|
+
- `No job file found for [version]` — missing job file, need to run a milestone job first
|
|
115
|
+
- `No code changes detected` — fast-forwarded quick task (informational, not an error)
|
|
116
|
+
</step>
|
|
117
|
+
|
|
118
|
+
## Success Criteria
|
|
119
|
+
|
|
120
|
+
- [ ] Auto-detects quick task vs milestone context
|
|
121
|
+
- [ ] Delegates to existing CLI commands (no code duplication)
|
|
122
|
+
- [ ] --detailed flag passed through to underlying command
|
|
123
|
+
- [ ] Shows context line before generating
|
|
124
|
+
- [ ] Error messages are actionable (from underlying CLI commands)
|
|
@@ -1,42 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dgs:new-project
|
|
3
|
-
description: Initialize a new project
|
|
4
|
-
argument-hint: "[
|
|
3
|
+
description: Initialize a new project as a thin skeleton (name + one-liner).
|
|
4
|
+
argument-hint: "[<name>]"
|
|
5
5
|
allowed-tools:
|
|
6
6
|
- Read
|
|
7
7
|
- Bash
|
|
8
8
|
- Write
|
|
9
|
-
- Task
|
|
10
|
-
- AskUserQuestion
|
|
11
9
|
---
|
|
12
|
-
<context>
|
|
13
|
-
**Flags:**
|
|
14
|
-
- `--auto` — Automatic mode. After config questions, runs research → requirements → roadmap without further interaction. Expects idea document via @ reference.
|
|
15
|
-
</context>
|
|
16
|
-
|
|
17
10
|
<objective>
|
|
18
|
-
Initialize a new project
|
|
11
|
+
Initialize a new project as a thin skeleton. Projects are holders — specs and
|
|
12
|
+
milestones carry the real work.
|
|
19
13
|
|
|
20
14
|
**Creates:**
|
|
21
|
-
- `${project_path}` —
|
|
22
|
-
- `config.json` — workflow preferences
|
|
23
|
-
- `${project_root}/research/` — domain research (optional)
|
|
24
|
-
- `${project_root}/REQUIREMENTS.md` — scoped requirements
|
|
25
|
-
- `${roadmap_path}` — phase structure
|
|
26
|
-
- `${state_path}` — project memory
|
|
15
|
+
- `${project_path}` — thin PROJECT.md (title + one-line placeholder)
|
|
27
16
|
|
|
28
|
-
**After this command:** Run `/dgs:
|
|
17
|
+
**After this command:** Run `/dgs:write-spec` to capture what you're building,
|
|
18
|
+
then `/dgs:new-milestone --auto <spec-id>` to start the first milestone.
|
|
29
19
|
</objective>
|
|
30
20
|
|
|
31
21
|
<execution_context>
|
|
32
22
|
@~/.claude/deliver-great-systems/workflows/new-project.md
|
|
33
|
-
@~/.claude/deliver-great-systems/references/questioning.md
|
|
34
23
|
@~/.claude/deliver-great-systems/references/ui-brand.md
|
|
35
24
|
@~/.claude/deliver-great-systems/templates/project.md
|
|
36
|
-
@~/.claude/deliver-great-systems/templates/requirements.md
|
|
37
25
|
</execution_context>
|
|
38
26
|
|
|
39
27
|
<process>
|
|
40
|
-
Execute the new-project workflow
|
|
41
|
-
Preserve all workflow gates (validation, approvals, commits, routing).
|
|
28
|
+
Execute the new-project workflow end-to-end. Preserve gates (--auto error, commit).
|
|
42
29
|
</process>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dgs:package-scan
|
|
3
|
+
description: Scan all repos for dependency vulnerabilities and licence compliance
|
|
4
|
+
argument-hint: "[--threshold <sev>] [--repo <name>]"
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Read
|
|
7
|
+
- Bash
|
|
8
|
+
- Edit
|
|
9
|
+
- Write
|
|
10
|
+
- Glob
|
|
11
|
+
- Grep
|
|
12
|
+
---
|
|
13
|
+
<objective>
|
|
14
|
+
Scan all registered repos and the product root for dependency vulnerabilities via a tool cascade (Snyk → OSV-Scanner → ecosystem-native). Produces a markdown report with YAML frontmatter (programmatic consumption) and a human-readable body, committed atomically to the active phase directory / active milestone / project root depending on lifecycle context.
|
|
15
|
+
|
|
16
|
+
Purpose: Surface known CVEs and licence compliance issues across every language ecosystem in the project within seconds, with no configuration beyond REPOS.md.
|
|
17
|
+
|
|
18
|
+
Output: `{phase-dir}/{phase}-PACKAGE-SCAN.md` (when run during a phase), or `milestones/v{X}.{Y}-PACKAGE-SCAN.md` (during a milestone), or `PACKAGE-SCAN-{YYYY-MM-DD-HHmm}.md` at project root (standalone). The report is atomically committed via `dgs-tools commit --files`.
|
|
19
|
+
</objective>
|
|
20
|
+
|
|
21
|
+
<execution_context>
|
|
22
|
+
@~/.claude/deliver-great-systems/workflows/package-scan.md
|
|
23
|
+
</execution_context>
|
|
24
|
+
|
|
25
|
+
<context>
|
|
26
|
+
Arguments: $ARGUMENTS
|
|
27
|
+
|
|
28
|
+
**Flags** (Phase 153 will wire these; the command accepts them silently now):
|
|
29
|
+
- `--threshold <sev>` — filter to findings at `<sev>` severity or higher (critical/high/medium/low)
|
|
30
|
+
- `--repo <name>` — scan a single repo by name (must match REPOS.md entry)
|
|
31
|
+
|
|
32
|
+
**Config keys** (see `deliver-great-systems/references/package-scan-config.md`):
|
|
33
|
+
- `testing.packages.tool` — `auto` (default), `snyk`, `osv`, or `native`
|
|
34
|
+
- `testing.packages.severity_threshold` — minimum severity to include
|
|
35
|
+
- `testing.packages.include_dev_dependencies` — boolean, default `true`
|
|
36
|
+
- `testing.packages.timeout_seconds` — integer, default 300
|
|
37
|
+
- `testing.packages.snyk_token` — local-only (use `dgs-tools config-local-set`)
|
|
38
|
+
</context>
|
|
39
|
+
|
|
40
|
+
<process>
|
|
41
|
+
Execute the package-scan workflow from @~/.claude/deliver-great-systems/workflows/package-scan.md end-to-end.
|
|
42
|
+
Preserve all workflow gates (init, scan invocation, report-write-and-commit composition).
|
|
43
|
+
</process>
|
|
@@ -55,4 +55,17 @@ Progress: {status.progress}%
|
|
|
55
55
|
**If error:**
|
|
56
56
|
Display the error message from the response. Suggest `/dgs:list-projects` to see available projects.
|
|
57
57
|
|
|
58
|
+
## 4. Commit PROJECTS.md if modified
|
|
59
|
+
|
|
60
|
+
The `projects list` call in step 2 regenerates PROJECTS.md. Commit it if changed:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
git -C "$(node -e "const{getPlanningRoot}=require('$HOME/.claude/deliver-great-systems/bin/lib/core.cjs');process.stdout.write(getPlanningRoot(process.cwd()))")" diff --quiet PROJECTS.md 2>/dev/null
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
If the above exits non-zero (file has changes):
|
|
67
|
+
```bash
|
|
68
|
+
node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" commit "chore(project): regenerate PROJECTS.md on switch" --push
|
|
69
|
+
```
|
|
70
|
+
|
|
58
71
|
</process>
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* summary-extract <path> [--fields] Extract structured data from SUMMARY.md
|
|
31
31
|
* state-snapshot Structured parse of STATE.md
|
|
32
32
|
* phase-plan-index <phase> Index plans with waves and status
|
|
33
|
+
* package-scan [--raw] Scan all repos for dependency vulnerabilities; writes committed report
|
|
33
34
|
* websearch <query> Search web via Brave API (if configured)
|
|
34
35
|
* [--limit N] [--freshness day|week|month]
|
|
35
36
|
*
|
|
@@ -790,6 +791,88 @@ async function main() {
|
|
|
790
791
|
break;
|
|
791
792
|
}
|
|
792
793
|
|
|
794
|
+
case 'final-commit-precondition': {
|
|
795
|
+
// REL-08 (Phase 157): pre-commit precondition gate. Aborts with
|
|
796
|
+
// `summary-frontmatter-mismatch` label when PLAN.md `requirements:` is
|
|
797
|
+
// non-empty AND SUMMARY.md `requirements_completed:` is empty. Read-only —
|
|
798
|
+
// never writes to the working tree.
|
|
799
|
+
const planIdx = args.indexOf('--plan');
|
|
800
|
+
const summaryIdx = args.indexOf('--summary');
|
|
801
|
+
const opts = {
|
|
802
|
+
plan: planIdx !== -1 ? args[planIdx + 1] : undefined,
|
|
803
|
+
summary: summaryIdx !== -1 ? args[summaryIdx + 1] : undefined,
|
|
804
|
+
};
|
|
805
|
+
return commands.cmdFinalCommitPrecondition(cwd, opts);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
case 'commit-verify-plan': {
|
|
809
|
+
// REL-01 (Phase 156): orchestrator-side commit + verification helper
|
|
810
|
+
// for /dgs:plan-phase. Commits a planner-emitted createdFiles list and
|
|
811
|
+
// verifies every reported path appears in HEAD; on mismatch, returns
|
|
812
|
+
// plan-commit-incomplete with working tree unchanged.
|
|
813
|
+
gateIdentity();
|
|
814
|
+
const message = args[1];
|
|
815
|
+
// --files <paths...> (collect args after --files until next --flag)
|
|
816
|
+
const filesIndex = args.indexOf('--files');
|
|
817
|
+
const createdFiles = filesIndex !== -1
|
|
818
|
+
? args.slice(filesIndex + 1).filter(a => !a.startsWith('--'))
|
|
819
|
+
: [];
|
|
820
|
+
// --extra-files <paths...> (e.g. ROADMAP.md)
|
|
821
|
+
const extraIdx = args.indexOf('--extra-files');
|
|
822
|
+
const extraFiles = extraIdx !== -1
|
|
823
|
+
? args.slice(extraIdx + 1).filter(a => !a.startsWith('--'))
|
|
824
|
+
: [];
|
|
825
|
+
// --repo-cwd <path>
|
|
826
|
+
const repoCwdIdxV = args.indexOf('--repo-cwd');
|
|
827
|
+
const repoCwdV = repoCwdIdxV !== -1 ? args[repoCwdIdxV + 1] : undefined;
|
|
828
|
+
const pushV = args.includes('--push');
|
|
829
|
+
const result = commands.verifyPlanCommit(cwd, {
|
|
830
|
+
message,
|
|
831
|
+
createdFiles,
|
|
832
|
+
extraFiles,
|
|
833
|
+
repoCwd: repoCwdV,
|
|
834
|
+
push: pushV,
|
|
835
|
+
}, raw);
|
|
836
|
+
// verifyPlanCommit is a pure helper — emit output and exit non-zero
|
|
837
|
+
// on plan-commit-incomplete so the calling workflow can detect failure.
|
|
838
|
+
if (raw) {
|
|
839
|
+
process.stdout.write(JSON.stringify(result));
|
|
840
|
+
} else {
|
|
841
|
+
if (result.ok) {
|
|
842
|
+
process.stdout.write(result.hash || result.reason || 'ok');
|
|
843
|
+
} else {
|
|
844
|
+
process.stdout.write(`[${result.exitLabel}] ${result.reason}`);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
process.exit(result.ok ? 0 : 1);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
case 'compute-phase-sweep': {
|
|
851
|
+
// REL-02 (Phase 156): scope-bounded executor sweep helper.
|
|
852
|
+
// Returns the UNION of git-discovered phase-dir paths and the
|
|
853
|
+
// executor-reported modified_files list, scope-filtered to
|
|
854
|
+
// ${phasesDir}/${phaseDir}/ only.
|
|
855
|
+
const phasesDirIdx = args.indexOf('--phases-dir');
|
|
856
|
+
const phaseDirIdx = args.indexOf('--phase-dir');
|
|
857
|
+
const modifiedIdx = args.indexOf('--modified-files');
|
|
858
|
+
const phasesDirV = phasesDirIdx !== -1 ? args[phasesDirIdx + 1] : undefined;
|
|
859
|
+
const phaseDirV = phaseDirIdx !== -1 ? args[phaseDirIdx + 1] : undefined;
|
|
860
|
+
const modifiedFiles = modifiedIdx !== -1
|
|
861
|
+
? args.slice(modifiedIdx + 1).filter(a => !a.startsWith('--'))
|
|
862
|
+
: [];
|
|
863
|
+
const result = commands.computePhaseSweep(cwd, {
|
|
864
|
+
phasesDir: phasesDirV,
|
|
865
|
+
phaseDir: phaseDirV,
|
|
866
|
+
modifiedFiles,
|
|
867
|
+
}, raw);
|
|
868
|
+
if (raw) {
|
|
869
|
+
process.stdout.write(JSON.stringify(result));
|
|
870
|
+
} else {
|
|
871
|
+
process.stdout.write(`Swept: ${result.swept.length} | Dropped: ${result.dropped.length}`);
|
|
872
|
+
}
|
|
873
|
+
process.exit(result.error ? 1 : 0);
|
|
874
|
+
}
|
|
875
|
+
|
|
793
876
|
case 'verify-summary': {
|
|
794
877
|
const summaryPath = args[1];
|
|
795
878
|
const countIndex = args.indexOf('--check-count');
|
|
@@ -1123,6 +1206,7 @@ async function main() {
|
|
|
1123
1206
|
if (subcommand === 'complete') {
|
|
1124
1207
|
const nameIndex = args.indexOf('--name');
|
|
1125
1208
|
const archivePhases = args.includes('--archive-phases');
|
|
1209
|
+
const force = args.includes('--force');
|
|
1126
1210
|
// Collect --name value (everything after --name until next flag or end)
|
|
1127
1211
|
let milestoneName = null;
|
|
1128
1212
|
if (nameIndex !== -1) {
|
|
@@ -1133,7 +1217,7 @@ async function main() {
|
|
|
1133
1217
|
}
|
|
1134
1218
|
milestoneName = nameArgs.join(' ') || null;
|
|
1135
1219
|
}
|
|
1136
|
-
milestone.cmdMilestoneComplete(cwd, args[2], { name: milestoneName, archivePhases }, raw);
|
|
1220
|
+
milestone.cmdMilestoneComplete(cwd, args[2], { name: milestoneName, archivePhases, force }, raw);
|
|
1137
1221
|
} else {
|
|
1138
1222
|
error('Unknown milestone subcommand. Available: complete');
|
|
1139
1223
|
}
|
|
@@ -1211,7 +1295,7 @@ async function main() {
|
|
|
1211
1295
|
init.cmdInitPlanPhase(cwd, args[2], raw);
|
|
1212
1296
|
break;
|
|
1213
1297
|
case 'new-project':
|
|
1214
|
-
init.cmdInitNewProject(cwd, raw);
|
|
1298
|
+
init.cmdInitNewProject(cwd, args[2], raw);
|
|
1215
1299
|
break;
|
|
1216
1300
|
case 'new-milestone':
|
|
1217
1301
|
init.cmdInitNewMilestone(cwd, raw);
|
|
@@ -1697,6 +1781,7 @@ async function main() {
|
|
|
1697
1781
|
jobs.cmdJobsUpdateStep(cwd, args[2], args[3], args[4], { timestamp: timestampVal, error: errorVal }, raw);
|
|
1698
1782
|
} else if (subcommand === 'move') {
|
|
1699
1783
|
if (!args[2] || !args[3]) error('Usage: jobs move <file> <target-dir>');
|
|
1784
|
+
process.stderr.write('[DGS] Deprecation: "jobs move" is deprecated. Use "jobs set-status <version> --status <status>" for state transitions.\n');
|
|
1700
1785
|
jobs.cmdJobsMove(cwd, args[2], args[3], raw);
|
|
1701
1786
|
} else if (subcommand === 'create-milestone') {
|
|
1702
1787
|
const noCheckIdx = args.indexOf('--no-check');
|
|
@@ -1769,6 +1854,11 @@ async function main() {
|
|
|
1769
1854
|
} else if (subcommand === 'rollback') {
|
|
1770
1855
|
if (!args[2]) error('Usage: jobs rollback <version>');
|
|
1771
1856
|
jobs.cmdJobsRollback(cwd, args[2], raw);
|
|
1857
|
+
} else if (subcommand === 'generate-review') {
|
|
1858
|
+
const review = require('./lib/review.cjs');
|
|
1859
|
+
const detailed = args.includes('--detailed');
|
|
1860
|
+
const versionArg = args.slice(2).filter(a => a !== '--detailed' && a !== '--raw')[0];
|
|
1861
|
+
review.cmdJobsGenerateReview(cwd, versionArg, raw, detailed);
|
|
1772
1862
|
} else if (subcommand === 'set-status') {
|
|
1773
1863
|
const version = args[2];
|
|
1774
1864
|
const statusIdx = args.indexOf('--status');
|
|
@@ -1785,7 +1875,7 @@ async function main() {
|
|
|
1785
1875
|
error(err.message);
|
|
1786
1876
|
}
|
|
1787
1877
|
} else {
|
|
1788
|
-
error('Unknown jobs subcommand: ' + (subcommand || '(none)') + '. Available: parse, update-step, move, find-job, update-header, insert-steps, insert-gap-fix-section, insert-phase-gap-fix, create-milestone, milestone-preview, list-jobs, cancel-job, health, dry-run, generate-summary, record-start-shas, rollback, set-status');
|
|
1878
|
+
error('Unknown jobs subcommand: ' + (subcommand || '(none)') + '. Available: parse, update-step, move, find-job, update-header, insert-steps, insert-gap-fix-section, insert-phase-gap-fix, create-milestone, milestone-preview, list-jobs, cancel-job, health, dry-run, generate-summary, generate-review, record-start-shas, rollback, set-status');
|
|
1789
1879
|
}
|
|
1790
1880
|
break;
|
|
1791
1881
|
}
|
|
@@ -1823,6 +1913,12 @@ async function main() {
|
|
|
1823
1913
|
break;
|
|
1824
1914
|
}
|
|
1825
1915
|
|
|
1916
|
+
case 'package-scan': {
|
|
1917
|
+
const packageScan = require('./lib/package-scan.cjs');
|
|
1918
|
+
packageScan.cmdPackageScan(cwd, args, raw);
|
|
1919
|
+
break;
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1826
1922
|
case 'phase-uat-status': {
|
|
1827
1923
|
const autoTest = require('./lib/auto-test.cjs');
|
|
1828
1924
|
autoTest.cmdPhaseUatStatus(cwd, args[1], raw);
|
|
@@ -1971,7 +2067,7 @@ async function main() {
|
|
|
1971
2067
|
case 'complete-quick':
|
|
1972
2068
|
case 'quick-complete': {
|
|
1973
2069
|
const { cmdQuickComplete } = require('./lib/quick.cjs');
|
|
1974
|
-
cmdQuickComplete(cwd);
|
|
2070
|
+
cmdQuickComplete(cwd, args);
|
|
1975
2071
|
break;
|
|
1976
2072
|
}
|
|
1977
2073
|
|
|
@@ -1984,8 +2080,15 @@ async function main() {
|
|
|
1984
2080
|
|
|
1985
2081
|
case 'quick': {
|
|
1986
2082
|
const subcommand = args[1];
|
|
2083
|
+
if (subcommand === 'generate-review') {
|
|
2084
|
+
const review = require('./lib/review.cjs');
|
|
2085
|
+
const detailed = args.includes('--detailed');
|
|
2086
|
+
const slugArg = args.slice(2).filter(a => a !== '--detailed' && a !== '--raw')[0];
|
|
2087
|
+
review.cmdQuickGenerateReview(cwd, slugArg, raw, detailed);
|
|
2088
|
+
break;
|
|
2089
|
+
}
|
|
1987
2090
|
if (subcommand !== 'finalize') {
|
|
1988
|
-
error('Usage: dgs-tools quick
|
|
2091
|
+
error('Usage: dgs-tools quick <generate-review [slug]|finalize <quick_id> [options]>');
|
|
1989
2092
|
return;
|
|
1990
2093
|
}
|
|
1991
2094
|
gateIdentity();
|
|
@@ -2033,6 +2136,18 @@ async function main() {
|
|
|
2033
2136
|
break;
|
|
2034
2137
|
}
|
|
2035
2138
|
|
|
2139
|
+
case 'fast-route': {
|
|
2140
|
+
// REL-05/06: fast-mode commit routing helper. Surveys planning root +
|
|
2141
|
+
// registered sub-repos for dirty state, then computes a routing decision.
|
|
2142
|
+
// Used by /dgs:fast workflow F0.5 (pre-edit dirt check, REL-06) and F4/F5
|
|
2143
|
+
// (post-edit routing, REL-05). Exits 1 if action == 'fail'.
|
|
2144
|
+
const { surveyDirty, decideRouting } = require('./lib/fast-routing.cjs');
|
|
2145
|
+
const survey = surveyDirty(cwd);
|
|
2146
|
+
const decision = decideRouting(survey);
|
|
2147
|
+
process.stdout.write(JSON.stringify({ survey, decision }, null, 2));
|
|
2148
|
+
process.exit(decision.action === 'fail' ? 1 : 0);
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2036
2151
|
default:
|
|
2037
2152
|
error(`Unknown command: ${command}`);
|
|
2038
2153
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// deliver-great-systems/bin/lib/audit-tolerance.cjs
|
|
2
|
+
// REL-10: cross-reference matrix for /dgs:audit-milestone status determination.
|
|
3
|
+
// Extends the existing 5d matrix with soft-tolerance for empty requirements_completed
|
|
4
|
+
// when VERIFICATION explicitly lists the ID and status: passed.
|
|
5
|
+
//
|
|
6
|
+
// Soft-warning channel: 'summary-frontmatter-empty-but-verified' — distinct from
|
|
7
|
+
// real partials. Surfaces under audit JSON `soft_warnings.summary_frontmatter_empty_but_verified`,
|
|
8
|
+
// NOT under `gaps.requirements`. Removal trigger: 3 consecutive milestones ship
|
|
9
|
+
// with zero soft-warnings → drop the tolerance row, restore strict default.
|
|
10
|
+
|
|
11
|
+
const SOFT_WARNING_EMPTY_BUT_VERIFIED = 'summary-frontmatter-empty-but-verified';
|
|
12
|
+
|
|
13
|
+
function applyMatrix(input) {
|
|
14
|
+
const {
|
|
15
|
+
verificationStatus,
|
|
16
|
+
requirementsClaimed = [],
|
|
17
|
+
summaryRequirementsCompleted = [],
|
|
18
|
+
reqId,
|
|
19
|
+
strictAudit = false,
|
|
20
|
+
} = input;
|
|
21
|
+
|
|
22
|
+
if (!reqId) {
|
|
23
|
+
return { status: 'unsatisfied', softWarning: null };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// gaps_found short-circuits everything — VERIFICATION explicitly failed.
|
|
27
|
+
if (verificationStatus === 'gaps_found') {
|
|
28
|
+
return { status: 'unsatisfied', softWarning: null };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const summaryListsId = summaryRequirementsCompleted.includes(reqId);
|
|
32
|
+
const verificationListsId = requirementsClaimed.includes(reqId);
|
|
33
|
+
|
|
34
|
+
// Happy path: VERIFICATION passed AND SUMMARY explicitly populated.
|
|
35
|
+
if (verificationStatus === 'passed' && summaryListsId) {
|
|
36
|
+
return { status: 'satisfied', softWarning: null };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Tolerance path: VERIFICATION passed AND lists ID, SUMMARY empty/missing, NOT strict.
|
|
40
|
+
if (
|
|
41
|
+
verificationStatus === 'passed' &&
|
|
42
|
+
!summaryListsId &&
|
|
43
|
+
verificationListsId &&
|
|
44
|
+
!strictAudit
|
|
45
|
+
) {
|
|
46
|
+
return { status: 'satisfied', softWarning: SOFT_WARNING_EMPTY_BUT_VERIFIED };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Strict path: same input as tolerance path but --strict-audit forces partial.
|
|
50
|
+
if (
|
|
51
|
+
verificationStatus === 'passed' &&
|
|
52
|
+
!summaryListsId &&
|
|
53
|
+
verificationListsId &&
|
|
54
|
+
strictAudit
|
|
55
|
+
) {
|
|
56
|
+
return { status: 'partial', softWarning: null };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// VERIFICATION passed but does NOT list the ID, SUMMARY empty → real partial.
|
|
60
|
+
// (Tolerance must NOT mask this — the safety net per spec.)
|
|
61
|
+
if (verificationStatus === 'passed' && !summaryListsId && !verificationListsId) {
|
|
62
|
+
return { status: 'partial', softWarning: null };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// VERIFICATION missing → unsatisfied (orphan-style).
|
|
66
|
+
if (verificationStatus === 'missing') {
|
|
67
|
+
if (summaryListsId) {
|
|
68
|
+
return { status: 'partial', softWarning: null };
|
|
69
|
+
}
|
|
70
|
+
return { status: 'unsatisfied', softWarning: null };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Default fallthrough.
|
|
74
|
+
return { status: 'unsatisfied', softWarning: null };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = { applyMatrix, SOFT_WARNING_EMPTY_BUT_VERIFIED };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// deliver-great-systems/bin/lib/audit-tolerance.test.cjs
|
|
2
|
+
// REL-10 regression test scaffold — initially RED. Turns GREEN after plan 03
|
|
3
|
+
// extends the audit cross-reference matrix with soft-tolerance + adds
|
|
4
|
+
// --strict-audit flag handling.
|
|
5
|
+
|
|
6
|
+
const test = require('node:test');
|
|
7
|
+
const assert = require('node:assert');
|
|
8
|
+
|
|
9
|
+
// REL-10 surfaces a function applyMatrix(input) -> { status, softWarning? }
|
|
10
|
+
// in a new module bin/lib/audit-tolerance.cjs. Plan 03 implements it.
|
|
11
|
+
// applyMatrix input shape:
|
|
12
|
+
// { verificationStatus: 'passed'|'gaps_found'|'missing',
|
|
13
|
+
// requirementsClaimed: string[], // from VERIFICATION.md frontmatter
|
|
14
|
+
// summaryRequirementsCompleted: string[], // from SUMMARY.md frontmatter (canonical key)
|
|
15
|
+
// reqId: string, // requirement ID under evaluation
|
|
16
|
+
// strictAudit: boolean // --strict-audit flag
|
|
17
|
+
// }
|
|
18
|
+
// applyMatrix output:
|
|
19
|
+
// { status: 'satisfied'|'partial'|'unsatisfied',
|
|
20
|
+
// softWarning: 'summary-frontmatter-empty-but-verified' | null
|
|
21
|
+
// }
|
|
22
|
+
|
|
23
|
+
function getApplyMatrix() {
|
|
24
|
+
try {
|
|
25
|
+
return require('./audit-tolerance.cjs').applyMatrix;
|
|
26
|
+
} catch (err) {
|
|
27
|
+
assert.fail('REL-10 audit-tolerance module not yet implemented: bin/lib/audit-tolerance.cjs (plan 03 task)');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
test('REL-10: empty SUMMARY + VERIFICATION lists ID + status passed → satisfied + soft-warning', () => {
|
|
32
|
+
const applyMatrix = getApplyMatrix();
|
|
33
|
+
const result = applyMatrix({
|
|
34
|
+
verificationStatus: 'passed',
|
|
35
|
+
requirementsClaimed: ['TEST-01'],
|
|
36
|
+
summaryRequirementsCompleted: [],
|
|
37
|
+
reqId: 'TEST-01',
|
|
38
|
+
strictAudit: false,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
assert.strictEqual(result.status, 'satisfied');
|
|
42
|
+
assert.strictEqual(result.softWarning, 'summary-frontmatter-empty-but-verified');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('REL-10: --strict-audit preserves old strict behaviour (empty SUMMARY → partial)', () => {
|
|
46
|
+
const applyMatrix = getApplyMatrix();
|
|
47
|
+
const result = applyMatrix({
|
|
48
|
+
verificationStatus: 'passed',
|
|
49
|
+
requirementsClaimed: ['TEST-01'],
|
|
50
|
+
summaryRequirementsCompleted: [],
|
|
51
|
+
reqId: 'TEST-01',
|
|
52
|
+
strictAudit: true,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
assert.strictEqual(result.status, 'partial');
|
|
56
|
+
// soft-warning may be null OR may still flag; spec is silent; canonical: null under strict
|
|
57
|
+
assert.strictEqual(result.softWarning || null, null);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('REL-10: tolerance does NOT mask real partials (VERIFICATION not listing ID still partial)', () => {
|
|
61
|
+
const applyMatrix = getApplyMatrix();
|
|
62
|
+
const result = applyMatrix({
|
|
63
|
+
verificationStatus: 'passed',
|
|
64
|
+
requirementsClaimed: ['OTHER-01'], // does NOT list TEST-01
|
|
65
|
+
summaryRequirementsCompleted: [],
|
|
66
|
+
reqId: 'TEST-01',
|
|
67
|
+
strictAudit: false,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
assert.strictEqual(result.status, 'partial');
|
|
71
|
+
assert.strictEqual(result.softWarning || null, null);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('REL-10: gaps_found VERIFICATION → unsatisfied regardless of SUMMARY shape', () => {
|
|
75
|
+
const applyMatrix = getApplyMatrix();
|
|
76
|
+
const result = applyMatrix({
|
|
77
|
+
verificationStatus: 'gaps_found',
|
|
78
|
+
requirementsClaimed: ['TEST-01'],
|
|
79
|
+
summaryRequirementsCompleted: ['TEST-01'],
|
|
80
|
+
reqId: 'TEST-01',
|
|
81
|
+
strictAudit: false,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
assert.strictEqual(result.status, 'unsatisfied');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('REL-10: SUMMARY explicitly populated + VERIFICATION passed → satisfied (no soft-warning)', () => {
|
|
88
|
+
const applyMatrix = getApplyMatrix();
|
|
89
|
+
const result = applyMatrix({
|
|
90
|
+
verificationStatus: 'passed',
|
|
91
|
+
requirementsClaimed: ['TEST-01'],
|
|
92
|
+
summaryRequirementsCompleted: ['TEST-01'],
|
|
93
|
+
reqId: 'TEST-01',
|
|
94
|
+
strictAudit: false,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
assert.strictEqual(result.status, 'satisfied');
|
|
98
|
+
assert.strictEqual(result.softWarning || null, null);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// REL-10 sentinel — flag this file as a Wave-0 RED scaffold for plan 03.
|