@ktpartners/dgs-platform 2.7.5 → 2.8.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 (55) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/agents/dgs-executor.md +0 -52
  3. package/deliver-great-systems/bin/dgs-tools.cjs +66 -10
  4. package/deliver-great-systems/bin/lib/commands.cjs +1 -8
  5. package/deliver-great-systems/bin/lib/config.cjs +9 -90
  6. package/deliver-great-systems/bin/lib/context.cjs +2 -2
  7. package/deliver-great-systems/bin/lib/context.test.cjs +100 -100
  8. package/deliver-great-systems/bin/lib/core.cjs +17 -57
  9. package/deliver-great-systems/bin/lib/core.test.cjs +166 -170
  10. package/deliver-great-systems/bin/lib/docs.cjs +3 -3
  11. package/deliver-great-systems/bin/lib/docs.test.cjs +14 -7
  12. package/deliver-great-systems/bin/lib/execution.cjs +2 -2
  13. package/deliver-great-systems/bin/lib/execution.test.cjs +65 -67
  14. package/deliver-great-systems/bin/lib/ideas.cjs +4 -4
  15. package/deliver-great-systems/bin/lib/ideas.test.cjs +45 -44
  16. package/deliver-great-systems/bin/lib/init.cjs +9 -4
  17. package/deliver-great-systems/bin/lib/init.test.cjs +242 -175
  18. package/deliver-great-systems/bin/lib/jobs.cjs +1 -1
  19. package/deliver-great-systems/bin/lib/jobs.test.cjs +203 -202
  20. package/deliver-great-systems/bin/lib/migration.cjs +256 -281
  21. package/deliver-great-systems/bin/lib/migration.test.cjs +385 -440
  22. package/deliver-great-systems/bin/lib/milestone.cjs +1 -1
  23. package/deliver-great-systems/bin/lib/overlap.cjs +4 -4
  24. package/deliver-great-systems/bin/lib/overlap.test.cjs +45 -44
  25. package/deliver-great-systems/bin/lib/path-audit.test.cjs +16 -22
  26. package/deliver-great-systems/bin/lib/paths.cjs +60 -59
  27. package/deliver-great-systems/bin/lib/paths.test.cjs +192 -225
  28. package/deliver-great-systems/bin/lib/phase.cjs +5 -4
  29. package/deliver-great-systems/bin/lib/projects.cjs +8 -8
  30. package/deliver-great-systems/bin/lib/projects.test.cjs +75 -74
  31. package/deliver-great-systems/bin/lib/repos.cjs +94 -230
  32. package/deliver-great-systems/bin/lib/repos.test.cjs +84 -75
  33. package/deliver-great-systems/bin/lib/search.cjs +4 -4
  34. package/deliver-great-systems/bin/lib/specs.cjs +2 -2
  35. package/deliver-great-systems/bin/lib/sync.cjs +1 -1
  36. package/deliver-great-systems/bin/lib/template.cjs +3 -3
  37. package/deliver-great-systems/bin/lib/test-helpers.cjs +59 -162
  38. package/deliver-great-systems/bin/lib/verify.cjs +3 -3
  39. package/deliver-great-systems/references/planning-config.md +7 -8
  40. package/deliver-great-systems/workflows/add-tests.md +1 -1
  41. package/deliver-great-systems/workflows/approve-spec.md +1 -11
  42. package/deliver-great-systems/workflows/complete-milestone.md +2 -2
  43. package/deliver-great-systems/workflows/consolidate-ideas.md +1 -1
  44. package/deliver-great-systems/workflows/create-milestone-job.md +2 -2
  45. package/deliver-great-systems/workflows/discuss-phase.md +2 -2
  46. package/deliver-great-systems/workflows/execute-phase.md +63 -4
  47. package/deliver-great-systems/workflows/execute-plan.md +0 -51
  48. package/deliver-great-systems/workflows/find-related-ideas.md +1 -1
  49. package/deliver-great-systems/workflows/help.md +25 -58
  50. package/deliver-great-systems/workflows/init-product.md +14 -451
  51. package/deliver-great-systems/workflows/map-codebase.md +109 -0
  52. package/deliver-great-systems/workflows/new-project.md +0 -1
  53. package/deliver-great-systems/workflows/quick.md +2 -2
  54. package/deliver-great-systems/workflows/run-job.md +56 -0
  55. package/package.json +1 -1
@@ -676,8 +676,8 @@ describe('jobs', () => {
676
676
  assert.equal(steps[1].args, '50 --non-interactive');
677
677
  assert.equal(steps[2].command, 'execute-phase');
678
678
  assert.equal(steps[2].args, '50 --non-interactive');
679
- assert.equal(steps[3].command, 'verify-work');
680
- assert.equal(steps[3].args, '50 --auto-test');
679
+ assert.equal(steps[3].command, 'audit-phase');
680
+ assert.equal(steps[3].args, '50');
681
681
  });
682
682
 
683
683
  it('produces 4 steps for unplanned phase (empty)', () => {
@@ -690,7 +690,7 @@ describe('jobs', () => {
690
690
  assert.equal(steps[0].command, 'map-codebase');
691
691
  assert.equal(steps[1].command, 'plan-phase');
692
692
  assert.equal(steps[2].command, 'execute-phase');
693
- assert.equal(steps[3].command, 'verify-work');
693
+ assert.equal(steps[3].command, 'audit-phase');
694
694
  });
695
695
 
696
696
  it('produces 4 steps for discussed phase (context but no plan)', () => {
@@ -703,7 +703,7 @@ describe('jobs', () => {
703
703
  assert.equal(steps[0].command, 'map-codebase');
704
704
  assert.equal(steps[1].command, 'plan-phase');
705
705
  assert.equal(steps[2].command, 'execute-phase');
706
- assert.equal(steps[3].command, 'verify-work');
706
+ assert.equal(steps[3].command, 'audit-phase');
707
707
  });
708
708
 
709
709
  it('produces 4 steps for researched phase', () => {
@@ -716,7 +716,7 @@ describe('jobs', () => {
716
716
  assert.equal(steps[0].command, 'map-codebase');
717
717
  assert.equal(steps[1].command, 'plan-phase');
718
718
  assert.equal(steps[2].command, 'execute-phase');
719
- assert.equal(steps[3].command, 'verify-work');
719
+ assert.equal(steps[3].command, 'audit-phase');
720
720
  });
721
721
 
722
722
  it('produces 2 steps for planned phase', () => {
@@ -728,8 +728,8 @@ describe('jobs', () => {
728
728
  assert.equal(steps.length, 2);
729
729
  assert.equal(steps[0].command, 'execute-phase');
730
730
  assert.equal(steps[0].args, '50 --non-interactive');
731
- assert.equal(steps[1].command, 'verify-work');
732
- assert.equal(steps[1].args, '50 --auto-test');
731
+ assert.equal(steps[1].command, 'audit-phase');
732
+ assert.equal(steps[1].args, '50');
733
733
  });
734
734
 
735
735
  it('produces 2 steps for partially executed phase', () => {
@@ -740,8 +740,8 @@ describe('jobs', () => {
740
740
 
741
741
  assert.equal(steps.length, 2);
742
742
  assert.equal(steps[0].command, 'execute-phase');
743
- assert.equal(steps[1].command, 'verify-work');
744
- assert.equal(steps[1].args, '50 --auto-test');
743
+ assert.equal(steps[1].command, 'audit-phase');
744
+ assert.equal(steps[1].args, '50');
745
745
  });
746
746
 
747
747
  it('produces 0 steps for completed phase (disk_status complete)', () => {
@@ -776,16 +776,16 @@ describe('jobs', () => {
776
776
  assert.equal(steps.length, 6);
777
777
  assert.equal(steps[0].command, 'execute-phase');
778
778
  assert.equal(steps[0].args, '50 --non-interactive');
779
- assert.equal(steps[1].command, 'verify-work');
780
- assert.equal(steps[1].args, '50 --auto-test');
779
+ assert.equal(steps[1].command, 'audit-phase');
780
+ assert.equal(steps[1].args, '50');
781
781
  assert.equal(steps[2].command, 'map-codebase');
782
782
  assert.equal(steps[2].args, '51 --auto');
783
783
  assert.equal(steps[3].command, 'plan-phase');
784
784
  assert.equal(steps[3].args, '51 --non-interactive');
785
785
  assert.equal(steps[4].command, 'execute-phase');
786
786
  assert.equal(steps[4].args, '51 --non-interactive');
787
- assert.equal(steps[5].command, 'verify-work');
788
- assert.equal(steps[5].args, '51 --auto-test');
787
+ assert.equal(steps[5].command, 'audit-phase');
788
+ assert.equal(steps[5].args, '51');
789
789
  });
790
790
 
791
791
  it('appends audit and complete steps when check=true', () => {
@@ -855,7 +855,7 @@ describe('jobs', () => {
855
855
  assert.equal(steps[6].args, '51 --non-interactive');
856
856
  });
857
857
 
858
- it('includes correct flags on plan-phase (--non-interactive), execute-phase (--non-interactive), and map-codebase (--auto) steps', () => {
858
+ it('includes correct flags on plan-phase (--non-interactive), execute-phase (--non-interactive), map-codebase (--auto), and audit-phase (phase number only) steps', () => {
859
859
  const phases = [
860
860
  { number: '50', name: 'Job Creation', disk_status: 'no_directory', roadmap_complete: false },
861
861
  ];
@@ -864,12 +864,12 @@ describe('jobs', () => {
864
864
  const mapStep = steps.find(s => s.command === 'map-codebase');
865
865
  const planStep = steps.find(s => s.command === 'plan-phase');
866
866
  const executeStep = steps.find(s => s.command === 'execute-phase');
867
- const verifyStep = steps.find(s => s.command === 'verify-work');
867
+ const auditStep = steps.find(s => s.command === 'audit-phase');
868
868
 
869
869
  assert.ok(mapStep.args.includes('--auto'), 'map-codebase should have --auto');
870
870
  assert.ok(planStep.args.includes('--non-interactive'), 'plan-phase should have --non-interactive');
871
871
  assert.ok(executeStep.args.includes('--non-interactive'), 'execute-phase should have --non-interactive');
872
- assert.ok(verifyStep.args.includes('--auto-test'), 'verify-work should have --auto-test');
872
+ assert.strictEqual(auditStep.args, '50', 'audit-phase should have just the phase number');
873
873
  });
874
874
 
875
875
  it('sorts phases by number numerically, not lexicographically', () => {
@@ -883,9 +883,9 @@ describe('jobs', () => {
883
883
  // Phase 49 complete (0 steps), Phase 50 planned (2 steps), Phase 51 planned (2 steps) = 4
884
884
  assert.equal(steps.length, 4);
885
885
  assert.equal(steps[0].args, '50 --non-interactive');
886
- assert.equal(steps[1].args, '50 --auto-test');
886
+ assert.equal(steps[1].args, '50');
887
887
  assert.equal(steps[2].args, '51 --non-interactive');
888
- assert.equal(steps[3].args, '51 --auto-test');
888
+ assert.equal(steps[3].args, '51');
889
889
  });
890
890
 
891
891
  it('returns steps as objects with command and args properties', () => {
@@ -914,17 +914,18 @@ describe('jobs', () => {
914
914
  }
915
915
  });
916
916
 
917
- it('verify-work steps include --auto-test flag', () => {
917
+ it('audit-phase steps use just the phase number (no extra flags)', () => {
918
918
  const phases = [
919
919
  { number: '50', name: 'Job Creation', disk_status: 'planned', roadmap_complete: false },
920
920
  { number: '51', name: 'Job Execution', disk_status: 'no_directory', roadmap_complete: false },
921
921
  ];
922
922
  const steps = generateMilestoneSteps(phases, { check: false, version: 'v6.0' });
923
923
 
924
- const verifySteps = steps.filter(s => s.command === 'verify-work');
925
- assert.ok(verifySteps.length > 0, 'Should have verify-work steps');
926
- for (const step of verifySteps) {
927
- assert.ok(step.args.includes('--auto-test'), `verify-work step for ${step.args} should have --auto-test`);
924
+ const auditSteps = steps.filter(s => s.command === 'audit-phase');
925
+ assert.ok(auditSteps.length > 0, 'Should have audit-phase steps');
926
+ for (const step of auditSteps) {
927
+ assert.strictEqual(step.args, step.args.trim(), 'audit-phase args should be just the phase number');
928
+ assert.ok(!step.args.includes('--'), 'audit-phase should not have flag arguments');
928
929
  }
929
930
  });
930
931
 
@@ -1070,13 +1071,13 @@ Plans:
1070
1071
 
1071
1072
  it('auto-detects active milestone version from ROADMAP.md', () => {
1072
1073
  fixture = createFixture({
1073
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1074
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1075
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1076
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1077
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1078
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1079
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1074
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1075
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1076
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1077
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1078
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1079
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1080
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1080
1081
  });
1081
1082
 
1082
1083
  const result = cmdJobsCreateMilestone(fixture.cwd, null, true, false);
@@ -1084,15 +1085,15 @@ Plans:
1084
1085
  assert.equal(result.created, true);
1085
1086
  });
1086
1087
 
1087
- it('writes job file to .planning/jobs/pending/', () => {
1088
+ it('writes job file to jobs/pending/', () => {
1088
1089
  fixture = createFixture({
1089
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1090
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1091
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1092
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1093
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1094
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1095
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1090
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1091
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1092
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1093
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1094
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1095
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1096
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1096
1097
  });
1097
1098
 
1098
1099
  const result = cmdJobsCreateMilestone(fixture.cwd, 'v6.0', true, false);
@@ -1103,19 +1104,19 @@ Plans:
1103
1104
  assert.ok(fs.existsSync(jobFilePath), 'Job file should exist on disk');
1104
1105
  });
1105
1106
 
1106
- it('auto-creates .planning/jobs/pending/ directory', () => {
1107
+ it('auto-creates jobs/pending/ directory', () => {
1107
1108
  fixture = createFixture({
1108
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1109
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1110
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1111
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1112
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1113
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1114
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1109
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1110
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1111
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1112
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1113
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1114
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1115
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1115
1116
  });
1116
1117
 
1117
1118
  // Ensure pending dir does not exist yet
1118
- const pendingDir = path.join(fixture.cwd, '.planning', 'jobs', 'pending');
1119
+ const pendingDir = path.join(fixture.cwd, 'jobs', 'pending');
1119
1120
  assert.ok(!fs.existsSync(pendingDir), 'pending dir should not exist before call');
1120
1121
 
1121
1122
  cmdJobsCreateMilestone(fixture.cwd, 'v6.0', true, false);
@@ -1124,13 +1125,13 @@ Plans:
1124
1125
 
1125
1126
  it('returns JSON with expected fields', () => {
1126
1127
  fixture = createFixture({
1127
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1128
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1129
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1130
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1131
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1132
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1133
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1128
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1129
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1130
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1131
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1132
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1133
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1134
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1134
1135
  });
1135
1136
 
1136
1137
  const result = cmdJobsCreateMilestone(fixture.cwd, 'v6.0', true, false);
@@ -1145,7 +1146,7 @@ Plans:
1145
1146
 
1146
1147
  it('throws error when no ROADMAP.md exists', () => {
1147
1148
  fixture = createFixture({
1148
- '.planning/phases/': null,
1149
+ 'phases/': null,
1149
1150
  });
1150
1151
 
1151
1152
  assert.throws(
@@ -1156,8 +1157,8 @@ Plans:
1156
1157
 
1157
1158
  it('throws error when specified version not found in ROADMAP', () => {
1158
1159
  fixture = createFixture({
1159
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1160
- '.planning/phases/': null,
1160
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1161
+ 'phases/': null,
1161
1162
  });
1162
1163
 
1163
1164
  assert.throws(
@@ -1212,13 +1213,13 @@ Plans:
1212
1213
 
1213
1214
  it('returns preview JSON with expected fields', () => {
1214
1215
  fixture = createFixture({
1215
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1216
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1217
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1218
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1219
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1220
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1221
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1216
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1217
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1218
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1219
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1220
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1221
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1222
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1222
1223
  });
1223
1224
 
1224
1225
  const result = cmdJobsMilestonePreview(fixture.cwd, 'v6.0', true, false);
@@ -1233,30 +1234,30 @@ Plans:
1233
1234
 
1234
1235
  it('does NOT write any file to disk', () => {
1235
1236
  fixture = createFixture({
1236
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1237
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1238
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1239
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1240
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1241
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1242
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1237
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1238
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1239
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1240
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1241
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1242
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1243
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1243
1244
  });
1244
1245
 
1245
1246
  cmdJobsMilestonePreview(fixture.cwd, 'v6.0', true, false);
1246
1247
 
1247
- const pendingDir = path.join(fixture.cwd, '.planning', 'jobs', 'pending');
1248
+ const pendingDir = path.join(fixture.cwd, 'jobs', 'pending');
1248
1249
  assert.ok(!fs.existsSync(pendingDir), 'No jobs directory should be created for preview');
1249
1250
  });
1250
1251
 
1251
1252
  it('steps_preview is array of step command strings', () => {
1252
1253
  fixture = createFixture({
1253
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1254
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1255
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1256
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1257
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1258
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1259
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1254
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1255
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1256
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1257
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1258
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1259
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1260
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1260
1261
  });
1261
1262
 
1262
1263
  const result = cmdJobsMilestonePreview(fixture.cwd, 'v6.0', true, false);
@@ -1268,13 +1269,13 @@ Plans:
1268
1269
 
1269
1270
  it('content is the full markdown that would be written', () => {
1270
1271
  fixture = createFixture({
1271
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1272
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1273
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1274
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1275
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1276
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1277
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1272
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1273
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1274
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1275
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1276
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1277
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1278
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1278
1279
  });
1279
1280
 
1280
1281
  const result = cmdJobsMilestonePreview(fixture.cwd, 'v6.0', true, false);
@@ -1284,13 +1285,13 @@ Plans:
1284
1285
 
1285
1286
  it('phase_count counts distinct phases with steps', () => {
1286
1287
  fixture = createFixture({
1287
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1288
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1289
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1290
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1291
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1292
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1293
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1288
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1289
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1290
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1291
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1292
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1293
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1294
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1294
1295
  });
1295
1296
 
1296
1297
  const result = cmdJobsMilestonePreview(fixture.cwd, 'v6.0', true, false);
@@ -1300,13 +1301,13 @@ Plans:
1300
1301
 
1301
1302
  it('combines correctly with --no-check (omits audit/complete from preview)', () => {
1302
1303
  fixture = createFixture({
1303
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1304
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1305
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1306
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1307
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1308
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1309
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1304
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1305
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1306
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1307
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1308
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1309
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1310
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1310
1311
  });
1311
1312
 
1312
1313
  const withCheck = cmdJobsMilestonePreview(fixture.cwd, 'v6.0', true, false);
@@ -1321,13 +1322,13 @@ Plans:
1321
1322
 
1322
1323
  it('auto-detects milestone version same as create', () => {
1323
1324
  fixture = createFixture({
1324
- '.planning/ROADMAP.md': FIXTURE_ROADMAP,
1325
- '.planning/phases/49-job-file-format/49-01-PLAN.md': '',
1326
- '.planning/phases/49-job-file-format/49-02-PLAN.md': '',
1327
- '.planning/phases/49-job-file-format/49-01-SUMMARY.md': '',
1328
- '.planning/phases/49-job-file-format/49-02-SUMMARY.md': '',
1329
- '.planning/phases/50-job-creation/50-01-PLAN.md': '',
1330
- '.planning/phases/50-job-creation/50-02-PLAN.md': '',
1325
+ 'ROADMAP.md': FIXTURE_ROADMAP,
1326
+ 'phases/49-job-file-format/49-01-PLAN.md': '',
1327
+ 'phases/49-job-file-format/49-02-PLAN.md': '',
1328
+ 'phases/49-job-file-format/49-01-SUMMARY.md': '',
1329
+ 'phases/49-job-file-format/49-02-SUMMARY.md': '',
1330
+ 'phases/50-job-creation/50-01-PLAN.md': '',
1331
+ 'phases/50-job-creation/50-02-PLAN.md': '',
1331
1332
  });
1332
1333
 
1333
1334
  const result = cmdJobsMilestonePreview(fixture.cwd, null, true, false);
@@ -1336,7 +1337,7 @@ Plans:
1336
1337
 
1337
1338
  it('throws error when no ROADMAP.md exists', () => {
1338
1339
  fixture = createFixture({
1339
- '.planning/phases/': null,
1340
+ 'phases/': null,
1340
1341
  });
1341
1342
 
1342
1343
  assert.throws(
@@ -1357,7 +1358,7 @@ Plans:
1357
1358
 
1358
1359
  it('finds job in in-progress/ when file exists there', () => {
1359
1360
  fixture = createFixture({
1360
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
1361
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
1361
1362
  });
1362
1363
  const result = findJobFile(fixture.cwd, 'v6.0');
1363
1364
  assert.equal(result.found, true);
@@ -1368,7 +1369,7 @@ Plans:
1368
1369
 
1369
1370
  it('finds job in pending/ when not in in-progress/', () => {
1370
1371
  fixture = createFixture({
1371
- '.planning/jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
1372
+ 'jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
1372
1373
  });
1373
1374
  const result = findJobFile(fixture.cwd, 'v6.0');
1374
1375
  assert.equal(result.found, true);
@@ -1378,8 +1379,8 @@ Plans:
1378
1379
 
1379
1380
  it('prefers in-progress/ over pending/ when file exists in both', () => {
1380
1381
  fixture = createFixture({
1381
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
1382
- '.planning/jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
1382
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
1383
+ 'jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
1383
1384
  });
1384
1385
  const result = findJobFile(fixture.cwd, 'v6.0');
1385
1386
  assert.equal(result.found, true);
@@ -1388,8 +1389,8 @@ Plans:
1388
1389
 
1389
1390
  it('returns found:false when file exists in neither directory', () => {
1390
1391
  fixture = createFixture({
1391
- '.planning/jobs/pending/': null,
1392
- '.planning/jobs/in-progress/': null,
1392
+ 'jobs/pending/': null,
1393
+ 'jobs/in-progress/': null,
1393
1394
  });
1394
1395
  const result = findJobFile(fixture.cwd, 'v6.0');
1395
1396
  assert.equal(result.found, false);
@@ -1397,7 +1398,7 @@ Plans:
1397
1398
 
1398
1399
  it('checks completed/ as fallback for inspection', () => {
1399
1400
  fixture = createFixture({
1400
- '.planning/jobs/completed/milestone-v6.0.md': ALL_COMPLETED_JOB,
1401
+ 'jobs/completed/milestone-v6.0.md': ALL_COMPLETED_JOB,
1401
1402
  });
1402
1403
  const result = findJobFile(fixture.cwd, 'v6.0');
1403
1404
  assert.equal(result.found, true);
@@ -1407,7 +1408,7 @@ Plans:
1407
1408
 
1408
1409
  it('handles version without v prefix (e.g., "6.0" -> milestone-v6.0.md)', () => {
1409
1410
  fixture = createFixture({
1410
- '.planning/jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
1411
+ 'jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
1411
1412
  });
1412
1413
  const result = findJobFile(fixture.cwd, '6.0');
1413
1414
  assert.equal(result.found, true);
@@ -1416,7 +1417,7 @@ Plans:
1416
1417
 
1417
1418
  it('handles version with v prefix correctly', () => {
1418
1419
  fixture = createFixture({
1419
- '.planning/jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
1420
+ 'jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
1420
1421
  });
1421
1422
  const result = findJobFile(fixture.cwd, 'v6.0');
1422
1423
  assert.equal(result.found, true);
@@ -1425,7 +1426,7 @@ Plans:
1425
1426
 
1426
1427
  it('finds job in project subdirectory completed/', () => {
1427
1428
  fixture = createFixture({
1428
- '.planning/projects/test-project/jobs/completed/milestone-v6.0.md': ALL_COMPLETED_JOB,
1429
+ 'projects/test-project/jobs/completed/milestone-v6.0.md': ALL_COMPLETED_JOB,
1429
1430
  });
1430
1431
  const result = findJobFile(fixture.cwd, 'v6.0');
1431
1432
  assert.equal(result.found, true);
@@ -1437,8 +1438,8 @@ Plans:
1437
1438
 
1438
1439
  it('prefers top-level jobs/ over project subdirectory', () => {
1439
1440
  fixture = createFixture({
1440
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
1441
- '.planning/projects/test-project/jobs/completed/milestone-v6.0.md': ALL_COMPLETED_JOB,
1441
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
1442
+ 'projects/test-project/jobs/completed/milestone-v6.0.md': ALL_COMPLETED_JOB,
1442
1443
  });
1443
1444
  const result = findJobFile(fixture.cwd, 'v6.0');
1444
1445
  assert.equal(result.found, true);
@@ -1448,7 +1449,7 @@ Plans:
1448
1449
 
1449
1450
  it('finds job in project subdirectory in-progress/', () => {
1450
1451
  fixture = createFixture({
1451
- '.planning/projects/my-app/jobs/in-progress/milestone-v7.0.md': WELL_FORMED_JOB,
1452
+ 'projects/my-app/jobs/in-progress/milestone-v7.0.md': WELL_FORMED_JOB,
1452
1453
  });
1453
1454
  const result = findJobFile(fixture.cwd, 'v7.0');
1454
1455
  assert.equal(result.found, true);
@@ -1458,8 +1459,8 @@ Plans:
1458
1459
 
1459
1460
  it('returns found:false when not in top-level or project subdirectories', () => {
1460
1461
  fixture = createFixture({
1461
- '.planning/jobs/pending/': null,
1462
- '.planning/projects/test-project/jobs/pending/': null,
1462
+ 'jobs/pending/': null,
1463
+ 'projects/test-project/jobs/pending/': null,
1463
1464
  });
1464
1465
  const result = findJobFile(fixture.cwd, 'v99.0');
1465
1466
  assert.equal(result.found, false);
@@ -1942,9 +1943,9 @@ Plans:
1942
1943
 
1943
1944
  it('returns empty groups when no job files exist in any directory', () => {
1944
1945
  fixture = createFixture({
1945
- '.planning/jobs/pending/': null,
1946
- '.planning/jobs/in-progress/': null,
1947
- '.planning/jobs/completed/': null,
1946
+ 'jobs/pending/': null,
1947
+ 'jobs/in-progress/': null,
1948
+ 'jobs/completed/': null,
1948
1949
  });
1949
1950
  const result = listJobs(fixture.cwd);
1950
1951
 
@@ -1955,8 +1956,8 @@ Plans:
1955
1956
 
1956
1957
  it('returns jobs grouped by status with correct fields', () => {
1957
1958
  fixture = createFixture({
1958
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
1959
- '.planning/jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
1959
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
1960
+ 'jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
1960
1961
  });
1961
1962
  const result = listJobs(fixture.cwd);
1962
1963
 
@@ -1980,7 +1981,7 @@ Plans:
1980
1981
 
1981
1982
  it('shows check flag false when --no-check was used', () => {
1982
1983
  fixture = createFixture({
1983
- '.planning/jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
1984
+ 'jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
1984
1985
  });
1985
1986
  const result = listJobs(fixture.cwd);
1986
1987
 
@@ -1990,7 +1991,7 @@ Plans:
1990
1991
 
1991
1992
  it('handles missing directories gracefully with empty groups', () => {
1992
1993
  fixture = createFixture({
1993
- '.planning/': null,
1994
+ '': null,
1994
1995
  });
1995
1996
  const result = listJobs(fixture.cwd);
1996
1997
 
@@ -2001,7 +2002,7 @@ Plans:
2001
2002
 
2002
2003
  it('each entry includes progress as fraction string like "4/12"', () => {
2003
2004
  fixture = createFixture({
2004
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2005
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2005
2006
  });
2006
2007
  const result = listJobs(fixture.cwd);
2007
2008
  const entry = result.in_progress[0];
@@ -2020,8 +2021,8 @@ Plans:
2020
2021
 
2021
2022
  it('cancels in-progress job: resets [>] steps to [ ], updates Status, moves to pending/', () => {
2022
2023
  fixture = createFixture({
2023
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2024
- '.planning/jobs/pending/': null,
2024
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2025
+ 'jobs/pending/': null,
2025
2026
  });
2026
2027
  const result = cancelJob(fixture.cwd, 'v6.0');
2027
2028
 
@@ -2031,11 +2032,11 @@ Plans:
2031
2032
  assert.equal(result.steps_reset, 1); // one [>] step
2032
2033
 
2033
2034
  // Verify file moved to pending
2034
- assert.ok(fs.existsSync(path.join(fixture.cwd, '.planning', 'jobs', 'pending', 'milestone-v6.0.md')));
2035
- assert.ok(!fs.existsSync(path.join(fixture.cwd, '.planning', 'jobs', 'in-progress', 'milestone-v6.0.md')));
2035
+ assert.ok(fs.existsSync(path.join(fixture.cwd, 'jobs', 'pending', 'milestone-v6.0.md')));
2036
+ assert.ok(!fs.existsSync(path.join(fixture.cwd, 'jobs', 'in-progress', 'milestone-v6.0.md')));
2036
2037
 
2037
2038
  // Verify content: [>] reset to [ ], [x] preserved
2038
- const content = fs.readFileSync(path.join(fixture.cwd, '.planning', 'jobs', 'pending', 'milestone-v6.0.md'), 'utf-8');
2039
+ const content = fs.readFileSync(path.join(fixture.cwd, 'jobs', 'pending', 'milestone-v6.0.md'), 'utf-8');
2039
2040
  assert.ok(content.includes('**Status:** pending'), 'Status should be pending');
2040
2041
  assert.ok(!content.includes('[>]'), 'No in-progress markers should remain');
2041
2042
  // completed steps preserved
@@ -2058,8 +2059,8 @@ Plans:
2058
2059
  - [ ] \`/dgs:execute-phase 42\`
2059
2060
  `;
2060
2061
  fixture = createFixture({
2061
- '.planning/jobs/in-progress/milestone-v6.0.md': twoInProgress,
2062
- '.planning/jobs/pending/': null,
2062
+ 'jobs/in-progress/milestone-v6.0.md': twoInProgress,
2063
+ 'jobs/pending/': null,
2063
2064
  });
2064
2065
  const result = cancelJob(fixture.cwd, 'v6.0');
2065
2066
 
@@ -2069,12 +2070,12 @@ Plans:
2069
2070
 
2070
2071
  it('keeps completed [x] steps marked done', () => {
2071
2072
  fixture = createFixture({
2072
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2073
- '.planning/jobs/pending/': null,
2073
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2074
+ 'jobs/pending/': null,
2074
2075
  });
2075
2076
  cancelJob(fixture.cwd, 'v6.0');
2076
2077
 
2077
- const content = fs.readFileSync(path.join(fixture.cwd, '.planning', 'jobs', 'pending', 'milestone-v6.0.md'), 'utf-8');
2078
+ const content = fs.readFileSync(path.join(fixture.cwd, 'jobs', 'pending', 'milestone-v6.0.md'), 'utf-8');
2078
2079
  const stepLines = content.split('\n').filter(l => l.trim().startsWith('- ['));
2079
2080
  const completedSteps = stepLines.filter(l => l.includes('[x]'));
2080
2081
  assert.ok(completedSteps.length > 0, 'Completed steps should be preserved');
@@ -2082,9 +2083,9 @@ Plans:
2082
2083
 
2083
2084
  it('returns not_found when no job exists for version', () => {
2084
2085
  fixture = createFixture({
2085
- '.planning/jobs/pending/': null,
2086
- '.planning/jobs/in-progress/': null,
2087
- '.planning/jobs/completed/': null,
2086
+ 'jobs/pending/': null,
2087
+ 'jobs/in-progress/': null,
2088
+ 'jobs/completed/': null,
2088
2089
  });
2089
2090
  const result = cancelJob(fixture.cwd, 'v99.0');
2090
2091
 
@@ -2094,7 +2095,7 @@ Plans:
2094
2095
 
2095
2096
  it('returns not_in_progress when job is in pending/', () => {
2096
2097
  fixture = createFixture({
2097
- '.planning/jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
2098
+ 'jobs/pending/milestone-v6.0.md': WELL_FORMED_JOB,
2098
2099
  });
2099
2100
  const result = cancelJob(fixture.cwd, 'v6.0');
2100
2101
 
@@ -2104,7 +2105,7 @@ Plans:
2104
2105
 
2105
2106
  it('returns not_in_progress when job is in completed/', () => {
2106
2107
  fixture = createFixture({
2107
- '.planning/jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2108
+ 'jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2108
2109
  });
2109
2110
  const result = cancelJob(fixture.cwd, 'v5.0');
2110
2111
 
@@ -2124,9 +2125,9 @@ Plans:
2124
2125
 
2125
2126
  it('returns healthy: true with valid directory structure', () => {
2126
2127
  fixture = createFixture({
2127
- '.planning/jobs/pending/': null,
2128
- '.planning/jobs/in-progress/': null,
2129
- '.planning/jobs/completed/': null,
2128
+ 'jobs/pending/': null,
2129
+ 'jobs/in-progress/': null,
2130
+ 'jobs/completed/': null,
2130
2131
  });
2131
2132
  const result = healthCheck(fixture.cwd);
2132
2133
 
@@ -2137,16 +2138,16 @@ Plans:
2137
2138
 
2138
2139
  it('returns healthy: false listing issues for missing directories, then auto-creates them', () => {
2139
2140
  fixture = createFixture({
2140
- '.planning/': null,
2141
+ '': null,
2141
2142
  });
2142
2143
  const result = healthCheck(fixture.cwd);
2143
2144
 
2144
2145
  // Should report missing directories but auto-create them
2145
2146
  assert.ok(Array.isArray(result.directories));
2146
2147
  // After auto-create, directories should exist
2147
- assert.ok(fs.existsSync(path.join(fixture.cwd, '.planning', 'jobs', 'pending')));
2148
- assert.ok(fs.existsSync(path.join(fixture.cwd, '.planning', 'jobs', 'in-progress')));
2149
- assert.ok(fs.existsSync(path.join(fixture.cwd, '.planning', 'jobs', 'completed')));
2148
+ assert.ok(fs.existsSync(path.join(fixture.cwd, 'jobs', 'pending')));
2149
+ assert.ok(fs.existsSync(path.join(fixture.cwd, 'jobs', 'in-progress')));
2150
+ assert.ok(fs.existsSync(path.join(fixture.cwd, 'jobs', 'completed')));
2150
2151
  });
2151
2152
 
2152
2153
  it('validates each job file parses successfully; reports parse failures as issues', () => {
@@ -2157,9 +2158,9 @@ No version or anything
2157
2158
  - [ ] random line
2158
2159
  `;
2159
2160
  fixture = createFixture({
2160
- '.planning/jobs/pending/milestone-v99.0.md': malformedJob,
2161
- '.planning/jobs/in-progress/': null,
2162
- '.planning/jobs/completed/': null,
2161
+ 'jobs/pending/milestone-v99.0.md': malformedJob,
2162
+ 'jobs/in-progress/': null,
2163
+ 'jobs/completed/': null,
2163
2164
  });
2164
2165
  const result = healthCheck(fixture.cwd);
2165
2166
 
@@ -2170,9 +2171,9 @@ No version or anything
2170
2171
 
2171
2172
  it('counts total job files across all directories', () => {
2172
2173
  fixture = createFixture({
2173
- '.planning/jobs/pending/milestone-v7.0.md': EMPTY_STEPS_JOB,
2174
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2175
- '.planning/jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2174
+ 'jobs/pending/milestone-v7.0.md': EMPTY_STEPS_JOB,
2175
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2176
+ 'jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2176
2177
  });
2177
2178
  const result = healthCheck(fixture.cwd);
2178
2179
 
@@ -2191,8 +2192,8 @@ No version or anything
2191
2192
 
2192
2193
  it('returns step list with status annotations', () => {
2193
2194
  fixture = createFixture({
2194
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2195
- '.planning/ROADMAP.md': '# Roadmap',
2195
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2196
+ 'ROADMAP.md': '# Roadmap',
2196
2197
  });
2197
2198
  const result = dryRunPreview(fixture.cwd, 'v6.0');
2198
2199
 
@@ -2204,8 +2205,8 @@ No version or anything
2204
2205
 
2205
2206
  it('each step includes index, command, args, status, display', () => {
2206
2207
  fixture = createFixture({
2207
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2208
- '.planning/ROADMAP.md': '# Roadmap',
2208
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2209
+ 'ROADMAP.md': '# Roadmap',
2209
2210
  });
2210
2211
  const result = dryRunPreview(fixture.cwd, 'v6.0');
2211
2212
 
@@ -2220,8 +2221,8 @@ No version or anything
2220
2221
 
2221
2222
  it('shows resume_from as first non-completed step', () => {
2222
2223
  fixture = createFixture({
2223
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2224
- '.planning/ROADMAP.md': '# Roadmap',
2224
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2225
+ 'ROADMAP.md': '# Roadmap',
2225
2226
  });
2226
2227
  const result = dryRunPreview(fixture.cwd, 'v6.0');
2227
2228
 
@@ -2232,18 +2233,18 @@ No version or anything
2232
2233
 
2233
2234
  it('returns found: false when job does not exist', () => {
2234
2235
  fixture = createFixture({
2235
- '.planning/jobs/pending/': null,
2236
- '.planning/jobs/in-progress/': null,
2237
- '.planning/jobs/completed/': null,
2236
+ 'jobs/pending/': null,
2237
+ 'jobs/in-progress/': null,
2238
+ 'jobs/completed/': null,
2238
2239
  });
2239
2240
  const result = dryRunPreview(fixture.cwd, 'v99.0');
2240
2241
 
2241
2242
  assert.equal(result.found, false);
2242
2243
  });
2243
2244
 
2244
- it('validates preconditions: warns if .planning/ missing or ROADMAP.md missing', () => {
2245
+ it('validates preconditions: warns if ROADMAP.md missing', () => {
2245
2246
  fixture = createFixture({
2246
- '.planning/jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2247
+ 'jobs/in-progress/milestone-v6.0.md': WELL_FORMED_JOB,
2247
2248
  });
2248
2249
  // No ROADMAP.md
2249
2250
  const result = dryRunPreview(fixture.cwd, 'v6.0');
@@ -2265,7 +2266,7 @@ No version or anything
2265
2266
 
2266
2267
  it('produces markdown string with correct header', () => {
2267
2268
  fixture = createFixture({
2268
- '.planning/jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2269
+ 'jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2269
2270
  });
2270
2271
  const result = generateJobSummary(fixture.cwd, 'v5.0');
2271
2272
 
@@ -2277,7 +2278,7 @@ No version or anything
2277
2278
 
2278
2279
  it('includes per-step timing table', () => {
2279
2280
  fixture = createFixture({
2280
- '.planning/jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2281
+ 'jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2281
2282
  });
2282
2283
  const result = generateJobSummary(fixture.cwd, 'v5.0');
2283
2284
 
@@ -2301,7 +2302,7 @@ No version or anything
2301
2302
  - [ ] \`/dgs:verify-work 41\`
2302
2303
  `;
2303
2304
  fixture = createFixture({
2304
- '.planning/jobs/in-progress/milestone-v6.0.md': failedJob,
2305
+ 'jobs/in-progress/milestone-v6.0.md': failedJob,
2305
2306
  });
2306
2307
  const result = generateJobSummary(fixture.cwd, 'v6.0');
2307
2308
 
@@ -2324,7 +2325,7 @@ No version or anything
2324
2325
  - [x] \`/dgs:verify-work 41\` \u2014 completed 2026-03-02T15:30:00Z
2325
2326
  `;
2326
2327
  fixture = createFixture({
2327
- '.planning/jobs/completed/milestone-v6.0.md': autoJob,
2328
+ 'jobs/completed/milestone-v6.0.md': autoJob,
2328
2329
  });
2329
2330
  const result = generateJobSummary(fixture.cwd, 'v6.0');
2330
2331
 
@@ -2333,7 +2334,7 @@ No version or anything
2333
2334
 
2334
2335
  it('handles completed, failed, and cancelled jobs', () => {
2335
2336
  fixture = createFixture({
2336
- '.planning/jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2337
+ 'jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2337
2338
  });
2338
2339
  const result = generateJobSummary(fixture.cwd, 'v5.0');
2339
2340
  assert.equal(result.found, true);
@@ -2342,9 +2343,9 @@ No version or anything
2342
2343
 
2343
2344
  it('returns found: false when job does not exist', () => {
2344
2345
  fixture = createFixture({
2345
- '.planning/jobs/pending/': null,
2346
- '.planning/jobs/in-progress/': null,
2347
- '.planning/jobs/completed/': null,
2346
+ 'jobs/pending/': null,
2347
+ 'jobs/in-progress/': null,
2348
+ 'jobs/completed/': null,
2348
2349
  });
2349
2350
  const result = generateJobSummary(fixture.cwd, 'v99.0');
2350
2351
 
@@ -2353,9 +2354,9 @@ No version or anything
2353
2354
 
2354
2355
  it('includes human verifications section when UAT has human_needed entries', () => {
2355
2356
  fixture = createFixture({
2356
- '.planning/jobs/completed/milestone-v6.0.md': COMPLETED_JOB_V6,
2357
- '.planning/ROADMAP.md': ROADMAP_WITH_PHASE_50,
2358
- '.planning/phases/50-test-phase/50-UAT.md': UAT_WITH_HUMAN_NEEDED,
2357
+ 'jobs/completed/milestone-v6.0.md': COMPLETED_JOB_V6,
2358
+ 'ROADMAP.md': ROADMAP_WITH_PHASE_50,
2359
+ 'phases/50-test-phase/50-UAT.md': UAT_WITH_HUMAN_NEEDED,
2359
2360
  });
2360
2361
  const result = generateJobSummary(fixture.cwd, 'v6.0');
2361
2362
 
@@ -2368,9 +2369,9 @@ No version or anything
2368
2369
 
2369
2370
  it('omits human verifications section when no human_needed entries', () => {
2370
2371
  fixture = createFixture({
2371
- '.planning/jobs/completed/milestone-v6.0.md': COMPLETED_JOB_V6,
2372
- '.planning/ROADMAP.md': ROADMAP_WITH_PHASE_50,
2373
- '.planning/phases/50-test-phase/50-UAT.md': UAT_ALL_PASSED,
2372
+ 'jobs/completed/milestone-v6.0.md': COMPLETED_JOB_V6,
2373
+ 'ROADMAP.md': ROADMAP_WITH_PHASE_50,
2374
+ 'phases/50-test-phase/50-UAT.md': UAT_ALL_PASSED,
2374
2375
  });
2375
2376
  const result = generateJobSummary(fixture.cwd, 'v6.0');
2376
2377
 
@@ -2381,9 +2382,9 @@ No version or anything
2381
2382
 
2382
2383
  it('omits human verifications when no UAT files exist', () => {
2383
2384
  fixture = createFixture({
2384
- '.planning/jobs/completed/milestone-v6.0.md': COMPLETED_JOB_V6,
2385
- '.planning/ROADMAP.md': ROADMAP_WITH_PHASE_50,
2386
- '.planning/phases/50-test-phase/': null,
2385
+ 'jobs/completed/milestone-v6.0.md': COMPLETED_JOB_V6,
2386
+ 'ROADMAP.md': ROADMAP_WITH_PHASE_50,
2387
+ 'phases/50-test-phase/': null,
2387
2388
  });
2388
2389
  const result = generateJobSummary(fixture.cwd, 'v6.0');
2389
2390
 
@@ -2394,9 +2395,9 @@ No version or anything
2394
2395
 
2395
2396
  it('skips UAT files without mode: auto-test', () => {
2396
2397
  fixture = createFixture({
2397
- '.planning/jobs/completed/milestone-v6.0.md': COMPLETED_JOB_V6,
2398
- '.planning/ROADMAP.md': ROADMAP_WITH_PHASE_50,
2399
- '.planning/phases/50-test-phase/50-UAT.md': UAT_MANUAL_WITH_HUMAN_NEEDED,
2398
+ 'jobs/completed/milestone-v6.0.md': COMPLETED_JOB_V6,
2399
+ 'ROADMAP.md': ROADMAP_WITH_PHASE_50,
2400
+ 'phases/50-test-phase/50-UAT.md': UAT_MANUAL_WITH_HUMAN_NEEDED,
2400
2401
  });
2401
2402
  const result = generateJobSummary(fixture.cwd, 'v6.0');
2402
2403
 
@@ -2454,7 +2455,7 @@ No version or anything
2454
2455
  it('generateJobSummary includes Created_by in overview when present', () => {
2455
2456
  const jobWithCreatedBy = WELL_FORMED_JOB_WITH_CREATED_BY.replace('in-progress', 'completed');
2456
2457
  fixture = createFixture({
2457
- '.planning/jobs/completed/milestone-v6.0.md': jobWithCreatedBy,
2458
+ 'jobs/completed/milestone-v6.0.md': jobWithCreatedBy,
2458
2459
  });
2459
2460
  const result = generateJobSummary(fixture.cwd, 'v6.0');
2460
2461
  assert.equal(result.found, true);
@@ -2463,7 +2464,7 @@ No version or anything
2463
2464
 
2464
2465
  it('generateJobSummary omits Created_by in overview when absent', () => {
2465
2466
  fixture = createFixture({
2466
- '.planning/jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2467
+ 'jobs/completed/milestone-v5.0.md': ALL_COMPLETED_JOB,
2467
2468
  });
2468
2469
  const result = generateJobSummary(fixture.cwd, 'v5.0');
2469
2470
  assert.equal(result.found, true);
@@ -2485,7 +2486,7 @@ describe('jobs root-layout', () => {
2485
2486
 
2486
2487
  it('findJobFile resolves jobs dir at root layout', () => {
2487
2488
  fixture = createTempProject({ layout: 'root' });
2488
- // Create a job file at root/jobs/pending/ (not .planning/jobs/pending/)
2489
+ // Create a job file at jobs/pending/
2489
2490
  const jobsDir = path.join(fixture.cwd, 'jobs', 'pending');
2490
2491
  fs.mkdirSync(jobsDir, { recursive: true });
2491
2492
  const jobContent = `# Milestone Job: v1.0\n\n**Version:** v1.0\n**Created:** 2026-01-01T00:00:00Z\n**Status:** pending\n**Check:** true\n\n## Steps\n\n- [ ] \`/dgs:plan-phase 1\`\n`;
@@ -2494,16 +2495,16 @@ describe('jobs root-layout', () => {
2494
2495
  const result = findJobFile(fixture.cwd, 'v1.0');
2495
2496
  assert.equal(result.found, true);
2496
2497
  assert.equal(result.directory, 'pending');
2497
- // Should NOT be at .planning/jobs/
2498
+ // Should be at root jobs/
2498
2499
  assert.ok(result.path.includes(path.join(fixture.cwd, 'jobs')));
2499
- assert.ok(!result.path.includes('.planning'));
2500
+
2500
2501
  });
2501
2502
 
2502
2503
  it('healthCheck creates jobs dirs at root layout', () => {
2503
2504
  fixture = createTempProject({ layout: 'root' });
2504
2505
  const result = healthCheck(fixture.cwd);
2505
2506
  assert.ok(result.directories.length >= 3);
2506
- // Verify dirs were created at root, not at .planning/
2507
+ // Verify dirs were created at root
2507
2508
  assert.ok(fs.existsSync(path.join(fixture.cwd, 'jobs', 'pending')));
2508
2509
  assert.ok(fs.existsSync(path.join(fixture.cwd, 'jobs', 'in-progress')));
2509
2510
  assert.ok(fs.existsSync(path.join(fixture.cwd, 'jobs', 'completed')));
@@ -2573,11 +2574,11 @@ describe('parseJobFile with StartShas', () => {
2573
2574
  const jobContent = `# Milestone Job: v1.0\n\n**Version:** v1.0\n**Created:** 2026-01-01T00:00:00Z\n**Status:** in-progress\n**Check:** true\n**StartShas:** ${JSON.stringify(shaObj)}\n\n## Steps\n\n- [ ] \`/dgs:plan-phase 1\`\n`;
2574
2575
 
2575
2576
  fixture = createFixture({
2576
- '.planning/config.json': '{}',
2577
- '.planning/job.md': jobContent,
2577
+ 'config.json': '{}',
2578
+ 'job.md': jobContent,
2578
2579
  });
2579
2580
 
2580
- const parsed = parseJobFile(path.join(fixture.cwd, '.planning', 'job.md'));
2581
+ const parsed = parseJobFile(path.join(fixture.cwd, 'job.md'));
2581
2582
  assert.deepEqual(parsed.startShas, shaObj);
2582
2583
  });
2583
2584
 
@@ -2585,11 +2586,11 @@ describe('parseJobFile with StartShas', () => {
2585
2586
  const jobContent = `# Milestone Job: v1.0\n\n**Version:** v1.0\n**Created:** 2026-01-01T00:00:00Z\n**Status:** pending\n**Check:** true\n\n## Steps\n\n- [ ] \`/dgs:plan-phase 1\`\n`;
2586
2587
 
2587
2588
  fixture = createFixture({
2588
- '.planning/config.json': '{}',
2589
- '.planning/job.md': jobContent,
2589
+ 'config.json': '{}',
2590
+ 'job.md': jobContent,
2590
2591
  });
2591
2592
 
2592
- const parsed = parseJobFile(path.join(fixture.cwd, '.planning', 'job.md'));
2593
+ const parsed = parseJobFile(path.join(fixture.cwd, 'job.md'));
2593
2594
  assert.equal(parsed.startShas, null);
2594
2595
  });
2595
2596
  });