@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
@@ -0,0 +1,40 @@
1
+ // deliver-great-systems/bin/lib/wave-0-template-rename.test.cjs
2
+ // REL-03 convergence test scaffold — initially RED. Turns GREEN after plan 02
3
+ // lands the planner-prompt edits and the VALIDATION.md template rename.
4
+
5
+ const test = require('node:test');
6
+ const assert = require('node:assert');
7
+ const fs = require('node:fs');
8
+ const path = require('node:path');
9
+
10
+ const repoRoot = path.resolve(__dirname, '../../..');
11
+ const planner = path.join(repoRoot, 'agents/dgs-planner.md');
12
+ const template = path.join(repoRoot, 'deliver-great-systems/templates/VALIDATION.md');
13
+
14
+ test('REL-03: VALIDATION template uses heading "Wave 0 Task Requirements"', () => {
15
+ const content = fs.readFileSync(template, 'utf-8');
16
+ assert.match(content, /## Wave 0 Task Requirements/, 'template must use new heading');
17
+ });
18
+
19
+ test('REL-03: VALIDATION template no longer uses "Wave 0 Requirements" as a section heading', () => {
20
+ const content = fs.readFileSync(template, 'utf-8');
21
+ // The OLD heading must NOT exist as a section heading (paragraph mentions are OK)
22
+ assert.doesNotMatch(content, /^## Wave 0 Requirements\s*$/m, 'old heading must be gone');
23
+ });
24
+
25
+ test('REL-03: planner prompt unambiguously states "Plans are numbered starting at 01"', () => {
26
+ const content = fs.readFileSync(planner, 'utf-8');
27
+ assert.match(content, /Plans are numbered starting at 01/, 'planner must state plan-numbering rule');
28
+ });
29
+
30
+ test('REL-03: planner prompt explicitly forbids plan: 00 and wave: 0', () => {
31
+ const content = fs.readFileSync(planner, 'utf-8');
32
+ assert.match(content, /Never create a plan with `plan: 00` or `wave: 0`/, 'planner must forbid plan: 00 / wave: 0');
33
+ });
34
+
35
+ test('REL-03: planner prompt mentions Wave 0 lives as Task 0 inside plan 01', () => {
36
+ const content = fs.readFileSync(planner, 'utf-8');
37
+ assert.match(content, /Wave 0 work lives as Task 0 inside plan 01/, 'planner must locate Wave 0 inside plan 01');
38
+ });
39
+
40
+ // REL-03 sentinel — flag this file as a Wave-0 RED scaffold for plan 02.
@@ -21,6 +21,7 @@ const { execGit, output, error, loadConfig } = require('./core.cjs');
21
21
  const { getLocalConfigPath } = require('./config.cjs');
22
22
  const { getPlanningRoot } = require('./paths.cjs');
23
23
  const { parseReposMd } = require('./repos.cjs');
24
+ const { extractFrontmatter } = require('./frontmatter.cjs');
24
25
 
25
26
  // ─── Internal helpers ─────────────────────────────────────────────────────────
26
27
 
@@ -223,6 +224,27 @@ function _findMainCheckoutPath(cwd, repoName) {
223
224
  return _resolveRepoAbsPath(cwd, repo.path);
224
225
  }
225
226
 
227
+ /**
228
+ * Read active milestone version from projects/{project}/STATE.md frontmatter.
229
+ * Returns null on any failure — callers must not throw.
230
+ * @param {string} cwd
231
+ * @param {string} project
232
+ * @returns {string|null}
233
+ */
234
+ function _readMilestoneVersion(cwd, project) {
235
+ try {
236
+ const statePath = path.join(cwd, 'projects', project, 'STATE.md');
237
+ if (!fs.existsSync(statePath)) return null;
238
+ const content = fs.readFileSync(statePath, 'utf-8');
239
+ const fm = extractFrontmatter(content);
240
+ const v = fm && fm.milestone;
241
+ if (typeof v === 'string' && /^v\d+(\.\d+)?$/.test(v)) return v;
242
+ return null;
243
+ } catch {
244
+ return null;
245
+ }
246
+ }
247
+
226
248
  // ─── Exported command functions ───────────────────────────────────────────────
227
249
 
228
250
  /**
@@ -319,11 +341,15 @@ function cmdWorktreesCreate(cwd, args) {
319
341
  process.stderr.write('Re-run setup: dgs-tools worktrees setup ' + slug + '\n');
320
342
  }
321
343
 
322
- // Write state
344
+ // Write state. milestone_version is captured from STATE.md frontmatter at
345
+ // creation time for milestone-type worktrees; quick worktrees and
346
+ // unresolvable STATE reads degrade cleanly to null.
347
+ const milestoneVersion = type === 'milestone' ? _readMilestoneVersion(cwd, project) : null;
323
348
  _setWorktreeState(cwd, project, slug, {
324
349
  type: type,
325
350
  mode: mode,
326
351
  setup_complete: setupComplete,
352
+ milestone_version: milestoneVersion,
327
353
  repos: { [repo.name]: worktreePath },
328
354
  });
329
355
 
@@ -852,6 +852,82 @@ describe('checkWorktreeHealth', () => {
852
852
  });
853
853
  });
854
854
 
855
+ // ─── cmdWorktreesCreate — milestone_version ──────────────────────────────────
856
+
857
+ describe('cmdWorktreesCreate — milestone_version', () => {
858
+ let env;
859
+ afterEach(() => { if (env) env.cleanup(); });
860
+
861
+ it('records milestone_version from STATE.md frontmatter on milestone worktree entries', () => {
862
+ env = createTestEnv();
863
+ // Overwrite STATE.md with real frontmatter containing a milestone field
864
+ fs.writeFileSync(
865
+ path.join(env.planDir, 'projects', 'tp', 'STATE.md'),
866
+ '---\nmilestone: v42.0\nstatus: executing\n---\n\n# State\n'
867
+ );
868
+ // Commit STATE update so git state is clean (test parity)
869
+ execSync('git add .', { cwd: env.planDir, stdio: 'pipe' });
870
+ execSync('git commit -m "state"', { cwd: env.planDir, stdio: 'pipe', env: { ...process.env, ...GIT_ENV } });
871
+
872
+ const result = runCmd(env.planDir, 'worktrees create ms-versioned --type milestone');
873
+ assert.ok(result.created);
874
+ assert.equal(result.type, 'milestone');
875
+
876
+ const config = readLocalConfig(env.planDir);
877
+ const entry = config.projects.tp.worktrees['ms-versioned'];
878
+ assert.ok(entry, 'worktree entry should exist');
879
+ assert.equal(entry.type, 'milestone');
880
+ assert.equal(entry.milestone_version, 'v42.0', 'milestone_version should be read from STATE.md frontmatter');
881
+ assert.ok(entry.repos && entry.repos['code-repo'], 'repos field should still be populated');
882
+ });
883
+
884
+ it('falls back to milestone_version: null when STATE.md has no milestone field', () => {
885
+ env = createTestEnv();
886
+ // STATE.md with no frontmatter at all (default from createTestEnv)
887
+ // createTestEnv already writes `# State\nStatus: planning\n` — no frontmatter.
888
+
889
+ const result = runCmd(env.planDir, 'worktrees create ms-nofm --type milestone');
890
+ assert.ok(result.created);
891
+
892
+ const config = readLocalConfig(env.planDir);
893
+ const entry = config.projects.tp.worktrees['ms-nofm'];
894
+ assert.ok(entry, 'worktree entry should exist — creation must not fail on missing frontmatter');
895
+ assert.equal(entry.type, 'milestone');
896
+ assert.equal(entry.milestone_version, null, 'milestone_version should be null when no milestone frontmatter');
897
+ });
898
+
899
+ it('falls back to milestone_version: null when STATE.md is missing entirely', () => {
900
+ env = createTestEnv();
901
+ // Delete STATE.md
902
+ fs.rmSync(path.join(env.planDir, 'projects', 'tp', 'STATE.md'));
903
+
904
+ const result = runCmd(env.planDir, 'worktrees create ms-nostate --type milestone');
905
+ assert.ok(result.created, 'creation must succeed even when STATE.md is missing');
906
+
907
+ const config = readLocalConfig(env.planDir);
908
+ const entry = config.projects.tp.worktrees['ms-nostate'];
909
+ assert.ok(entry);
910
+ assert.equal(entry.milestone_version, null);
911
+ });
912
+
913
+ it('falls back to milestone_version: null when frontmatter milestone value is malformed', () => {
914
+ env = createTestEnv();
915
+ fs.writeFileSync(
916
+ path.join(env.planDir, 'projects', 'tp', 'STATE.md'),
917
+ '---\nmilestone: not-a-version\n---\n\n# State\n'
918
+ );
919
+ execSync('git add .', { cwd: env.planDir, stdio: 'pipe' });
920
+ execSync('git commit -m "state"', { cwd: env.planDir, stdio: 'pipe', env: { ...process.env, ...GIT_ENV } });
921
+
922
+ const result = runCmd(env.planDir, 'worktrees create ms-malformed --type milestone');
923
+ assert.ok(result.created);
924
+
925
+ const config = readLocalConfig(env.planDir);
926
+ const entry = config.projects.tp.worktrees['ms-malformed'];
927
+ assert.equal(entry.milestone_version, null, 'malformed version string should degrade to null');
928
+ });
929
+ });
930
+
855
931
  // ─── main checkout invariant ─────────────────────────────────────────────────
856
932
 
857
933
  describe('main checkout invariant', () => {
@@ -0,0 +1,60 @@
1
+ # Agent-Step Reliability
2
+
3
+ Reference for the silent-skip diagnostic pattern and the canonical fail-loudly contract that DGS workflows and agents in milestone v23.2 ("Agent-Step Reliability") and beyond must satisfy.
4
+
5
+ ## The silent-skip diagnostic pattern
6
+
7
+ A workflow or agent step that should commit something — or copy a value from an upstream source — silently doesn't. Five concrete instances surfaced during v23.1 (ideas #25-#29 in `projects/gsd/ideas/done/`).
8
+
9
+ Symptoms: the step's caller logs success; the user discovers the gap later via `git status`, audit reports, or noticing a fresh clone is missing files. Because the operation appears to have succeeded, no remediation message reaches the user at the moment the failure occurs — only at debug time, possibly milestones later.
10
+
11
+ Family signature: any "must happen" side-effect step where the agent or workflow has shell access but the success of the side-effect is **not verified in the same control-flow scope**. The classic instance is a `commit --files <list>` invocation whose `<list>` was not derived from the prior scaffold step's actual writes — so the commit "succeeds" while the scaffolded files remain untracked. The same shape applies to copy-from-upstream steps (e.g., a SUMMARY writer that fails to copy the PLAN's `requirements` array into `requirements_completed`).
12
+
13
+ The silent-skip label refers to the silent absence of a side-effect that the surrounding workflow assumed had happened. Recognising the family signature is the first defence against re-introducing it in new workflows.
14
+
15
+ ## Rejected anti-features (with rationale)
16
+
17
+ The following four solutions were considered during the v23.2 spec rounds and explicitly rejected. They are documented here so future contributors do not propose them again without reading the rationale.
18
+
19
+ - **File locking / concurrent-orchestrator handling.** DGS is single-user, single-shell. No parallel orchestrators ever run on the same phase directory. Adding lock files, advisory locks, or coordination primitives would solve a problem we do not have, at the cost of new failure modes (stale locks after crashes, lock-contention spurious failures). (Source: spec round 3 disposition #3.)
20
+ - **Generic agent-output verification framework.** Out of scope for this milestone — would be a much larger investment (declarative output schemas, schema registry, runtime validators, error-mapping infrastructure). Targeted per-step assertions only: each known offender gets a precise post-condition check at the exact place its silent-skip manifested. The targeted approach matches actual recurrence patterns and keeps the feature surface small. (Source: spec Non-Goals.)
21
+ - **Database-backed state model.** State remains Markdown-in-Git per `codebase/ARCHITECTURE.md` ("State is always Markdown-in-Git. No database, no long-lived process."). Git status — what is committed, what is staged, what is untracked — IS the source of truth for whether a step's side-effect happened. A separate database would only duplicate that ground truth and introduce divergence bugs.
22
+ - **Auto-fixing existing untracked artifacts in already-completed milestones.** Forward-looking only; auto-fix risks unintended side-effects on already-archived state and adds maintenance burden disproportionate to value vs catching new instances early. Historical untracked artifacts are addressed by ad-hoc quick tasks (e.g., the v23.1 audit cleanup) when discovered, not by automated sweeps over archived milestones. (Source: spec Non-Goals + round 1 disposition #3.)
23
+
24
+ ## Canonical fail-loudly contract
25
+
26
+ Failures in the silent-skip family MUST satisfy ALL of the following four properties (the "operational definition of fail loudly", taken verbatim from the spec Goals):
27
+
28
+ 1. **Exit non-zero with a documented label** — the failure produces a non-zero process exit AND emits a named label (see the "Named exit-code labels" registry in `references/workflow-conventions.md`). Labels — not numeric codes — are what users grep for in remediation messages and search documentation by.
29
+ 2. **Leave the working tree in the same state as before the offending step** — no partial commits, no half-written scaffolds, no orphan staged files. Either the step's full intent landed in HEAD, or none of it did.
30
+ 3. **Print a 1-3 line user-facing message including the recommended remediation command** — concise, actionable, and pointing at a single next command the user can run to recover (e.g., `Run: dgs-tools commit --files <missing-paths>`).
31
+ 4. **Be discoverable in `dgs-tools health`** — so a user who lost the live output (closed terminal, lost session) can reproduce the diagnosis later via the standing health check.
32
+
33
+ (Health-check coverage for the AGENT-13 family lands in phases 156 + 158 of milestone v23.2.)
34
+
35
+ ## Named exit-code labels (silent-skip family)
36
+
37
+ ### `summary-frontmatter-mismatch`
38
+
39
+ **Source:** REL-08 (idea #28 closure, Phase 157).
40
+ **Where it fires:** `dgs-tools final-commit-precondition` CLI; invoked at the top of the executor's `<final_commit>` step (step 0) before any commit attempt.
41
+ **What it checks:** PLAN.md frontmatter `requirements:` is non-empty AND the to-be-written SUMMARY.md frontmatter `requirements_completed:` is empty (canonical key — the legacy hyphen variant is also accepted via the dual-read in `cmdSummaryExtract`, but new SUMMARYs must use underscore).
42
+
43
+ **On fire:**
44
+ - Exit non-zero with the label in stderr.
45
+ - 1-3 line user-facing message naming the missing IDs and the recommended remediation ("Re-run executor or manually populate before committing.").
46
+ - Working tree is unchanged from when the executor started `<final_commit>`.
47
+ - Discoverable via `/dgs:health` (downstream — REL-08 ships the gate; the health surfacing is a future enhancement).
48
+
49
+ **Remediation:**
50
+ 1. Inspect the to-be-written SUMMARY.md against the PLAN.md `requirements:` field.
51
+ 2. If the executor produced an empty `requirements_completed` despite non-empty PLAN, the writer regression has fired — re-run the executor (which now uses the canonical writer in `bin/lib/summary-frontmatter.cjs`).
52
+ 3. If you intentionally want to mark the plan complete without claiming the requirements, either remove the PLAN.md `requirements:` field OR proceed with a manual edit and re-invoke the precondition.
53
+
54
+ **Related companion:** `plan-commit-incomplete` (REL-01, Phase 156) — same fail-loudly shape applied to the planner's `git_commit` step.
55
+
56
+ ## See also
57
+
58
+ - `references/workflow-conventions.md` — the `scaffolded_files` contract and the named exit-code label registry that operationalise this reference.
59
+ - `references/conflict-resolution.md` — broader DGS conflict-handling patterns; complementary to the silent-skip family but distinct (conflicts are loud failures already).
60
+ - `specs/spec-agent-step-reliability-detect-and-prevent-silently-skipped-commit-steps.md` — the source spec that derived this reference (milestone v23.2).
@@ -64,3 +64,7 @@ Conflict Resolution Summary:
64
64
  - {S} semantic warnings
65
65
  - Report: {path to RESOLUTION-REPORT.md}
66
66
  ```
67
+
68
+ ## See also
69
+
70
+ - [Agent-Step Reliability](agent-step-reliability.md) — silent-skip diagnostic pattern; rejected anti-features; canonical fail-loudly contract.
@@ -25,6 +25,8 @@ includes_tier: null
25
25
  files:
26
26
  - path: "PROJECT.md"
27
27
  category: "project"
28
+ - path: "docs/product/PRODUCT-SUMMARY.md"
29
+ category: "product"
28
30
  - path: "STATE.md"
29
31
  category: "state"
30
32
  - path: "config.json"
@@ -46,6 +48,8 @@ files:
46
48
  category: "requirements"
47
49
  - path: "REPOS.md"
48
50
  category: "repos"
51
+ - path: "docs/product/ARCHITECTURE.md"
52
+ category: "product-architecture"
49
53
  dynamic:
50
54
  - type: "glob"
51
55
  pattern: "codebase/**/*.md"
@@ -0,0 +1,151 @@
1
+ # Package Scan Configuration
2
+
3
+ User-facing reference for `/dgs:package-scan` configuration keys, tool installation, and report placement.
4
+
5
+ ## Shared config keys (`config.json`)
6
+
7
+ ### `testing.packages.tool`
8
+ Tool cascade selection.
9
+
10
+ - **Values:** `auto` (default), `snyk`, `osv`, `native`
11
+ - **Default:** `auto` — cascade Snyk → OSV-Scanner → ecosystem-native tool based on availability
12
+ - **When to pin:** lock to `snyk` in CI, or to `osv` when Snyk is unavailable, to catch regressions loudly rather than silently falling back. Pinned tool unavailable = scan fails with install hint (does NOT fall through the cascade).
13
+
14
+ Set via: `dgs-tools config-set testing.packages.tool snyk`
15
+
16
+ ### `testing.packages.severity_threshold`
17
+ Minimum severity to include in the report.
18
+
19
+ - **Values:** `critical`, `high`, `medium`, `low`
20
+ - **Default:** `low` (include everything)
21
+ - **Filtering lands in Phase 153.** The key already exists (Phase 150) and is validated at set-time, but the filtering behaviour is P1.
22
+
23
+ Set via: `dgs-tools config-set testing.packages.severity_threshold high`
24
+
25
+ ### `testing.packages.include_dev_dependencies`
26
+ Whether to scan devDependencies (npm / pip / etc.).
27
+
28
+ - **Values:** `true`, `false`
29
+ - **Default:** `true`
30
+ - **Effect on tool argv:** Snyk → adds `--production` flag when false; npm-audit → adds `--omit=dev`; other ecosystems' tools behave idiomatically.
31
+
32
+ Set via: `dgs-tools config-set testing.packages.include_dev_dependencies false`
33
+
34
+ ### `testing.packages.timeout_seconds`
35
+ Per-scan-invocation timeout.
36
+
37
+ - **Values:** integer between 10 and 3600
38
+ - **Default:** `300` (5 minutes)
39
+
40
+ Set via: `dgs-tools config-set testing.packages.timeout_seconds 600`
41
+
42
+ ### `testing.packages.snyk_org`
43
+ Snyk org UUID. When set and the tool is Snyk, the scan argv gets `--org=<ID>` appended so multi-org Snyk accounts resolve to the correct organization without needing `SNYK_CFG_ORG` exported.
44
+
45
+ - **Values:** Snyk org UUID string (e.g., `5cb2d43f-6064-4fe2-80f8-4a14cef84a5a`), or `null` to omit.
46
+ - **Default:** `null` (no `--org` flag appended; Snyk uses the account's default org).
47
+ - **Precedence:** `config.local.json` wins over `config.json` (consistent with `snyk_token`).
48
+ - **Report visibility:** the chosen `snyk_org` is emitted in the report YAML frontmatter as `snyk_org: "<ID>"` for auditability.
49
+
50
+ Set via: `dgs-tools config-set testing.packages.snyk_org <UUID>` (shared) or `dgs-tools config-local-set testing.packages.snyk_org <UUID>` (per-machine override).
51
+
52
+ ## Local-only config keys (`config.local.json`)
53
+
54
+ ### `testing.packages.snyk_token`
55
+ Snyk API token. **Never commit to `config.json`** — this key is gitignored.
56
+
57
+ Set via: `dgs-tools config-local-set testing.packages.snyk_token <your-token>`
58
+
59
+ Get your token from: https://app.snyk.io/account
60
+
61
+ ## Tool installation
62
+
63
+ ### Snyk
64
+ - Install: `npm install -g snyk`
65
+ - Authenticate: either `snyk auth` (interactive browser, stores credential in `~/.config/configstore/snyk.json`) OR `dgs-tools config-local-set testing.packages.snyk_token <token>` OR set `SNYK_TOKEN=<token>` in your shell env.
66
+ - Priority order: `config.local.json testing.packages.snyk_token` → `SNYK_TOKEN` env → `snyk config get api` → `snyk whoami` (configstore-OAuth from `snyk auth`) → none.
67
+ - The fourth probe (`snyk whoami`) detects users who authenticated via the browser-OAuth flow without setting a token; DGS then lets the Snyk CLI consult its own configstore at invocation time (no token is read by DGS).
68
+
69
+ ### OSV-Scanner
70
+ - Install: https://github.com/google/osv-scanner/releases (single binary)
71
+ - No authentication required.
72
+ - Covers all ecosystems in one invocation via `osv-scanner --json -r .`.
73
+
74
+ ### Native fallbacks
75
+ - Node.js: `npm` (bundled with Node)
76
+ - Python: `pip install pip-audit`
77
+ - Go: `go install golang.org/x/vuln/cmd/govulncheck@latest`
78
+ - Ruby: `gem install bundler-audit`
79
+ - Java: no standard native tool (scan falls back to `no_native_tool_for_ecosystem` outcome — use Snyk or OSV-Scanner for Maven/Gradle).
80
+
81
+ ## Report placement
82
+
83
+ `/dgs:package-scan` writes its report file to one of three locations, resolved in this order:
84
+
85
+ 1. **Active phase** — when `config.local.json execution.active_context` points at a valid phase directory, report lands at `{phase-dir}/{phase}-PACKAGE-SCAN.md`.
86
+ 2. **Active milestone** — when a milestone slug is the active context (no phase), report lands at `{planning-root}/milestones/v{X}.{Y}-PACKAGE-SCAN.md`.
87
+ 3. **No active context** — report lands at `{planning-root}/PACKAGE-SCAN-{YYYY-MM-DD-HHmm}.md` (timestamped).
88
+
89
+ The report is atomically committed via `dgs-tools commit --files <report-path>`.
90
+
91
+ ## Report format
92
+
93
+ ### Frontmatter fields
94
+ - `type: package-scan` (constant)
95
+ - `date: YYYY-MM-DD` (UTC)
96
+ - `tool: snyk|osv-scanner|npm-audit|pip-audit|govulncheck|bundler-audit|mixed|none`
97
+ - `repos_scanned: <int>`
98
+ - `critical | high | medium | low: <int>` (severity counts)
99
+ - `duration: <int>` (seconds)
100
+ - `findings: [...]` (canonical entries)
101
+
102
+ ### Findings array entry
103
+ Each entry has: `id` (`pkg-NNN`), `test_source`, `gap_type`, `severity`, `resource_id` (`pkg@version`), `repo`, `manifest_path`, `title`, `description`, `remediation`, `reference`, `cve`, `cvss`, `dependency_chain`, `chain_available`, `direct_or_transitive`, `tool`.
104
+
105
+ ### Body
106
+ - Per-repo × severity summary table
107
+ - Per-severity sections (Critical → High → Medium → Low) with CVE, CVSS, dependency chain, fix command, and reference URL per finding
108
+ - `## Diagnostics` section when the scan emitted any (e.g., a pinned tool was unavailable for a specific ecosystem)
109
+
110
+ ## Private package / URL warning
111
+
112
+ When Snyk is the tool, scan output may include org-identifying URL parameters. The report itself includes a one-line warning. Active redaction is a future enhancement (Phase 153).
113
+
114
+ ## Gap-planner integration contract (PKG-29)
115
+
116
+ The report's YAML frontmatter `findings` array is the data contract between `/dgs:package-scan`
117
+ and `/dgs:plan-test-gaps`. Every entry carries the canonical ordered key-set (see §5a of the
118
+ test-gate spec) including `gap_type` and `repo`. The gap-planner:
119
+
120
+ 1. Reads the frontmatter via a hand-rolled YAML parser (`_parseEmittedYaml` in
121
+ `package-scan-report.cjs`).
122
+ 2. Groups findings by `gap_type` first (`dependency-security` vs `dependency-licence`), then by
123
+ `repo`.
124
+ 3. Generates one fix phase per (repo, gap_type) pair.
125
+
126
+ Cross-repo deduplication happens in the REPORT BODY (Cross-Repo Summary + Dependency Overlap
127
+ sections) — the YAML frontmatter retains one finding per repo so the gap-planner can slot work
128
+ into per-repo fix phases without inferring repo membership from aggregated summaries.
129
+
130
+ ## Plan provenance (PKG-33)
131
+
132
+ Each finding optionally carries `introduced_in_commit` (7-char SHA) and `introduced_in_plan`
133
+ (DGS plan-id like `152-03`). The `package-scan-provenance.cjs` module runs
134
+ `git log --format=%H%x00%s -S <package_name> -- <manifest_path>` in each repo directory and
135
+ extracts the plan-id from the OLDEST commit's subject via regex `/\b(\d{3}-\d{2})\b/`.
136
+
137
+ **Commit-message convention:** DGS atomic commits follow `type(NNN-NN): subject` (e.g.
138
+ `feat(149-01): implement scanner`). The regex matches the `NNN-NN` pattern in any position of
139
+ the commit subject, including inline mentions like `Merge branch feature/149-01-foo`.
140
+
141
+ **Resolution failures:** when git is unavailable, the directory is not a git repo, the manifest
142
+ file has no history, or the commit subject contains no plan-id, the fields are `null` and the
143
+ body renders `**Introduced in:** unknown`.
144
+
145
+ **Performance:** lookups are memoised per (repoDir, manifestPath, packageName) within a single
146
+ scan; the same dependency appearing in multiple workspaces costs one git subprocess call.
147
+
148
+ ## See also
149
+ - Spec: `specs/spec-package-dependency-scanning.md`
150
+ - Architecture: `projects/gsd/research/ARCHITECTURE.md`
151
+ - Pitfalls: `projects/gsd/research/PITFALLS.md`
@@ -12,20 +12,6 @@ Don't interrogate. Collaborate. Don't follow a script. Follow the thread.
12
12
 
13
13
  </philosophy>
14
14
 
15
- <the_goal>
16
-
17
- By the end of questioning, you need enough clarity to write a PROJECT.md that downstream phases can act on:
18
-
19
- - **Research** needs: what domain to research, what the user already knows, what unknowns exist
20
- - **Requirements** needs: clear enough vision to scope v1 features
21
- - **Roadmap** needs: clear enough vision to decompose into phases, what "done" looks like
22
- - **plan-phase** needs: specific requirements to break into tasks, context for implementation choices
23
- - **execute-phase** needs: success criteria to verify against, the "why" behind requirements
24
-
25
- A vague PROJECT.md forces every downstream phase to guess. The cost compounds.
26
-
27
- </the_goal>
28
-
29
15
  <how_to_question>
30
16
 
31
17
  **Start open.** Let them dump their mental model. Don't interrupt with structure.
@@ -130,22 +116,6 @@ Four things. If they volunteer more, capture it.
130
116
 
131
117
  </context_checklist>
132
118
 
133
- <decision_gate>
134
-
135
- When you could write a clear PROJECT.md, offer to proceed:
136
-
137
- - header: "Ready?"
138
- - question: "I think I understand what you're after. Ready to create PROJECT.md?"
139
- - options:
140
- - "Create PROJECT.md" — Let's move forward
141
- - "Keep exploring" — I want to share more / ask me more
142
-
143
- If "Keep exploring" — ask what they want to add or identify gaps and probe naturally.
144
-
145
- Loop until "Create PROJECT.md" selected.
146
-
147
- </decision_gate>
148
-
149
119
  <anti_patterns>
150
120
 
151
121
  - **Checklist walking** — Going through domains regardless of what they said
@@ -28,8 +28,7 @@ payload = {
28
28
  'messages': [
29
29
  {'role': 'system', 'content': 'You are a senior product manager reviewing a PRD spec. Provide specific, actionable feedback organized by section. For each item, indicate severity: [critical], [important], or [suggestion]. If the spec is solid, respond with only: LGTM - no changes needed.'},
30
30
  {'role': 'user', 'content': 'Review this PRD spec:\n\n' + spec}
31
- ],
32
- 'temperature': 0.3
31
+ ]
33
32
  }
34
33
  json.dump(payload, open('/tmp/dgs-review-openai.json', 'w'))
35
34
  " < "$SPEC_FILE"
@@ -0,0 +1,29 @@
1
+ # Workflow Conventions
2
+
3
+ Canonical conventions DGS workflows and their helper CLI commands MUST follow. Authoritative for the milestone v23.2 "Agent-Step Reliability" family of contracts.
4
+
5
+ ## The scaffolded_files contract (AGENT-13)
6
+
7
+ Any CLI command in `bin/lib/*.cjs` that **scaffolds files** — that is, writes new files to disk on behalf of the caller — MUST emit a `scaffolded_files: []` array in its raw JSON output. Each entry is a path relative to the planning root. The list MUST be derived from the actual files written by the run; it MUST NOT be hardcoded. If a future scaffolding addition extends what the CLI writes, the array automatically widens — the workflow consumer needs no code change.
8
+
9
+ Any `workflows/*.md` that invokes such a CLI command MUST consume the returned `scaffolded_files` array and pass it to a subsequent `node $TOOLS commit ... --files <scaffolded_files>` invocation in the same workflow. Capturing the JSON without forwarding the paths to a commit step is exactly the silent-skip pattern this contract exists to prevent (see `references/agent-step-reliability.md`).
10
+
11
+ This contract is enforced by `tests/workflow-conventions.test.cjs`, which runs in default `npm test`. The test fails the build if a workflow invokes a known scaffold-emitting CLI command but does not consume the returned `scaffolded_files` array in a subsequent commit step. A meta-assertion within the same test file guards against silent disablement or relocation of the lint.
12
+
13
+ ## Named exit-code labels (registry)
14
+
15
+ Workflows and CLI commands in the AGENT-13 family fail loudly with **named labels** — never with bare numeric exit codes — so users can search documentation, remediation messages, and `dgs-tools health` output by label. The labels are stable identifiers.
16
+
17
+ | Label | Owner | Meaning | Doc reference |
18
+ | --- | --- | --- | --- |
19
+ | `plan-commit-incomplete` | `/dgs:plan-phase` orchestrator | Planner-reported `created_files` not all present in HEAD after commit | `references/agent-step-reliability.md` |
20
+ | `multi-repo-dirt` | `/dgs:fast` orchestrator | Multiple sub-repos dirty (or planning-root + sub-repo both have new files) | `references/agent-step-reliability.md` |
21
+ | `pre-existing-dirt` | `/dgs:fast` orchestrator | Working tree dirty before fast-mode edit step | `references/agent-step-reliability.md` |
22
+ | `summary-frontmatter-mismatch` | `/dgs:execute-plan` (executor pre-commit precondition) | PLAN `requirements` non-empty AND about-to-be-written SUMMARY `requirements_completed` empty | `references/agent-step-reliability.md` |
23
+
24
+ Future labels in this family must be added to this table when introduced.
25
+
26
+ ## See also
27
+
28
+ - `references/agent-step-reliability.md` — the silent-skip diagnostic pattern, rejected anti-features, and canonical fail-loudly contract that this conventions doc operationalises.
29
+ - `specs/spec-agent-step-reliability-detect-and-prevent-silently-skipped-commit-steps.md` — the source spec that derived these conventions (milestone v23.2).
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: package-scan
3
+ display_name: Package Scanning
4
+ description: Checks project dependencies for known vulnerabilities and licence compliance issues
5
+ command: /dgs:package-scan
6
+ enabled: true
7
+ execution_order: 10
8
+ prerequisites:
9
+ - check: "find . -maxdepth 3 \\( -name 'package.json' -o -name 'package-lock.json' -o -name 'yarn.lock' -o -name 'requirements.txt' -o -name 'Pipfile.lock' -o -name 'poetry.lock' -o -name 'pyproject.toml' -o -name 'go.mod' -o -name 'Gemfile.lock' -o -name 'pom.xml' \\) 2>/dev/null | head -1 | grep -q ."
10
+ description: "At least one recognised manifest file exists in any repo or at the product root"
11
+ type: file_exists
12
+ config_key: testing.packages
13
+ finding_prefix: pkg
14
+ ---
15
+
16
+ # Package Scan — Test Type Plugin
17
+
18
+ This skill registers `/dgs:package-scan` as a built-in test type for the DGS test-gate pipeline. It ships inert in v23.1 — the skill-discovery engine (`skills.cjs`) lands in the future test-gate milestone. The frontmatter above conforms to the Test Type Plugin Contract defined in `orig-specs/dgs-test-gate-spec.md` §5a so the discovery engine can consume this file unchanged when it arrives.
19
+
20
+ ## What this test type does
21
+
22
+ Scans every registered repo plus the product root for dependency vulnerabilities and licence compliance issues. Uses a tool cascade (Snyk if authenticated → OSV-Scanner if on PATH → ecosystem-native tools). Produces a canonical findings array consumable by the gate's gap-planner.
23
+
24
+ ## How to run standalone
25
+
26
+ Run the standalone command directly:
27
+
28
+ ```
29
+ /dgs:package-scan
30
+ ```
31
+
32
+ Configuration keys live under `testing.packages.*` in `{planning-root}/config.json` (see `deliver-great-systems/references/package-scan-config.md`).
33
+
34
+ ## Prerequisites
35
+
36
+ The `prerequisites[].check` command returns exit 0 when at least one recognised manifest file is discoverable from the current working directory (depth 3 by default — sufficient for product root + direct child repos + workspace roots). The canonical, code-reachable equivalent lives in `deliver-great-systems/bin/lib/package-scan-skill.cjs` `checkPrerequisites(cwd)` — Phase 152+ consumers should prefer the module API over the shell check because the module iterates REPOS.md explicitly.
37
+
38
+ ## Finding contract
39
+
40
+ Every finding this type produces conforms to the canonical shape in `orig-specs/dgs-test-gate-spec.md` §5a Canonical Finding Output Format, with the package-specific extensions (manifest_path, cve, cvss, dependency_chain, chain_available, direct_or_transitive, tool) appended. The `finding_prefix` is `pkg`; every id follows the form `pkg-NNN` (zero-padded 3-digit, orchestrator-assigned). Licence-violation findings derive their id as `pkg-NNN-lic`.
41
+
42
+ ## Versioning
43
+
44
+ This skill contract is pinned to test-gate-spec §5a v1.0. If the spec's frontmatter schema changes, this file must be updated to match before the future `skills.cjs` discovery engine is deployed.
@@ -0,0 +1,35 @@
1
+ # Review: {title}
2
+
3
+ {stats_banner}
4
+
5
+ ## Goal
6
+
7
+ {goal}
8
+
9
+ ## What Was Built
10
+
11
+ {what_was_built}
12
+
13
+ ## Code Changes
14
+
15
+ {code_changes}
16
+
17
+ ## Aggregate Statistics
18
+
19
+ {aggregate_stats}
20
+
21
+ ## Verification
22
+
23
+ {verification}
24
+
25
+ ## Risk Flags
26
+
27
+ {risk_flags}
28
+
29
+ ## Overall
30
+
31
+ {overall}
32
+
33
+ ---
34
+ *Generated: {date}*
35
+ *Mode: {mode}*
@@ -48,7 +48,7 @@ verified_by: "" # Author who initiated verification (set from init a
48
48
 
49
49
  ---
50
50
 
51
- ## Wave 0 Requirements
51
+ ## Wave 0 Task Requirements
52
52
 
53
53
  - [ ] `{tests/test_file.py}` — stubs for REQ-{XX}
54
54
  - [ ] `{tests/conftest.py}` — shared fixtures
@@ -88,3 +88,14 @@ When the user mentions work for later (not for immediate execution):
88
88
  - Specific tasks to remember: `/dgs:add-todo`
89
89
 
90
90
  These capture without executing.
91
+
92
+ ## 6. Completion Gates? Stop and Report
93
+
94
+ Never take these actions without explicit user instruction:
95
+
96
+ - **`/dgs:quick-complete`** or **`/dgs:quick-abandon`** -- merging or discarding a quick task is the user's decision
97
+ - **`/dgs:complete-milestone`** -- milestone completion involves branch merging, tagging, and archival
98
+ - **`--force`** flags on any command -- force flags bypass safety checks (e.g., four-eyes governance)
99
+ - **`git push --force`**, **`git reset --hard`**, or other destructive git operations
100
+
101
+ When a gate blocks execution (e.g., four-eyes enforcement, missing REVIEW.md), **stop and report the error**. Tell the user what command to run with what flag. Do not retry with the bypass flag yourself.