@cassiomc1/forgeloop 1.2.4 → 1.5.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 (92) hide show
  1. package/.github/copilot-instructions.md +1 -0
  2. package/AGENTS.md +1 -0
  3. package/AGENT_COMPATIBILITY.md +4 -0
  4. package/CLAUDE.md +1 -0
  5. package/DOCS_INDEX.md +14 -0
  6. package/EXECUTION_STATE.md +48 -0
  7. package/LOOP_ENGINEERING.md +55 -6
  8. package/LOOP_SYSTEM_DESIGN.md +32 -1
  9. package/PROTOCOL_INTEGRATION.md +71 -0
  10. package/README.md +86 -0
  11. package/TERMINOLOGY.md +15 -0
  12. package/THIRD_PARTY_NOTICES.md +15 -0
  13. package/THREAT_MODEL.md +22 -1
  14. package/docs/ARTIFACT_REFERENCE.md +54 -0
  15. package/docs/CLI_REFERENCE.md +177 -5
  16. package/docs/CROSS_HARNESS_CONTINUITY.md +34 -0
  17. package/docs/DOCUMENTATION_GUIDE.md +31 -0
  18. package/docs/GETTING_STARTED.md +10 -0
  19. package/docs/MCP.md +126 -0
  20. package/docs/RECIPES.md +87 -1
  21. package/docs/RELEASE_CHECKLIST_1_4.md +38 -0
  22. package/docs/RELEASE_CHECKLIST_1_5_MCP.md +78 -0
  23. package/docs/TROUBLESHOOTING.md +243 -40
  24. package/docs/UNIVERSAL_INTEGRATION.md +48 -0
  25. package/package.json +17 -3
  26. package/schemas/execution.schema.json +11 -1
  27. package/schemas/task-recovery.schema.json +61 -0
  28. package/schemas/work-state.schema.json +1 -0
  29. package/src/cli.js +182 -337
  30. package/src/commands/audit.js +5 -0
  31. package/src/commands/doctor.js +22 -0
  32. package/src/commands/inspect.js +6 -0
  33. package/src/commands/migrate-protocol.js +18 -0
  34. package/src/commands/progress.js +6 -2
  35. package/src/commands/protocol-info.js +16 -0
  36. package/src/commands/run-check.js +2 -0
  37. package/src/commands/status.js +17 -0
  38. package/src/commands/task-create.js +42 -3
  39. package/src/commands/task-list.js +14 -1
  40. package/src/commands/task-lock-status.js +29 -0
  41. package/src/commands/task-recover.js +202 -0
  42. package/src/commands/task-repair-legacy-recovery.js +417 -0
  43. package/src/commands/task-resume.js +172 -0
  44. package/src/commands/task-scope.js +23 -4
  45. package/src/commands/task-show.js +21 -7
  46. package/src/commands/task-unlock.js +8 -6
  47. package/src/commands/validate-protocol.js +19 -2
  48. package/src/core/artifact-registry.js +12 -0
  49. package/src/core/artifacts.js +17 -4
  50. package/src/core/audit.js +20 -4
  51. package/src/core/bundles.js +15 -0
  52. package/src/core/cli-command-definitions.js +94 -4
  53. package/src/core/command-executors.js +387 -0
  54. package/src/core/command-input.js +107 -0
  55. package/src/core/command-runtime.js +106 -0
  56. package/src/core/completion-artifacts.js +17 -6
  57. package/src/core/completion-ownership.js +88 -0
  58. package/src/core/completion.js +15 -3
  59. package/src/core/diagnosis.js +15 -11
  60. package/src/core/error-codes.js +136 -1
  61. package/src/core/events.js +239 -9
  62. package/src/core/execution.js +73 -9
  63. package/src/core/filesystem.js +75 -8
  64. package/src/core/inspect.js +27 -0
  65. package/src/core/integration-invocation-policy.js +170 -0
  66. package/src/core/integration-limits.js +20 -0
  67. package/src/core/integration-resources.js +127 -0
  68. package/src/core/next-action-model.js +60 -0
  69. package/src/core/next-action.js +31 -0
  70. package/src/core/phase.js +10 -3
  71. package/src/core/project-root.js +21 -0
  72. package/src/core/protocol-info.js +54 -0
  73. package/src/core/protocol-migration.js +59 -0
  74. package/src/core/reconcile-closure.js +54 -14
  75. package/src/core/recovery-history.js +116 -0
  76. package/src/core/resumability.js +8 -6
  77. package/src/core/schema-validation.js +1 -0
  78. package/src/core/task-claim-state.js +272 -0
  79. package/src/core/task-command.js +8 -4
  80. package/src/core/task-conflict-inspection.js +321 -0
  81. package/src/core/task-context.js +32 -29
  82. package/src/core/task-discovery.js +14 -1
  83. package/src/core/task-lock.js +248 -18
  84. package/src/core/task-migration.js +24 -1
  85. package/src/core/task-paths.js +6 -3
  86. package/src/core/task-recovery-migration.js +192 -0
  87. package/src/core/task-recovery.js +205 -0
  88. package/src/core/task-scope.js +33 -1
  89. package/src/core/templates.js +1 -0
  90. package/src/core/transaction.js +285 -0
  91. package/src/core/work-state.js +70 -6
  92. package/src/integration.js +47 -0
package/src/cli.js CHANGED
@@ -4,50 +4,55 @@ import { readFile } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
 
7
- import { runDoctor } from "./commands/doctor.js";
8
- import { formatStatusResult, runStatus } from "./commands/status.js";
9
- import { formatValidateStateResult, runValidateState } from "./commands/validate-state.js";
10
- import { formatClearStateResult, runClearState } from "./commands/clear-state.js";
11
- import { formatInspectResult, inspectTarget } from "./commands/inspect.js";
12
- import { runInit } from "./commands/init.js";
13
- import { formatRouteResult, runRoute } from "./commands/route.js";
14
- import { runValidateReceipt } from "./commands/validate-receipt.js";
15
- import { formatValidateProtocolResult, runValidateProtocol } from "./commands/validate-protocol.js";
16
- import { runUpdate } from "./commands/update.js";
17
- import { formatActivateResult, runActivate } from "./commands/activate.js";
18
- import { formatAdvanceResult, runAdvance } from "./commands/advance.js";
19
- import { formatPreflightResult, runPreflight } from "./commands/preflight.js";
20
- import { formatCompleteResult, runComplete } from "./commands/complete.js";
21
- import { formatAuditResult, runAudit } from "./commands/audit.js";
22
- import { formatReportResult, runReport } from "./commands/report.js";
23
- import { formatPolicyResult, runPolicy } from "./commands/policy.js";
24
- import { formatPolicyDiscoverResult, runPolicyDiscover } from "./commands/policy-discover.js";
25
- import { formatPolicyStatusResult, runPolicyStatus } from "./commands/policy-status.js";
26
- import { formatPolicyDiffResult, runPolicyDiff } from "./commands/policy-diff.js";
27
- import { formatRuleVerifyResult, runRuleVerify } from "./commands/rule-verify.js";
28
- import { formatBaselineResult, runBaseline } from "./commands/baseline.js";
29
- import { formatProfileInterviewResult, runProfileInterview } from "./commands/profile-interview.js";
30
- import { formatBundleResult, runBundle } from "./commands/bundle.js";
31
- import { formatPrepareCompletionResult, runPrepareCompletion } from "./commands/prepare-completion.js";
32
- import { formatRecordCheckResult, runRecordCheck } from "./commands/record-check.js";
33
- import { formatRunCheckResult, runCheck } from "./commands/run-check.js";
34
- import { formatReconcileClosureResult, reconcileClosure } from "./commands/reconcile-closure.js";
35
- import { formatRecordTerminalResult, runRecordTerminalResult } from "./commands/record-terminal-result.js";
36
- import { formatRecordDiagnosisResult, runRecordDiagnosis } from "./commands/record-diagnosis.js";
37
- import { formatProgressResult, runProgress } from "./commands/progress.js";
38
- import { formatRecordDecisionCriterionResult, runRecordDecisionCriterion } from "./commands/record-decision-criterion.js";
39
- import { formatNextActionResult, runNext } from "./commands/next.js";
40
- import { formatContinuityResult, runContinuity } from "./commands/continuity.js";
41
- import { formatRecordContinuityResult, runRecordContinuity } from "./commands/record-continuity.js";
42
- import { formatReconcileContinuityResult, runReconcileContinuity } from "./commands/reconcile-continuity.js";
43
- import { formatClearContinuityResult, runClearContinuity } from "./commands/clear-continuity.js";
44
- import { formatTaskCreateResult, runTaskCreate } from "./commands/task-create.js";
45
- import { formatTaskListResult, runTaskList } from "./commands/task-list.js";
46
- import { formatTaskShowResult, runTaskShow } from "./commands/task-show.js";
47
- import { formatTaskScopeResult, runTaskScope } from "./commands/task-scope.js";
48
- import { formatTaskMigrateResult, runTaskMigrate } from "./commands/task-migrate.js";
49
- import { formatTaskUnlockResult, runTaskUnlock } from "./commands/task-unlock.js";
50
- import { continuityOptionDefaults, validateContinuityOptions } from "./core/continuity-cli-options.js";
7
+ import { formatStatusResult } from "./commands/status.js";
8
+ import { formatValidateStateResult } from "./commands/validate-state.js";
9
+ import { formatClearStateResult } from "./commands/clear-state.js";
10
+ import { formatInspectResult } from "./commands/inspect.js";
11
+ import { formatRouteResult } from "./commands/route.js";
12
+ import { formatValidateProtocolResult } from "./commands/validate-protocol.js";
13
+ import { formatActivateResult } from "./commands/activate.js";
14
+ import { formatAdvanceResult } from "./commands/advance.js";
15
+ import { formatPreflightResult } from "./commands/preflight.js";
16
+ import { formatCompleteResult } from "./commands/complete.js";
17
+ import { formatAuditResult } from "./commands/audit.js";
18
+ import { formatReportResult } from "./commands/report.js";
19
+ import { formatPolicyResult } from "./commands/policy.js";
20
+ import { formatPolicyDiscoverResult } from "./commands/policy-discover.js";
21
+ import { formatPolicyStatusResult } from "./commands/policy-status.js";
22
+ import { formatPolicyDiffResult } from "./commands/policy-diff.js";
23
+ import { formatRuleVerifyResult } from "./commands/rule-verify.js";
24
+ import { formatBaselineResult } from "./commands/baseline.js";
25
+ import { formatProfileInterviewResult } from "./commands/profile-interview.js";
26
+ import { formatBundleResult } from "./commands/bundle.js";
27
+ import { formatPrepareCompletionResult } from "./commands/prepare-completion.js";
28
+ import { formatRecordCheckResult } from "./commands/record-check.js";
29
+ import { formatRunCheckResult } from "./commands/run-check.js";
30
+ import { formatReconcileClosureResult } from "./commands/reconcile-closure.js";
31
+ import { formatRecordTerminalResult } from "./commands/record-terminal-result.js";
32
+ import { formatRecordDiagnosisResult } from "./commands/record-diagnosis.js";
33
+ import { formatProgressResult } from "./commands/progress.js";
34
+ import { formatRecordDecisionCriterionResult } from "./commands/record-decision-criterion.js";
35
+ import { formatNextActionResult } from "./commands/next.js";
36
+ import { formatContinuityResult } from "./commands/continuity.js";
37
+ import { formatRecordContinuityResult } from "./commands/record-continuity.js";
38
+ import { formatReconcileContinuityResult } from "./commands/reconcile-continuity.js";
39
+ import { formatClearContinuityResult } from "./commands/clear-continuity.js";
40
+ import { formatTaskCreateResult } from "./commands/task-create.js";
41
+ import { formatTaskListResult } from "./commands/task-list.js";
42
+ import { formatTaskShowResult } from "./commands/task-show.js";
43
+ import { formatTaskScopeResult } from "./commands/task-scope.js";
44
+ import { formatTaskMigrateResult } from "./commands/task-migrate.js";
45
+ import { formatMigrateProtocolResult } from "./commands/migrate-protocol.js";
46
+ import { formatTaskUnlockResult } from "./commands/task-unlock.js";
47
+ import { formatTaskRecoverResult } from "./commands/task-recover.js";
48
+ import { formatTaskResumeResult } from "./commands/task-resume.js";
49
+ import {
50
+ formatTaskRepairLegacyRecoveryResult,
51
+ } from "./commands/task-repair-legacy-recovery.js";
52
+ import { formatTaskLockStatusResult } from "./commands/task-lock-status.js";
53
+ import { formatProtocolInfoResult } from "./commands/protocol-info.js";
54
+ import { defaultCommandInputValues, validateForgeLoopCommandInput } from "./core/command-input.js";
55
+ import { COMMAND_EXECUTORS } from "./core/command-executors.js";
51
56
  import { resolveTarget } from "./core/filesystem.js";
52
57
  import { getPackageRoot } from "./core/templates.js";
53
58
  import { CLI_COMMAND_DEFINITIONS, buildOptionLookup, getPositionalDefinitions } from "./core/cli-command-definitions.js";
@@ -193,48 +198,7 @@ export function discoverCommand(argv) {
193
198
  }
194
199
 
195
200
  export function parseCliSyntax(argv) {
196
- const options = {
197
- path: ".",
198
- dryRun: false,
199
- json: false,
200
- strict: false,
201
- fix: false,
202
- adopt: [],
203
- work: null,
204
- surfaces: [],
205
- risks: [],
206
- platforms: [],
207
- behaviorChange: false,
208
- executableChange: false,
209
- to: null,
210
- file: null,
211
- contractFile: null,
212
- routeFile: null,
213
- stateFile: null,
214
- receiptFile: null,
215
- continuityFile: null,
216
- ...continuityOptionDefaults(),
217
- taskBriefFiles: [],
218
- delegatedResultFiles: [],
219
- checkId: null,
220
- checkKind: null,
221
- checkRequirement: null,
222
- checkStatus: null,
223
- checkEvidenceKind: null,
224
- checkCommand: null,
225
- checkResult: null,
226
- checkExitCode: null,
227
- checkDetails: null,
228
- checkExecutionRef: null,
229
- checkProvenance: null,
230
- commandArgv: [],
231
- checkType: null,
232
- checkSource: null,
233
- policy: null,
234
- task: null,
235
- help: false,
236
- version: false,
237
- };
201
+ const options = defaultCommandInputValues();
238
202
 
239
203
  const command = discoverCommand(argv);
240
204
  const bootstrapLookup = buildOptionLookup(null);
@@ -311,53 +275,7 @@ export function parseCliSyntax(argv) {
311
275
  }
312
276
 
313
277
  export function validateCliSemantics({ command, options } = {}) {
314
- if (!command) return;
315
-
316
- if (command === "policy" && !options.policy) {
317
- throw new Error("policy requires a name");
318
- }
319
- if (command !== "policy" && options.policy) {
320
- throw new Error(`Policy name is not valid for ${command}`);
321
- }
322
- if (command === "bundle" && !options.task) {
323
- throw new Error("bundle requires --task");
324
- }
325
- if (command === "task-create" && !options.task) {
326
- throw new Error("task-create requires --task");
327
- }
328
-
329
- validateContinuityOptions(command, options);
330
-
331
- if (command === "record-check" && !options.help) {
332
- if (!options.checkId) throw new Error("record-check requires --id");
333
- if (!options.checkRequirement) throw new Error("record-check requires --requirement");
334
- if (!options.checkStatus) throw new Error("record-check requires --status");
335
- if (!options.checkEvidenceKind) throw new Error("record-check requires --evidence-kind");
336
- if (!options.checkCommand && !options.checkResult) throw new Error("record-check requires --command or --result");
337
- }
338
- if (command === "run-check" && !options.help) {
339
- if (!options.checkId) throw new Error("run-check requires --id");
340
- if (!options.checkRequirement) throw new Error("run-check requires --requirement");
341
- if (options.checkKind || options.checkStatus || options.checkEvidenceKind || options.checkCommand
342
- || options.checkResult || options.checkExitCode !== null || options.checkExecutionRef || options.checkProvenance) {
343
- throw new Error("run-check accepts only --id, --requirement, --details, and -- <argv>");
344
- }
345
- if (!Array.isArray(options.commandArgv) || options.commandArgv.length === 0) {
346
- throw new Error("run-check requires -- followed by an exact command argv");
347
- }
348
- }
349
- if (command === "reconcile-closure" && !options.help) {
350
- if (!options.task) throw new Error("reconcile-closure requires --task");
351
- if (!options.checkId) throw new Error("reconcile-closure requires --id");
352
- if (!options.checkRequirement) throw new Error("reconcile-closure requires --requirement");
353
- if (options.checkKind || options.checkStatus || options.checkEvidenceKind || options.checkCommand
354
- || options.checkResult || options.checkExitCode !== null || options.checkExecutionRef || options.checkProvenance) {
355
- throw new Error("reconcile-closure accepts only --id, --requirement, --details, and -- <argv>");
356
- }
357
- if (!Array.isArray(options.commandArgv) || options.commandArgv.length === 0) {
358
- throw new Error("reconcile-closure requires -- followed by an exact command argv");
359
- }
360
- }
278
+ validateForgeLoopCommandInput({ command, input: options, help: options?.help ?? false });
361
279
  }
362
280
 
363
281
  export function parseArgs(argv) {
@@ -380,20 +298,23 @@ function printActions(actions) {
380
298
  }
381
299
  }
382
300
 
301
+ function renderJsonOr(options, result, formatter) {
302
+ console.log(options.json ? JSON.stringify(result, null, 2) : formatter(result));
303
+ }
304
+
383
305
  export const COMMAND_HANDLERS = Object.freeze({
306
+ "protocol-info": async ({ packageVersion, options }) => {
307
+ const { result } = await COMMAND_EXECUTORS["protocol-info"]({ packageVersion, options });
308
+ renderJsonOr(options, result, formatProtocolInfoResult);
309
+ return 0;
310
+ },
384
311
  init: async ({ target, packageRoot, packageVersion, options }) => {
385
- const result = await runInit({ target, dryRun: options.dryRun, packageRoot, packageVersion });
312
+ const { result } = await COMMAND_EXECUTORS.init({ target, packageRoot, packageVersion, options });
386
313
  printActions(result.actions);
387
314
  return 0;
388
315
  },
389
316
  doctor: async ({ target, packageRoot, options }) => {
390
- const result = await runDoctor({
391
- target,
392
- packageRoot,
393
- adoptPaths: options.adopt,
394
- strict: options.strict,
395
- fix: options.fix,
396
- });
317
+ const { result } = await COMMAND_EXECUTORS.doctor({ target, packageRoot, options });
397
318
  if (options.json) {
398
319
  console.log(JSON.stringify(result, null, 2));
399
320
  } else {
@@ -405,317 +326,241 @@ export const COMMAND_HANDLERS = Object.freeze({
405
326
  return result.ok ? 0 : 1;
406
327
  },
407
328
  route: async ({ target, packageRoot, options }) => {
408
- const result = await runRoute({
409
- target,
410
- packageRoot,
411
- workType: options.work,
412
- surfaces: options.surfaces,
413
- risks: options.risks,
414
- platforms: options.platforms,
415
- behaviorChange: options.behaviorChange,
416
- executableChange: options.executableChange,
417
- taskId: options.task,
418
- });
419
- console.log(options.json ? JSON.stringify(result, null, 2) : formatRouteResult(result));
329
+ const { result } = await COMMAND_EXECUTORS.route({ target, packageRoot, options });
330
+ renderJsonOr(options, result, formatRouteResult);
420
331
  return 0;
421
332
  },
422
333
  activate: async ({ target, packageRoot, options }) => {
423
- const result = await runActivate({ target, packageRoot });
424
- console.log(options.json ? JSON.stringify(result, null, 2) : formatActivateResult(result));
334
+ const { result } = await COMMAND_EXECUTORS.activate({ target, packageRoot, options });
335
+ renderJsonOr(options, result, formatActivateResult);
425
336
  return 0;
426
337
  },
427
338
  preflight: async ({ target, packageRoot, options }) => {
428
- const result = await runPreflight({ target, packageRoot, strict: options.strict, taskId: options.task });
429
- console.log(options.json ? JSON.stringify(result, null, 2) : formatPreflightResult(result));
430
- return result.status === "READY" ? 0 : 1;
339
+ const { result, exitCode } = await COMMAND_EXECUTORS.preflight({ target, packageRoot, options });
340
+ renderJsonOr(options, result, formatPreflightResult);
341
+ return exitCode;
431
342
  },
432
343
  advance: async ({ target, packageRoot, options }) => {
433
- const result = await runAdvance({ target, packageRoot, to: options.to, taskId: options.task });
434
- console.log(options.json ? JSON.stringify(result, null, 2) : formatAdvanceResult(result));
344
+ const { result } = await COMMAND_EXECUTORS.advance({ target, packageRoot, options });
345
+ renderJsonOr(options, result, formatAdvanceResult);
435
346
  return 0;
436
347
  },
437
348
  next: async ({ target, packageRoot, options }) => {
438
- const result = await runNext({ target, packageRoot, taskId: options.task });
439
- console.log(options.json ? JSON.stringify(result, null, 2) : formatNextActionResult(result));
349
+ const { result } = await COMMAND_EXECUTORS.next({ target, packageRoot, options });
350
+ renderJsonOr(options, result, formatNextActionResult);
440
351
  return 0;
441
352
  },
442
353
  continuity: async ({ target, packageRoot, options }) => {
443
- const result = await runContinuity({ target, packageRoot, taskId: options.task });
444
- console.log(options.json ? JSON.stringify(result, null, 2) : formatContinuityResult(result));
354
+ const { result } = await COMMAND_EXECUTORS.continuity({ target, packageRoot, options });
355
+ renderJsonOr(options, result, formatContinuityResult);
445
356
  return 0;
446
357
  },
447
358
  "record-continuity": async ({ target, packageRoot, options }) => {
448
- const result = await runRecordContinuity({
449
- target, packageRoot,
450
- focusId: options.continuityFocusId,
451
- focusSummary: options.continuityFocusSummary,
452
- remaining: options.continuityRemaining,
453
- knownIssues: options.continuityKnownIssues,
454
- changedAreas: options.continuityChangedAreas,
455
- inspectFirst: options.continuityInspectFirst,
456
- resumeNote: options.continuityResumeNote,
457
- taskId: options.task,
458
- });
459
- console.log(options.json ? JSON.stringify(result, null, 2) : formatRecordContinuityResult(result));
359
+ const { result } = await COMMAND_EXECUTORS["record-continuity"]({ target, packageRoot, options });
360
+ renderJsonOr(options, result, formatRecordContinuityResult);
460
361
  return 0;
461
362
  },
462
363
  "reconcile-continuity": async ({ target, packageRoot, options }) => {
463
- const result = await runReconcileContinuity({ target, packageRoot, taskId: options.task });
464
- console.log(options.json ? JSON.stringify(result, null, 2) : formatReconcileContinuityResult(result));
364
+ const { result } = await COMMAND_EXECUTORS["reconcile-continuity"]({ target, packageRoot, options });
365
+ renderJsonOr(options, result, formatReconcileContinuityResult);
465
366
  return 0;
466
367
  },
467
368
  "clear-continuity": async ({ target, options }) => {
468
- const result = await runClearContinuity({ target, taskId: options.task });
469
- console.log(options.json ? JSON.stringify(result, null, 2) : formatClearContinuityResult(result));
369
+ const { result } = await COMMAND_EXECUTORS["clear-continuity"]({ target, options });
370
+ renderJsonOr(options, result, formatClearContinuityResult);
470
371
  return 0;
471
372
  },
472
373
  "prepare-completion": async ({ target, packageRoot, options }) => {
473
- const result = await runPrepareCompletion({ target, packageRoot, taskId: options.task });
474
- console.log(options.json ? JSON.stringify(result, null, 2) : formatPrepareCompletionResult(result));
374
+ const { result } = await COMMAND_EXECUTORS["prepare-completion"]({ target, packageRoot, options });
375
+ renderJsonOr(options, result, formatPrepareCompletionResult);
475
376
  return 0;
476
377
  },
477
378
  "run-check": async ({ target, packageRoot, options }) => {
478
- const result = await runCheck({
479
- target,
480
- packageRoot,
481
- id: options.checkId,
482
- requirement: options.checkRequirement,
483
- argv: options.commandArgv,
484
- details: options.checkDetails ?? undefined,
485
- taskId: options.task,
486
- });
487
- console.log(options.json ? JSON.stringify(result, null, 2) : formatRunCheckResult(result));
488
- return result.check.status === "passed" ? 0 : 1;
379
+ const { result, exitCode } = await COMMAND_EXECUTORS["run-check"]({ target, packageRoot, options });
380
+ renderJsonOr(options, result, formatRunCheckResult);
381
+ return exitCode;
489
382
  },
490
383
  "record-check": async ({ target, packageRoot, options }) => {
491
- const result = await runRecordCheck({
492
- target,
493
- packageRoot,
494
- id: options.checkId,
495
- kind: options.checkKind ?? "command",
496
- requirement: options.checkRequirement,
497
- status: options.checkStatus,
498
- evidenceKind: options.checkEvidenceKind,
499
- command: options.checkCommand ?? undefined,
500
- result: options.checkResult ?? undefined,
501
- ...(options.checkExitCode === null ? {} : { exitCode: options.checkExitCode }),
502
- details: options.checkDetails ?? undefined,
503
- executionRef: options.checkExecutionRef ?? undefined,
504
- provenance: options.checkProvenance ?? undefined,
505
- taskId: options.task,
506
- });
507
- console.log(options.json ? JSON.stringify(result, null, 2) : formatRecordCheckResult(result));
384
+ const { result } = await COMMAND_EXECUTORS["record-check"]({ target, packageRoot, options });
385
+ renderJsonOr(options, result, formatRecordCheckResult);
508
386
  return 0;
509
387
  },
510
388
  "record-terminal-result": async ({ target, packageRoot, options }) => {
511
- const result = await runRecordTerminalResult({
512
- target,
513
- packageRoot,
514
- requirement: options.checkRequirement,
515
- type: options.checkType,
516
- status: options.checkStatus,
517
- source: options.checkSource ?? options.checkCommand,
518
- result: options.checkResult,
519
- details: options.checkDetails ?? undefined,
520
- taskId: options.task,
521
- });
522
- console.log(options.json ? JSON.stringify(result, null, 2) : formatRecordTerminalResult(result));
389
+ const { result } = await COMMAND_EXECUTORS["record-terminal-result"]({ target, packageRoot, options });
390
+ renderJsonOr(options, result, formatRecordTerminalResult);
523
391
  return 0;
524
392
  },
525
393
  "record-diagnosis": async ({ target, packageRoot, options }) => {
526
- const result = await runRecordDiagnosis({
527
- target,
528
- packageRoot,
529
- hypothesis: options.hypothesis,
530
- failureClass: options.failureClass,
531
- evidenceRefs: options.evidenceRefs,
532
- settledBy: options.settledBy,
533
- nextSafeAction: options.nextSafeAction,
534
- taskId: options.task,
535
- });
536
- console.log(options.json ? JSON.stringify(result, null, 2) : formatRecordDiagnosisResult(result));
394
+ const { result } = await COMMAND_EXECUTORS["record-diagnosis"]({ target, packageRoot, options });
395
+ renderJsonOr(options, result, formatRecordDiagnosisResult);
537
396
  return 0;
538
397
  },
539
398
  progress: async ({ target, packageRoot, options }) => {
540
- const result = await runProgress({ target, packageRoot, taskId: options.task });
541
- console.log(options.json ? JSON.stringify(result, null, 2) : formatProgressResult(result));
542
- return result.status === "STALLED" ? 1 : 0;
399
+ const { result, exitCode } = await COMMAND_EXECUTORS.progress({ target, packageRoot, options });
400
+ renderJsonOr(options, result, formatProgressResult);
401
+ return exitCode;
543
402
  },
544
403
  "record-decision-criterion": async ({ target, packageRoot, options }) => {
545
- const result = await runRecordDecisionCriterion({
546
- target,
547
- packageRoot,
548
- decision: options.decision,
549
- settledBy: options.settledBy,
550
- taskId: options.task,
551
- });
552
- console.log(options.json ? JSON.stringify(result, null, 2) : formatRecordDecisionCriterionResult(result));
404
+ const { result } = await COMMAND_EXECUTORS["record-decision-criterion"]({ target, packageRoot, options });
405
+ renderJsonOr(options, result, formatRecordDecisionCriterionResult);
553
406
  return 0;
554
407
  },
555
408
  complete: async ({ target, packageRoot, options }) => {
556
- const result = await runComplete({ target, packageRoot, strict: options.strict, taskId: options.task });
557
- console.log(options.json ? JSON.stringify(result, null, 2) : formatCompleteResult(result));
558
- return result.status === "VALID" ? 0 : 1;
409
+ const { result, exitCode } = await COMMAND_EXECUTORS.complete({ target, packageRoot, options });
410
+ renderJsonOr(options, result, formatCompleteResult);
411
+ return exitCode;
559
412
  },
560
413
  audit: async ({ target, packageRoot, options }) => {
561
- const result = await runAudit({ target, packageRoot, strict: options.strict, taskId: options.task });
562
- console.log(options.json ? JSON.stringify(result, null, 2) : formatAuditResult(result));
563
- return result.status === "VALID" ? 0 : 1;
414
+ const { result, exitCode } = await COMMAND_EXECUTORS.audit({ target, packageRoot, options });
415
+ renderJsonOr(options, result, formatAuditResult);
416
+ return exitCode;
564
417
  },
565
418
  report: async ({ target, packageRoot, options }) => {
566
- const result = await runReport({ target, packageRoot, strict: options.strict, taskId: options.task });
567
- console.log(options.json ? JSON.stringify(result, null, 2) : formatReportResult(result));
568
- return result.verdict === "VALID" ? 0 : 1;
419
+ const { result, exitCode } = await COMMAND_EXECUTORS.report({ target, packageRoot, options });
420
+ renderJsonOr(options, result, formatReportResult);
421
+ return exitCode;
569
422
  },
570
423
  policy: async ({ target, packageRoot, options }) => {
571
- const result = await runPolicy({ target, packageRoot, name: options.policy, taskId: options.task });
572
- console.log(options.json ? JSON.stringify(result, null, 2) : formatPolicyResult(result));
424
+ const { result } = await COMMAND_EXECUTORS.policy({ target, packageRoot, options });
425
+ renderJsonOr(options, result, formatPolicyResult);
573
426
  return 0;
574
427
  },
575
428
  "policy-discover": async ({ target, packageRoot, options }) => {
576
- const result = await runPolicyDiscover({ target, packageRoot, write: options.write });
577
- console.log(options.json ? JSON.stringify(result, null, 2) : formatPolicyDiscoverResult(result));
429
+ const { result } = await COMMAND_EXECUTORS["policy-discover"]({ target, packageRoot, options });
430
+ renderJsonOr(options, result, formatPolicyDiscoverResult);
578
431
  return 0;
579
432
  },
580
433
  "policy-status": async ({ target, packageRoot, options }) => {
581
- const result = await runPolicyStatus({ target, packageRoot, taskId: options.task });
582
- console.log(options.json ? JSON.stringify(result, null, 2) : formatPolicyStatusResult(result));
583
- return result.status === "VALID" ? 0 : 1;
434
+ const { result, exitCode } = await COMMAND_EXECUTORS["policy-status"]({ target, packageRoot, options });
435
+ renderJsonOr(options, result, formatPolicyStatusResult);
436
+ return exitCode;
584
437
  },
585
438
  "policy-diff": async ({ target, packageRoot, options }) => {
586
- const result = await runPolicyDiff({ target, packageRoot, taskId: options.task, before: options.before, after: options.after });
587
- console.log(options.json ? JSON.stringify(result, null, 2) : formatPolicyDiffResult(result));
439
+ const { result } = await COMMAND_EXECUTORS["policy-diff"]({ target, packageRoot, options });
440
+ renderJsonOr(options, result, formatPolicyDiffResult);
588
441
  return 0;
589
442
  },
590
443
  "rule-verify": async ({ target, packageRoot, options }) => {
591
- const result = await runRuleVerify({ target, packageRoot, rule: options.rule });
592
- console.log(options.json ? JSON.stringify(result, null, 2) : formatRuleVerifyResult(result));
593
- return result.status === "VALID" ? 0 : 1;
444
+ const { result, exitCode } = await COMMAND_EXECUTORS["rule-verify"]({ target, packageRoot, options });
445
+ renderJsonOr(options, result, formatRuleVerifyResult);
446
+ return exitCode;
594
447
  },
595
448
  baseline: async ({ target, packageRoot, options }) => {
596
- const result = await runBaseline({
597
- target,
598
- packageRoot,
599
- record: options.record,
600
- update: options.update,
601
- policyResetAuthorized: options.policyResetAuthorized,
602
- });
603
- console.log(options.json ? JSON.stringify(result, null, 2) : formatBaselineResult(result));
449
+ const { result } = await COMMAND_EXECUTORS.baseline({ target, packageRoot, options });
450
+ renderJsonOr(options, result, formatBaselineResult);
604
451
  return 0;
605
452
  },
606
453
  "profile-interview": async ({ target, packageRoot, options }) => {
607
- const result = await runProfileInterview({ target, packageRoot, dryRun: options.dryRun });
608
- console.log(options.json ? JSON.stringify(result, null, 2) : formatProfileInterviewResult(result));
454
+ const { result } = await COMMAND_EXECUTORS["profile-interview"]({ target, packageRoot, options });
455
+ renderJsonOr(options, result, formatProfileInterviewResult);
609
456
  return 0;
610
457
  },
611
458
  bundle: async ({ target, packageRoot, options }) => {
612
- const result = await runBundle({ target, packageRoot, taskId: options.task });
613
- console.log(options.json ? JSON.stringify(result, null, 2) : formatBundleResult(result));
459
+ const { result } = await COMMAND_EXECUTORS.bundle({ target, packageRoot, options });
460
+ renderJsonOr(options, result, formatBundleResult);
614
461
  return 0;
615
462
  },
616
463
  inspect: async ({ target, packageRoot, options }) => {
617
- const result = await inspectTarget({ target, packageRoot, contractFile: options.contractFile, taskId: options.task });
618
- console.log(options.json ? JSON.stringify(result, null, 2) : formatInspectResult(result));
619
- return result.ok ? 0 : 1;
464
+ const { result, exitCode } = await COMMAND_EXECUTORS.inspect({ target, packageRoot, options });
465
+ renderJsonOr(options, result, formatInspectResult);
466
+ return exitCode;
620
467
  },
621
468
  "validate-receipt": async ({ target, packageRoot, options }) => {
622
- const result = await runValidateReceipt({ target, packageRoot, file: options.file, taskId: options.task });
469
+ const { result } = await COMMAND_EXECUTORS["validate-receipt"]({ target, packageRoot, options });
623
470
  console.log(options.json ? JSON.stringify(result, null, 2) : "valid: execution receipt");
624
471
  return 0;
625
472
  },
626
473
  "validate-protocol": async ({ target, packageRoot, options }) => {
627
- const result = await runValidateProtocol({
628
- target,
629
- packageRoot,
630
- stateFile: options.stateFile,
631
- receiptFile: options.receiptFile,
632
- routeFile: options.routeFile,
633
- contractFile: options.contractFile,
634
- continuityFile: options.continuityFile,
635
- taskBriefFiles: options.taskBriefFiles,
636
- delegatedResultFiles: options.delegatedResultFiles,
637
- taskId: options.task,
638
- });
639
- console.log(options.json ? JSON.stringify(result, null, 2) : formatValidateProtocolResult(result));
640
- return result.status === "VALID" ? 0 : 1;
474
+ const { result, exitCode } = await COMMAND_EXECUTORS["validate-protocol"]({ target, packageRoot, options });
475
+ renderJsonOr(options, result, formatValidateProtocolResult);
476
+ return exitCode;
641
477
  },
642
478
  status: async ({ target, packageRoot, options }) => {
643
- const result = await runStatus({ target, packageRoot, contractFile: options.contractFile, taskId: options.task });
644
- console.log(options.json ? JSON.stringify(result, null, 2) : formatStatusResult(result));
479
+ const { result } = await COMMAND_EXECUTORS.status({ target, packageRoot, options });
480
+ renderJsonOr(options, result, formatStatusResult);
645
481
  return 0;
646
482
  },
647
483
  "validate-state": async ({ target, packageRoot, options }) => {
648
- const result = await runValidateState({ target, packageRoot, taskId: options.task });
649
- console.log(options.json ? JSON.stringify(result, null, 2) : formatValidateStateResult(result));
650
- return result.ok ? 0 : 1;
484
+ const { result, exitCode } = await COMMAND_EXECUTORS["validate-state"]({ target, packageRoot, options });
485
+ renderJsonOr(options, result, formatValidateStateResult);
486
+ return exitCode;
651
487
  },
652
488
  "clear-state": async ({ target, options }) => {
653
- const result = await runClearState({ target, taskId: options.task });
654
- console.log(options.json ? JSON.stringify(result, null, 2) : formatClearStateResult(result));
489
+ const { result } = await COMMAND_EXECUTORS["clear-state"]({ target, options });
490
+ renderJsonOr(options, result, formatClearStateResult);
655
491
  return 0;
656
492
  },
657
493
  "task-create": async ({ target, packageRoot, options }) => {
658
- const result = await runTaskCreate({
659
- target,
660
- packageRoot,
661
- taskId: options.task,
662
- claims: options.claims,
663
- contractFile: options.contractFile,
664
- });
665
- console.log(options.json ? JSON.stringify(result, null, 2) : formatTaskCreateResult(result));
494
+ const { result } = await COMMAND_EXECUTORS["task-create"]({ target, packageRoot, options });
495
+ renderJsonOr(options, result, formatTaskCreateResult);
666
496
  return 0;
667
497
  },
668
498
  "task-list": async ({ target, packageRoot, options }) => {
669
- const result = await runTaskList({ target, packageRoot });
670
- console.log(options.json ? JSON.stringify(result, null, 2) : formatTaskListResult(result));
499
+ const { result } = await COMMAND_EXECUTORS["task-list"]({ target, packageRoot, options });
500
+ renderJsonOr(options, result, formatTaskListResult);
671
501
  return 0;
672
502
  },
673
503
  "task-show": async ({ target, packageRoot, options }) => {
674
- const result = await runTaskShow({ target, packageRoot, taskId: options.task });
675
- console.log(options.json ? JSON.stringify(result, null, 2) : formatTaskShowResult(result));
504
+ const { result } = await COMMAND_EXECUTORS["task-show"]({ target, packageRoot, options });
505
+ renderJsonOr(options, result, formatTaskShowResult);
506
+ return 0;
507
+ },
508
+ "task-lock-status": async ({ target, packageRoot, options }) => {
509
+ const { result } = await COMMAND_EXECUTORS["task-lock-status"]({ target, packageRoot, options });
510
+ renderJsonOr(options, result, formatTaskLockStatusResult);
676
511
  return 0;
677
512
  },
678
513
  "task-scope": async ({ target, packageRoot, options }) => {
679
- const result = await runTaskScope({
680
- target,
681
- packageRoot,
682
- taskId: options.task,
683
- claims: options.claims,
684
- });
685
- console.log(options.json ? JSON.stringify(result, null, 2) : formatTaskScopeResult(result));
514
+ const { result } = await COMMAND_EXECUTORS["task-scope"]({ target, packageRoot, options });
515
+ renderJsonOr(options, result, formatTaskScopeResult);
686
516
  return 0;
687
517
  },
688
518
  "task-migrate": async ({ target, packageRoot, options }) => {
689
- const result = await runTaskMigrate({ target, packageRoot, dryRun: options.dryRun });
690
- console.log(options.json ? JSON.stringify(result, null, 2) : formatTaskMigrateResult(result));
519
+ const { result } = await COMMAND_EXECUTORS["task-migrate"]({ target, packageRoot, options });
520
+ renderJsonOr(options, result, formatTaskMigrateResult);
521
+ return 0;
522
+ },
523
+ "migrate-protocol": async ({ target, packageRoot, options }) => {
524
+ const { result } = await COMMAND_EXECUTORS["migrate-protocol"]({ target, packageRoot, options });
525
+ renderJsonOr(options, result, formatMigrateProtocolResult);
691
526
  return 0;
692
527
  },
693
528
  "task-unlock": async ({ target, packageRoot, options }) => {
694
- const result = await runTaskUnlock({ target, packageRoot, taskId: options.task, force: options.force });
695
- console.log(options.json ? JSON.stringify(result, null, 2) : formatTaskUnlockResult(result));
529
+ const { result } = await COMMAND_EXECUTORS["task-unlock"]({ target, packageRoot, options });
530
+ renderJsonOr(options, result, formatTaskUnlockResult);
531
+ return 0;
532
+ },
533
+ "task-recover": async ({ target, packageRoot, options }) => {
534
+ if (options.operatorAuthorized && !options.acknowledgeRecovery) {
535
+ console.error("DEPRECATION: --operator-authorized is caller acknowledgement, not host attestation; use --acknowledge-recovery.");
536
+ }
537
+ const { result } = await COMMAND_EXECUTORS["task-recover"]({ target, packageRoot, options });
538
+ renderJsonOr(options, result, formatTaskRecoverResult);
539
+ return 0;
540
+ },
541
+ "task-resume": async ({ target, packageRoot, options }) => {
542
+ const { result } = await COMMAND_EXECUTORS["task-resume"]({ target, packageRoot, options });
543
+ renderJsonOr(options, result, formatTaskResumeResult);
544
+ return 0;
545
+ },
546
+ "task-repair-legacy-recovery": async ({ target, packageRoot, options }) => {
547
+ const { result } = await COMMAND_EXECUTORS["task-repair-legacy-recovery"]({ target, packageRoot, options });
548
+ renderJsonOr(options, result, formatTaskRepairLegacyRecoveryResult);
696
549
  return 0;
697
550
  },
698
551
  "reconcile-closure": async ({ target, packageRoot, options }) => {
699
- const result = await reconcileClosure({
700
- target,
701
- packageRoot,
702
- taskId: options.task,
703
- checkId: options.checkId,
704
- checkRequirement: options.checkRequirement,
705
- checkDetails: options.checkDetails,
706
- commandArgv: options.commandArgv,
707
- });
708
- console.log(options.json ? JSON.stringify(result, null, 2) : formatReconcileClosureResult(result));
552
+ const { result } = await COMMAND_EXECUTORS["reconcile-closure"]({ target, packageRoot, options });
553
+ renderJsonOr(options, result, formatReconcileClosureResult);
709
554
  return 0;
710
555
  },
711
556
  update: async ({ target, packageRoot, packageVersion, options }) => {
712
- const result = await runUpdate({ target, dryRun: options.dryRun, packageRoot, packageVersion });
557
+ const { result, exitCode } = await COMMAND_EXECUTORS.update({ target, packageRoot, packageVersion, options });
713
558
  printActions(result.actions);
714
559
  for (const conflict of result.conflicts) {
715
560
  const code = conflict.code ? `${conflict.code}: ` : "";
716
561
  console.log(`conflict: ${code}${conflict.path} - ${conflict.message}`);
717
562
  }
718
- return result.conflicts.length === 0 ? 0 : 1;
563
+ return exitCode;
719
564
  },
720
565
  });
721
566