@intentius/chant 0.124.25 → 0.124.27

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 (113) hide show
  1. package/dist/cli/commands/build.d.ts.map +1 -1
  2. package/dist/cli/commands/build.js +4 -2
  3. package/dist/cli/commands/lint.d.ts.map +1 -1
  4. package/dist/cli/commands/lint.js +4 -2
  5. package/dist/cli/handlers/approve.d.ts.map +1 -1
  6. package/dist/cli/handlers/approve.js +39 -4
  7. package/dist/gate-decision.d.ts +1 -1
  8. package/dist/gate-decision.d.ts.map +1 -1
  9. package/dist/gate-decision.js +1 -1
  10. package/dist/lifecycle/gate-audit.d.ts +7 -1
  11. package/dist/lifecycle/gate-audit.d.ts.map +1 -1
  12. package/dist/lifecycle/gate-audit.js +40 -3
  13. package/dist/lifecycle/gate-checkpoint.d.ts +78 -0
  14. package/dist/lifecycle/gate-checkpoint.d.ts.map +1 -0
  15. package/dist/lifecycle/gate-checkpoint.js +103 -0
  16. package/dist/lifecycle/gate-ledger.d.ts +41 -0
  17. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  18. package/dist/lifecycle/gate-ledger.js +18 -0
  19. package/dist/lifecycle/run-ledger.d.ts +2 -0
  20. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  21. package/dist/lifecycle/run-ledger.js +2 -0
  22. package/dist/lint/rules/op/index.d.ts +6 -2
  23. package/dist/lint/rules/op/index.d.ts.map +1 -1
  24. package/dist/lint/rules/op/index.js +7 -3
  25. package/dist/lint/rules/op/ops016-gate-resume.d.ts +14 -0
  26. package/dist/lint/rules/op/ops016-gate-resume.d.ts.map +1 -0
  27. package/dist/lint/rules/op/ops016-gate-resume.js +31 -0
  28. package/dist/lint/rules/op/ops017-gate-alias.d.ts +30 -0
  29. package/dist/lint/rules/op/ops017-gate-alias.d.ts.map +1 -0
  30. package/dist/lint/rules/op/ops017-gate-alias.js +67 -0
  31. package/dist/op/activity-contract.d.ts +14 -0
  32. package/dist/op/activity-contract.d.ts.map +1 -1
  33. package/dist/op/activity-contract.js +16 -0
  34. package/dist/op/activity-registry.d.ts +6 -3
  35. package/dist/op/activity-registry.d.ts.map +1 -1
  36. package/dist/op/activity-registry.js +7 -5
  37. package/dist/op/builders.d.ts +7 -0
  38. package/dist/op/builders.d.ts.map +1 -1
  39. package/dist/op/builders.js +13 -0
  40. package/dist/op/discover.d.ts.map +1 -1
  41. package/dist/op/discover.js +14 -7
  42. package/dist/op/gate-alias.d.ts +57 -0
  43. package/dist/op/gate-alias.d.ts.map +1 -0
  44. package/dist/op/gate-alias.js +127 -0
  45. package/dist/op/gate-checkpoint.d.ts +123 -0
  46. package/dist/op/gate-checkpoint.d.ts.map +1 -0
  47. package/dist/op/gate-checkpoint.js +280 -0
  48. package/dist/op/gate.d.ts +54 -2
  49. package/dist/op/gate.d.ts.map +1 -1
  50. package/dist/op/gate.js +142 -1
  51. package/dist/op/index.d.ts +4 -1
  52. package/dist/op/index.d.ts.map +1 -1
  53. package/dist/op/index.js +2 -1
  54. package/dist/op/local-executor.d.ts +57 -2
  55. package/dist/op/local-executor.d.ts.map +1 -1
  56. package/dist/op/local-executor.js +136 -6
  57. package/dist/op/local-output.d.ts.map +1 -1
  58. package/dist/op/local-output.js +20 -2
  59. package/dist/op/op-ir.d.ts +4 -0
  60. package/dist/op/op-ir.d.ts.map +1 -1
  61. package/dist/op/op-ir.js +4 -0
  62. package/dist/op/runtime.d.ts +15 -0
  63. package/dist/op/runtime.d.ts.map +1 -1
  64. package/dist/op/runtimes/local.d.ts.map +1 -1
  65. package/dist/op/runtimes/local.js +9 -2
  66. package/dist/op/types.d.ts +31 -0
  67. package/dist/op/types.d.ts.map +1 -1
  68. package/dist/wave-runtime.mjs +225 -245
  69. package/dist/workspace/trust/gate-seal.d.ts +32 -1
  70. package/dist/workspace/trust/gate-seal.d.ts.map +1 -1
  71. package/dist/workspace/trust/gate-seal.js +41 -2
  72. package/dist/workspace/trust/seal.d.ts +1 -1
  73. package/dist/workspace/trust/seal.d.ts.map +1 -1
  74. package/dist/workspace/trust/seal.js +1 -1
  75. package/package.json +1 -1
  76. package/src/cli/commands/build.ts +9 -2
  77. package/src/cli/commands/lint.ts +4 -2
  78. package/src/cli/compiled-cli.e2e.test.ts +31 -6
  79. package/src/cli/handlers/approve.ts +46 -4
  80. package/src/cli/handlers/operator.test.ts +91 -0
  81. package/src/gate-decision.ts +2 -0
  82. package/src/lifecycle/gate-audit.ts +41 -4
  83. package/src/lifecycle/gate-checkpoint.test.ts +128 -0
  84. package/src/lifecycle/gate-checkpoint.ts +133 -0
  85. package/src/lifecycle/gate-ledger.ts +61 -0
  86. package/src/lifecycle/run-ledger.ts +4 -0
  87. package/src/lint/rules/op/index.ts +9 -3
  88. package/src/lint/rules/op/ops016-gate-resume.test.ts +53 -0
  89. package/src/lint/rules/op/ops016-gate-resume.ts +48 -0
  90. package/src/lint/rules/op/ops017-gate-alias.test.ts +85 -0
  91. package/src/lint/rules/op/ops017-gate-alias.ts +89 -0
  92. package/src/op/activity-contract.ts +22 -1
  93. package/src/op/activity-registry.ts +7 -5
  94. package/src/op/builders.ts +21 -1
  95. package/src/op/discover-root.test.ts +39 -0
  96. package/src/op/discover.ts +15 -8
  97. package/src/op/gate-alias.e2e.test.ts +78 -0
  98. package/src/op/gate-alias.test.ts +350 -0
  99. package/src/op/gate-alias.ts +137 -0
  100. package/src/op/gate-checkpoint.test.ts +284 -0
  101. package/src/op/gate-checkpoint.ts +322 -0
  102. package/src/op/gate.ts +198 -4
  103. package/src/op/index.ts +4 -1
  104. package/src/op/local-executor.ts +180 -7
  105. package/src/op/local-output.ts +18 -2
  106. package/src/op/op-ir.test.ts +25 -0
  107. package/src/op/op-ir.ts +8 -0
  108. package/src/op/runtime.ts +8 -0
  109. package/src/op/runtimes/local.ts +9 -2
  110. package/src/op/types.ts +32 -0
  111. package/src/workspace/trust/gate-seal.test.ts +29 -2
  112. package/src/workspace/trust/gate-seal.ts +46 -2
  113. package/src/workspace/trust/seal.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,7 @@ import { coreOutputChecks } from "../../lint/output-checks.js";
15
15
  import { coreKnowledgeChecks } from "../../lint/knowledge-checks.js";
16
16
  import { applyConfiguredSeverity, applyConfiguredPreset, resolvePresetIds } from "../../lint/config.js";
17
17
  import { applyInlineSuppressions } from "../../lint/suppressions.js";
18
- import { coreOpChecks } from "../../lint/rules/op/index.js";
18
+ import { coreOpChecks, workspaceIdentityGates } from "../../lint/rules/op/index.js";
19
19
  import { loadPolicyChecks } from "../../lint/policy.js";
20
20
  import { armSandboxPolicyExecution, runProjectPolicies } from "../../lint/policy-sandbox.js";
21
21
  import { sortedJsonReplacer } from "../../utils.js";
@@ -427,7 +427,9 @@ export async function buildCommand(options) {
427
427
  // FULL build result regardless of which plugins loaded — same as the
428
428
  // receipt/output/knowledge checks above.
429
429
  if (result.errors.length === 0) {
430
- const opDiags = runPostSynthChecks(coreOpChecks({ decideBackends: config.decide?.backends }), result, env, { activityContracts });
430
+ // OPS017 (#3949) reads the workspace's identity.gates, when an Op has gate aliases.
431
+ const identityGates = await workspaceIdentityGates(configDir, result.entities);
432
+ const opDiags = runPostSynthChecks(coreOpChecks({ decideBackends: config.decide?.backends, ...(identityGates ? { identityGates } : {}) }), result, env, { activityContracts });
431
433
  const { diagnostics: activeDiags, suppressed } = applyConfiguredSeverity(opDiags, config.lint?.rules);
432
434
  suppressedPostSynthCount += suppressed.length;
433
435
  for (const diag of activeDiags) {
@@ -1 +1 @@
1
- {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/lint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAW,MAAM,iBAAiB,CAAC;AAyCzE;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAW5D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAoBhC;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,WAAW,CAAC;AAsBnD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,WAAW,CAAC;AA2I9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACrC,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,oBAAoB;IACpB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,qCAAqC;IACrC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AA6eD;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA+N3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAIxD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GACtC,MAAM,IAAI,CAiCZ"}
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/lint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAG7D,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAW,MAAM,iBAAiB,CAAC;AAyCzE;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAW5D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAoBhC;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,WAAW,CAAC;AAsBnD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,WAAW,CAAC;AA2I9C;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACrC,uBAAuB;IACvB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,oBAAoB;IACpB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACrC,qCAAqC;IACrC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;IACnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AA+eD;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA+N3E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAIxD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,GACtC,MAAM,IAAI,CAiCZ"}
@@ -9,7 +9,7 @@ import { loadCoreRules } from "../../lint/rules/index.js";
9
9
  import { loadComponentChecks } from "../../lint/rules/comp/index.js";
10
10
  import { runComponentChecks } from "../../lint/component-checks.js";
11
11
  import { buildCapabilityRegistry } from "../../components/capability-plugin-loader.js";
12
- import { coreOpChecks } from "../../lint/rules/op/index.js";
12
+ import { coreOpChecks, workspaceIdentityGates } from "../../lint/rules/op/index.js";
13
13
  import { loadActivityContracts } from "../../op/activity-contract-registry.js";
14
14
  import { runPostSynthChecks } from "../../lint/post-synth.js";
15
15
  import { rule } from "../../lint/declarative.js";
@@ -513,7 +513,9 @@ async function runOpCheckDiagnostics(infraPath, files, buildParams, plugins = []
513
513
  const decideBackends = await loadChantConfig(findProjectRoot(infraPath))
514
514
  .then((loaded) => loaded.config.decide?.backends)
515
515
  .catch(() => undefined);
516
- const raw = runPostSynthChecks(coreOpChecks({ decideBackends }), {
516
+ // OPS017 (#3949) reads the workspace's identity.gates, when an Op has gate aliases.
517
+ const identityGates = await workspaceIdentityGates(findProjectRoot(infraPath), entities);
518
+ const raw = runPostSynthChecks(coreOpChecks({ decideBackends, ...(identityGates ? { identityGates } : {}) }), {
517
519
  outputs: new Map(),
518
520
  entities: entities,
519
521
  warnings: [],
@@ -1 +1 @@
1
- {"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/approve.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACuE,KAAK,UAAU,EAC5F,MAAM,6BAA6B,CAAC;AAOrC,OAAO,EAEuC,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAChG,MAAM,wBAAwB,CAAC;AAQhC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAkDlD,wBAAsB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuGrE;AAED,8DAA8D;AAC9D,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oGAAoG;IACpG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,SAAS,CAAC,EAAE,mBAAmB,CAAC;CACjC;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC3D;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAElB;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAyT9B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,oBAAoB,EAAE,EAC7B,QAAQ,EAAE,iBAAiB,GAAG,SAAS,EACvC,OAAO,GAAE,SAAS,iBAAiB,EAA+B,GACjE,MAAM,EAAE,CA8BV"}
1
+ {"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/approve.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EACuE,KAAK,UAAU,EAC5F,MAAM,6BAA6B,CAAC;AAOrC,OAAO,EAEuC,KAAK,mBAAmB,EAAE,KAAK,oBAAoB,EAChG,MAAM,wBAAwB,CAAC;AAQhC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAkDlD,wBAAsB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuGrE;AAED,8DAA8D;AAC9D,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oGAAoG;IACpG,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,SAAS,CAAC,EAAE,mBAAmB,CAAC;CACjC;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC3D;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAElB;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAkW9B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,oBAAoB,EAAE,EAC7B,QAAQ,EAAE,iBAAiB,GAAG,SAAS,EACvC,OAAO,GAAE,SAAS,iBAAiB,EAA+B,GACjE,MAAM,EAAE,CA8BV"}
@@ -5,6 +5,7 @@
5
5
  * re-exports everything here.
6
6
  */
7
7
  import { discoverOps } from "../../op/discover.js";
8
+ import { aliasingGate } from "../../op/gate-alias.js";
8
9
  import { currentGateOrigin, isModelAuthored, sameOriginRefusal, UNATTESTED_APPROVER, } from "../../lifecycle/gate-origin.js";
9
10
  import { appendGateResolution, appendPendingGate, readGateLedger, latestPendingGate, isPendingGateExpired, resolveApprovalUrl, isApprovalUrl, } from "../../lifecycle/gate-ledger.js";
10
11
  import { isPlanDigest, samePlanDigest } from "../../lifecycle/plan-digest.js";
@@ -184,7 +185,9 @@ export async function recordGateApproval(opName, gate, opts) {
184
185
  // `fan-out` is the op name every `chant components fan-out` gate is recorded
185
186
  // under (../handlers/fan-out.ts). It is a command rather than a declaration,
186
187
  // so there is no `*.op.ts` to find and nothing is wrong when none is there.
187
- if (!ops.has(opName) && opName !== FAN_OUT_GATE_OP && opName !== WORKSPACE_UPGRADE_GATE_OP && opName !== OVERRIDE_GATE_OP) {
188
+ // #3949: a gate that lists this one as an alias, after an Op was restructured.
189
+ const successor = aliasingGate([...ops.values()].map((o) => o.config), opName, gate);
190
+ if (!successor && !ops.has(opName) && opName !== FAN_OUT_GATE_OP && opName !== WORKSPACE_UPGRADE_GATE_OP && opName !== OVERRIDE_GATE_OP) {
188
191
  console.error(formatWarning({
189
192
  message: `Op "${opName}" was not found among discovered *.op.ts declarations — recording the resolution anyway`,
190
193
  }));
@@ -204,6 +207,22 @@ export async function recordGateApproval(opName, gate, opts) {
204
207
  }));
205
208
  return { ok: false };
206
209
  }
210
+ // #3949: an approval under an alias counts toward the new gate only while
211
+ // the new gate has no standing fact of its own. Once it has one, approve
212
+ // the gate the runs now stop at.
213
+ if (successor) {
214
+ const theirs = latestPendingGate((await readGateLedger(successor.op)).pending, successor.gate);
215
+ if (theirs && !isPendingGateExpired(theirs, new Date().toISOString())) {
216
+ console.error(formatError({
217
+ message: `Gate "${gate}" on "${opName}" is now gate "${successor.gate}" on "${successor.op}", which lists it as an alias, ` +
218
+ `and "${successor.gate}" has a standing pending fact`,
219
+ hint: `Approve that gate instead: chant approve ${successor.op} ${successor.gate}`,
220
+ }));
221
+ return { ok: false };
222
+ }
223
+ console.error(formatInfo(`Gate "${gate}" on "${opName}" is an alias of gate "${successor.gate}" on "${successor.op}": ` +
224
+ `the next run of ${successor.op} counts this approval there while the pending fact it answers stands and the plan is the same.`));
225
+ }
207
226
  // #2028: the resolution's link is typed. `--url` wins; otherwise, running
208
227
  // inside the PR/MR job that carries the change is itself the address, the
209
228
  // same env fallback `--actor` uses. `--note` stays free-text prose.
@@ -258,6 +277,13 @@ export async function recordGateApproval(opName, gate, opts) {
258
277
  }
259
278
  planDigest = standing.planDigest;
260
279
  }
280
+ // #3947: a gate that resumes recorded a checkpoint with its pending fact.
281
+ // An approval of that fact's plan copies the checkpoint's digest, the way it
282
+ // copies the plan's, so the run that resumes checks the file against what
283
+ // was approved here. An approval of another plan copies none.
284
+ const checkpointDigest = standing?.checkpointDigest !== undefined && samePlanDigest(planDigest, standing.planDigest)
285
+ ? standing.checkpointDigest
286
+ : undefined;
261
287
  // chant#2384 — the gate's whole value is that its two halves have different
262
288
  // authors. At a shell they do: a person runs, reads the plan, and approves.
263
289
  // On MCP and ACP the person's only act was launching the server, and every
@@ -352,11 +378,11 @@ export async function recordGateApproval(opName, gate, opts) {
352
378
  const timestamp = new Date().toISOString();
353
379
  let seal;
354
380
  if (opts.sign !== undefined) {
355
- const { resolveSigningKey, sealGateApproval, SealError } = await import("../../workspace/trust/seal.js");
381
+ const { resolveSigningKey, sealGateApproval, gateSealVersion, SealError } = await import("../../workspace/trust/seal.js");
356
382
  try {
357
383
  const key = resolveSigningKey(opts.sign, cwd);
358
384
  try {
359
- seal = sealGateApproval(key.file, {
385
+ const sealed = {
360
386
  op: opName,
361
387
  gate,
362
388
  ...(environment !== undefined ? { environment } : {}),
@@ -364,7 +390,10 @@ export async function recordGateApproval(opName, gate, opts) {
364
390
  resolvedBy,
365
391
  ...(relayedBy ? { relayedBy } : {}),
366
392
  timestamp,
367
- });
393
+ ...(checkpointDigest !== undefined ? { checkpointDigest } : {}),
394
+ };
395
+ // #3947: a seal over a checkpoint digest is seal version 2.
396
+ seal = { ...sealGateApproval(key.file, sealed), ...(gateSealVersion(sealed) === 2 ? { version: 2 } : {}) };
368
397
  }
369
398
  finally {
370
399
  key.cleanup();
@@ -386,6 +415,7 @@ export async function recordGateApproval(opName, gate, opts) {
386
415
  resolvedBy,
387
416
  ...(relayedBy ? { relayedBy } : {}),
388
417
  timestamp,
418
+ ...(checkpointDigest !== undefined ? { checkpointDigest } : {}),
389
419
  seal,
390
420
  });
391
421
  if (why !== null) {
@@ -444,6 +474,7 @@ export async function recordGateApproval(opName, gate, opts) {
444
474
  ...(opts.note ? { note: opts.note } : {}),
445
475
  ...(url ? { url } : {}),
446
476
  ...(planDigest !== undefined ? { planDigest } : {}),
477
+ ...(checkpointDigest !== undefined ? { checkpointDigest } : {}),
447
478
  ...(environment !== undefined ? { environment } : {}),
448
479
  origin,
449
480
  ...(refusal && opts.allowSameOrigin ? { sameOriginOverride: true } : {}),
@@ -461,6 +492,10 @@ export async function recordGateApproval(opName, gate, opts) {
461
492
  (record.environment !== undefined ? ` in environment "${record.environment}"` : "") +
462
493
  ", and only that plan. A run whose fresh plan differs refuses rather than applying it."));
463
494
  }
495
+ if (record.checkpointDigest) {
496
+ console.error(formatInfo(`The next run resumes at this gate from run ${standing?.runId ?? "(unknown)"}'s checkpoint ${record.checkpointDigest}, ` +
497
+ "after it plans again. A moved plan or another commit starts it at the first phase."));
498
+ }
464
499
  if (approval) {
465
500
  for (const line of describeApprovalProgress(approval, record, ledger.resolutions, standingForOrigin, ledger.pending)) {
466
501
  console.error(formatInfo(line));
@@ -43,7 +43,7 @@ import type { MergedReview } from "./op/gate-review.js";
43
43
  import type { GateApprovalSource } from "./op/op-waves.js";
44
44
  export { GATE_APPROVAL_SOURCES, type GateApprovalSource } from "./op/op-waves.js";
45
45
  export { isPendingGateExpired, latestPendingGate, latestResolutionForPlan, latestResolutionSince, type PlanBoundResolution, } from "./lifecycle/gate-ledger-select.js";
46
- export { GATE_SEAL_NAMESPACE, gateSealPayload, gateSealRefusal, sshKeyFingerprint, verifySshSignatureWith, type GateSigners, type SealedGateApproval, type SshSignatureCheck, } from "./workspace/trust/gate-seal.js";
46
+ export { GATE_SEAL_NAMESPACE, gateSealPayload, gateSealRefusal, gateSealVersion, sealedFieldsOf, sshKeyFingerprint, verifySshSignatureWith, type GateSigners, type SealedGateApproval, type SshSignatureCheck, } from "./workspace/trust/gate-seal.js";
47
47
  export { DEFAULT_SIGNERS_PATH, TRUST_CONFIG_PATH, parseAllowedSigners, trustConfigProblems, type Signer, type SignerSet, } from "./workspace/trust/trust-files.js";
48
48
  export type { GateResolutionRecord, PendingGateRecord } from "./lifecycle/gate-ledger.js";
49
49
  export { CORE_CLASSES, admitApprover, grantedClasses, type ClassGrant, type GateAdmissionRule, type PrincipalClass, } from "./workspace/identity-gate-rule.js";
@@ -1 +1 @@
1
- {"version":3,"file":"gate-decision.d.ts","sourceRoot":"","sources":["../src/gate-decision.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gate-decision.d.ts","sourceRoot":"","sources":["../src/gate-decision.ts"],"names":[],"mappings":"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"}
@@ -48,7 +48,7 @@ import { CORE_CLASSES, admitApprover } from "./workspace/identity-gate-rule.js";
48
48
  import { diskFiles, findInstalledPackage, mergePinClasses, parseClassDataByHand, readClassFiles } from "./workspace/class-data.js";
49
49
  export { GATE_APPROVAL_SOURCES } from "./op/op-waves.js";
50
50
  export { isPendingGateExpired, latestPendingGate, latestResolutionForPlan, latestResolutionSince, } from "./lifecycle/gate-ledger-select.js";
51
- export { GATE_SEAL_NAMESPACE, gateSealPayload, gateSealRefusal, sshKeyFingerprint, verifySshSignatureWith, } from "./workspace/trust/gate-seal.js";
51
+ export { GATE_SEAL_NAMESPACE, gateSealPayload, gateSealRefusal, gateSealVersion, sealedFieldsOf, sshKeyFingerprint, verifySshSignatureWith, } from "./workspace/trust/gate-seal.js";
52
52
  export { DEFAULT_SIGNERS_PATH, TRUST_CONFIG_PATH, parseAllowedSigners, trustConfigProblems, } from "./workspace/trust/trust-files.js";
53
53
  export { CORE_CLASSES, admitApprover, grantedClasses, } from "./workspace/identity-gate-rule.js";
54
54
  export { appliedGateApplies, appliedGatePath, isApprovalSpent, parseAppliedGateLines, } from "./lifecycle/gate-applied.js";
@@ -138,12 +138,18 @@ export interface GateAuditEntry {
138
138
  subject?: "approval" | "override";
139
139
  /** An applied entry: the approval entry it ran under, if one is held. An override-spent entry: the override entry. */
140
140
  under?: string;
141
+ /** An approval a run carried from one of the gate's aliases (#3949): the op, gate and time of the line it came from. */
142
+ carriedFrom?: {
143
+ op: string;
144
+ gate: string;
145
+ at: string;
146
+ };
141
147
  /** Everything else the line carries, such as `members`, `via` or a product's own fields. */
142
148
  detail: Record<string, unknown>;
143
149
  source: GateAuditSource;
144
150
  }
145
151
  export interface GateAuditGap {
146
- kind: "approval-without-request" | "unsealed" | "approval" | "override" | "malformed-line";
152
+ kind: "approval-without-request" | "unsealed" | "approval" | "override" | "malformed-line" | "carried-without-source";
147
153
  op?: string;
148
154
  gate?: string;
149
155
  digest?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"gate-audit.d.ts","sourceRoot":"","sources":["../../src/lifecycle/gate-audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gate-audit.d.ts","sourceRoot":"","sources":["../../src/lifecycle/gate-audit.ts"],"names":[],"mappings":"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"}
@@ -48,6 +48,13 @@
48
48
  * - `override`: an apply cites an override that no line holds.
49
49
  * - `malformed-line`: a line that is not a gate record. Its content is lost
50
50
  * to the trail, so it is said.
51
+ * - `carried-without-source`: an approval carried from a gate's alias
52
+ * (#3949, `carriedFrom`) whose cited line is not in the cited op's
53
+ * ledger. Checked only when that ledger is passed in.
54
+ *
55
+ * A carried approval's request is the pending fact of the name it was
56
+ * carried from, in that op's ledger. When that ledger is not passed in,
57
+ * neither gap is looked for, and the entry's `carriedFrom` says where to look.
51
58
  *
52
59
  * ## Sources and ids
53
60
  *
@@ -96,7 +103,7 @@ export function isOverrideGate(op, gate) {
96
103
  }
97
104
  const KNOWN = new Set([
98
105
  "version", "kind", "op", "gate", "resolvedBy", "relayedBy", "timestamp", "note", "url", "planDigest", "environment",
99
- "approver", "seal", "review", "runId", "expiresAt", "description", "wave", "heldBy", "approvalMode", "rules", "pr", "head", "reviewers",
106
+ "approver", "seal", "review", "runId", "expiresAt", "description", "wave", "heldBy", "approvalMode", "rules", "pr", "head", "reviewers", "carriedFrom",
100
107
  ]);
101
108
  const waveOf = (v) => {
102
109
  const w = v;
@@ -145,6 +152,10 @@ function approverOf(r) {
145
152
  const roles = strings(a.roles);
146
153
  return { kind: a.kind, ...(roles ? { roles } : {}) };
147
154
  }
155
+ const carriedOf = (v) => {
156
+ const c = v;
157
+ return c && typeof c === "object" && typeof c.op === "string" && typeof c.gate === "string" && typeof c.timestamp === "string" ? { op: c.op, gate: c.gate, at: c.timestamp } : undefined;
158
+ };
148
159
  const drop = (o) => Object.fromEntries(Object.entries(o).filter(([, v]) => v !== undefined));
149
160
  const idOf = (...parts) => contentDigest(canonicalJson(parts));
150
161
  /** Whether two digests, either absent, can be the same plan: absent matches anything, as an old line records none. */
@@ -174,6 +185,21 @@ export function deriveGateAudit(input) {
174
185
  const keyed = (e) => (rekey ? { ...e, id: rekey(e) } : e);
175
186
  const entries = [];
176
187
  const gaps = [];
188
+ // #3949: every ledger's requests and approvals by op, for an approval carried from another op's gate.
189
+ const byOp = new Map();
190
+ for (const ledger of input.ledgers) {
191
+ const held = byOp.get(ledger.op) ?? { requests: [], approvals: [] };
192
+ byOp.set(ledger.op, held);
193
+ for (const line of ledger.lines) {
194
+ const r = rowOf(line);
195
+ if (!r || line.removed || typeof r.gate !== "string" || typeof r.timestamp !== "string")
196
+ continue;
197
+ if (r.kind === "pending")
198
+ held.requests.push({ op: ledger.op, gate: r.gate, at: time(r.timestamp), ...(str(r.planDigest) ? { digest: str(r.planDigest) } : {}) });
199
+ else
200
+ held.approvals.push(r);
201
+ }
202
+ }
177
203
  for (const ledger of input.ledgers) {
178
204
  const path = ledger.path ?? `_gates/${ledger.op}.jsonl`;
179
205
  const parsed = [];
@@ -249,11 +275,22 @@ export function deriveGateAudit(input) {
249
275
  at: String(r.timestamp),
250
276
  by: String(r.resolvedBy),
251
277
  seal,
252
- ...drop({ sealed, signer, committedBy: line.added?.by, relayedBy: str(r.relayedBy), approver: approverOf(r), note: str(r.note), url: str(r.url), review: reviewOf(r), rules }),
278
+ ...drop({ sealed, signer, committedBy: line.added?.by, relayedBy: str(r.relayedBy), approver: approverOf(r), note: str(r.note), url: str(r.url), review: reviewOf(r), rules, carriedFrom: carriedOf(r.carriedFrom) }),
253
279
  detail: extra,
254
280
  });
255
281
  entries.push(entry);
256
- if (!override) {
282
+ const carried = entry.carriedFrom;
283
+ if (!override && carried) {
284
+ const cited = byOp.get(carried.op);
285
+ const from = `${carried.op}/${carried.gate}`;
286
+ if (cited && !cited.approvals.some((a) => a.gate === carried.gate && time(String(a.timestamp)) === time(carried.at) && a.resolvedBy === r.resolvedBy)) {
287
+ gaps.push({ kind: "carried-without-source", op: ledger.op, gate, ...(digest ? { digest } : {}), detail: `${path} holds an approval of ${gate} by ${entry.by} carried from ${from} at ${carried.at}, and _gates/${carried.op}.jsonl holds no such approval` });
288
+ }
289
+ if (cited && !cited.requests.some((q) => q.gate === carried.gate && q.at <= time(carried.at) && compatible(q.digest, digest))) {
290
+ gaps.push({ kind: "approval-without-request", op: ledger.op, gate, ...(digest ? { digest } : {}), detail: `${path} holds an approval of ${gate} by ${entry.by} carried from ${from} at ${carried.at} with no pending fact of ${from}${digest ? " and digest" : ""} before it` });
291
+ }
292
+ }
293
+ else if (!override) {
257
294
  const at = time(entry.at);
258
295
  const env = str(r.environment);
259
296
  const asked = requests.some((q) => q.gate === gate && q.at <= at && compatible(q.digest, digest) && (q.environment === undefined || env === undefined || q.environment === env));
@@ -0,0 +1,78 @@
1
+ /**
2
+ * A gate's checkpoint (#3947): the step outputs a run held when it stopped at
3
+ * a gate that resumes, kept on `chant/lifecycle` at
4
+ * `_gates/<op>/checkpoints/<runId>.json`.
5
+ *
6
+ * The run writes the file just before it appends the pending fact, and puts
7
+ * the file's digest on that fact as `checkpointDigest`. `chant approve`
8
+ * copies the digest onto the approval, the way it copies the plan digest, and
9
+ * a seal covers it (`../workspace/trust/gate-seal.ts`). A later run that
10
+ * resumes at the gate reads the file back and checks it against the digest
11
+ * the approver saw, so a value pushed onto the branch after the approval is
12
+ * refused rather than carried into the steps after the gate.
13
+ *
14
+ * Only the outputs some step after the gate references are stored, worked
15
+ * out from the Op's references (`../op/gate-checkpoint.ts`). An output that
16
+ * an activity contract marks secret is never stored: the gate doesn't
17
+ * resume, and the next run starts at the first phase.
18
+ *
19
+ * Pure apart from the two git helpers at the bottom.
20
+ */
21
+ /** One gate checkpoint file. */
22
+ export interface GateCheckpoint {
23
+ version: 1;
24
+ /** The op the gate belongs to. */
25
+ op: string;
26
+ /** The gate's name. */
27
+ gate: string;
28
+ /** The run that stopped at the gate, and the file's name. The pending fact names the same run. */
29
+ runId: string;
30
+ /** The commit the run ran at. A resumed run must be at the same one. */
31
+ commit: string;
32
+ /** The environment the run was started for (`--env`), when it named one. */
33
+ environment?: string;
34
+ /** The plan the run reached the gate with, when the gate binds one. */
35
+ planDigest?: string;
36
+ /** Step id to the output that step returned, for each step a later step references. */
37
+ outputs: Record<string, unknown>;
38
+ }
39
+ /** The prefix a checkpoint digest is written with: the JCS form of the file, hashed with SHA-256. */
40
+ export declare const CHECKPOINT_DIGEST_PREFIX = "jcs1-sha256:";
41
+ /** Whether `raw` is a checkpoint digest this code wrote. */
42
+ export declare function isCheckpointDigest(raw: unknown): raw is string;
43
+ /** The digest of a checkpoint: SHA-256 over its RFC 8785 (JCS) form. Throws when an output can't be put in JSON. */
44
+ export declare function gateCheckpointDigest(checkpoint: GateCheckpoint): string;
45
+ /**
46
+ * A run id is the checkpoint's file name, so it may hold only letters,
47
+ * digits, `.`, `_` and `-`, and may not start with a dot. A run named
48
+ * otherwise (a caller-chosen id with a slash in it) gets no checkpoint.
49
+ */
50
+ export declare function isCheckpointRunId(runId: string): boolean;
51
+ /** Where the checkpoint of `runId` lives on `chant/lifecycle`: the directory and the file, as `writeBlobToPath` takes them. */
52
+ export declare function gateCheckpointPath(op: string, runId: string): {
53
+ dir: string;
54
+ file: string;
55
+ };
56
+ /** The file's text: the checkpoint as JSON, keys sorted, one value per line. */
57
+ export declare function gateCheckpointText(checkpoint: GateCheckpoint): string;
58
+ /**
59
+ * Put `outputs` in the form a checkpoint stores: each value as JSON would
60
+ * carry it. Returns the step whose output JSON can't hold (a cycle, a bigint)
61
+ * instead, so the caller can say which one blocks the gate's resume.
62
+ */
63
+ export declare function checkpointOutputs(outputs: ReadonlyMap<string, unknown>, ids: readonly string[]): {
64
+ outputs: Record<string, unknown>;
65
+ } | {
66
+ unstorable: string;
67
+ };
68
+ /** A checkpoint file's text read back, or null when it isn't one. */
69
+ export declare function parseGateCheckpoint(text: string): GateCheckpoint | null;
70
+ /** Write a checkpoint to the local `chant/lifecycle` branch. Does not push: the pending fact appended after it does. */
71
+ export declare function writeGateCheckpoint(checkpoint: GateCheckpoint, opts?: {
72
+ cwd?: string;
73
+ }): Promise<void>;
74
+ /** The text of `runId`'s checkpoint for `op`, or null when there is none. */
75
+ export declare function readGateCheckpointText(op: string, runId: string, opts?: {
76
+ cwd?: string;
77
+ }): Promise<string | null>;
78
+ //# sourceMappingURL=gate-checkpoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-checkpoint.d.ts","sourceRoot":"","sources":["../../src/lifecycle/gate-checkpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,gCAAgC;AAChC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,CAAC;IACX,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,qGAAqG;AACrG,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AAIvD,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAE9D;AAED,oHAAoH;AACpH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,+HAA+H;AAC/H,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAE3F;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,CAErE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAe9J;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAkBvE;AAED,wHAAwH;AACxH,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5G;AAED,6EAA6E;AAC7E,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGvH"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * A gate's checkpoint (#3947): the step outputs a run held when it stopped at
3
+ * a gate that resumes, kept on `chant/lifecycle` at
4
+ * `_gates/<op>/checkpoints/<runId>.json`.
5
+ *
6
+ * The run writes the file just before it appends the pending fact, and puts
7
+ * the file's digest on that fact as `checkpointDigest`. `chant approve`
8
+ * copies the digest onto the approval, the way it copies the plan digest, and
9
+ * a seal covers it (`../workspace/trust/gate-seal.ts`). A later run that
10
+ * resumes at the gate reads the file back and checks it against the digest
11
+ * the approver saw, so a value pushed onto the branch after the approval is
12
+ * refused rather than carried into the steps after the gate.
13
+ *
14
+ * Only the outputs some step after the gate references are stored, worked
15
+ * out from the Op's references (`../op/gate-checkpoint.ts`). An output that
16
+ * an activity contract marks secret is never stored: the gate doesn't
17
+ * resume, and the next run starts at the first phase.
18
+ *
19
+ * Pure apart from the two git helpers at the bottom.
20
+ */
21
+ import { canonicalJson } from "../effect-receipt.js";
22
+ import { contentDigest } from "../content-digest.js";
23
+ import { sortedJsonReplacer } from "../utils.js";
24
+ import { readBlobFromPath, writeBlobToPath } from "./git.js";
25
+ /** The prefix a checkpoint digest is written with: the JCS form of the file, hashed with SHA-256. */
26
+ export const CHECKPOINT_DIGEST_PREFIX = "jcs1-sha256:";
27
+ const CHECKPOINT_DIGEST_PATTERN = /^jcs1-sha256:[0-9a-f]{64}$/;
28
+ /** Whether `raw` is a checkpoint digest this code wrote. */
29
+ export function isCheckpointDigest(raw) {
30
+ return typeof raw === "string" && CHECKPOINT_DIGEST_PATTERN.test(raw);
31
+ }
32
+ /** The digest of a checkpoint: SHA-256 over its RFC 8785 (JCS) form. Throws when an output can't be put in JSON. */
33
+ export function gateCheckpointDigest(checkpoint) {
34
+ return CHECKPOINT_DIGEST_PREFIX + contentDigest(canonicalJson(checkpoint)).slice("sha256:".length);
35
+ }
36
+ /**
37
+ * A run id is the checkpoint's file name, so it may hold only letters,
38
+ * digits, `.`, `_` and `-`, and may not start with a dot. A run named
39
+ * otherwise (a caller-chosen id with a slash in it) gets no checkpoint.
40
+ */
41
+ export function isCheckpointRunId(runId) {
42
+ return /^[A-Za-z0-9_-][A-Za-z0-9._-]*$/.test(runId) && runId.length <= 200;
43
+ }
44
+ /** Where the checkpoint of `runId` lives on `chant/lifecycle`: the directory and the file, as `writeBlobToPath` takes them. */
45
+ export function gateCheckpointPath(op, runId) {
46
+ return { dir: `_gates/${op}/checkpoints`, file: `${runId}.json` };
47
+ }
48
+ /** The file's text: the checkpoint as JSON, keys sorted, one value per line. */
49
+ export function gateCheckpointText(checkpoint) {
50
+ return `${JSON.stringify(checkpoint, sortedJsonReplacer, 2)}\n`;
51
+ }
52
+ /**
53
+ * Put `outputs` in the form a checkpoint stores: each value as JSON would
54
+ * carry it. Returns the step whose output JSON can't hold (a cycle, a bigint)
55
+ * instead, so the caller can say which one blocks the gate's resume.
56
+ */
57
+ export function checkpointOutputs(outputs, ids) {
58
+ const out = {};
59
+ for (const id of ids) {
60
+ if (!outputs.has(id))
61
+ continue;
62
+ const value = outputs.get(id);
63
+ try {
64
+ const text = JSON.stringify(value === undefined ? null : value);
65
+ const parsed = JSON.parse(text);
66
+ canonicalJson(parsed);
67
+ out[id] = parsed;
68
+ }
69
+ catch {
70
+ return { unstorable: id };
71
+ }
72
+ }
73
+ return { outputs: out };
74
+ }
75
+ /** A checkpoint file's text read back, or null when it isn't one. */
76
+ export function parseGateCheckpoint(text) {
77
+ let raw;
78
+ try {
79
+ raw = JSON.parse(text);
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ const r = raw;
85
+ if (r === null || typeof r !== "object" || r.version !== 1 || typeof r.op !== "string" || typeof r.gate !== "string" ||
86
+ typeof r.runId !== "string" || typeof r.commit !== "string" ||
87
+ r.outputs === null || typeof r.outputs !== "object" || Array.isArray(r.outputs) ||
88
+ (r.environment !== undefined && typeof r.environment !== "string") ||
89
+ (r.planDigest !== undefined && typeof r.planDigest !== "string")) {
90
+ return null;
91
+ }
92
+ return r;
93
+ }
94
+ /** Write a checkpoint to the local `chant/lifecycle` branch. Does not push: the pending fact appended after it does. */
95
+ export async function writeGateCheckpoint(checkpoint, opts) {
96
+ const { dir, file } = gateCheckpointPath(checkpoint.op, checkpoint.runId);
97
+ await writeBlobToPath(dir, file, gateCheckpointText(checkpoint), `Gate checkpoint for ${checkpoint.gate}`, opts);
98
+ }
99
+ /** The text of `runId`'s checkpoint for `op`, or null when there is none. */
100
+ export async function readGateCheckpointText(op, runId, opts) {
101
+ const { dir, file } = gateCheckpointPath(op, runId);
102
+ return readBlobFromPath(dir, file, opts);
103
+ }
@@ -75,6 +75,12 @@ export interface GateResolutionRecord {
75
75
  * such a record proves is that somebody approved *something*.
76
76
  */
77
77
  planDigest?: string;
78
+ /**
79
+ * The checkpoint this approval lets a run resume from (#3947), copied off
80
+ * the pending fact it answers. Set only on an approval of a gate that
81
+ * resumes (`resume: true`) whose run stored a checkpoint. A seal covers it.
82
+ */
83
+ checkpointDigest?: string;
78
84
  /**
79
85
  * The environment this approval is for (#2574), copied off the pending fact
80
86
  * it answers. Set for a component gate, whose ledger is keyed by component
@@ -145,12 +151,37 @@ export interface GateResolutionRecord {
145
151
  * `constrains` names the gate back (`gate:<op>/<gate>`).
146
152
  */
147
153
  answer?: GateAnswerRef;
154
+ /**
155
+ * The line this approval was carried from (#3949): an approval recorded
156
+ * under one of the gate's aliases, which a run counted toward the gate and
157
+ * wrote again under its new name. `op`, `gate` and `timestamp` name that
158
+ * line; `checkpointDigest` is the one it carried, if any, since a seal
159
+ * signs it. `resolvedBy`, the plan, the environment and the seal are the
160
+ * original's, and the seal verifies against the names in here. This
161
+ * record's own `timestamp` is when it was carried.
162
+ */
163
+ carriedFrom?: GateCarriedFrom;
164
+ }
165
+ /** Where a carried approval came from (#3949): the original line's op, gate and time, and its checkpoint digest when it had one. */
166
+ export interface GateCarriedFrom {
167
+ op: string;
168
+ gate: string;
169
+ timestamp: string;
170
+ checkpointDigest?: string;
148
171
  }
172
+ /** Whether `raw` is a {@link GateCarriedFrom}. */
173
+ export declare function isGateCarriedFrom(raw: unknown): raw is GateCarriedFrom;
149
174
  /** A gate approval's seal (#3163): who signed, the key's fingerprint (reported, never trusted), and the armored signature. */
150
175
  export interface GateApprovalSeal {
151
176
  signer: string;
152
177
  key: string;
153
178
  signature: string;
179
+ /**
180
+ * The seal's version (#3947). `2` on a seal over an approval that carries a
181
+ * `checkpointDigest`, whose payload signs the digest as one more line.
182
+ * Absent on every other seal, which is version 1.
183
+ */
184
+ version?: 2;
154
185
  }
155
186
  export type GateResolutionInput = Omit<GateResolutionRecord, "version" | "kind">;
156
187
  /**
@@ -214,6 +245,16 @@ export interface PendingGateRecord {
214
245
  * binds one since #2574.
215
246
  */
216
247
  planDigest?: string;
248
+ /**
249
+ * The digest of the checkpoint the run stored when it stopped here (#3947),
250
+ * on a gate that resumes (`resume: true`). The file is at
251
+ * `_gates/<op>/checkpoints/<runId>.json` (`./gate-checkpoint.ts`). `chant
252
+ * approve` copies it onto the approval, and a run resumes at this gate only
253
+ * from a checkpoint that matches it. Absent when the gate doesn't resume,
254
+ * or when its run could not store one, such as when an output it needs is
255
+ * secret.
256
+ */
257
+ checkpointDigest?: string;
217
258
  /**
218
259
  * The environment the run reached this gate in (#2574). Set by the
219
260
  * component driver, whose gate ledger is keyed by component, so pending