gsd-pi 2.31.1-dev.ffe48ad → 2.31.2-dev.2453512

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 (37) hide show
  1. package/dist/resources/extensions/gsd/auto-constants.ts +6 -0
  2. package/dist/resources/extensions/gsd/auto-dashboard.ts +20 -26
  3. package/dist/resources/extensions/gsd/auto-direct-dispatch.ts +1 -6
  4. package/dist/resources/extensions/gsd/auto-dispatch.ts +18 -22
  5. package/dist/resources/extensions/gsd/auto-post-unit.ts +27 -32
  6. package/dist/resources/extensions/gsd/auto-prompts.ts +43 -46
  7. package/dist/resources/extensions/gsd/auto-start.ts +4 -4
  8. package/dist/resources/extensions/gsd/auto.ts +54 -33
  9. package/dist/resources/extensions/gsd/commands-workflow-templates.ts +3 -5
  10. package/dist/resources/extensions/gsd/git-service.ts +9 -0
  11. package/dist/resources/extensions/gsd/guided-flow-queue.ts +1 -8
  12. package/dist/resources/extensions/gsd/preferences-types.ts +8 -0
  13. package/dist/resources/extensions/gsd/preferences-validation.ts +3 -10
  14. package/dist/resources/extensions/gsd/prompts/run-uat.md +1 -42
  15. package/dist/resources/extensions/gsd/quick.ts +3 -5
  16. package/dist/resources/extensions/gsd/tests/auto-reentrancy-guard.test.ts +127 -0
  17. package/dist/resources/extensions/gsd/tests/run-uat.test.ts +101 -2
  18. package/package.json +1 -1
  19. package/packages/pi-coding-agent/package.json +1 -1
  20. package/pkg/package.json +1 -1
  21. package/src/resources/extensions/gsd/auto-constants.ts +6 -0
  22. package/src/resources/extensions/gsd/auto-dashboard.ts +20 -26
  23. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -6
  24. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -22
  25. package/src/resources/extensions/gsd/auto-post-unit.ts +27 -32
  26. package/src/resources/extensions/gsd/auto-prompts.ts +43 -46
  27. package/src/resources/extensions/gsd/auto-start.ts +4 -4
  28. package/src/resources/extensions/gsd/auto.ts +54 -33
  29. package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -5
  30. package/src/resources/extensions/gsd/git-service.ts +9 -0
  31. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -8
  32. package/src/resources/extensions/gsd/preferences-types.ts +8 -0
  33. package/src/resources/extensions/gsd/preferences-validation.ts +3 -10
  34. package/src/resources/extensions/gsd/prompts/run-uat.md +1 -42
  35. package/src/resources/extensions/gsd/quick.ts +3 -5
  36. package/src/resources/extensions/gsd/tests/auto-reentrancy-guard.test.ts +127 -0
  37. package/src/resources/extensions/gsd/tests/run-uat.test.ts +101 -2
@@ -6,6 +6,8 @@
6
6
  // (a)–(j) extractUatType classification (17 assertions from T01)
7
7
  // (k) run-uat prompt template loading and content integrity (8 assertions)
8
8
  // (l) dispatch precondition assertions via resolveSliceFile (4 assertions)
9
+ // (m) non-artifact UAT skip: human-experience UATs are not dispatched (1 assertion)
10
+ // (n) stale replay guard: existing UAT-RESULT never re-dispatches (1 assertion)
9
11
 
10
12
  import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
11
13
  import { join, dirname } from 'node:path';
@@ -14,6 +16,7 @@ import { fileURLToPath } from 'node:url';
14
16
 
15
17
  import { extractUatType } from '../files.ts';
16
18
  import { resolveSliceFile } from '../paths.ts';
19
+ import { checkNeedsRunUat } from '../auto-prompts.ts';
17
20
  import { createTestContext } from './test-helpers.ts';
18
21
 
19
22
  // ─── Worktree-aware prompt loader ──────────────────────────────────────────
@@ -252,8 +255,8 @@ async function main(): Promise<void> {
252
255
  'prompt contains artifact-driven execution language (artifact/execute/run)',
253
256
  );
254
257
  assertTrue(
255
- /surfaced for human review/i.test(promptResult ?? ''),
256
- 'prompt contains "surfaced for human review" text for non-artifact-driven path',
258
+ !/surfaced for human review/i.test(promptResult ?? ''),
259
+ 'prompt does not contain "surfaced for human review" (non-artifact UATs are skipped, not dispatched)',
257
260
  );
258
261
 
259
262
  // ─── (l) dispatch precondition assertions via resolveSliceFile ────────────
@@ -308,6 +311,102 @@ async function main(): Promise<void> {
308
311
  }
309
312
  }
310
313
 
314
+ // ─── (m) non-artifact UATs are skipped (not dispatched) ─────────────────
315
+ console.log('\n── (m) non-artifact UAT skip');
316
+
317
+ {
318
+ const base = createFixtureBase();
319
+ try {
320
+ const roadmapDir = join(base, '.gsd', 'milestones', 'M001');
321
+ mkdirSync(roadmapDir, { recursive: true });
322
+ writeFileSync(
323
+ join(roadmapDir, 'M001-ROADMAP.md'),
324
+ [
325
+ '# M001: Test roadmap',
326
+ '',
327
+ '## Slices',
328
+ '',
329
+ '- [x] **S01: First slice** `risk:low` `depends:[]`',
330
+ '- [ ] **S02: Next slice** `risk:low` `depends:[S01]`',
331
+ '',
332
+ '## Boundary Map',
333
+ '',
334
+ ].join('\n'),
335
+ );
336
+
337
+ // human-experience UAT — should not dispatch
338
+ writeSliceFile(base, 'M001', 'S01', 'UAT', makeUatContent('human-experience'));
339
+
340
+ const state = {
341
+ activeMilestone: { id: 'M001', title: 'Test roadmap' },
342
+ activeSlice: { id: 'S02', title: 'Next slice' },
343
+ activeTask: null,
344
+ phase: 'planning',
345
+ recentDecisions: [],
346
+ blockers: [],
347
+ nextAction: 'Plan S02',
348
+ registry: [],
349
+ } as const;
350
+
351
+ const result = await checkNeedsRunUat(base, 'M001', state as any, { uat_dispatch: true } as any);
352
+ assertEq(
353
+ result,
354
+ null,
355
+ 'human-experience UAT is skipped — auto-mode only dispatches artifact-driven UATs',
356
+ );
357
+ } finally {
358
+ cleanup(base);
359
+ }
360
+ }
361
+
362
+ // ─── (n) existing UAT-RESULT never re-dispatches ──────────────────────
363
+ console.log('\n── (n) stale replay guard');
364
+
365
+ {
366
+ const base = createFixtureBase();
367
+ try {
368
+ const roadmapDir = join(base, '.gsd', 'milestones', 'M001');
369
+ mkdirSync(roadmapDir, { recursive: true });
370
+ writeFileSync(
371
+ join(roadmapDir, 'M001-ROADMAP.md'),
372
+ [
373
+ '# M001: Test roadmap',
374
+ '',
375
+ '## Slices',
376
+ '',
377
+ '- [x] **S01: First slice** `risk:low` `depends:[]`',
378
+ '- [ ] **S02: Next slice** `risk:low` `depends:[S01]`',
379
+ '',
380
+ '## Boundary Map',
381
+ '',
382
+ ].join('\n'),
383
+ );
384
+
385
+ writeSliceFile(base, 'M001', 'S01', 'UAT', makeUatContent('artifact-driven'));
386
+ writeSliceFile(base, 'M001', 'S01', 'UAT-RESULT', '---\nverdict: FAIL\n---\n');
387
+
388
+ const state = {
389
+ activeMilestone: { id: 'M001', title: 'Test roadmap' },
390
+ activeSlice: { id: 'S02', title: 'Next slice' },
391
+ activeTask: null,
392
+ phase: 'planning',
393
+ recentDecisions: [],
394
+ blockers: [],
395
+ nextAction: 'Plan S02',
396
+ registry: [],
397
+ } as const;
398
+
399
+ const result = await checkNeedsRunUat(base, 'M001', state as any, { uat_dispatch: true } as any);
400
+ assertEq(
401
+ result,
402
+ null,
403
+ 'existing UAT-RESULT with FAIL verdict does not re-dispatch; verdict gate owns blocking',
404
+ );
405
+ } finally {
406
+ cleanup(base);
407
+ }
408
+ }
409
+
311
410
  report();
312
411
  }
313
412