@ktpartners/dgs-platform 3.3.0 → 3.4.1

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 (31) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +4 -1
  3. package/bin/install.js +1 -1
  4. package/commands/dgs/abandon-milestone.md +28 -0
  5. package/commands/dgs/new-milestone.md +3 -1
  6. package/deliver-great-systems/bin/dgs-tools.cjs +22 -4
  7. package/deliver-great-systems/bin/lib/context.cjs +45 -15
  8. package/deliver-great-systems/bin/lib/core.cjs +2 -6
  9. package/deliver-great-systems/bin/lib/docs.cjs +95 -41
  10. package/deliver-great-systems/bin/lib/docs.test.cjs +49 -6
  11. package/deliver-great-systems/bin/lib/init.cjs +60 -13
  12. package/deliver-great-systems/bin/lib/init.test.cjs +61 -3
  13. package/deliver-great-systems/bin/lib/milestone.cjs +470 -2
  14. package/deliver-great-systems/bin/lib/milestone.test.cjs +653 -0
  15. package/deliver-great-systems/bin/lib/search.cjs +5 -16
  16. package/deliver-great-systems/bin/lib/state.cjs +152 -1
  17. package/deliver-great-systems/bin/lib/sync.cjs +2 -6
  18. package/deliver-great-systems/bin/lib/verify.cjs +2 -1
  19. package/deliver-great-systems/bin/lib/worktrees.cjs +182 -1
  20. package/deliver-great-systems/bin/lib/worktrees.test.cjs +409 -0
  21. package/deliver-great-systems/templates/claude-md.md +2 -0
  22. package/deliver-great-systems/templates/state.md +16 -0
  23. package/deliver-great-systems/workflows/abandon-milestone.md +120 -0
  24. package/deliver-great-systems/workflows/complete-milestone.md +58 -4
  25. package/deliver-great-systems/workflows/create-milestone-job.md +15 -0
  26. package/deliver-great-systems/workflows/help.md +7 -0
  27. package/deliver-great-systems/workflows/new-milestone.md +69 -0
  28. package/deliver-great-systems/workflows/progress.md +5 -1
  29. package/deliver-great-systems/workflows/run-job.md +23 -1
  30. package/hooks/dist/dgs-enforce-discipline.js +34 -1
  31. package/package.json +1 -1
@@ -81,6 +81,19 @@ Milestone completion requires manual oversight for conflict resolution.
81
81
  ```
82
82
  **STOP.** Do not proceed. Exit the workflow.
83
83
 
84
+ **ADH-14 — ad-hoc container preamble.** Read the read-only ad-hoc marker:
85
+
86
+ ```bash
87
+ # ADH-14: surface ad-hoc container status in the completion preamble (read-only)
88
+ ADHOC=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" state read-adhoc --raw 2>/dev/null)
89
+ ```
90
+
91
+ If `$ADHOC` is `true`, show this note before proceeding (omit it entirely for non-ad-hoc milestones):
92
+
93
+ ```
94
+ ℹ Ad-hoc container milestone — quicks & fasts routed into this milestone. Completion will relax the readiness gate and clean up ad-hoc bookkeeping.
95
+ ```
96
+
84
97
  </step>
85
98
 
86
99
  <step name="verify_readiness">
@@ -96,6 +109,32 @@ This returns all phases with plan/summary counts and disk status. Use this to ve
96
109
  - All phases complete (all plans have summaries)? Check `disk_status === 'complete'` for each.
97
110
  - `progress_percent` should be 100%.
98
111
 
112
+ **── Ad-hoc relaxed gate (ADH-10/11/13) ──────────────────────────────────**
113
+
114
+ Read the ad-hoc marker + minimum-bar readiness BEFORE the strict checks below:
115
+
116
+ ```bash
117
+ READINESS=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" state adhoc-readiness --raw)
118
+ ADHOC=$(echo "$READINESS" | jq -r '.adhoc')
119
+ ADHOC_READY=$(echo "$READINESS" | jq -r '.ready')
120
+ ```
121
+
122
+ **If `ADHOC` is `true`:** This is an ad-hoc container milestone. Apply the relaxed gate:
123
+
124
+ - **If `ADHOC_READY` is not `true`:** Refuse completion. Output exactly this line:
125
+
126
+ ```
127
+ Nothing to ship — run a quick/fast or execute a phase first, or `/dgs:abandon-milestone`
128
+ ```
129
+
130
+ Then **STOP** — do not proceed to gather_stats and do not run any of the strict checks below. (ADH-13)
131
+
132
+ - **Otherwise (`ADHOC_READY` is `true`):** Take the RELAXED path — **SKIP** the strict 100%-phase-completion check, **SKIP** the REQUIREMENTS-traceability parse and the "Unchecked Requirements" presentation, and DO **NOT** recommend `/dgs:audit-milestone`. Proceed directly to gather_stats. (ADH-10)
133
+
134
+ **If `ADHOC` is not `true`:** Proceed with the strict gate exactly as specified below — no behavioral change. (ADH-11)
135
+
136
+ **── Strict gate (non-ad-hoc only; runs only when `ADHOC` is not `true`) ──**
137
+
99
138
  **Requirements completion check (REQUIRED before presenting):**
100
139
 
101
140
  Parse REQUIREMENTS.md traceability table:
@@ -140,6 +179,8 @@ MUST present 3 options:
140
179
 
141
180
  If user selects "Proceed anyway": note incomplete requirements in MILESTONES.md under `### Known Gaps` with REQ-IDs and descriptions.
142
181
 
182
+ **── End strict gate. The checks below run for BOTH ad-hoc and non-ad-hoc milestones. ──**
183
+
143
184
  **REVIEW.md existence check:**
144
185
 
145
186
  ```bash
@@ -292,7 +333,13 @@ MERGE_RESULT=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" work
292
333
  ```
293
334
  ✓ ${REPO_NAME}: Rebased and merged to ${BASE_BRANCH}
294
335
  ```
295
- Continue to next repo.
336
+ On the success path, `rebaseAndMerge` also deletes the owned remote
337
+ `milestone/${MILESTONE_SLUG}` branch per-repo (`git push origin --delete
338
+ milestone/<slug>`) to reclaim the milestone name and prevent future branch-name
339
+ collisions. This remote delete is **non-fatal**: if it fails (offline, no remote
340
+ branch, etc.) the result still reports `success: true` with
341
+ `remoteBranchDeleted: false` and a warning on stderr — completion is never
342
+ blocked by a failed remote delete. Continue to next repo.
296
343
 
297
344
  **If `conflicted: true`:**
298
345
  Display the `manualInstructions` from the result:
@@ -337,8 +384,15 @@ This removes:
337
384
  - Milestone branches
338
385
  - active_context cleared to null
339
386
 
387
+ ```bash
388
+ # ADH-21: remove residual ad-hoc bookkeeping (base ref + any stale entry).
389
+ # No-op for non-ad-hoc milestones (no base ref to delete).
390
+ node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" milestone cleanup-adhoc "${MILESTONE_SLUG}" 2>/dev/null || true
391
+ ```
392
+
340
393
  ```
341
394
  ✓ Worktree cleanup complete for milestone '${MILESTONE_SLUG}'
395
+ ✓ Ad-hoc bookkeeping cleaned (base ref removed if present)
342
396
  ✓ Active context cleared
343
397
  ```
344
398
 
@@ -679,11 +733,11 @@ After `milestone complete` has archived, reorganize ROADMAP.md with milestone gr
679
733
  </details>
680
734
  ```
681
735
 
682
- **Then delete originals:**
736
+ **Then delete originals** (REQUIREMENTS.md deletion is existence-guarded so a quicks-only ad-hoc milestone with no REQUIREMENTS.md does not error — ADH-10):
683
737
 
684
738
  ```bash
685
- rm ${roadmap_path}
686
- rm ${project_root}/REQUIREMENTS.md
739
+ [ -f "${roadmap_path}" ] && rm "${roadmap_path}"
740
+ [ -f "${project_root}/REQUIREMENTS.md" ] && rm "${project_root}/REQUIREMENTS.md"
687
741
  ```
688
742
 
689
743
  </step>
@@ -102,6 +102,21 @@ N. audit-milestone v6.0
102
102
  Create this job? (yes/no)
103
103
  ```
104
104
 
105
+ **Non-blocking collision advisory.** Before waiting for approval, surface a
106
+ warning (NOT a halt — writing a job file is harmless) if the milestone branch
107
+ name is already squatted on origin:
108
+
109
+ ```bash
110
+ MILESTONE_SLUG=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" init milestone-op | node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>{try{console.log(JSON.parse(d).milestone_slug||"")}catch{console.log("")}})')
111
+ COLLISION=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" worktrees check-collision "${MILESTONE_SLUG}")
112
+ ```
113
+
114
+ If the parsed `collision` is `true`, display the `message` (which names the
115
+ colliding `branch` and repo(s)) as an advisory so the user can clean up the
116
+ squatting remote branch before running the job. The job-start guard in
117
+ `run-job` will REFUSE if the collision is still present at run time, so this is
118
+ an early heads-up, not a blocker.
119
+
105
120
  Wait for user response.
106
121
  </step>
107
122
 
@@ -313,6 +313,13 @@ Start a new milestone (or the first milestone after `/dgs:new-project`). *(Tier
313
313
  Handles both first milestones (creates STATE.md, defaults to v1.0) and subsequent milestones (continues from MILESTONES.md).
314
314
 
315
315
  Usage: `/dgs:new-milestone "v2.0 Features"`
316
+ Usage: `/dgs:new-milestone --adhoc "Quick experiments"` (ad-hoc container — quicks & fasts route in)
317
+
318
+ **`/dgs:abandon-milestone`**
319
+
320
+ Cleanly discard an ad-hoc container milestone — removes milestone worktrees/branches and
321
+ restores the project-scoped planning docs to their pre-milestone state. Ad-hoc-only;
322
+ refuses on spec/phase-driven milestones. Destructive — requires confirmation.
316
323
 
317
324
  **`/dgs:complete-milestone <version>`**
318
325
  Archive completed milestone and prepare for next version. *(Tier 4: verification)*
@@ -68,6 +68,75 @@ All subsequent steps use these resolved paths. Never reference PROJECT.md, STATE
68
68
  - Read `${state_path}` (pending todos, blockers) — if file does not exist, will be created in Step 5
69
69
  - Check for `${project_root}/MILESTONE-CONTEXT.md` (from /dgs:discuss-milestone)
70
70
 
71
+ ## 1a. Ad-hoc Container (--adhoc)
72
+
73
+ **Triggered when:** `--adhoc` is present in `$ARGUMENTS`.
74
+
75
+ This branch establishes a worktree-isolated milestone container DIRECTLY and
76
+ **skips questioning, research, requirements, and roadmap** (steps 2, 8, 9, 10).
77
+ On completion it jumps straight to `## 11. Done`. `detectQuickMode` is never
78
+ modified — once the container exists, quicks/fasts auto-route into it.
79
+
80
+ **Step 0 — derive slug + version.**
81
+ Derive `{slug}` from the milestone name argument (same slug derivation used
82
+ elsewhere in this workflow). Determine the version using the major/minor prompt
83
+ from `## 3. Determine Milestone Version`, but for `--adhoc` **always present
84
+ minor as the recommended option** (default minor). The chosen `vX.Y` is
85
+ provisional — nothing product-global is written at creation.
86
+
87
+ **Atomic, canonically-ordered creation with full rollback.** The 6 ordered
88
+ steps below are performed atomically by a single CLI verb. The verb captures the
89
+ planning base ref, creates the code worktrees, mirrors the marker, commits
90
+ STATE.md, and sets `active_context` LAST — rolling everything back (in reverse)
91
+ on any failure so there is no leak window and no residue:
92
+
93
+ ```bash
94
+ node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" milestone create-adhoc "{name}" --version {vX.Y}
95
+ ```
96
+
97
+ The verb implements, in this exact canonical order:
98
+
99
+ 1. **Assert preconditions (ADH-19).** Refuse with a non-zero exit and ZERO
100
+ mutation if any planning-repo or registered-code-repo working tree is dirty
101
+ (`git -C <repo> status --porcelain` non-empty, ignoring machine-local
102
+ `config.local.json`), or if `execution.active_context` is already set
103
+ (`config-get execution.active_context` non-empty). The error tells the user
104
+ to "commit or stash changes first" / "complete or abandon the active context
105
+ first", making a repeated invocation deterministic.
106
+ 2. **Capture planning base ref (ADH-06).**
107
+ `git -C <planning_root> update-ref refs/dgs/adhoc/{slug}/base HEAD` — tracked
108
+ for rollback.
109
+ 3. **Create code worktrees (ADH-02).**
110
+ `worktrees create {slug} --type milestone --adhoc --base-ref refs/dgs/adhoc/{slug}/base`
111
+ loops every registered code repo and stamps the entry with `adhoc:true` +
112
+ `adhoc_base_ref`. Any repo failure → ROLLBACK.
113
+ 4. **Confirm marker on the worktree entry (ADH-04 mirror).** Verify the entry
114
+ now carries `adhoc:true` and `adhoc_base_ref`. If absent → ROLLBACK.
115
+ 5. **Commit STATE.md with `adhoc:true` (ADH-04 primary).** Write the milestone
116
+ fields (name, `vX.Y`, status) PLUS `adhoc: true` to STATE.md frontmatter (the
117
+ `state set-adhoc` helper) and commit it. Commit failure → ROLLBACK.
118
+ 6. **Set `execution.active_context` LAST (ADH-03).**
119
+ `config-local-set execution.active_context {slug}` — set ONLY after steps 2–5
120
+ succeed, so `detectQuickMode` never observes a half-created milestone (no leak
121
+ window).
122
+
123
+ **ROLLBACK (ADH-18) — undo in reverse, only this invocation's artifacts:**
124
+ 1. `active_context` is set last, so a pre-step-6 failure never set it.
125
+ 2. Reset the just-made STATE.md commit if step 5 committed.
126
+ 3. Remove created worktrees: `worktrees remove {slug} --force` (also nulls
127
+ `active_context`).
128
+ 4. Delete the base ref: `git -C <planning_root> update-ref -d refs/dgs/adhoc/{slug}/base`.
129
+ 5. Print an actionable error naming what was rolled back; exit non-zero.
130
+ Leave NO residue — no ref, no worktree entry, no marker, `active_context` unset.
131
+
132
+ **On success — ADH-22 advisory.** The verb prints:
133
+ "Advisory: while this ad-hoc milestone is active, any product-level (`--main`)
134
+ quick that commits to `base_branch` will have its STATE.md row reverted if you
135
+ later run `/dgs:abandon-milestone`."
136
+
137
+ Then **jump directly to `## 11. Done`** (skipping steps 2/8/9/10). Do NOT run
138
+ questioning, research, requirements, or roadmap for an ad-hoc container.
139
+
71
140
  ## 1b. Spec-Driven Milestone (auto mode only)
72
141
 
73
142
  **Triggered when:** `--auto` argument references a spec file.
@@ -94,15 +94,19 @@ Use this instead of manually reading/parsing ROADMAP.md.
94
94
  ```bash
95
95
  # Get formatted progress bar
96
96
  PROGRESS_BAR=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" progress bar --raw)
97
+
98
+ # ADH-14: detect ad-hoc container milestone (read-only marker)
99
+ ADHOC=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" state read-adhoc --raw 2>/dev/null)
97
100
  ```
98
101
 
99
- Present:
102
+ Present (if `ADHOC` is `true`, include the `**Ad-hoc container:**` line below; otherwise omit it):
100
103
 
101
104
  ```
102
105
  # [Project Name]
103
106
 
104
107
  **Progress:** {PROGRESS_BAR}
105
108
  **Profile:** [quality/balanced/budget]
109
+ **Ad-hoc container:** active — quicks & fasts route into this milestone
106
110
 
107
111
  ## Recent Work
108
112
  - [Phase X, Plan Y]: [what was accomplished - 1 line from summary-extract]
@@ -20,7 +20,11 @@ Load planning context:
20
20
  INIT=$(node ~/.claude/deliver-great-systems/bin/dgs-tools.cjs init milestone-op)
21
21
  ```
22
22
 
23
- Extract: `project_root`, `jobs_root`, `sync_push`, `sync_pull`, `cadence_push`, `cadence_pull` as needed by the workflow.
23
+ Extract: `project_root`, `jobs_root`, `sync_push`, `sync_pull`, `cadence_push`, `cadence_pull`, and `milestone_slug` as needed by the workflow. `milestone_slug` (the stamped/legacy-resolved structural slug) feeds the pre-flight collision guard in `sync_before`:
24
+
25
+ ```bash
26
+ MILESTONE_SLUG=$(echo "$INIT" | node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>{try{console.log(JSON.parse(d).milestone_slug||"")}catch{console.log("")}})')
27
+ ```
24
28
 
25
29
  Set `WORKFLOW_NAME = "run-job"`.
26
30
  Initialize `SYNC_WARNINGS = []` (accumulates mid-workflow push warnings).
@@ -221,6 +225,24 @@ node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" sync workflow-pull
221
225
  If `action` is `"aborted"`: halt job before any steps run with diagnosis.
222
226
 
223
227
  - **If `suppressed` is true:** Pull silently (recent Yes answer).
228
+
229
+ **Pre-flight collision guard (REFUSE — safe default).** After the pull, and
230
+ BEFORE any job step runs, check that the milestone branch name is not already
231
+ squatted on origin by an unrelated lingering branch. **Refuse (not warn) is the
232
+ deliberate safe default for job start**: starting a job whose `milestone/<slug>`
233
+ collides with unmerged remote commits would silently entangle two milestones'
234
+ histories, so we halt loudly at the one moment a clean abort costs nothing.
235
+
236
+ ```bash
237
+ COLLISION=$(node "$HOME/.claude/deliver-great-systems/bin/dgs-tools.cjs" worktrees check-collision "${MILESTONE_SLUG}")
238
+ ```
239
+
240
+ Parse the JSON. **If `collision` is `true`:** HALT the job before any steps run.
241
+ Surface the `branch` and the colliding repo(s) from `message`, and instruct the
242
+ user to merge or delete the squatting remote branch
243
+ (`git push origin --delete milestone/<slug>`) and then re-run. Do NOT proceed.
244
+
245
+ **If `collision` is `false`:** continue normally.
224
246
  </step>
225
247
 
226
248
  <step name="execute_steps">
@@ -28,6 +28,17 @@ const ALLOWED_PATH_PATTERNS = [
28
28
  /\.claude\/projects\/.*\/memory\//, // Auto-memory system
29
29
  /\.claude\/.*\/memory\//, // Memory in any .claude subfolder
30
30
  /\/tmp\//, // Temp files
31
+ // DGS planning-artifact paths (safety net): workflow doc writes are allowed
32
+ // purely by path even with no active marker. Anchored to a path-segment
33
+ // boundary so arbitrary CODE files in registered repos are NOT exempted.
34
+ /(^|\/)projects\/[^/]+\/phases\/.*\.md$/, // phase docs
35
+ /(^|\/)projects\/[^/]+\/(PROJECT|ROADMAP|STATE|REQUIREMENTS)\.md$/, // project-level docs
36
+ /(^|\/)(STATE|PROJECTS|MILESTONES|RETROSPECTIVE)\.md$/, // top-level docs
37
+ /(^|\/)ideas\/.*\.md$/, // ideas
38
+ /(^|\/)specs\/.*\.md$/, // specs
39
+ /(^|\/)todos\/.*\.md$/, // todos
40
+ /(^|\/)jobs\/.*\.md$/, // jobs
41
+ /(^|\/)quick\/.*$/, // quick tasks
31
42
  ];
32
43
 
33
44
  // DGS-managed paths that should be committed (relative to planning root)
@@ -101,7 +112,6 @@ process.stdin.on('end', () => {
101
112
  if (skillName.startsWith('dgs:')) {
102
113
  // Delete the active marker
103
114
  const markerPath = getMarkerPath(sessionId);
104
- try { fs.unlinkSync(markerPath); } catch { /* already gone */ }
105
115
 
106
116
  // Safety net: check for uncommitted DGS-managed files
107
117
  if (isDgsProject(cwd)) {
@@ -156,6 +166,29 @@ process.stdin.on('end', () => {
156
166
  process.exit(0);
157
167
  }
158
168
 
169
+ // ── PreToolUse: Bash → opportunistic marker-on-init (never blocks) ──
170
+ // Every /dgs:* workflow's first step is `dgs-tools.cjs init <workflow>`.
171
+ // Inline slash-command expansion emits no Skill event, so the marker is
172
+ // otherwise never written. Seeing any dgs-tools Bash invocation is a
173
+ // reliable signal that a workflow is active — write the marker so
174
+ // subsequent Edit/Write calls in this session are allowed. This branch
175
+ // NEVER denies: all Bash is allowed regardless of whether it matched.
176
+ if (hookEvent === 'PreToolUse' && toolName === 'Bash') {
177
+ const cmd = toolInput.command || '';
178
+ if (/\bdgs-tools(\.cjs)?\b/.test(cmd)) {
179
+ try {
180
+ const markerPath = getMarkerPath(sessionId);
181
+ const marker = {
182
+ command: 'bash:dgs-tools',
183
+ started: new Date().toISOString(),
184
+ session_id: sessionId,
185
+ };
186
+ fs.writeFileSync(markerPath, JSON.stringify(marker));
187
+ } catch { /* marker write failure must never block Bash */ }
188
+ }
189
+ process.exit(0);
190
+ }
191
+
159
192
  // ── PreToolUse: Edit/Write → check marker ──
160
193
  if (hookEvent === 'PreToolUse' && (toolName === 'Edit' || toolName === 'Write')) {
161
194
  // Not a DGS project? Allow everything.
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.3.0",
11
+ "version": "3.4.1",
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"