perttool 0.8.1 → 0.9.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 (139) hide show
  1. package/CHANGELOG.md +37 -1
  2. package/README.md +100 -38
  3. package/dist/application/cli-facade.d.ts +12 -7
  4. package/dist/application/cli-facade.d.ts.map +1 -1
  5. package/dist/application/cli-facade.js +16 -7
  6. package/dist/application/cli-facade.js.map +1 -1
  7. package/dist/application/contract8-milestone-acceptance.d.ts +74 -0
  8. package/dist/application/contract8-milestone-acceptance.d.ts.map +1 -0
  9. package/dist/application/contract8-milestone-acceptance.js +185 -0
  10. package/dist/application/contract8-milestone-acceptance.js.map +1 -0
  11. package/dist/application/editor-milestone-acceptance.d.ts +75 -0
  12. package/dist/application/editor-milestone-acceptance.d.ts.map +1 -0
  13. package/dist/application/editor-milestone-acceptance.js +161 -0
  14. package/dist/application/editor-milestone-acceptance.js.map +1 -0
  15. package/dist/application/target-governance-init.d.ts +1 -1
  16. package/dist/application/target-governance-init.d.ts.map +1 -1
  17. package/dist/application/target-governance-init.js +3 -5
  18. package/dist/application/target-governance-init.js.map +1 -1
  19. package/dist/application/target-governance-project.d.ts +2 -2
  20. package/dist/application/target-governance-project.d.ts.map +1 -1
  21. package/dist/application/target-historical-graph.d.ts +3 -1
  22. package/dist/application/target-historical-graph.d.ts.map +1 -1
  23. package/dist/application/target-historical-graph.js +85 -2
  24. package/dist/application/target-historical-graph.js.map +1 -1
  25. package/dist/application/target-project-history.d.ts +10 -0
  26. package/dist/application/target-project-history.d.ts.map +1 -1
  27. package/dist/application/target-project-history.js +54 -0
  28. package/dist/application/target-project-history.js.map +1 -1
  29. package/dist/application/target-velocity-observation.d.ts +6 -1
  30. package/dist/application/target-velocity-observation.d.ts.map +1 -1
  31. package/dist/application/target-velocity-observation.js +72 -4
  32. package/dist/application/target-velocity-observation.js.map +1 -1
  33. package/dist/cli.js +377 -37
  34. package/dist/cli.js.map +1 -1
  35. package/dist/command/assurance-discovery.d.ts +4 -3
  36. package/dist/command/assurance-discovery.d.ts.map +1 -1
  37. package/dist/command/assurance-discovery.js +96 -9
  38. package/dist/command/assurance-discovery.js.map +1 -1
  39. package/dist/command/assurance-usage.js +2 -2
  40. package/dist/command/assurance-usage.js.map +1 -1
  41. package/dist/command/discovery.js +4 -4
  42. package/dist/command/discovery.js.map +1 -1
  43. package/dist/command/registry.d.ts +1 -1
  44. package/dist/command/registry.d.ts.map +1 -1
  45. package/dist/command/registry.js +2 -2
  46. package/dist/command/registry.js.map +1 -1
  47. package/dist/command/usage.d.ts.map +1 -1
  48. package/dist/command/usage.js +12 -4
  49. package/dist/command/usage.js.map +1 -1
  50. package/dist/core/index.d.ts +1 -1
  51. package/dist/core/index.d.ts.map +1 -1
  52. package/dist/help/assurance-guide.d.ts +1 -1
  53. package/dist/help/assurance-guide.d.ts.map +1 -1
  54. package/dist/help/assurance-guide.js +46 -19
  55. package/dist/help/assurance-guide.js.map +1 -1
  56. package/dist/help/guide.d.ts +1 -1
  57. package/dist/help/guide.d.ts.map +1 -1
  58. package/dist/help/registry.js +5 -5
  59. package/dist/help/registry.js.map +1 -1
  60. package/dist/history/historical-graph.d.ts +2 -0
  61. package/dist/history/historical-graph.d.ts.map +1 -1
  62. package/dist/history/historical-graph.js +98 -24
  63. package/dist/history/historical-graph.js.map +1 -1
  64. package/dist/history/milestone-acceptance-history.d.ts +59 -0
  65. package/dist/history/milestone-acceptance-history.d.ts.map +1 -0
  66. package/dist/history/milestone-acceptance-history.js +332 -0
  67. package/dist/history/milestone-acceptance-history.js.map +1 -0
  68. package/dist/index.d.ts +10 -9
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +7 -6
  71. package/dist/index.js.map +1 -1
  72. package/dist/migration/grammar-boundary.d.ts +1 -1
  73. package/dist/migration/grammar-boundary.d.ts.map +1 -1
  74. package/dist/migration/grammar-boundary.js +7 -3
  75. package/dist/migration/grammar-boundary.js.map +1 -1
  76. package/dist/milestone-acceptance/advance.d.ts +39 -0
  77. package/dist/milestone-acceptance/advance.d.ts.map +1 -0
  78. package/dist/milestone-acceptance/advance.js +112 -0
  79. package/dist/milestone-acceptance/advance.js.map +1 -0
  80. package/dist/milestone-acceptance/evaluate.d.ts +51 -0
  81. package/dist/milestone-acceptance/evaluate.d.ts.map +1 -0
  82. package/dist/milestone-acceptance/evaluate.js +114 -0
  83. package/dist/milestone-acceptance/evaluate.js.map +1 -0
  84. package/dist/milestone-acceptance/migration.d.ts +25 -0
  85. package/dist/milestone-acceptance/migration.d.ts.map +1 -0
  86. package/dist/milestone-acceptance/migration.js +76 -0
  87. package/dist/milestone-acceptance/migration.js.map +1 -0
  88. package/dist/milestone-acceptance/mutation.d.ts +49 -0
  89. package/dist/milestone-acceptance/mutation.d.ts.map +1 -0
  90. package/dist/milestone-acceptance/mutation.js +136 -0
  91. package/dist/milestone-acceptance/mutation.js.map +1 -0
  92. package/dist/milestone-acceptance/source.d.ts +83 -0
  93. package/dist/milestone-acceptance/source.d.ts.map +1 -0
  94. package/dist/milestone-acceptance/source.js +301 -0
  95. package/dist/milestone-acceptance/source.js.map +1 -0
  96. package/dist/mutation/advance-deletion.d.ts.map +1 -1
  97. package/dist/mutation/advance-deletion.js +6 -1
  98. package/dist/mutation/advance-deletion.js.map +1 -1
  99. package/dist/perttool-vscode-private-0.0.0-d1578b9.vsix +0 -0
  100. package/dist/recommendation/override-types.d.ts +2 -2
  101. package/dist/recommendation/override.d.ts +1 -1
  102. package/dist/recommendation/override.js +2 -2
  103. package/dist/schema/registry.d.ts +1 -1
  104. package/dist/schema/registry.d.ts.map +1 -1
  105. package/dist/schema/registry.js +8 -6
  106. package/dist/schema/registry.js.map +1 -1
  107. package/dist/semantic/validator.d.ts.map +1 -1
  108. package/dist/semantic/validator.js +14 -3
  109. package/dist/semantic/validator.js.map +1 -1
  110. package/dist/session/document-session.d.ts +5 -0
  111. package/dist/session/document-session.d.ts.map +1 -1
  112. package/dist/session/document-session.js +25 -2
  113. package/dist/session/document-session.js.map +1 -1
  114. package/dist/version.d.ts +1 -1
  115. package/dist/version.js +1 -1
  116. package/package.json +1 -1
  117. package/schemas/{Perttool.AdvanceResult.v2.schema.json → Perttool.AdvanceResult.v3.schema.json} +36 -5
  118. package/schemas/Perttool.AgentGuidanceResult.v1.schema.json +1 -1
  119. package/schemas/{Perttool.AnalysisResult.v5.schema.json → Perttool.AnalysisResult.v6.schema.json} +12 -5
  120. package/schemas/{Perttool.CheckResult.v4.schema.json → Perttool.CheckResult.v5.schema.json} +12 -5
  121. package/schemas/Perttool.CliError.v1.schema.json +1 -1
  122. package/schemas/Perttool.CommandHelpResult.v1.schema.json +3 -3
  123. package/schemas/Perttool.ExportResult.v1.schema.json +1 -1
  124. package/schemas/Perttool.FormatResult.v1.schema.json +1 -1
  125. package/schemas/Perttool.GuideResult.v1.schema.json +1 -1
  126. package/schemas/Perttool.HistoricalGraphResult.v1.schema.json +100 -2
  127. package/schemas/Perttool.ImportResult.v1.schema.json +1 -1
  128. package/schemas/Perttool.InitResult.v1.schema.json +1 -1
  129. package/schemas/Perttool.MilestoneAcceptanceMigrationResult.v1.schema.json +24 -0
  130. package/schemas/Perttool.MilestoneAcceptanceResult.v1.schema.json +79 -0
  131. package/schemas/{Perttool.MutationResult.v4.schema.json → Perttool.MutationResult.v5.schema.json} +4 -4
  132. package/schemas/{Perttool.NextResult.v6.schema.json → Perttool.NextResult.v7.schema.json} +12 -5
  133. package/schemas/Perttool.OverrideDecision.v1.schema.json +1 -1
  134. package/schemas/Perttool.PlanAssuranceResult.v1.schema.json +1 -1
  135. package/schemas/Perttool.ProjectHistoryResult.v1.schema.json +1 -1
  136. package/schemas/Perttool.ProjectResult.v4.schema.json +2 -2
  137. package/schemas/Perttool.SchemaResult.v1.schema.json +1 -1
  138. package/schemas/Perttool.UnitMigrationResult.v3.schema.json +5 -3
  139. package/schemas/Perttool.VelocityObservationResult.v1.schema.json +1 -1
package/dist/cli.js CHANGED
@@ -19,11 +19,29 @@ import { formatDecimal } from "./model/rational.js";
19
19
  import { convertWithVelocity, durationSuffix } from "./model/units.js";
20
20
  import { recommendationInvariantExitCode } from "./recommendation/failure.js";
21
21
  import { recommendationAnalysisToJson } from "./recommendation/json.js";
22
+ import { applyTextEdits, normalizeTextEdits } from "./mutation/text-edits.js";
23
+ import { createUnifiedDiff } from "./editing/unified-diff.js";
24
+ import { sha256DigestUtf8 } from "./model/sha256.js";
22
25
  import { TARGET_GRAMMAR_6_CAPABILITY, } from "./parser/document-parser.js";
23
26
  import { exportPlanAssuranceMermaid, importPlanAssuranceMermaid, } from "./assurance/mermaid.js";
24
27
  import { getJsonSchemaResult, renderJsonSchemaResult, serializeJsonSchemaResult, } from "./schema/registry.js";
25
28
  import { TOOL_VERSION } from "./version.js";
26
- const { analyzeDocument, checkDocument, selectNextTasks, planFormat, planProjectInit, projectInitResultToJson, renderProjectInitResult, withProjectInitOutput, planUnitMigration, withUnitMigrationWrite, getProjectMetadata, contract7ProjectResultToJson, renderContract7ProjectText, planAdvance, planBatchMutation, planFinishActuals, planLifecycle, planMutation, planAssuranceMutation, renderTargetGovernanceDecision, contract7InspectionResultToJson, contract7MutationResultToJson, contract7SnakeJson, contract6WorkEventToJson, renderAdvanceHistoryGuard, prepareTargetPlanAssuranceAdvanceHistory, withTargetPlanAssuranceAdvanceHistoryRace, persistTargetPlanAssuranceResult, inspectTargetPlanAssurance, inspectTargetProjectHistoryFile, renderTargetProjectHistoryText, targetProjectHistoryResultToJson, observeTargetProjectVelocity, renderTargetVelocityObservationText, targetVelocityObservationResultToJson, getAgentHelp, documentContentFromBytes, readDocumentContent, readBytes, recheckAdvanceHistoryBaseline, createArtifactFile, createTargetGrammar6DocumentFile, replaceTargetGrammar6DocumentFile, inspectTargetHistoricalGraphFile, renderTargetHistoricalGraphText, targetHistoricalGraphResultToJson, } = createCliApplicationFacade(createNodeHost(), createHistoricalGraphGitEvidenceHost());
29
+ import { analyzeDocument as analyzeContract8Document, checkDocument as checkContract8Document, selectNextTasks as selectContract8NextTasks, } from "./application/contract8-milestone-acceptance.js";
30
+ import { persistMilestoneAcceptanceMutation, planAcceptanceReceiptMutation, planCriterionSetReplacement, showMilestoneAcceptance, } from "./milestone-acceptance/mutation.js";
31
+ import { planMilestoneAcceptanceMigration, recheckCommittedMigrationProof, } from "./milestone-acceptance/migration.js";
32
+ import { MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY, milestoneAcceptanceBaseText, parseMilestoneAcceptanceSource } from "./milestone-acceptance/source.js";
33
+ import { planMilestoneAcceptanceAdvance } from "./milestone-acceptance/advance.js";
34
+ const { analyzeDocument: _analyzeContract7Document, checkDocument: _checkContract7Document, selectNextTasks: _selectContract7NextTasks, planFormat, planProjectInit, projectInitResultToJson, renderProjectInitResult, withProjectInitOutput, planUnitMigration, withUnitMigrationWrite, getProjectMetadata, contract7ProjectResultToJson, renderContract7ProjectText, planAdvance, planBatchMutation, planFinishActuals, planLifecycle, planMutation, planAssuranceMutation, renderTargetGovernanceDecision, contract7InspectionResultToJson, contract7MutationResultToJson, contract7SnakeJson, contract6WorkEventToJson, renderAdvanceHistoryGuard, prepareTargetPlanAssuranceAdvanceHistory, prepareAdvanceHistory, withAdvanceHistoryRace, withTargetPlanAssuranceAdvanceHistoryRace, persistTargetPlanAssuranceResult, inspectTargetPlanAssurance, inspectTargetCurrentProjectActuals, inspectTargetProjectHistoryFile, renderTargetProjectHistoryText, targetProjectHistoryResultToJson, observeTargetProjectVelocity, renderTargetVelocityObservationText, targetVelocityObservationResultToJson, getAgentHelp, documentContentFromBytes, readDocumentContent, readBytes, recheckAdvanceHistoryBaseline, captureAdvanceHistoryBaseline, createArtifactFile, createValidatedDocumentFile, createTargetGrammar6DocumentFile, replaceTargetGrammar6DocumentFile, replaceValidatedDocumentFile, inspectTargetHistoricalGraphFile, renderTargetHistoricalGraphText, targetHistoricalGraphResultToJson, } = createCliApplicationFacade(createNodeHost(), createHistoricalGraphGitEvidenceHost());
35
+ const analyzeDocument = analyzeContract8Document;
36
+ const checkDocument = checkContract8Document;
37
+ const selectNextTasks = selectContract8NextTasks;
38
+ function contract8MutationResultToJson(result, ...args) {
39
+ return Object.freeze({
40
+ ...contract7MutationResultToJson(result, ...args),
41
+ schema_version: "Perttool.MutationResult.v5",
42
+ cli_contract_version: 8,
43
+ });
44
+ }
27
45
  class UsageError extends Error {
28
46
  code = "PTCLI-001";
29
47
  }
@@ -195,7 +213,11 @@ async function readStdin() {
195
213
  return Buffer.concat(chunks);
196
214
  }
197
215
  function writeJson(value) {
198
- process.stdout.write(`${JSON.stringify(value)}\n`);
216
+ const contract8Value = typeof value === "object" && value !== null && !Array.isArray(value) &&
217
+ "cli_contract_version" in value
218
+ ? { ...value, cli_contract_version: 8 }
219
+ : value;
220
+ process.stdout.write(`${JSON.stringify(contract8Value)}\n`);
199
221
  }
200
222
  function snakeJson(value) {
201
223
  if (typeof value === "bigint")
@@ -232,7 +254,7 @@ function cliError(error, exitCode, operation, json) {
232
254
  if (json) {
233
255
  writeJson({
234
256
  schema_version: "Perttool.CliError.v1",
235
- cli_contract_version: 7,
257
+ cli_contract_version: 8,
236
258
  tool_version: TOOL_VERSION,
237
259
  operation,
238
260
  ok: false,
@@ -268,7 +290,7 @@ async function runCheck(args) {
268
290
  if (format === "json") {
269
291
  writeJson({
270
292
  schema_version: result.schemaVersion,
271
- cli_contract_version: 7,
293
+ cli_contract_version: 8,
272
294
  tool_version: TOOL_VERSION,
273
295
  operation: "document.check",
274
296
  ok,
@@ -288,6 +310,7 @@ async function runCheck(args) {
288
310
  },
289
311
  assurance: contract7SnakeJson(result.assurance),
290
312
  assurance_state_counts: contract7SnakeJson(result.assuranceStateCounts),
313
+ acceptance: snakeJson(result.acceptance),
291
314
  });
292
315
  }
293
316
  else {
@@ -345,7 +368,7 @@ async function runProjectInit(args) {
345
368
  const parsed = parseCommandOptions("project.init", args);
346
369
  const format = outputFormat(parsed.values.get("format"));
347
370
  const color = colorMode(parsed.values.get("color"), format);
348
- const durationUnit = enumOption(requiredOption(parsed, "duration-unit"), "duration-unit", new Set(["day", "hour", "point"]));
371
+ const durationUnit = enumOption(parsed.values.get("duration-unit") ?? "point", "duration-unit", new Set(["day", "hour", "point"]));
349
372
  const version = optionalInteger(parsed, "version", 0, 2_147_483_647);
350
373
  let result = planProjectInit({
351
374
  projectId: parsed.positionals[0],
@@ -518,6 +541,28 @@ async function persistGovernedResult(result, request, sourceOperand) {
518
541
  target: request.target,
519
542
  });
520
543
  }
544
+ async function persistContract8CandidateResult(result, request) {
545
+ if (request.mode === "preview" || !result.changed) {
546
+ return Object.freeze({ mode: request.mode, target: request.target, written: false });
547
+ }
548
+ if (!result.ok || !result.governance?.writeAuthorized || result.updatedText === null) {
549
+ throw new TypeError("authorized Contract 8 result does not contain a digest-bound candidate");
550
+ }
551
+ const validator = (candidate) => {
552
+ const parsed = parseMilestoneAcceptanceSource(candidate, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
553
+ return { ok: parsed.ok, diagnostics: [] };
554
+ };
555
+ if (request.mode === "in_place") {
556
+ await replaceValidatedDocumentFile(request.target, result.updatedText, {
557
+ initialDigest: result.originalDigest,
558
+ ...(request.expectedDigest === undefined ? {} : { expectedDigest: request.expectedDigest }),
559
+ }, validator);
560
+ }
561
+ else {
562
+ await createValidatedDocumentFile(request.target, result.updatedText, validator);
563
+ }
564
+ return Object.freeze({ mode: request.mode, target: request.target, written: true });
565
+ }
521
566
  function assertExpectedDigest(request, initialDigest) {
522
567
  if (request.mode === "in_place" &&
523
568
  request.expectedDigest !== undefined &&
@@ -529,6 +574,21 @@ async function commitCandidate(request, candidateText, initialDigest) {
529
574
  if (candidateText === null) {
530
575
  throw new SafeWriteVerificationError("invalid_candidate", "successful editing result has no candidate text");
531
576
  }
577
+ const acceptanceSource = parseMilestoneAcceptanceSource(candidateText, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
578
+ if (acceptanceSource.grammarVersion === 7) {
579
+ const validator = (candidate) => {
580
+ const parsed = parseMilestoneAcceptanceSource(candidate, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
581
+ return { ok: parsed.ok, diagnostics: [] };
582
+ };
583
+ return request.mode === "in_place"
584
+ ? replaceValidatedDocumentFile(request.target, candidateText, {
585
+ initialDigest,
586
+ ...(request.expectedDigest === undefined
587
+ ? {}
588
+ : { expectedDigest: request.expectedDigest }),
589
+ }, validator)
590
+ : createValidatedDocumentFile(request.target, candidateText, validator);
591
+ }
532
592
  return request.mode === "in_place"
533
593
  ? replaceTargetGrammar6DocumentFile(request.target, candidateText, TARGET_GRAMMAR_6_CAPABILITY, {
534
594
  initialDigest,
@@ -596,7 +656,7 @@ async function runFormat(args) {
596
656
  if (format === "json") {
597
657
  writeJson({
598
658
  schema_version: "Perttool.FormatResult.v1",
599
- cli_contract_version: 7,
659
+ cli_contract_version: 8,
600
660
  tool_version: TOOL_VERSION,
601
661
  operation: "document.format",
602
662
  ok,
@@ -1197,7 +1257,7 @@ async function runMutation(resource, action, args) {
1197
1257
  if (result.ok) {
1198
1258
  try {
1199
1259
  if (ok && writeRequest.mode !== "preview") {
1200
- writeResult = await persistGovernedResult(result, writeRequest, sourceOperand);
1260
+ writeResult = await persistContract8CandidateResult(result, writeRequest);
1201
1261
  }
1202
1262
  }
1203
1263
  catch (error) {
@@ -1205,7 +1265,7 @@ async function runMutation(resource, action, args) {
1205
1265
  }
1206
1266
  }
1207
1267
  if (format === "json") {
1208
- writeJson(contract7MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), operation, source, writeResult));
1268
+ writeJson(contract8MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), operation, source, writeResult));
1209
1269
  }
1210
1270
  else {
1211
1271
  if (ok) {
@@ -1281,14 +1341,14 @@ async function runLifecycleMutation(action, args) {
1281
1341
  });
1282
1342
  if (result.ok && ok && writeRequest.mode !== "preview") {
1283
1343
  try {
1284
- writeResult = await persistGovernedResult(result, writeRequest, sourceOperand);
1344
+ writeResult = await persistContract8CandidateResult(result, writeRequest);
1285
1345
  }
1286
1346
  catch (error) {
1287
1347
  return writeFailureExit(error, operation, format === "json");
1288
1348
  }
1289
1349
  }
1290
1350
  if (format === "json") {
1291
- writeJson(contract7MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), operation, source, writeResult));
1351
+ writeJson(contract8MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), operation, source, writeResult));
1292
1352
  }
1293
1353
  else {
1294
1354
  if (ok) {
@@ -1327,7 +1387,7 @@ function unitMigrationJson(result, source, sourceDigest, ok) {
1327
1387
  });
1328
1388
  return {
1329
1389
  schema_version: result.schemaVersion,
1330
- cli_contract_version: 7,
1390
+ cli_contract_version: 8,
1331
1391
  tool_version: TOOL_VERSION,
1332
1392
  operation: "project.migrate-unit",
1333
1393
  ok,
@@ -1455,7 +1515,7 @@ async function runUnitMigration(args) {
1455
1515
  }
1456
1516
  return ok ? 0 : 1;
1457
1517
  }
1458
- async function readHistoryForCommand(operation, parsed, format) {
1518
+ async function readHistoryForCommand(operation, parsed, format, expectedSourceDigest) {
1459
1519
  if (parsed.positionals.length !== 1) {
1460
1520
  throw new UsageError(`${operation.replace(".", " ")} requires exactly one <file>`);
1461
1521
  }
@@ -1472,6 +1532,9 @@ async function readHistoryForCommand(operation, parsed, format) {
1472
1532
  ...(parsed.repeatedValues.get("task") === undefined
1473
1533
  ? {}
1474
1534
  : { taskIds: parsed.repeatedValues.get("task") }),
1535
+ ...(expectedSourceDigest === undefined
1536
+ ? {}
1537
+ : { expectedSourceDigest }),
1475
1538
  }, TARGET_GRAMMAR_6_CAPABILITY);
1476
1539
  }
1477
1540
  catch (error) {
@@ -1559,20 +1622,37 @@ async function runProjectVelocityObservation(args) {
1559
1622
  const parsed = parseCommandOptions("project.observe-velocity", args);
1560
1623
  const format = outputFormat(parsed.values.get("format"));
1561
1624
  const color = colorMode(parsed.values.get("color"), format);
1562
- const history = await readHistoryForCommand("project.observe-velocity", parsed, format);
1563
- if (history instanceof Error) {
1564
- return cliError(history, 3, "project.observe-velocity", format === "json");
1565
- }
1566
1625
  const evidenceValue = parsed.values.get("evidence") ?? "declared";
1567
1626
  const evidence = evidenceValue === "git-recorded"
1568
1627
  ? "git_recorded"
1569
1628
  : evidenceValue;
1629
+ const source = parsed.positionals[0];
1630
+ let current = null;
1631
+ if (evidence !== "git_recorded" && source !== undefined && source !== "-") {
1632
+ try {
1633
+ current = await readDocumentContent(source);
1634
+ }
1635
+ catch (error) {
1636
+ return cliError(error instanceof Error ? error : new Error(String(error)), 3, "project.observe-velocity", format === "json");
1637
+ }
1638
+ }
1639
+ const history = await readHistoryForCommand("project.observe-velocity", parsed, format, current?.digest);
1640
+ if (history instanceof Error) {
1641
+ return cliError(history, 3, "project.observe-velocity", format === "json");
1642
+ }
1643
+ const taskIds = parsed.repeatedValues.get("task");
1644
+ const currentActuals = current === null
1645
+ ? null
1646
+ : inspectTargetCurrentProjectActuals({ bytes: current.bytes, digest: current.digest }, taskIds === undefined ? {} : { taskIds }, TARGET_GRAMMAR_6_CAPABILITY);
1570
1647
  const result = observeTargetProjectVelocity(history, {
1571
- ...(parsed.repeatedValues.get("task") === undefined
1572
- ? {}
1573
- : { taskIds: parsed.repeatedValues.get("task") }),
1648
+ ...(taskIds === undefined ? {} : { taskIds }),
1574
1649
  evidence,
1575
- });
1650
+ }, currentActuals === null || current === null
1651
+ ? {}
1652
+ : {
1653
+ currentActuals,
1654
+ currentSourceDigest: current.digest,
1655
+ });
1576
1656
  const warningFailure = parsed.flags.has("warnings-as-errors") &&
1577
1657
  result.diagnostics.some((diagnostic) => diagnostic.severity === "warning");
1578
1658
  const ok = result.ok && !warningFailure;
@@ -1628,16 +1708,94 @@ async function runAdvance(args) {
1628
1708
  catch (error) {
1629
1709
  return cliError(error instanceof Error ? error : new Error(String(error)), 3, "dag.advance", format === "json");
1630
1710
  }
1631
- const planned = planAdvance(input.text, {
1711
+ const acceptancePlan = planMilestoneAcceptanceAdvance(input.text, {
1712
+ maxDiagnostics,
1713
+ originalLabel: source,
1714
+ updatedLabel: "candidate",
1715
+ provisionalPlanner: (baseText) => planAdvance(baseText, {
1716
+ maxDiagnostics,
1717
+ originalLabel: source,
1718
+ updatedLabel: "candidate",
1719
+ }),
1720
+ });
1721
+ if (!acceptancePlan.ok) {
1722
+ if (format === "json")
1723
+ writeJson({
1724
+ schema_version: "Perttool.AdvanceResult.v3",
1725
+ cli_contract_version: 8,
1726
+ tool_version: TOOL_VERSION,
1727
+ operation: "dag.advance",
1728
+ ok: false,
1729
+ document_id: /^project ([A-Za-z][A-Za-z0-9_-]*):$/mu.exec(input.text)?.[1] ?? null,
1730
+ source,
1731
+ source_digest: input.digest,
1732
+ diagnostics: acceptancePlan.diagnostics.map(jsonDiagnostic),
1733
+ diagnostics_truncated: false,
1734
+ changed: acceptancePlan.provisional !== null,
1735
+ original_digest: acceptancePlan.originalDigest,
1736
+ updated_digest: acceptancePlan.provisional?.updatedDigest ?? null,
1737
+ updated_text: acceptancePlan.provisional?.updatedText ?? null,
1738
+ diff: acceptancePlan.provisional?.diff ?? null,
1739
+ edits: snakeJson(acceptancePlan.provisional?.edits ?? []),
1740
+ write: { mode: writeRequest.mode, target: writeRequest.target, written: false },
1741
+ governance: null,
1742
+ lifecycle: null,
1743
+ advance: acceptancePlan.provisional === null ? null : snakeJson({
1744
+ ...acceptancePlan.provisional.advance,
1745
+ removedWorkEventIds: [],
1746
+ removedAssuranceRecordIds: [],
1747
+ updatedAssuranceReceiptIds: [],
1748
+ }),
1749
+ history_guard: null,
1750
+ assurance_guard: null,
1751
+ acceptance_guard: snakeJson(acceptancePlan.acceptanceGuard),
1752
+ });
1753
+ else {
1754
+ if (acceptancePlan.provisional !== null)
1755
+ process.stdout.write(parsed.flags.has("diff") ? acceptancePlan.provisional.diff : acceptancePlan.provisional.updatedText);
1756
+ for (const diagnostic of acceptancePlan.diagnostics)
1757
+ process.stderr.write(`${renderDiagnostic(diagnostic, source, color)}\n`);
1758
+ }
1759
+ return 1;
1760
+ }
1761
+ const contract7BaseText = milestoneAcceptanceBaseText(input.text);
1762
+ const contract7Planned = planAdvance(contract7BaseText, {
1632
1763
  maxDiagnostics,
1633
1764
  originalLabel: source,
1634
1765
  updatedLabel: "candidate",
1635
1766
  governance: governanceRequest(parsed, writeRequest),
1636
1767
  });
1768
+ const combinedEdits = contract7Planned.updatedText === null
1769
+ ? contract7Planned.edits
1770
+ : normalizeTextEdits(input.text, [...contract7Planned.edits, ...acceptancePlan.provisional.edits].filter((edit, index, values) => values.findIndex((candidate) => candidate.startOffset === edit.startOffset &&
1771
+ candidate.endOffset === edit.endOffset &&
1772
+ candidate.replacement === edit.replacement) === index), "Contract 8 acceptance-aware advance");
1773
+ const combinedText = contract7Planned.updatedText === null
1774
+ ? null
1775
+ : applyTextEdits(input.text, combinedEdits);
1776
+ const combinedSource = combinedText === null
1777
+ ? null
1778
+ : parseMilestoneAcceptanceSource(combinedText, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
1779
+ if (combinedSource !== null && !combinedSource.ok) {
1780
+ throw new Error("acceptance-aware assurance advance lost Grammar 7 validation");
1781
+ }
1782
+ const planned = Object.freeze({
1783
+ ...contract7Planned,
1784
+ schemaVersion: "Perttool.AdvanceResult.v3",
1785
+ originalDigest: input.digest,
1786
+ updatedText: combinedText,
1787
+ updatedDigest: combinedText === null ? null : sha256DigestUtf8(combinedText),
1788
+ diff: combinedText === null ? null : createUnifiedDiff(input.text, combinedText, {
1789
+ originalLabel: source,
1790
+ updatedLabel: "candidate",
1791
+ }),
1792
+ edits: combinedEdits,
1793
+ acceptanceGuard: acceptancePlan.acceptanceGuard,
1794
+ });
1637
1795
  const initialWarningFailure = parsed.flags.has("warnings-as-errors") &&
1638
1796
  (planned.diagnosticsTruncated ||
1639
1797
  planned.diagnostics.some((diagnostic) => diagnostic.severity === "warning"));
1640
- const prepared = await prepareTargetPlanAssuranceAdvanceHistory(input.text, planned, TARGET_GRAMMAR_6_CAPABILITY, {
1798
+ const preparedBase = await prepareAdvanceHistory(input.text, planned, {
1641
1799
  mode: writeRequest.mode === "out"
1642
1800
  ? "out"
1643
1801
  : writeRequest.mode,
@@ -1649,6 +1807,28 @@ async function runAdvance(args) {
1649
1807
  forceRequested,
1650
1808
  warningDenied: initialWarningFailure,
1651
1809
  maxDiagnostics,
1810
+ documentValidator: (candidateText, candidateMaxDiagnostics) => {
1811
+ const acceptanceSource = parseMilestoneAcceptanceSource(candidateText, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY);
1812
+ const checked = checkContract8Document(candidateText, { maxDiagnostics: candidateMaxDiagnostics });
1813
+ return {
1814
+ ok: checked.ok && acceptanceSource.ok,
1815
+ document: checked.document,
1816
+ documentId: checked.documentId,
1817
+ diagnostics: checked.diagnostics,
1818
+ diagnosticsTruncated: checked.diagnosticsTruncated,
1819
+ };
1820
+ },
1821
+ });
1822
+ const prepared = Object.freeze({
1823
+ ...preparedBase,
1824
+ result: Object.freeze({
1825
+ ...preparedBase.result,
1826
+ schemaVersion: "Perttool.AdvanceResult.v3",
1827
+ governance: planned.governance,
1828
+ assuranceGuard: planned.assuranceGuard,
1829
+ acceptanceGuard: acceptancePlan.acceptanceGuard,
1830
+ advance: planned.advance,
1831
+ }),
1652
1832
  });
1653
1833
  let result = prepared.result;
1654
1834
  const warningFailure = parsed.flags.has("warnings-as-errors") &&
@@ -1671,13 +1851,20 @@ async function runAdvance(args) {
1671
1851
  result.historyGuard?.status === "forced")) {
1672
1852
  const recheck = await recheckAdvanceHistoryBaseline(prepared.baseline, sourceOperand);
1673
1853
  if (!recheck.ok) {
1674
- result = withTargetPlanAssuranceAdvanceHistoryRace(result, recheck, maxDiagnostics);
1854
+ result = Object.freeze({
1855
+ ...withAdvanceHistoryRace(result, recheck, maxDiagnostics),
1856
+ schemaVersion: "Perttool.AdvanceResult.v3",
1857
+ governance: result.governance,
1858
+ assuranceGuard: result.assuranceGuard,
1859
+ acceptanceGuard: result.acceptanceGuard,
1860
+ advance: result.advance,
1861
+ });
1675
1862
  ok = false;
1676
1863
  historyRace = true;
1677
1864
  }
1678
1865
  }
1679
1866
  if (ok && writeRequest.mode !== "preview") {
1680
- writeResult = await persistGovernedResult(result, writeRequest, sourceOperand);
1867
+ writeResult = await persistContract8CandidateResult(result, writeRequest);
1681
1868
  }
1682
1869
  }
1683
1870
  catch (error) {
@@ -1685,7 +1872,12 @@ async function runAdvance(args) {
1685
1872
  }
1686
1873
  }
1687
1874
  if (format === "json") {
1688
- writeJson(contract7MutationResultToJson(ok ? result : Object.freeze({ ...result, ok: false }), "dag.advance", source, writeResult));
1875
+ writeJson({
1876
+ ...contract7MutationResultToJson((ok ? result : Object.freeze({ ...result, ok: false })), "dag.advance", source, writeResult),
1877
+ schema_version: "Perttool.AdvanceResult.v3",
1878
+ cli_contract_version: 8,
1879
+ acceptance_guard: snakeJson(result.acceptanceGuard),
1880
+ });
1689
1881
  }
1690
1882
  else {
1691
1883
  if (result.advance !== null) {
@@ -2046,7 +2238,7 @@ async function runAnalyze(args) {
2046
2238
  if (format === "json") {
2047
2239
  writeJson({
2048
2240
  schema_version: result.schemaVersion,
2049
- cli_contract_version: 7,
2241
+ cli_contract_version: 8,
2050
2242
  tool_version: TOOL_VERSION,
2051
2243
  operation: "dag.analyze",
2052
2244
  ok,
@@ -2079,6 +2271,7 @@ async function runAnalyze(args) {
2079
2271
  : resourceJson(result.resource, result.durationUnit, result.precision),
2080
2272
  temporal: snakeJson(result.temporal),
2081
2273
  assurance: contract7SnakeJson(result.assurance),
2274
+ acceptance: snakeJson(result.acceptance),
2082
2275
  });
2083
2276
  }
2084
2277
  else {
@@ -2193,7 +2386,7 @@ async function runRender(args) {
2193
2386
  if (format === "json") {
2194
2387
  writeJson({
2195
2388
  schema_version: "Perttool.ExportResult.v1",
2196
- cli_contract_version: 7,
2389
+ cli_contract_version: 8,
2197
2390
  tool_version: TOOL_VERSION,
2198
2391
  operation: "dag.render",
2199
2392
  ok,
@@ -2306,7 +2499,7 @@ async function runImport(args) {
2306
2499
  if (format === "json") {
2307
2500
  writeJson({
2308
2501
  schema_version: "Perttool.ImportResult.v1",
2309
- cli_contract_version: 7,
2502
+ cli_contract_version: 8,
2310
2503
  tool_version: TOOL_VERSION,
2311
2504
  operation: "dag.import",
2312
2505
  ok,
@@ -2615,7 +2808,7 @@ async function runNext(args) {
2615
2808
  if (format === "json") {
2616
2809
  writeJson({
2617
2810
  schema_version: "Perttool.CliError.v1",
2618
- cli_contract_version: 7,
2811
+ cli_contract_version: 8,
2619
2812
  tool_version: TOOL_VERSION,
2620
2813
  operation: "dag.next",
2621
2814
  ok: false,
@@ -2636,7 +2829,7 @@ async function runNext(args) {
2636
2829
  if (format === "json") {
2637
2830
  writeJson({
2638
2831
  schema_version: result.schemaVersion,
2639
- cli_contract_version: 7,
2832
+ cli_contract_version: 8,
2640
2833
  recommendation_interface_version: 1,
2641
2834
  tool_version: TOOL_VERSION,
2642
2835
  operation: "dag.next",
@@ -2650,6 +2843,7 @@ async function runNext(args) {
2650
2843
  ...(result.durationUnit === null ? {} : nextJson(result)),
2651
2844
  temporal: snakeJson(result.temporal),
2652
2845
  assurance: contract7SnakeJson(result.assurance),
2846
+ acceptance: snakeJson(result.acceptance),
2653
2847
  });
2654
2848
  }
2655
2849
  else {
@@ -2664,6 +2858,142 @@ async function runNext(args) {
2664
2858
  }
2665
2859
  return ok ? 0 : 1;
2666
2860
  }
2861
+ async function runMilestoneAcceptance(action, args) {
2862
+ const operation = `milestone-acceptance.${action}`;
2863
+ const parsed = parseCommandOptions(operation, args);
2864
+ const format = outputFormat(parsed.values.get("format"));
2865
+ const sourceOperand = parsed.positionals[0];
2866
+ if (sourceOperand === undefined)
2867
+ throw new UsageError(`${operation} requires <file>`);
2868
+ const input = await readDocument(sourceOperand);
2869
+ if (action === "show") {
2870
+ if (parsed.positionals.length !== 1)
2871
+ throw new UsageError("milestone acceptance show requires exactly one <file>");
2872
+ const result = checkDocument(input.text).acceptance ?? showMilestoneAcceptance(input.text, []);
2873
+ if (format === "json")
2874
+ writeJson({ schema_version: "Perttool.MilestoneAcceptanceResult.v1", cli_contract_version: 8, tool_version: TOOL_VERSION, operation, ok: result.ok, milestones: snakeJson(result.milestones), diagnostics: snakeJson(result.diagnostics) });
2875
+ else
2876
+ process.stdout.write(`${result.milestones.map(({ milestoneId, closure, acceptance }) => `${milestoneId} closure=${closure} acceptance=${acceptance}`).join("\n")}\n`);
2877
+ return result.ok ? 0 : 1;
2878
+ }
2879
+ if (parsed.positionals.length !== 4)
2880
+ throw new UsageError(`${operation} requires four operands`);
2881
+ const request = editingWriteRequest(parsed, sourceOperand);
2882
+ if (request.mode === "out")
2883
+ throw new UsageError(`${operation} does not support --out in Contract 8`);
2884
+ const governance = governanceRequest(parsed, request);
2885
+ let result;
2886
+ if (action === "replace") {
2887
+ const criteria = (parsed.repeatedValues.get("criterion") ?? []).map((value) => {
2888
+ const [criterionId, requiredText, evidenceKind, ...description] = value.split(":");
2889
+ if (criterionId === undefined || !["required", "optional"].includes(requiredText ?? "") || !["test", "command", "artifact", "observation", "owner"].includes(evidenceKind ?? "") || description.length === 0)
2890
+ throw new UsageError("--criterion must be ID:required|optional:kind:description");
2891
+ return { criterionId, required: requiredText === "required", evidenceKind: evidenceKind, description: description.join(":") };
2892
+ });
2893
+ result = planCriterionSetReplacement(input.text, { milestoneId: parsed.positionals[1], setId: parsed.positionals[2], revisionId: parsed.positionals[3], criteria }, { governance });
2894
+ }
2895
+ else {
2896
+ result = planAcceptanceReceiptMutation(input.text, {
2897
+ setId: parsed.positionals[1], criterionId: parsed.positionals[2], receiptId: parsed.positionals[3], action: action,
2898
+ ...(parsed.values.get("evidence-kind") === undefined ? {} : { evidenceKind: parsed.values.get("evidence-kind") }),
2899
+ ...(parsed.values.get("evidence-reference") === undefined ? {} : { evidenceReference: parsed.values.get("evidence-reference") }),
2900
+ ...(parsed.values.get("evidence-revision") === undefined ? {} : { evidenceRevision: parsed.values.get("evidence-revision") }),
2901
+ ...(parsed.values.get("verifier") === undefined ? {} : { verifier: parsed.values.get("verifier") }),
2902
+ ...(parsed.values.get("occurred-at") === undefined ? {} : { occurredAt: parsed.values.get("occurred-at") }),
2903
+ ...(parsed.values.get("reason") === undefined ? {} : { reason: parsed.values.get("reason") }),
2904
+ ...(parsed.values.get("revokes") === undefined ? {} : { revokes: parsed.values.get("revokes") }),
2905
+ }, { governance });
2906
+ }
2907
+ let written = false;
2908
+ if (result.ok && request.mode === "in_place" && result.changed) {
2909
+ await persistMilestoneAcceptanceMutation(sourceOperand, result, request.expectedDigest);
2910
+ written = true;
2911
+ }
2912
+ if (format === "json")
2913
+ writeJson({
2914
+ schema_version: "Perttool.MutationResult.v5",
2915
+ cli_contract_version: 8,
2916
+ tool_version: TOOL_VERSION,
2917
+ operation,
2918
+ ok: result.ok,
2919
+ document_id: /^project ([A-Za-z][A-Za-z0-9_-]*):$/mu.exec(input.text)?.[1] ?? null,
2920
+ source: sourceOperand,
2921
+ source_digest: input.digest,
2922
+ diagnostics: result.diagnostics.map((code) => jsonDiagnostic({
2923
+ code,
2924
+ severity: code === "PTGOV-103" || code === "PTGOV-104" ? "warning" : "error",
2925
+ message: code,
2926
+ helpTopic: "editing",
2927
+ })),
2928
+ diagnostics_truncated: false,
2929
+ changed: result.changed,
2930
+ original_digest: result.originalDigest,
2931
+ updated_digest: result.updatedDigest,
2932
+ updated_text: result.updatedText,
2933
+ diff: result.updatedText === null ? null : createUnifiedDiff(input.text, result.updatedText, { originalLabel: sourceOperand, updatedLabel: "candidate" }),
2934
+ edits: result.changed && result.updatedText !== null ? [{ start_offset: 0, end_offset: input.text.length, replacement: result.updatedText }] : [],
2935
+ write: { mode: request.mode, target: request.target, written },
2936
+ governance: result.governance === null ? null : {
2937
+ ...snakeJson(result.governance),
2938
+ schema_version: "Perttool.GovernanceDecision.v2",
2939
+ governance_interface_version: 2,
2940
+ governance_semantics_version: 2,
2941
+ },
2942
+ lifecycle: null,
2943
+ assurance_impact: null,
2944
+ });
2945
+ else if (result.updatedText !== null)
2946
+ process.stdout.write(result.updatedText);
2947
+ return result.ok ? 0 : 1;
2948
+ }
2949
+ async function runDocumentMigration(args) {
2950
+ const parsed = parseCommandOptions("document.migrate", args);
2951
+ if (parsed.positionals.length !== 1 || parsed.values.get("target-grammar") !== "7")
2952
+ throw new UsageError("document migrate requires <file> --target-grammar 7");
2953
+ const sourceOperand = parsed.positionals[0];
2954
+ if (sourceOperand === "-")
2955
+ throw new UsageError("document migrate requires a repository file");
2956
+ const format = outputFormat(parsed.values.get("format"));
2957
+ const input = await readDocument(sourceOperand);
2958
+ const baseline = await captureAdvanceHistoryBaseline({ targetPath: sourceOperand, expectedSourceDigest: input.digest });
2959
+ const toProof = (value) => value.status === "complete" && value.repositorySnapshotId !== null &&
2960
+ value.repositoryRelativePath !== null && value.objectFormat !== null &&
2961
+ value.headCommitId !== null && value.headBlobId !== null &&
2962
+ value.indexBlobId !== null && value.currentSourceDigest !== null
2963
+ ? {
2964
+ repositoryId: value.repositorySnapshotId,
2965
+ repositoryRelativePath: value.repositoryRelativePath,
2966
+ objectFormat: value.objectFormat,
2967
+ headCommit: value.headCommitId,
2968
+ headBlob: value.headBlobId,
2969
+ stage0Blob: value.indexBlobId,
2970
+ sourceDigest: value.currentSourceDigest,
2971
+ }
2972
+ : null;
2973
+ const proof = toProof(baseline);
2974
+ let result = proof === null
2975
+ ? { ok: false, modelVersion: 1, changed: false, sourceGrammarVersion: null, targetGrammarVersion: null, sourceDigest: input.digest, candidateDigest: null, grandfatheredMilestoneIds: Object.freeze([]), candidateText: null, diagnostics: Object.freeze(["PTMAC-109"]) }
2976
+ : planMilestoneAcceptanceMigration(input.text, proof);
2977
+ let race = false;
2978
+ if (result.ok && result.changed && result.candidateText !== null && parsed.flags.has("write")) {
2979
+ const current = toProof(await captureAdvanceHistoryBaseline({
2980
+ targetPath: sourceOperand,
2981
+ expectedSourceDigest: input.digest,
2982
+ }));
2983
+ if (proof === null || current === null || !recheckCommittedMigrationProof(proof, current)) {
2984
+ result = Object.freeze({ ...result, ok: false, diagnostics: Object.freeze(["PTMAC-110"]) });
2985
+ race = true;
2986
+ }
2987
+ else {
2988
+ await replaceValidatedDocumentFile(sourceOperand, result.candidateText, { initialDigest: input.digest, ...(parsed.values.get("expect-digest") === undefined ? {} : { expectedDigest: parsed.values.get("expect-digest") }) }, (candidate) => ({ ok: parseMilestoneAcceptanceSource(candidate, MILESTONE_ACCEPTANCE_SOURCE_CAPABILITY).ok, diagnostics: [] }));
2989
+ }
2990
+ }
2991
+ if (format === "json")
2992
+ writeJson({ schema_version: "Perttool.MilestoneAcceptanceMigrationResult.v1", cli_contract_version: 8, tool_version: TOOL_VERSION, operation: "document.migrate", ...snakeJson(result) });
2993
+ else if (result.candidateText !== null)
2994
+ process.stdout.write(result.candidateText);
2995
+ return result.ok ? 0 : race ? 5 : 1;
2996
+ }
2667
2997
  function runGuide(args) {
2668
2998
  const parsed = parseCommandOptions("guide", args);
2669
2999
  if (parsed.positionals.length > 2) {
@@ -2690,13 +3020,13 @@ function runGuide(args) {
2690
3020
  }
2691
3021
  function runCommandHelp(args) {
2692
3022
  const parsed = parseCommandOptions("help", args);
2693
- if (parsed.positionals.length > 2) {
2694
- throw new UsageError("help accepts at most <resource> <action>");
3023
+ if (parsed.positionals.length > 3) {
3024
+ throw new UsageError("help accepts at most <resource> <group> <action>");
2695
3025
  }
2696
3026
  const format = outputFormat(parsed.values.get("format"));
2697
3027
  const result = getAssuranceCommandDiscovery({
2698
3028
  resource: parsed.positionals[0] ?? null,
2699
- action: parsed.positionals[1] ?? null,
3029
+ action: parsed.positionals.length < 2 ? null : parsed.positionals.slice(1).join(" "),
2700
3030
  });
2701
3031
  if (format === "json") {
2702
3032
  process.stdout.write(serializeAssuranceCommandHelpResult(result));
@@ -2770,7 +3100,7 @@ function runAgentHelp(args) {
2770
3100
  const { schema_version: schemaVersion, ...payload } = projected;
2771
3101
  writeJson({
2772
3102
  schema_version: schemaVersion,
2773
- cli_contract_version: 7,
3103
+ cli_contract_version: 8,
2774
3104
  ...payload,
2775
3105
  });
2776
3106
  }
@@ -2974,14 +3304,14 @@ async function runAssuranceMutation(resource, action, args) {
2974
3304
  });
2975
3305
  if (result.ok && writeRequest.mode !== "preview") {
2976
3306
  try {
2977
- writeResult = await persistGovernedResult(result, writeRequest, sourceOperand);
3307
+ writeResult = await persistContract8CandidateResult(result, writeRequest);
2978
3308
  }
2979
3309
  catch (error) {
2980
3310
  return writeFailureExit(error, operation, format === "json");
2981
3311
  }
2982
3312
  }
2983
3313
  if (format === "json") {
2984
- writeJson(contract7MutationResultToJson(result, operation, source, writeResult));
3314
+ writeJson(contract8MutationResultToJson(result, operation, source, writeResult));
2985
3315
  }
2986
3316
  else {
2987
3317
  if (result.ok) {
@@ -3021,6 +3351,8 @@ async function dispatchCommand(descriptor, args) {
3021
3351
  return runCheck(args);
3022
3352
  case "document.format":
3023
3353
  return runFormat(args);
3354
+ case "document.migrate":
3355
+ return runDocumentMigration(args);
3024
3356
  case "agent.help":
3025
3357
  return runAgentHelp(args);
3026
3358
  case "project.init":
@@ -3051,6 +3383,14 @@ async function dispatchCommand(descriptor, args) {
3051
3383
  return runLifecycleMutation("suspend", args);
3052
3384
  case "task.resume":
3053
3385
  return runLifecycleMutation("resume", args);
3386
+ case "milestone-acceptance.show":
3387
+ case "milestone-acceptance.replace":
3388
+ case "milestone-acceptance.verify":
3389
+ case "milestone-acceptance.fail":
3390
+ case "milestone-acceptance.unavailable":
3391
+ case "milestone-acceptance.revoke":
3392
+ case "milestone-acceptance.waive":
3393
+ return runMilestoneAcceptance(descriptor.path[2], args);
3054
3394
  case "plan-assurance.show":
3055
3395
  return runPlanAssuranceInspection("show", args);
3056
3396
  case "plan-assurance.hash":
@@ -3069,7 +3409,7 @@ async function dispatchCommand(descriptor, args) {
3069
3409
  const [resource, action] = descriptor.path;
3070
3410
  return runMutation(resource, action, args);
3071
3411
  }
3072
- throw new Error(`no Contract 7 handler for ${descriptor.operation}`);
3412
+ throw new Error(`no Contract 8 handler for ${descriptor.operation}`);
3073
3413
  }
3074
3414
  function emitCommandUsage(error, json) {
3075
3415
  if (json) {