agentic-workflow-manager 9.21.0 → 9.22.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 (71) hide show
  1. package/dist/src/commands/change/index.js +16 -5
  2. package/dist/src/commands/init.js +8 -4
  3. package/dist/src/commands/preflight/checks.js +22 -0
  4. package/dist/src/commands/registry/add.js +9 -3
  5. package/dist/src/commands/sensors/compatibility/contract.js +56 -3
  6. package/dist/src/commands/sensors/compatibility/manifest.js +16 -2
  7. package/dist/src/commands/sensors/index.js +10 -1
  8. package/dist/src/commands/sensors/inputs-digest.js +315 -0
  9. package/dist/src/commands/sensors/prepare.js +10 -0
  10. package/dist/src/commands/sensors/result-cache.js +278 -0
  11. package/dist/src/commands/sensors/result.js +31 -12
  12. package/dist/src/commands/sensors/run.js +265 -8
  13. package/dist/src/commands/sensors/status.js +66 -7
  14. package/dist/src/commands/sync.js +11 -5
  15. package/dist/src/commands/update.js +23 -12
  16. package/dist/src/core/changes/derive.js +6 -3
  17. package/dist/src/core/changes/git.js +1 -2
  18. package/dist/src/core/changes/receipt.js +219 -9
  19. package/dist/src/core/changes/worktree.js +15 -3
  20. package/dist/src/core/init/steps.js +3 -8
  21. package/dist/src/core/registries.js +20 -15
  22. package/dist/src/core/registry-git-errors.js +107 -0
  23. package/dist/src/core/registry-git.js +93 -0
  24. package/dist/src/core/registry-sync-report.js +74 -0
  25. package/dist/src/core/versioning.js +3 -6
  26. package/dist/src/index.js +5 -8
  27. package/dist/tests/commands/change/new.test.js +104 -58
  28. package/dist/tests/commands/change/validate-unmeasured.test.js +246 -0
  29. package/dist/tests/commands/change/validate.test.js +164 -108
  30. package/dist/tests/commands/changes/list.test.js +41 -22
  31. package/dist/tests/commands/job/gate-reconcile.test.js +13 -2
  32. package/dist/tests/commands/preflight/sensors-inputs.test.js +110 -0
  33. package/dist/tests/commands/registry-sync-honesty.test.js +175 -0
  34. package/dist/tests/commands/sensors/compatibility/contract.test.js +60 -0
  35. package/dist/tests/commands/sensors/compatibility/manifest.test.js +94 -0
  36. package/dist/tests/commands/sensors/exec.test.js +3 -1
  37. package/dist/tests/commands/sensors/inputs-digest.test.js +373 -0
  38. package/dist/tests/commands/sensors/result-cache.test.js +352 -0
  39. package/dist/tests/commands/sensors/run-cache.test.js +434 -0
  40. package/dist/tests/commands/sensors/run-slice.test.js +171 -0
  41. package/dist/tests/commands/sensors/status-inputs.test.js +271 -0
  42. package/dist/tests/commands/update.test.js +8 -8
  43. package/dist/tests/commands/watch/supervisor-loop.test.js +21 -5
  44. package/dist/tests/core/changes/helpers.js +15 -3
  45. package/dist/tests/core/changes/list-paging.test.js +131 -110
  46. package/dist/tests/core/changes/list.test.js +133 -83
  47. package/dist/tests/core/changes/receipt.test.js +279 -8
  48. package/dist/tests/core/diagnostics/provider-checks.test.js +3 -0
  49. package/dist/tests/core/init/steps-registry-sync.test.js +6 -8
  50. package/dist/tests/core/registry-git.test.js +153 -0
  51. package/dist/tests/helpers/commit-seeded-registry.js +18 -0
  52. package/dist/tests/integration/codex-provider-isolated.test.js +7 -2
  53. package/dist/tests/integration/copilot-init-isolated.test.js +7 -4
  54. package/dist/tests/structural/active-documentation.test.js +0 -41
  55. package/dist/tests/structural/bundle-skill-reference-contract.test.js +0 -12
  56. package/dist/tests/structural/cli-reference-matches-commander.test.js +94 -0
  57. package/dist/tests/structural/native-release-artifacts.test.js +116 -107
  58. package/dist/tests/structural/sensor-documentation-contract.test.js +0 -47
  59. package/dist/tests/structural/sensor-portability-contract.test.js +0 -7
  60. package/dist/tests/structural/simple-git-v4-pin.test.js +49 -0
  61. package/package.json +3 -2
  62. package/prebuilds/darwin-arm64/secure_fs.node +0 -0
  63. package/prebuilds/darwin-x64/secure_fs.node +0 -0
  64. package/prebuilds/win32-arm64/secure_fs.node +0 -0
  65. package/prebuilds/win32-x64/secure_fs.node +0 -0
  66. package/dist/tests/structural/cloud-admission-docs-contract.test.js +0 -54
  67. package/dist/tests/structural/documentation-phase-is-mechanized.test.js +0 -29
  68. package/dist/tests/structural/operator-environments-docs-contract.test.js +0 -70
  69. package/dist/tests/structural/process-model-description-contract.test.js +0 -34
  70. package/dist/tests/structural/project-declared-sensors-docs-contract.test.js +0 -104
  71. package/dist/tests/structural/r4-plan-currentness-docs.test.js +0 -37
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const fs_1 = __importDefault(require("fs"));
40
+ const path_1 = __importDefault(require("path"));
41
+ const helpers_1 = require("../../core/changes/helpers");
42
+ const change_1 = require("../../../src/commands/change");
43
+ const receipt_1 = require("../../../src/core/changes/receipt");
44
+ const types_1 = require("../../../src/core/changes/types");
45
+ const gitModule = __importStar(require("../../../src/core/changes/git"));
46
+ const REAL_CHANGES_DIR = path_1.default.resolve(__dirname, '..', '..', '..', '..', 'docs', 'changes');
47
+ const listReal = () => { try {
48
+ return fs_1.default.readdirSync(REAL_CHANGES_DIR).sort();
49
+ }
50
+ catch {
51
+ return null;
52
+ } };
53
+ const realBefore = listReal();
54
+ afterEach(() => expect(listReal()).toEqual(realBefore));
55
+ let repo;
56
+ let template;
57
+ const now = () => new Date('2026-10-17T12:00:00.000Z');
58
+ const REL = 'docs/changes/2026-10-17-rec.md';
59
+ const abs = (rel) => path_1.default.join(repo.root, ...rel.split('/'));
60
+ beforeAll(() => {
61
+ template = (0, helpers_1.makeRepo)();
62
+ template.git('checkout', '-q', '-b', 'feat/x');
63
+ // Track sensors.json / baseline for RF-4.5 always-measured late-path cases (default makeRepo ignores `.awm/`).
64
+ template.commit({
65
+ '.gitignore': 'node_modules\n.awm/sensors/runs\n.awm/journal\n.awm/ledger\n.awm/evidence\n',
66
+ 'cli/src/a.ts': '1',
67
+ 'cli/package.json': '{"name":"cli"}',
68
+ 'cli/package-lock.json': '{"lockfileVersion":3}',
69
+ '.awm/sensors.json': '{"schemaVersion":2,"pack":"js-ts","sensors":{}}',
70
+ '.awm/sensors.baseline.json': '{}',
71
+ 'README.md': '# root\n',
72
+ }, 'feat(changes): a');
73
+ });
74
+ afterAll(() => template.cleanup());
75
+ beforeEach(() => { repo = (0, helpers_1.cloneRepo)(template); });
76
+ afterEach(() => { jest.restoreAllMocks(); repo.cleanup(); });
77
+ const DIGEST = `sha256:${'a'.repeat(64)}`;
78
+ const FINGERPRINT = `sha256:${'b'.repeat(64)}`;
79
+ function measurement(overrides = {}) {
80
+ return {
81
+ inputs: ['src/**/*.ts'],
82
+ packageRootRel: 'cli',
83
+ inputDigest: DIGEST,
84
+ sensorFingerprint: FINGERPRINT,
85
+ measuredPaths: ['cli/src/a.ts', '.awm/sensors.json', 'cli/package.json', 'cli/package-lock.json'],
86
+ ...overrides,
87
+ };
88
+ }
89
+ function writeSchema2Receipt(args) {
90
+ const head = repo.git('rev-parse', 'HEAD');
91
+ const sensors = args.sensors.map((name) => ({
92
+ name,
93
+ status: 'pass',
94
+ errors: [],
95
+ ...(args.measurements?.[name]
96
+ ? { measurement: args.measurements[name] }
97
+ : {}),
98
+ }));
99
+ (0, receipt_1.writeReceipt)(repo.root, (0, receipt_1.buildReceipt)({
100
+ commit: head,
101
+ ranAt: '2026-10-17T11:00:00.000Z',
102
+ cliVersion: '9.21.0',
103
+ output: { overall: 'pass', sensors },
104
+ alwaysMeasuredPaths: args.alwaysMeasuredPaths ?? [
105
+ '.awm/sensors.json',
106
+ '.awm/sensors.baseline.json',
107
+ 'cli/package.json',
108
+ 'cli/package-lock.json',
109
+ ],
110
+ }));
111
+ }
112
+ function commitRecord(slug = 'rec', receipt = () => writeSchema2Receipt({
113
+ sensors: ['lint', 'typecheck'],
114
+ measurements: { lint: measurement(), typecheck: measurement({ inputs: ['src/**/*.ts'] }) },
115
+ })) {
116
+ receipt();
117
+ expect((0, change_1.runChangeNew)(repo.root, slug, {}, { now }).code).toBe(0);
118
+ const rel = `docs/changes/2026-10-17-${slug}.md`;
119
+ fs_1.default.writeFileSync(abs(rel), fs_1.default.readFileSync(abs(rel), 'utf8').split(types_1.PENDING_MARKER).join('filled'));
120
+ repo.git('add', '-A');
121
+ repo.git('commit', '-q', '-m', `docs(changes): ${slug}`);
122
+ return rel;
123
+ }
124
+ const run = (target = undefined, opts = {}) => (0, change_1.runChangeValidate)(repo.root, target, { json: true, ...opts });
125
+ const report = (r) => JSON.parse(r.stdout);
126
+ const diagsOf = (r, index = 0) => report(r).records[index].diagnostics;
127
+ const codesOf = (r, index = 0) => diagsOf(r, index).map((d) => d.code);
128
+ function diag(r, code, field) {
129
+ const found = diagsOf(r).filter((d) => d.code === code);
130
+ expect(found).toHaveLength(1);
131
+ expect(found[0].field).toBe(field);
132
+ return found[0];
133
+ }
134
+ describe('RF-4.5/4.6 schema 2 unmeasured late paths', () => {
135
+ test('RF-4.5: README-only after verify is OK when every sensor had authored inputs', () => {
136
+ commitRecord();
137
+ repo.commit({ 'README.md': '# docs only\n' }, 'docs: readme');
138
+ expect(codesOf(run())).not.toContain('code-changed-after-verification');
139
+ expect(report(run()).state).toBe('valid');
140
+ });
141
+ test('RF-4.6: any sensor without authored inputs keeps schema-1 late rules (README fails)', () => {
142
+ commitRecord('rec', () => writeSchema2Receipt({
143
+ sensors: ['lint', 'test'],
144
+ measurements: { lint: measurement() }, // test has no measurement / no authored inputs
145
+ }));
146
+ repo.commit({ 'README.md': '# docs only\n' }, 'docs: readme');
147
+ expect(codesOf(run())).toContain('code-changed-after-verification');
148
+ expect(diag(run(), 'code-changed-after-verification', undefined).message).toContain('README.md');
149
+ });
150
+ test('RF-4.5: measured path late still fails when relaxation applies', () => {
151
+ commitRecord();
152
+ repo.commit({ 'cli/src/a.ts': '2' }, 'fix: measured');
153
+ expect(codesOf(run())).toContain('code-changed-after-verification');
154
+ expect(diag(run(), 'code-changed-after-verification', undefined).message).toContain('cli/src/a.ts');
155
+ });
156
+ test('RF-4.5: NEW file matching authored inputs globs after verify fails (not frozen measuredPaths only)', () => {
157
+ // Certify with measuredPaths frozen to a.ts only; a later matching source must still count.
158
+ commitRecord('rec', () => writeSchema2Receipt({
159
+ sensors: ['lint'],
160
+ measurements: {
161
+ lint: measurement({
162
+ inputs: ['src/**/*.ts'],
163
+ packageRootRel: 'cli',
164
+ measuredPaths: ['cli/src/a.ts', '.awm/sensors.json', 'cli/package.json', 'cli/package-lock.json'],
165
+ }),
166
+ },
167
+ }));
168
+ repo.commit({ 'cli/src/brand-new.ts': 'export const x = 1;\n' }, 'feat: new matching source');
169
+ expect(codesOf(run())).toContain('code-changed-after-verification');
170
+ expect(diag(run(), 'code-changed-after-verification', undefined).message).toContain('cli/src/brand-new.ts');
171
+ });
172
+ test('RF-4.5: sensors.json late fails (always-measured)', () => {
173
+ commitRecord();
174
+ repo.commit({ '.awm/sensors.json': '{"schemaVersion":2,"pack":"js-ts","sensors":{"lint":{"enabled":false}}}' }, 'chore: sensors');
175
+ expect(codesOf(run())).toContain('code-changed-after-verification');
176
+ expect(diag(run(), 'code-changed-after-verification', undefined).message).toContain('.awm/sensors.json');
177
+ });
178
+ test('RF-4.5: lockfile late fails (always-measured)', () => {
179
+ commitRecord();
180
+ repo.commit({ 'cli/package-lock.json': '{"lockfileVersion":3,"x":1}' }, 'chore: lock');
181
+ expect(codesOf(run())).toContain('code-changed-after-verification');
182
+ expect(diag(run(), 'code-changed-after-verification', undefined).message).toContain('cli/package-lock.json');
183
+ });
184
+ test('RF-4.5: baseline.json late fails (validate always-measured includes baseline, unlike cache)', () => {
185
+ commitRecord();
186
+ repo.commit({ '.awm/sensors.baseline.json': '{"lint":[]}' }, 'chore: baseline');
187
+ expect(codesOf(run())).toContain('code-changed-after-verification');
188
+ expect(diag(run(), 'code-changed-after-verification', undefined).message).toContain('.awm/sensors.baseline.json');
189
+ });
190
+ test('RF-4.8: monorepo packageRoot paths compare as repo-root POSIX', () => {
191
+ commitRecord('rec', () => writeSchema2Receipt({
192
+ sensors: ['lint'],
193
+ measurements: {
194
+ lint: measurement({
195
+ inputs: ['src/**/*.ts'],
196
+ measuredPaths: ['cli/src/a.ts', '.awm/sensors.json', 'cli/package.json', 'cli/package-lock.json'],
197
+ }),
198
+ },
199
+ }));
200
+ repo.commit({ 'cli/src/a.ts': 'changed' }, 'fix: under packageRoot');
201
+ const d = diag(run(), 'code-changed-after-verification', undefined);
202
+ expect(d.message).toContain('cli/src/a.ts');
203
+ expect(d.message).not.toMatch(/(^|[^/])src\/a\.ts/);
204
+ });
205
+ test('schema 1 receipts keep strict late rules (only docs/changes carved out)', () => {
206
+ const head = repo.git('rev-parse', 'HEAD');
207
+ // Force a schema-1 write through the legacy shape helper used by older tests.
208
+ const { writeReceipt: write, computeReceiptDigest } = require('../../../src/core/changes/receipt');
209
+ const body = {
210
+ schema: 1,
211
+ commit: head,
212
+ ranAt: '2026-10-17T11:00:00.000Z',
213
+ cliVersion: '9.20.0',
214
+ overall: 'pass',
215
+ sensors: { lint: 'pass' },
216
+ };
217
+ // buildReceipt now yields schema 2; write a raw schema-1 receipt for this fixture.
218
+ const digest = computeReceiptDigest(body);
219
+ write(repo.root, { ...body, digest });
220
+ expect((0, change_1.runChangeNew)(repo.root, 'rec', {}, { now }).code).toBe(0);
221
+ fs_1.default.writeFileSync(abs(REL), fs_1.default.readFileSync(abs(REL), 'utf8').split(types_1.PENDING_MARKER).join('filled'));
222
+ repo.git('add', '-A');
223
+ repo.git('commit', '-q', '-m', 'docs(changes): rec');
224
+ repo.commit({ 'README.md': '# docs\n' }, 'docs: readme');
225
+ expect(codesOf(run())).toContain('code-changed-after-verification');
226
+ });
227
+ test('RF-E.2: git failure listing late files is git-failed (fail closed)', () => {
228
+ commitRecord();
229
+ const verified = repo.git('rev-parse', 'HEAD~1');
230
+ const real = gitModule.changedFiles;
231
+ jest.spyOn(gitModule, 'changedFiles').mockImplementation((root, from, to) => (from === verified ? null : real(root, from, to)));
232
+ const r = run();
233
+ expect(r.code).toBe(2);
234
+ expect(diag(r, 'git-failed', undefined).message).toContain('git could not list the files changed since');
235
+ });
236
+ });
237
+ describe('RF-4.7 change new remedy honesty', () => {
238
+ test('missing HEAD receipt remedy names full-gate sensors run and does not claim every binary must re-exec', () => {
239
+ const r = (0, change_1.runChangeNew)(repo.root, 'rec', {}, { now });
240
+ expect(r.code).toBe(2);
241
+ expect(r.stderr).toMatch(/^receipt-missing: /);
242
+ expect(r.stderr).toMatch(/full-gate awm sensors run/);
243
+ expect(r.stderr.toLowerCase()).not.toMatch(/every tool|re-exec|reexecute|must re-run every/);
244
+ expect(r.stderr).toMatch(/cache/i);
245
+ });
246
+ });