@zigrivers/scaffold 3.18.1 → 3.19.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 (85) hide show
  1. package/dist/cli/commands/adopt.d.ts.map +1 -1
  2. package/dist/cli/commands/adopt.js +6 -2
  3. package/dist/cli/commands/adopt.js.map +1 -1
  4. package/dist/cli/commands/complete.d.ts.map +1 -1
  5. package/dist/cli/commands/complete.js +1 -1
  6. package/dist/cli/commands/complete.js.map +1 -1
  7. package/dist/cli/commands/dashboard.d.ts.map +1 -1
  8. package/dist/cli/commands/dashboard.js +6 -1
  9. package/dist/cli/commands/dashboard.js.map +1 -1
  10. package/dist/cli/commands/info.d.ts.map +1 -1
  11. package/dist/cli/commands/info.js +2 -2
  12. package/dist/cli/commands/info.js.map +1 -1
  13. package/dist/cli/commands/next.d.ts.map +1 -1
  14. package/dist/cli/commands/next.js +7 -2
  15. package/dist/cli/commands/next.js.map +1 -1
  16. package/dist/cli/commands/next.test.js +95 -0
  17. package/dist/cli/commands/next.test.js.map +1 -1
  18. package/dist/cli/commands/reset.d.ts.map +1 -1
  19. package/dist/cli/commands/reset.js +1 -1
  20. package/dist/cli/commands/reset.js.map +1 -1
  21. package/dist/cli/commands/rework.d.ts.map +1 -1
  22. package/dist/cli/commands/rework.js +6 -1
  23. package/dist/cli/commands/rework.js.map +1 -1
  24. package/dist/cli/commands/run.d.ts.map +1 -1
  25. package/dist/cli/commands/run.js +1 -1
  26. package/dist/cli/commands/run.js.map +1 -1
  27. package/dist/cli/commands/skip.d.ts.map +1 -1
  28. package/dist/cli/commands/skip.js +1 -1
  29. package/dist/cli/commands/skip.js.map +1 -1
  30. package/dist/cli/commands/status.d.ts.map +1 -1
  31. package/dist/cli/commands/status.js +14 -5
  32. package/dist/cli/commands/status.js.map +1 -1
  33. package/dist/cli/commands/status.test.js +60 -0
  34. package/dist/cli/commands/status.test.js.map +1 -1
  35. package/dist/core/pipeline/graph-hash.d.ts +18 -0
  36. package/dist/core/pipeline/graph-hash.d.ts.map +1 -0
  37. package/dist/core/pipeline/graph-hash.js +35 -0
  38. package/dist/core/pipeline/graph-hash.js.map +1 -0
  39. package/dist/core/pipeline/graph-hash.test.d.ts +2 -0
  40. package/dist/core/pipeline/graph-hash.test.d.ts.map +1 -0
  41. package/dist/core/pipeline/graph-hash.test.js +107 -0
  42. package/dist/core/pipeline/graph-hash.test.js.map +1 -0
  43. package/dist/core/pipeline/read-eligible.d.ts +20 -0
  44. package/dist/core/pipeline/read-eligible.d.ts.map +1 -0
  45. package/dist/core/pipeline/read-eligible.js +28 -0
  46. package/dist/core/pipeline/read-eligible.js.map +1 -0
  47. package/dist/core/pipeline/read-eligible.test.d.ts +2 -0
  48. package/dist/core/pipeline/read-eligible.test.d.ts.map +1 -0
  49. package/dist/core/pipeline/read-eligible.test.js +99 -0
  50. package/dist/core/pipeline/read-eligible.test.js.map +1 -0
  51. package/dist/core/pipeline/resolver.d.ts.map +1 -1
  52. package/dist/core/pipeline/resolver.js +24 -1
  53. package/dist/core/pipeline/resolver.js.map +1 -1
  54. package/dist/core/pipeline/resolver.test.js +86 -0
  55. package/dist/core/pipeline/resolver.test.js.map +1 -1
  56. package/dist/core/pipeline/types.d.ts +5 -0
  57. package/dist/core/pipeline/types.d.ts.map +1 -1
  58. package/dist/e2e/eligible-cache.test.d.ts +2 -0
  59. package/dist/e2e/eligible-cache.test.d.ts.map +1 -0
  60. package/dist/e2e/eligible-cache.test.js +104 -0
  61. package/dist/e2e/eligible-cache.test.js.map +1 -0
  62. package/dist/state/root-counter-reader.d.ts +11 -0
  63. package/dist/state/root-counter-reader.d.ts.map +1 -0
  64. package/dist/state/root-counter-reader.js +25 -0
  65. package/dist/state/root-counter-reader.js.map +1 -0
  66. package/dist/state/root-counter-reader.test.d.ts +2 -0
  67. package/dist/state/root-counter-reader.test.d.ts.map +1 -0
  68. package/dist/state/root-counter-reader.test.js +43 -0
  69. package/dist/state/root-counter-reader.test.js.map +1 -0
  70. package/dist/state/state-manager.d.ts +23 -2
  71. package/dist/state/state-manager.d.ts.map +1 -1
  72. package/dist/state/state-manager.js +57 -5
  73. package/dist/state/state-manager.js.map +1 -1
  74. package/dist/state/state-manager.test.js +246 -1
  75. package/dist/state/state-manager.test.js.map +1 -1
  76. package/dist/types/state.d.ts +19 -0
  77. package/dist/types/state.d.ts.map +1 -1
  78. package/dist/types/state.test.d.ts +2 -0
  79. package/dist/types/state.test.d.ts.map +1 -0
  80. package/dist/types/state.test.js +40 -0
  81. package/dist/types/state.test.js.map +1 -0
  82. package/dist/wizard/wizard.d.ts.map +1 -1
  83. package/dist/wizard/wizard.js +3 -1
  84. package/dist/wizard/wizard.js.map +1 -1
  85. package/package.json +1 -1
@@ -0,0 +1,104 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import os from 'node:os';
5
+ import { loadPipelineContext } from '../core/pipeline/context.js';
6
+ import { resolvePipeline } from '../core/pipeline/resolver.js';
7
+ import { StateManager } from '../state/state-manager.js';
8
+ import { StatePathResolver } from '../state/state-path-resolver.js';
9
+ import { readEligible } from '../core/pipeline/read-eligible.js';
10
+ import { readRootSaveCounter } from '../state/root-counter-reader.js';
11
+ import { createOutputContext } from '../cli/output/context.js';
12
+ describe('Eligible-Step Cache v2 — E2E', () => {
13
+ let tmpRoot;
14
+ beforeEach(() => {
15
+ tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'ec2-e2e-'));
16
+ fs.mkdirSync(path.join(tmpRoot, '.scaffold', 'services', 'api'), { recursive: true });
17
+ fs.writeFileSync(path.join(tmpRoot, '.scaffold', 'config.yml'), `version: 2
18
+ methodology: deep
19
+ platforms: [claude-code]
20
+ project:
21
+ services:
22
+ - name: api
23
+ projectType: backend
24
+ backendConfig:
25
+ apiStyle: rest
26
+ `);
27
+ const baseState = {
28
+ 'schema-version': 3,
29
+ 'scaffold-version': '1.0.0',
30
+ init_methodology: 'deep',
31
+ config_methodology: 'deep',
32
+ 'init-mode': 'greenfield',
33
+ created: '2026-04-20T00:00:00.000Z',
34
+ in_progress: null,
35
+ steps: {},
36
+ next_eligible: [],
37
+ 'extra-steps': [],
38
+ };
39
+ fs.writeFileSync(path.join(tmpRoot, '.scaffold', 'state.json'), JSON.stringify(baseState));
40
+ fs.writeFileSync(path.join(tmpRoot, '.scaffold', 'services', 'api', 'state.json'), JSON.stringify(baseState));
41
+ });
42
+ afterEach(() => {
43
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
44
+ });
45
+ it('AC2: service cache is invalidated by root state mutation (cross-file)', () => {
46
+ const context = loadPipelineContext(tmpRoot);
47
+ const output = createOutputContext('auto');
48
+ const rootPipeline = resolvePipeline(context, { output });
49
+ const rootPathResolver = new StatePathResolver(tmpRoot);
50
+ const rootSm = new StateManager(tmpRoot, rootPipeline.computeEligible, () => context.config ?? undefined, rootPathResolver, rootPipeline.globalSteps, rootPipeline.getPipelineHash('global'));
51
+ // Seed root counter by doing an initial root save
52
+ rootSm.saveState(rootSm.loadState());
53
+ const svcPipeline = resolvePipeline(context, { output, serviceId: 'api' });
54
+ const pathResolver = new StatePathResolver(tmpRoot, 'api');
55
+ const sm = new StateManager(tmpRoot, svcPipeline.computeEligible, () => context.config ?? undefined, pathResolver, svcPipeline.globalSteps, svcPipeline.getPipelineHash('service'));
56
+ const state = sm.loadState();
57
+ state.steps['some-step'] = { status: 'pending', source: 'pipeline', produces: [] };
58
+ sm.saveState(state);
59
+ const svcDisk = JSON.parse(fs.readFileSync(path.join(tmpRoot, '.scaffold', 'services', 'api', 'state.json'), 'utf8'));
60
+ expect(svcDisk.next_eligible_root_counter).toBe(1);
61
+ expect(typeof svcDisk.next_eligible_hash).toBe('string');
62
+ // Mutate root — bumps save_counter from 1 to 2
63
+ rootSm.saveState(rootSm.loadState());
64
+ expect(readRootSaveCounter(tmpRoot)).toBe(2);
65
+ // readEligible must fall back because next_eligible_root_counter (1) !== current root counter (2)
66
+ const liveCalls = [];
67
+ const sentinelPipeline = {
68
+ ...svcPipeline,
69
+ computeEligible: ((steps, opts) => {
70
+ liveCalls.push('live-recompute-fired');
71
+ return svcPipeline.computeEligible(steps, opts);
72
+ }),
73
+ };
74
+ readEligible(sm.loadState(), sentinelPipeline, { scope: 'service', globalSteps: svcPipeline.globalSteps }, () => readRootSaveCounter(tmpRoot));
75
+ expect(liveCalls).toContain('live-recompute-fired');
76
+ });
77
+ it('AC3: pipeline-graph change (different hash on re-resolution) invalidates cache on read', () => {
78
+ const context = loadPipelineContext(tmpRoot);
79
+ const output = createOutputContext('auto');
80
+ const pipelineA = resolvePipeline(context, { output });
81
+ const pathResolver = new StatePathResolver(tmpRoot);
82
+ const sm = new StateManager(tmpRoot, pipelineA.computeEligible, () => context.config ?? undefined, pathResolver, pipelineA.globalSteps, pipelineA.getPipelineHash('global'));
83
+ sm.saveState(sm.loadState());
84
+ // Build a new context whose metaPrompts differs — delete first slug
85
+ const firstSlug = [...context.metaPrompts.keys()][0];
86
+ expect(firstSlug).toBeDefined();
87
+ const mutatedMetaPrompts = new Map(context.metaPrompts);
88
+ mutatedMetaPrompts.delete(firstSlug);
89
+ const mutatedContext = { ...context, metaPrompts: mutatedMetaPrompts };
90
+ const pipelineB = resolvePipeline(mutatedContext, { output });
91
+ expect(pipelineB.getPipelineHash('global')).not.toBe(pipelineA.getPipelineHash('global'));
92
+ const liveCalls = [];
93
+ const sentinelPipeline = {
94
+ ...pipelineB,
95
+ computeEligible: ((steps, opts) => {
96
+ liveCalls.push('live-fired');
97
+ return pipelineB.computeEligible(steps, opts);
98
+ }),
99
+ };
100
+ readEligible(sm.loadState(), sentinelPipeline, undefined, undefined);
101
+ expect(liveCalls).toContain('live-fired');
102
+ });
103
+ });
104
+ //# sourceMappingURL=eligible-cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eligible-cache.test.js","sourceRoot":"","sources":["../../src/e2e/eligible-cache.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Reads `.scaffold/state.json` and returns the `save_counter` field.
3
+ * Returns null on any failure (missing file, invalid JSON, missing field).
4
+ *
5
+ * Used by service-scope cache readers (readEligible) to verify that the
6
+ * service's cached next_eligible was written against the current root state
7
+ * (spec §6). Not used at cache WRITE time — StateManager captures the counter
8
+ * internally during loadState to avoid TOCTOU.
9
+ */
10
+ export declare function readRootSaveCounter(projectRoot: string): number | null;
11
+ //# sourceMappingURL=root-counter-reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-counter-reader.d.ts","sourceRoot":"","sources":["../../src/state/root-counter-reader.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUtE"}
@@ -0,0 +1,25 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ /**
4
+ * Reads `.scaffold/state.json` and returns the `save_counter` field.
5
+ * Returns null on any failure (missing file, invalid JSON, missing field).
6
+ *
7
+ * Used by service-scope cache readers (readEligible) to verify that the
8
+ * service's cached next_eligible was written against the current root state
9
+ * (spec §6). Not used at cache WRITE time — StateManager captures the counter
10
+ * internally during loadState to avoid TOCTOU.
11
+ */
12
+ export function readRootSaveCounter(projectRoot) {
13
+ const rootStatePath = path.join(projectRoot, '.scaffold', 'state.json');
14
+ try {
15
+ if (!fs.existsSync(rootStatePath))
16
+ return null;
17
+ const raw = JSON.parse(fs.readFileSync(rootStatePath, 'utf8'));
18
+ const counter = raw['save_counter'];
19
+ return typeof counter === 'number' ? counter : null;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ //# sourceMappingURL=root-counter-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-counter-reader.js","sourceRoot":"","sources":["../../src/state/root-counter-reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACrD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC,CAAA;IACvE,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,OAAO,IAAI,CAAA;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAA4B,CAAA;QACzF,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,CAAC,CAAA;QACnC,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=root-counter-reader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-counter-reader.test.d.ts","sourceRoot":"","sources":["../../src/state/root-counter-reader.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,43 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import os from 'node:os';
5
+ import { readRootSaveCounter } from './root-counter-reader.js';
6
+ describe('readRootSaveCounter', () => {
7
+ let tmpRoot;
8
+ beforeEach(() => {
9
+ tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'rcr-'));
10
+ fs.mkdirSync(path.join(tmpRoot, '.scaffold'), { recursive: true });
11
+ });
12
+ afterEach(() => {
13
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
14
+ });
15
+ it('returns null when root state file is missing', () => {
16
+ expect(readRootSaveCounter(tmpRoot)).toBeNull();
17
+ });
18
+ it('returns the counter when state file has a valid save_counter', () => {
19
+ fs.writeFileSync(path.join(tmpRoot, '.scaffold', 'state.json'), JSON.stringify({ save_counter: 42, 'schema-version': 3 }));
20
+ expect(readRootSaveCounter(tmpRoot)).toBe(42);
21
+ });
22
+ it('returns null when state file has invalid JSON', () => {
23
+ fs.writeFileSync(path.join(tmpRoot, '.scaffold', 'state.json'), '{ not valid json');
24
+ expect(readRootSaveCounter(tmpRoot)).toBeNull();
25
+ });
26
+ it('returns null when state file lacks save_counter (legacy file)', () => {
27
+ fs.writeFileSync(path.join(tmpRoot, '.scaffold', 'state.json'), JSON.stringify({ 'schema-version': 3 }));
28
+ expect(readRootSaveCounter(tmpRoot)).toBeNull();
29
+ });
30
+ it('returns null when save_counter is non-number (Codex + Gemini MMR coverage lock)', () => {
31
+ // Coverage lock: regression guard against a future change that forgets
32
+ // the typeof check and coerces with Number() or String().
33
+ fs.writeFileSync(path.join(tmpRoot, '.scaffold', 'state.json'), JSON.stringify({ save_counter: '42', 'schema-version': 3 }));
34
+ expect(readRootSaveCounter(tmpRoot)).toBeNull();
35
+ });
36
+ it('returns 0 (not null) when save_counter is the number zero', () => {
37
+ // Coverage lock: 0 is a valid counter value (truthy-confusing). A future
38
+ // refactor from `typeof === "number"` to `if (counter)` would regress.
39
+ fs.writeFileSync(path.join(tmpRoot, '.scaffold', 'state.json'), JSON.stringify({ save_counter: 0, 'schema-version': 3 }));
40
+ expect(readRootSaveCounter(tmpRoot)).toBe(0);
41
+ });
42
+ });
43
+ //# sourceMappingURL=root-counter-reader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root-counter-reader.test.js","sourceRoot":"","sources":["../../src/state/root-counter-reader.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AACpE,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,OAAe,CAAA;IAEnB,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAA;QACxD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,EAC7C,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAC1D,CAAA;QACD,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,EAAE,kBAAkB,CAAC,CAAA;QACnF,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,EAC7C,IAAI,CAAC,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CACxC,CAAA;QACD,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,uEAAuE;QACvE,0DAA0D;QAC1D,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,EAC7C,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAC5D,CAAA;QACD,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,yEAAyE;QACzE,uEAAuE;QACvE,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,EAC7C,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CACzD,CAAA;QACD,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -6,13 +6,34 @@ export declare class StateManager {
6
6
  private computeEligible;
7
7
  private configProvider?;
8
8
  private globalSteps?;
9
+ /**
10
+ * Pipeline-graph hash for the manager's scope. If omitted, saveState writes
11
+ * `next_eligible_hash: undefined`, which consumers treat as invalid cache
12
+ * (live recompute). Legacy-safe default.
13
+ */
14
+ private pipelineHash?;
9
15
  private statePath;
10
16
  private pathResolver;
11
- constructor(projectRoot: string, computeEligible: (steps: Record<string, StepStateEntry>) => string[], configProvider?: (() => {
17
+ /**
18
+ * Captured during service-mode loadState. Used by saveState to stamp
19
+ * next_eligible_root_counter TOCTOU-safely (spec §3). `undefined` = never
20
+ * loaded; `null` = loaded but root file had no save_counter (legacy).
21
+ */
22
+ private loadedRootCounter;
23
+ constructor(projectRoot: string, computeEligible: (steps: Record<string, StepStateEntry>, options?: {
24
+ scope?: 'global' | 'service';
25
+ globalSteps?: Set<string>;
26
+ }) => string[], configProvider?: (() => {
12
27
  project?: {
13
28
  services?: unknown[];
14
29
  };
15
- } | undefined) | undefined, pathResolver?: StatePathResolver, globalSteps?: Set<string> | undefined);
30
+ } | undefined) | undefined, pathResolver?: StatePathResolver, globalSteps?: Set<string> | undefined,
31
+ /**
32
+ * Pipeline-graph hash for the manager's scope. If omitted, saveState writes
33
+ * `next_eligible_hash: undefined`, which consumers treat as invalid cache
34
+ * (live recompute). Legacy-safe default.
35
+ */
36
+ pipelineHash?: string | undefined);
16
37
  /** Load and validate state.json from disk. Throws ScaffoldError on schema mismatch. */
17
38
  loadState(): PipelineState;
18
39
  /** Atomically persist state to disk (write tmp + rename). */
@@ -1 +1 @@
1
- {"version":3,"file":"state-manager.d.ts","sourceRoot":"","sources":["../../src/state/state-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAChH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAKtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAK5D,qBAAa,YAAY;IAKrB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,cAAc,CAAC;IAEvB,OAAO,CAAC,WAAW,CAAC;IARtB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,YAAY,CAAmB;gBAG7B,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,MAAM,EAAE,EACpE,cAAc,CAAC,GAAE,MAAM;QAAE,OAAO,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;SAAE,CAAA;KAAE,GAAG,SAAS,aAAA,EACjF,YAAY,CAAC,EAAE,iBAAiB,EACxB,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,YAAA;IAMnC,uFAAuF;IACvF,SAAS,IAAI,aAAa;IAmD1B,6DAA6D;IAC7D,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAerC,0EAA0E;IAC1E,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAoBhD,uEAAuE;IACvE,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAoB5F,4DAA4D;IAC5D,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAUlE,uEAAuE;IACvE,eAAe,IAAI,IAAI;IAMvB,6EAA6E;IAC7E,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAKnD;;;;;;;OAOG;IACH,qBAAqB,CACnB,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,GAC3E,OAAO;IAwBV;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE;QACvB,YAAY,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAA;QACzD,eAAe,EAAE,MAAM,CAAA;QACvB,WAAW,EAAE,MAAM,CAAA;QACnB,QAAQ,EAAE,YAAY,GAAG,YAAY,GAAG,cAAc,CAAA;QAGtD,MAAM,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE;gBAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;aAAE,CAAA;SAAE,CAAA;KAChD,GAAG,IAAI;IA8BR;;;;;OAKG;IACH,MAAM,CAAC,iBAAiB,CACtB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,iBAAiB,EAC/B,cAAc,CAAC,EAAE,MAAM;QAAE,OAAO,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;SAAE,CAAA;KAAE,GAAG,SAAS,GACxE,aAAa;CAmCjB;AAGD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAA"}
1
+ {"version":3,"file":"state-manager.d.ts","sourceRoot":"","sources":["../../src/state/state-manager.ts"],"names":[],"mappings":"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"}
@@ -10,13 +10,27 @@ export class StateManager {
10
10
  computeEligible;
11
11
  configProvider;
12
12
  globalSteps;
13
+ pipelineHash;
13
14
  statePath;
14
15
  pathResolver;
15
- constructor(projectRoot, computeEligible, configProvider, pathResolver, globalSteps) {
16
+ /**
17
+ * Captured during service-mode loadState. Used by saveState to stamp
18
+ * next_eligible_root_counter TOCTOU-safely (spec §3). `undefined` = never
19
+ * loaded; `null` = loaded but root file had no save_counter (legacy).
20
+ */
21
+ loadedRootCounter = undefined;
22
+ constructor(projectRoot, computeEligible, configProvider, pathResolver, globalSteps,
23
+ /**
24
+ * Pipeline-graph hash for the manager's scope. If omitted, saveState writes
25
+ * `next_eligible_hash: undefined`, which consumers treat as invalid cache
26
+ * (live recompute). Legacy-safe default.
27
+ */
28
+ pipelineHash) {
16
29
  this.projectRoot = projectRoot;
17
30
  this.computeEligible = computeEligible;
18
31
  this.configProvider = configProvider;
19
32
  this.globalSteps = globalSteps;
33
+ this.pipelineHash = pipelineHash;
20
34
  this.pathResolver = pathResolver ?? new StatePathResolver(projectRoot);
21
35
  this.statePath = this.pathResolver.statePath;
22
36
  }
@@ -62,20 +76,58 @@ export class StateManager {
62
76
  const globalState = globalParsed;
63
77
  // Merge: global steps as base, service steps override
64
78
  state.steps = { ...globalState.steps, ...state.steps };
79
+ // Capture root's save_counter at the SAME read moment (TOCTOU-safe, spec §3)
80
+ this.loadedRootCounter =
81
+ typeof globalParsed['save_counter'] === 'number'
82
+ ? globalParsed['save_counter']
83
+ : null;
84
+ }
85
+ else {
86
+ // Root state file missing — treat as legacy (null counter)
87
+ this.loadedRootCounter = null;
65
88
  }
66
89
  }
67
90
  return state;
68
91
  }
69
92
  /** Atomically persist state to disk (write tmp + rename). */
70
93
  saveState(state) {
71
- state.next_eligible = this.computeEligible(state.steps);
94
+ const isService = this.pathResolver.isServiceScoped && this.globalSteps;
95
+ const scopeOptions = isService
96
+ ? { scope: 'service', globalSteps: this.globalSteps }
97
+ : undefined;
98
+ // FIXES ORIGINAL P0: compute with proper scope so service state only caches
99
+ // service-eligible steps.
100
+ state.next_eligible = this.computeEligible(state.steps, scopeOptions);
101
+ state.next_eligible_hash = this.pipelineHash;
102
+ if (isService) {
103
+ // Cross-file invalidation stamp: capture root counter at load time,
104
+ // reuse at save time (TOCTOU-safe per spec §3). Only stamp when a concrete
105
+ // counter value was captured; under strict `exactOptionalPropertyTypes`,
106
+ // omitting the key (via delete) is safer than assigning `undefined`.
107
+ if (typeof this.loadedRootCounter === 'number') {
108
+ state.next_eligible_root_counter = this.loadedRootCounter;
109
+ }
110
+ else {
111
+ delete state.next_eligible_root_counter;
112
+ }
113
+ // Spec §1 exclusivity: service saves must NEVER write save_counter on
114
+ // their own state. Strip any leftover (e.g. from a previously-polluted
115
+ // file) before persisting.
116
+ delete state.save_counter;
117
+ }
118
+ else {
119
+ // Root state: bump the monotonic counter.
120
+ state.save_counter = (state.save_counter ?? 0) + 1;
121
+ // Spec §1 exclusivity: root state doesn't carry next_eligible_root_counter.
122
+ delete state.next_eligible_root_counter;
123
+ }
124
+ // Existing global-step stripping for service-mode persisted steps
72
125
  let stateToWrite = state;
73
- if (this.pathResolver.isServiceScoped && this.globalSteps) {
126
+ if (isService) {
74
127
  const filteredSteps = {};
75
128
  for (const [name, entry] of Object.entries(state.steps)) {
76
- if (!this.globalSteps.has(name)) {
129
+ if (!this.globalSteps.has(name))
77
130
  filteredSteps[name] = entry;
78
- }
79
131
  }
80
132
  stateToWrite = { ...state, steps: filteredSteps };
81
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"state-manager.js","sourceRoot":"","sources":["../../src/state/state-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state-manager.js","sourceRoot":"","sources":["../../src/state/state-manager.ts"],"names":[],"mappings":"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"}