@intentius/chant 0.122.0 → 0.123.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 (156) hide show
  1. package/dist/cli/commands/lint.d.ts.map +1 -1
  2. package/dist/cli/handlers/gate-resume.d.ts +1 -1
  3. package/dist/cli/handlers/gate-resume.d.ts.map +1 -1
  4. package/dist/cli/handlers/operator.d.ts +1 -1
  5. package/dist/cli/handlers/operator.d.ts.map +1 -1
  6. package/dist/cli/handlers/override-approve.d.ts +17 -0
  7. package/dist/cli/handlers/override-approve.d.ts.map +1 -0
  8. package/dist/cli/handlers/run-wave.d.ts.map +1 -1
  9. package/dist/cli/main.d.ts.map +1 -1
  10. package/dist/cli/registry.d.ts +4 -0
  11. package/dist/cli/registry.d.ts.map +1 -1
  12. package/dist/gate-decision.d.ts +157 -0
  13. package/dist/gate-decision.d.ts.map +1 -0
  14. package/dist/lifecycle/gate-applied.d.ts +75 -0
  15. package/dist/lifecycle/gate-applied.d.ts.map +1 -0
  16. package/dist/lifecycle/gate-audit.d.ts +145 -0
  17. package/dist/lifecycle/gate-audit.d.ts.map +1 -0
  18. package/dist/lifecycle/gate-ledger-select.d.ts +54 -0
  19. package/dist/lifecycle/gate-ledger-select.d.ts.map +1 -0
  20. package/dist/lifecycle/gate-ledger.d.ts +1 -45
  21. package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
  22. package/dist/lifecycle/override-ledger.d.ts +34 -0
  23. package/dist/lifecycle/override-ledger.d.ts.map +1 -0
  24. package/dist/lifecycle/rollback.d.ts.map +1 -1
  25. package/dist/lifecycle/work-item-id.d.ts +22 -0
  26. package/dist/lifecycle/work-item-id.d.ts.map +1 -0
  27. package/dist/lifecycle/work-lease.d.ts +2 -2
  28. package/dist/lifecycle/work-lease.d.ts.map +1 -1
  29. package/dist/lint/post-synth.d.ts +20 -1
  30. package/dist/lint/post-synth.d.ts.map +1 -1
  31. package/dist/notify-verify.d.ts +62 -0
  32. package/dist/notify-verify.d.ts.map +1 -0
  33. package/dist/notify.d.ts +202 -0
  34. package/dist/notify.d.ts.map +1 -0
  35. package/dist/op/activities/activity-contracts.d.ts +4 -4
  36. package/dist/op/activities/gh-host.d.ts +37 -0
  37. package/dist/op/activities/gh-host.d.ts.map +1 -0
  38. package/dist/op/activities/lexicon-upgrade.d.ts +11 -0
  39. package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
  40. package/dist/op/activities/propose-upgrade.d.ts.map +1 -1
  41. package/dist/op/activities/reconcile.d.ts +74 -76
  42. package/dist/op/activities/reconcile.d.ts.map +1 -1
  43. package/dist/op/gate-approval.d.ts +17 -1
  44. package/dist/op/gate-approval.d.ts.map +1 -1
  45. package/dist/op/gate-name.d.ts +8 -1
  46. package/dist/op/gate-name.d.ts.map +1 -1
  47. package/dist/op/gate-resume.d.ts +4 -2
  48. package/dist/op/gate-resume.d.ts.map +1 -1
  49. package/dist/op/gate-review.d.ts +2 -1
  50. package/dist/op/gate-review.d.ts.map +1 -1
  51. package/dist/op/gate.d.ts +43 -6
  52. package/dist/op/gate.d.ts.map +1 -1
  53. package/dist/op/index.d.ts +8 -6
  54. package/dist/op/index.d.ts.map +1 -1
  55. package/dist/op/op-waves-notify.d.ts +31 -0
  56. package/dist/op/op-waves-notify.d.ts.map +1 -0
  57. package/dist/op/op-waves-run.d.ts +91 -16
  58. package/dist/op/op-waves-run.d.ts.map +1 -1
  59. package/dist/op/op-waves.d.ts +99 -2
  60. package/dist/op/op-waves.d.ts.map +1 -1
  61. package/dist/op/operator.d.ts +15 -0
  62. package/dist/op/operator.d.ts.map +1 -1
  63. package/dist/op/work-lease-decl.d.ts.map +1 -1
  64. package/dist/op/work-lease-run.d.ts.map +1 -1
  65. package/dist/override-gate.d.ts +224 -0
  66. package/dist/override-gate.d.ts.map +1 -0
  67. package/dist/pr-forge.d.ts +198 -19
  68. package/dist/pr-forge.d.ts.map +1 -1
  69. package/dist/workspace/status-gates.d.ts +1 -0
  70. package/dist/workspace/status-gates.d.ts.map +1 -1
  71. package/dist/workspace/trust/gate-seal.d.ts +96 -0
  72. package/dist/workspace/trust/gate-seal.d.ts.map +1 -0
  73. package/dist/workspace/trust/policy.d.ts +2 -41
  74. package/dist/workspace/trust/policy.d.ts.map +1 -1
  75. package/dist/workspace/trust/seal.d.ts +2 -27
  76. package/dist/workspace/trust/seal.d.ts.map +1 -1
  77. package/dist/workspace/trust/trust-files.d.ts +57 -0
  78. package/dist/workspace/trust/trust-files.d.ts.map +1 -0
  79. package/dist/workspace/work-cli.d.ts.map +1 -1
  80. package/package.json +2 -1
  81. package/src/cli/commands/build.ts +1 -1
  82. package/src/cli/commands/lint.ts +5 -2
  83. package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
  84. package/src/cli/handlers/gate-resume.ts +3 -2
  85. package/src/cli/handlers/operator.test.ts +12 -1
  86. package/src/cli/handlers/operator.ts +25 -13
  87. package/src/cli/handlers/override-approve.test.ts +87 -0
  88. package/src/cli/handlers/override-approve.ts +103 -0
  89. package/src/cli/handlers/run-wave.ts +10 -2
  90. package/src/cli/main.test.ts +8 -0
  91. package/src/cli/main.ts +15 -0
  92. package/src/cli/registry.ts +4 -0
  93. package/src/gate-decision-bundle.test.ts +56 -0
  94. package/src/gate-decision.test.ts +237 -0
  95. package/src/gate-decision.ts +321 -0
  96. package/src/lifecycle/gate-applied.ts +115 -0
  97. package/src/lifecycle/gate-audit-bundle.test.ts +47 -0
  98. package/src/lifecycle/gate-audit.test.ts +134 -0
  99. package/src/lifecycle/gate-audit.ts +438 -0
  100. package/src/lifecycle/gate-ledger-select.ts +113 -0
  101. package/src/lifecycle/gate-ledger.test.ts +22 -0
  102. package/src/lifecycle/gate-ledger.ts +9 -104
  103. package/src/lifecycle/override-ledger.test.ts +63 -0
  104. package/src/lifecycle/override-ledger.ts +69 -0
  105. package/src/lifecycle/rollback.ts +5 -1
  106. package/src/lifecycle/work-item-id.test.ts +71 -0
  107. package/src/lifecycle/work-item-id.ts +35 -0
  108. package/src/lifecycle/work-lease.ts +4 -5
  109. package/src/lint/post-synth.test.ts +29 -0
  110. package/src/lint/post-synth.ts +21 -2
  111. package/src/notify-bundle.test.ts +50 -0
  112. package/src/notify-verify.test.ts +59 -0
  113. package/src/notify-verify.ts +93 -0
  114. package/src/notify.schema.json +72 -0
  115. package/src/notify.test.ts +279 -0
  116. package/src/notify.ts +398 -0
  117. package/src/op/activities/gh-host.test.ts +130 -0
  118. package/src/op/activities/gh-host.ts +79 -0
  119. package/src/op/activities/lexicon-upgrade.ts +22 -1
  120. package/src/op/activities/propose-upgrade.ts +5 -1
  121. package/src/op/activities/reconcile.test.ts +284 -280
  122. package/src/op/activities/reconcile.ts +128 -131
  123. package/src/op/gate-approval.test.ts +175 -7
  124. package/src/op/gate-approval.ts +27 -1
  125. package/src/op/gate-name.ts +10 -2
  126. package/src/op/gate-resume.ts +6 -3
  127. package/src/op/gate-review.ts +4 -7
  128. package/src/op/gate.ts +117 -16
  129. package/src/op/index.ts +20 -5
  130. package/src/op/op-waves-notify.test.ts +127 -0
  131. package/src/op/op-waves-notify.ts +101 -0
  132. package/src/op/op-waves-run.ts +527 -104
  133. package/src/op/op-waves.test.ts +383 -3
  134. package/src/op/op-waves.ts +187 -6
  135. package/src/op/operator.test.ts +29 -0
  136. package/src/op/operator.ts +27 -2
  137. package/src/op/run-context.test.ts +2 -2
  138. package/src/op/work-lease-decl.ts +4 -4
  139. package/src/op/work-lease-run.test.ts +5 -0
  140. package/src/op/work-lease-run.ts +4 -3
  141. package/src/override-gate-bundle.test.ts +47 -0
  142. package/src/override-gate.test.ts +239 -0
  143. package/src/override-gate.ts +395 -0
  144. package/src/pr-forge-bundle.test.ts +40 -0
  145. package/src/pr-forge.test.ts +303 -0
  146. package/src/pr-forge.ts +502 -47
  147. package/src/workspace/records-write-contract.test.ts +3 -2
  148. package/src/workspace/status-gates.ts +7 -4
  149. package/src/workspace/trust/gate-seal.test.ts +156 -0
  150. package/src/workspace/trust/gate-seal.ts +254 -0
  151. package/src/workspace/trust/policy.ts +10 -165
  152. package/src/workspace/trust/seal.ts +19 -34
  153. package/src/workspace/trust/trust-files.test.ts +50 -0
  154. package/src/workspace/trust/trust-files.ts +245 -0
  155. package/src/workspace/work-cli.ts +5 -3
  156. package/src/workspace/work-history.test.ts +7 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-seal.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/gate-seal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD,kIAAkI;AAClI,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAG7D;AA8BD,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAmCD,iDAAiD;AACjD,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1F;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CA0CtI;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU9D;AAID;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,uGAAuG;IACvG,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yFAAyF;IACzF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAID,kJAAkJ;AAClJ,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAYrF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAmB1F"}
@@ -22,47 +22,8 @@
22
22
  */
23
23
  import { z } from "zod";
24
24
  import type { RecordSource } from "../record-source.js";
25
- /** The trust config, relative to the repository root. Fixed: it is how the signers path is overridden. */
26
- export declare const TRUST_CONFIG_PATH = ".chant/trust.json";
27
- /** Where the signers are when `trust.json` names no other path. */
28
- export declare const DEFAULT_SIGNERS_PATH = ".chant/allowed_signers";
29
- /** One usable signer: a principal and the public key it signs with. */
30
- export interface Signer {
31
- principal: string;
32
- /** `<type> <base64>`, with no comment. */
33
- key: string;
34
- /** The `namespaces="..."` option as written, or undefined when the key may sign any namespace. */
35
- namespaces?: string;
36
- /** 1-based line in the signers file. */
37
- line: number;
38
- }
39
- /** A line of the signers file that is not used, and why. */
40
- export interface ExcludedSigner {
41
- line: number;
42
- reason: string;
43
- }
44
- export interface SignerSet {
45
- signers: Signer[];
46
- excluded: ExcludedSigner[];
47
- }
48
- /**
49
- * Parse an allowed_signers file, keeping only lines whose meaning does not
50
- * depend on anything the signer controls.
51
- *
52
- * Refused, each with a reason, rather than passed to ssh-keygen:
53
- *
54
- * - `valid-after` and `valid-before`. git checks them against the commit's own
55
- * date, which whoever makes the commit sets. A backdated commit would pass a
56
- * window its key has left. Revocation is by position in history (#2553),
57
- * never by date.
58
- * - `cert-authority`. A certificate's validity is also a date, and a CA key
59
- * vouches for keys this file never names.
60
- * - Principal patterns (`*`, `?`, `!`). A signer is named by one exact
61
- * principal, so role grants can name it.
62
- */
63
- export declare function parseAllowedSigners(text: string): SignerSet;
64
- /** The signers as an allowed_signers file ssh-keygen reads, holding only the usable lines. */
65
- export declare function renderAllowedSigners(signers: Signer[]): string;
25
+ import { type ExcludedSigner, type Signer } from "./trust-files.js";
26
+ export { DEFAULT_SIGNERS_PATH, TRUST_CONFIG_PATH, parseAllowedSigners, renderAllowedSigners, type ExcludedSigner, type Signer, type SignerSet, } from "./trust-files.js";
66
27
  export declare const trustConfigSchema: z.ZodObject<{
67
28
  schema: z.ZodLiteral<1>;
68
29
  signers: z.ZodOptional<z.ZodString>;
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAgE,KAAK,cAAc,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAE/H,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,KAAK,SAAS,GACf,MAAM,eAAe,CAAC;AAcvB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;kBA4DnB,CAAC;AAEZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,+FAA+F;AAC/F,eAAO,MAAM,UAAU,UAAU,CAAC;AAElC,kEAAkE;AAClE,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,mDAAmD;AACnD,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAChC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,qEAAqE;IACrE,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,iDAAiD;IACjD,eAAe,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,iHAAiH;IACjH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,IAAI,CAAC;CAC/E;AAED,0HAA0H;AAC1H,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAG5D;AAED,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAI9D;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,GAAE,MAAM,EAAO,GAAG,WAAW,CAErF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CAiDtF;AAWD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,CAE3E;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKnF"}
@@ -23,15 +23,12 @@
23
23
  */
24
24
  import type { SealCode } from "../records.js";
25
25
  import { type TrustPolicy } from "./policy.js";
26
+ import { type SealedGateApproval } from "./gate-seal.js";
27
+ export { GATE_SEAL_NAMESPACE, gateSealPayload, type SealedGateApproval } from "./gate-seal.js";
26
28
  /** The ssh signature namespace of a verdict seal. */
27
29
  export declare const REVIEW_SEAL_NAMESPACE = "chant-review";
28
30
  /** The ssh signature namespace of a record's author seal (#2688). */
29
31
  export declare const RECORD_SEAL_NAMESPACE = "chant-record";
30
- /**
31
- * The ssh signature namespace of a gate approval's seal (#3163, ws-080), so a
32
- * verdict, record or commit signature can't stand in for one.
33
- */
34
- export declare const GATE_SEAL_NAMESPACE = "chant-gate";
35
32
  /** A seal as a review entry holds it. */
36
33
  export interface VerdictSeal {
37
34
  /** The principal who signed: the reviewer, as the signers file names them. */
@@ -68,28 +65,6 @@ export declare function reviewSealPayload(record: string, digest: string, verdic
68
65
  * states signs an empty last line.
69
66
  */
70
67
  export declare function recordSealPayload(record: string, digest: string, author: string, state: string | null): Buffer;
71
- /** The gate approval a seal covers (#3163): the fields of a gate resolution line that say what was approved, by whom and when. */
72
- export interface SealedGateApproval {
73
- op: string;
74
- gate: string;
75
- environment?: string;
76
- planDigest?: string;
77
- resolvedBy: string;
78
- /** Who relayed the approval for `resolvedBy` (#3402), when someone did. */
79
- relayedBy?: string;
80
- timestamp: string;
81
- seal?: unknown;
82
- }
83
- /**
84
- * The bytes a gate approval's seal signs (#3163): the op (or component), the
85
- * gate, the environment, the plan digest, the approver and the time, joined
86
- * by LF with no final newline. An approval that binds no environment or plan
87
- * signs an empty line for it. A relayed approval (#3402) signs a seventh line,
88
- * `relayed-by <principal>`, so the relay can't be added, changed or removed
89
- * after sealing; an approval nobody relayed signs the six lines it always did,
90
- * so seals made before #3402 still verify.
91
- */
92
- export declare function gateSealPayload(a: SealedGateApproval): Buffer;
93
68
  /** The record an author seal covers (#2688). */
94
69
  export interface SealedRecord {
95
70
  record: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"seal.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/seal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,qDAAqD;AACrD,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAEpD,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,iBAAiB,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,gHAAgH;IAChH,GAAG,EAAE,MAAM,CAAC;IACZ,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,yCAAyC;AACzC,MAAM,WAAW,SAAS;IACxB,kKAAkK;IAClK,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,0FAA0F;IAC1F,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,sCAAsC;AACtC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEvH;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE9G;AAED,kIAAkI;AAClI,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAG7D;AAED,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;CACf;AAoBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,GAAG,SAAS,CAYjF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,GAAG,SAAS,CAgB/E;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE,kBAAkB,GAAG,SAAS,CASnF;AAkED,oCAAoC;AACpC,qBAAa,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAuBzG;AAMD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAE9I;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,WAAW,CAEpI;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,kBAAkB,GAAG,WAAW,CAEpF"}
1
+ {"version":3,"file":"seal.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/seal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The trust files' plain readers (#3763): the signers file's parser, and a
3
+ * check of `.chant/trust.json` that says what `./policy.ts`'s zod schema
4
+ * says, so a bundle can read both without zod. `./policy.ts` re-exports the
5
+ * parser; `trust-files.test.ts` holds the check to the schema.
6
+ */
7
+ /** The trust config, relative to the repository root. Fixed: it is how the signers path is overridden. */
8
+ export declare const TRUST_CONFIG_PATH = ".chant/trust.json";
9
+ /** Where the signers are when `trust.json` names no other path. */
10
+ export declare const DEFAULT_SIGNERS_PATH = ".chant/allowed_signers";
11
+ /** One usable signer: a principal and the public key it signs with. */
12
+ export interface Signer {
13
+ principal: string;
14
+ /** `<type> <base64>`, with no comment. */
15
+ key: string;
16
+ /** The `namespaces="..."` option as written, or undefined when the key may sign any namespace. */
17
+ namespaces?: string;
18
+ /** 1-based line in the signers file. */
19
+ line: number;
20
+ }
21
+ /** A line of the signers file that is not used, and why. */
22
+ export interface ExcludedSigner {
23
+ line: number;
24
+ reason: string;
25
+ }
26
+ export interface SignerSet {
27
+ signers: Signer[];
28
+ excluded: ExcludedSigner[];
29
+ }
30
+ /**
31
+ * Parse an allowed_signers file, keeping only lines whose meaning does not
32
+ * depend on anything the signer controls.
33
+ *
34
+ * Refused, each with a reason, rather than passed to ssh-keygen:
35
+ *
36
+ * - `valid-after` and `valid-before`. git checks them against the commit's own
37
+ * date, which whoever makes the commit sets. A backdated commit would pass a
38
+ * window its key has left. Revocation is by position in history (#2553),
39
+ * never by date.
40
+ * - `cert-authority`. A certificate's validity is also a date, and a CA key
41
+ * vouches for keys this file never names.
42
+ * - Principal patterns (`*`, `?`, `!`). A signer is named by one exact
43
+ * principal, so role grants can name it.
44
+ */
45
+ export declare function parseAllowedSigners(text: string): SignerSet;
46
+ /** The signers as an allowed_signers file ssh-keygen reads, holding only the usable lines. */
47
+ export declare function renderAllowedSigners(signers: Signer[]): string;
48
+ /** A repository-relative path: no `..`, not absolute, `/` separators. */
49
+ export declare function isRepoPath(p: unknown): p is string;
50
+ /**
51
+ * What is wrong with a parsed `.chant/trust.json`, one line per field, or an
52
+ * empty list when it is valid. It accepts exactly what `trustConfigSchema`
53
+ * in `./policy.ts` accepts, so a reader without zod treats a file as chant
54
+ * does: an invalid one turns attestation off.
55
+ */
56
+ export declare function trustConfigProblems(raw: unknown): string[];
57
+ //# sourceMappingURL=trust-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-files.d.ts","sourceRoot":"","sources":["../../../src/workspace/trust/trust-files.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,0GAA0G;AAC1G,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,mEAAmE;AACnE,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAe7D,uEAAuE;AACvE,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,kGAAkG;IAClG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAmDD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAkD3D;AAED,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAM9D;AASD,yEAAyE;AACzE,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAElD;AAOD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CA8C1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"work-cli.d.ts","sourceRoot":"","sources":["../../src/workspace/work-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"work-cli.d.ts","sourceRoot":"","sources":["../../src/workspace/work-cli.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant",
3
- "version": "0.122.0",
3
+ "version": "0.123.0",
4
4
  "description": "Declarative infrastructure-as-code toolkit — TypeScript on Node.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -50,6 +50,7 @@
50
50
  "default": "./src/cli/index.ts"
51
51
  },
52
52
  "./workspace/*.schema.json": "./src/workspace/*.schema.json",
53
+ "./notify.schema.json": "./src/notify.schema.json",
53
54
  "./workspace/factory-rules": {
54
55
  "development": "./src/workspace/factory-rules.ts",
55
56
  "types": "./dist/workspace/factory-rules.d.ts",
@@ -585,7 +585,7 @@ export async function buildCommand(options: BuildOptions): Promise<BuildResult>
585
585
  }
586
586
 
587
587
  if (result.errors.length === 0 && options.plugins) {
588
- for (const { plugin, diagnostics: postDiags } of runLexiconPostSynthChecks(options.plugins, result, env, { activityContracts, telemetry })) {
588
+ for (const { plugin, diagnostics: postDiags } of runLexiconPostSynthChecks(options.plugins, result, env, { activityContracts, telemetry, projectDir: configDir, projectConfig: config as unknown as Record<string, unknown> })) {
589
589
  // `lint.presets` (chant #2113) filters WHICH check ids are reported at
590
590
  // all, before `lint.rules`/inline suppression act on the reported
591
591
  // ones. It's a no-op for a lexicon that ships no `lintPresets()` (the
@@ -705,10 +705,13 @@ async function runLexiconPostSynthDiagnostics(
705
705
  let result: Awaited<ReturnType<typeof build>>;
706
706
  let env: string | undefined;
707
707
  let telemetry: Awaited<ReturnType<typeof resolveTelemetryAttribution>>;
708
+ let configDir = infraPath;
709
+ let loadedConfig: Record<string, unknown> | undefined;
708
710
  try {
709
711
  const loaded = await loadChantConfigUpward(infraPath);
710
712
  const config = loaded.config;
711
- const configDir = loaded.configPath ? dirname(loaded.configPath) : infraPath;
713
+ loadedConfig = config as unknown as Record<string, unknown>;
714
+ configDir = loaded.configPath ? dirname(loaded.configPath) : infraPath;
712
715
  if (loaded.configPath) fallbackFile = loaded.configPath;
713
716
  // The caller's parameters when it resolved them (the CLI does, from the
714
717
  // same upward config walk); otherwise the declared defaults and `env`
@@ -766,7 +769,7 @@ async function runLexiconPostSynthDiagnostics(
766
769
  message: `${d.entity ? `[${d.entity}] ` : ""}${d.message}`,
767
770
  });
768
771
 
769
- for (const { plugin, diagnostics: raw } of runLexiconPostSynthChecks(withChecks, result, env, { activityContracts, telemetry })) {
772
+ for (const { plugin, diagnostics: raw } of runLexiconPostSynthChecks(withChecks, result, env, { activityContracts, telemetry, projectDir: configDir, ...(loadedConfig ? { projectConfig: loadedConfig } : {}) })) {
770
773
  const presetIds = resolvePresetIds(plugin.lintPresets?.(), lintConfig.presets?.[plugin.name] ?? "recommended");
771
774
  const afterPreset = applyConfiguredPreset(raw, presetIds, lintConfig.rules).diagnostics;
772
775
  const afterConfig = applyConfiguredSeverity(afterPreset, lintConfig.rules).diagnostics;
@@ -12,7 +12,7 @@ env:
12
12
  jobs:
13
13
  shared-alb:
14
14
  runs-on: ubuntu-latest
15
- container: node:22-slim
15
+ container: node:22
16
16
  steps:
17
17
  - uses: actions/checkout@v7
18
18
  - run: chant run --components shared-alb --env staging --dump-outputs shared-alb.outputs.json
@@ -25,7 +25,7 @@ jobs:
25
25
  runs-on: ubuntu-latest
26
26
  needs:
27
27
  - shared-alb
28
- container: node:22-slim
28
+ container: node:22
29
29
  steps:
30
30
  - uses: actions/checkout@v7
31
31
  - name: Download shared-alb outputs
@@ -60,6 +60,7 @@ export async function resumeStanding(
60
60
  standing: PendingGateRecord,
61
61
  resolutions: readonly GateResolutionRecord[],
62
62
  opts: ResumeGateOptions = {},
63
+ pending: readonly PendingGateRecord[] = [standing],
63
64
  ): Promise<GateResumeReport> {
64
65
  const base = {
65
66
  op: standing.op,
@@ -67,7 +68,7 @@ export async function resumeStanding(
67
68
  ...(standing.environment !== undefined ? { environment: standing.environment } : {}),
68
69
  ...(standing.resume?.url ? { url: standing.resume.url } : {}),
69
70
  };
70
- const answer = resolutionAnswering(resolutions, standing);
71
+ const answer = resolutionAnswering(resolutions, standing, pending);
71
72
  if (!answer) return { ...base, status: "not-approved", message: "no approval answers it yet" };
72
73
  const approvedBy = { approvedBy: answer.resolvedBy };
73
74
  if (!isGateRunLocator(standing.resume)) {
@@ -99,7 +100,7 @@ export async function resumeOpGates(op: string, gate: string | undefined, opts:
99
100
  const reports: GateResumeReport[] = [];
100
101
  for (const standing of standingFacts(ledger.pending, gate)) {
101
102
  if (isPendingGateExpired(standing, now)) continue;
102
- reports.push(await resumeStanding(standing, ledger.resolutions, opts));
103
+ reports.push(await resumeStanding(standing, ledger.resolutions, opts, ledger.pending));
103
104
  }
104
105
  return reports;
105
106
  }
@@ -77,6 +77,7 @@ vi.mock("../../op/gate-approval", async () => {
77
77
 
78
78
  // Imported after the mocks above are registered.
79
79
  const { runOperator, runOperatorStatus, runOperatorLog, runApprove } = await import("./operator");
80
+ const { gateContextDigest } = await import("../../op/gate-approval");
80
81
 
81
82
  function ctx(args: Partial<ParsedArgs>) {
82
83
  return {
@@ -386,6 +387,16 @@ describe("runApprove", () => {
386
387
  errSpy.mockRestore();
387
388
  });
388
389
 
390
+ // #3760: --rule and --reason belong to an override of a denied plan.
391
+ test("refuses --rule and --reason on a gate that is not the override gate", async () => {
392
+ seedPending("fountain-apply", "rollout-gate", PLAN_A);
393
+ const errSpy = vi.spyOn(console, "error").mockImplementation(() => undefined);
394
+ expect(await runApprove(ctx({ path: "fountain-apply", extraPositional: "rollout-gate", rules: ["no-drop"], reason: "why" }))).toBe(1);
395
+ expect(errSpy.mock.calls.flat().join("\n")).toMatch(/--rule and --reason override a denied plan: chant approve policy-override <subject>/);
396
+ expect(appendGateResolutionMock).not.toHaveBeenCalled();
397
+ errSpy.mockRestore();
398
+ });
399
+
389
400
  test("appends a gate-resolution record and pushes, resolving --actor over env fallbacks", async () => {
390
401
  seedPending("fountain-apply", "rollout-gate", PLAN_A);
391
402
  appendGateResolutionMock.mockResolvedValue({
@@ -1115,7 +1126,7 @@ describe("runApprove — a gate with an approval policy (#2508)", () => {
1115
1126
  expect(appendGateResolutionMock).toHaveBeenCalledWith(expect.objectContaining({
1116
1127
  approver: { kind: "agent" },
1117
1128
  policyDecision: {
1118
- policy: "ship", version: "sha256:v1", mode: "enforce",
1129
+ policy: "ship", version: "sha256:v1", mode: "enforce", contextDigest: gateContextDigest({ risk: "low" }),
1119
1130
  decision: "allow", determining: ["agent-low-risk"], errors: [],
1120
1131
  },
1121
1132
  }));
@@ -42,13 +42,13 @@ import {
42
42
  latestResolutionSince, latestPendingGate, isPendingGateExpired,
43
43
  resolveApprovalUrl, isApprovalUrl,
44
44
  } from "../../lifecycle/gate-ledger";
45
- import { isPlanDigest } from "../../lifecycle/plan-digest";
45
+ import { isPlanDigest, samePlanDigest } from "../../lifecycle/plan-digest";
46
46
  import {
47
- gatePolicyRequest, loadGatePolicyEvaluator,
47
+ gateContextDigest, gatePolicyRequest, loadGatePolicyEvaluator,
48
48
  type GateApprover, type GatePolicyDecision, type GatePolicyEvaluator, type ResolvedGateApproval,
49
49
  } from "../../op/gate-approval";
50
- import { approverOf, tallyGateApprovals } from "../../op/gate";
51
- import { FAN_OUT_GATE_OP, WORKSPACE_UPGRADE_GATE_OP } from "../../op/gate-name";
50
+ import { approverOf, humanQuorumSince, tallyGateApprovals } from "../../op/gate";
51
+ import { FAN_OUT_GATE_OP, OVERRIDE_GATE_OP, WORKSPACE_UPGRADE_GATE_OP } from "../../op/gate-name";
52
52
  import { PR_GATE_OP } from "../../pr-loop";
53
53
  import { pushLifecycleReport, requireLifecycleLedger } from "../../lifecycle/git";
54
54
  import { LIFECYCLE_LOCAL_NOTE, isLifecycleLocalNote } from "../../lifecycle/local-note";
@@ -888,6 +888,19 @@ export async function runApprove(ctx: CommandContext): Promise<number> {
888
888
  return 0;
889
889
  }
890
890
 
891
+ // #3760: an override of a denied plan names its rules and gives a reason.
892
+ if (opName === OVERRIDE_GATE_OP) {
893
+ const { runOverrideApprove } = await import("./override-approve");
894
+ return runOverrideApprove(ctx);
895
+ }
896
+ if (ctx.args.rules !== undefined || ctx.args.reason !== undefined) {
897
+ console.error(formatError({
898
+ message: `--rule and --reason override a denied plan: chant approve ${OVERRIDE_GATE_OP} <subject> --rule <id> --reason <text>`,
899
+ hint: `To approve gate "${gate}" on "${opName}", put any prose in --note.`,
900
+ }));
901
+ return 1;
902
+ }
903
+
891
904
  // `--approver` wins over `--actor`, the same precedence `chant run approve`
892
905
  // has applied since #2126 (`../handlers/run.ts`'s `runOpApprove`). Reading
893
906
  // only `--actor` here meant every README that teaches `--approver you`
@@ -1016,7 +1029,7 @@ export async function recordGateApproval(
1016
1029
  // `fan-out` is the op name every `chant components fan-out` gate is recorded
1017
1030
  // under (../handlers/fan-out.ts). It is a command rather than a declaration,
1018
1031
  // so there is no `*.op.ts` to find and nothing is wrong when none is there.
1019
- if (!ops.has(opName) && opName !== FAN_OUT_GATE_OP && opName !== WORKSPACE_UPGRADE_GATE_OP) {
1032
+ if (!ops.has(opName) && opName !== FAN_OUT_GATE_OP && opName !== WORKSPACE_UPGRADE_GATE_OP && opName !== OVERRIDE_GATE_OP) {
1020
1033
  console.error(formatWarning({
1021
1034
  message: `Op "${opName}" was not found among discovered *.op.ts declarations — recording the resolution anyway`,
1022
1035
  }));
@@ -1260,6 +1273,7 @@ export async function recordGateApproval(
1260
1273
  policy: approval.policy.name,
1261
1274
  version: approval.policy.version,
1262
1275
  mode: approval.mode,
1276
+ contextDigest: gateContextDigest(approval.context),
1263
1277
  decision: answer.decision,
1264
1278
  determining: answer.determining,
1265
1279
  errors: answer.errors,
@@ -1310,7 +1324,7 @@ export async function recordGateApproval(
1310
1324
  ));
1311
1325
  }
1312
1326
  if (approval) {
1313
- for (const line of describeApprovalProgress(approval, record, ledger.resolutions, standingForOrigin)) {
1327
+ for (const line of describeApprovalProgress(approval, record, ledger.resolutions, standingForOrigin, ledger.pending)) {
1314
1328
  console.error(formatInfo(line));
1315
1329
  }
1316
1330
  }
@@ -1328,6 +1342,7 @@ export function describeApprovalProgress(
1328
1342
  record: GateResolutionRecord,
1329
1343
  prior: GateResolutionRecord[],
1330
1344
  standing: PendingGateRecord | undefined,
1345
+ pending: readonly PendingGateRecord[] = standing ? [standing] : [],
1331
1346
  ): string[] {
1332
1347
  const lines: string[] = [];
1333
1348
  const decision = record.policyDecision;
@@ -1343,13 +1358,10 @@ export function describeApprovalProgress(
1343
1358
  for (const error of decision.errors) lines.push(`Policy evaluation error: ${error}`);
1344
1359
  }
1345
1360
 
1346
- const tally = tallyGateApprovals(
1347
- [...prior, record],
1348
- record.gate,
1349
- standing?.timestamp ?? new Date(0).toISOString(),
1350
- record.planDigest,
1351
- approval,
1352
- );
1361
+ const since = standing?.timestamp ?? new Date(0).toISOString();
1362
+ // #3206: count the humans the way the run will, back past facts re-recorded for this plan.
1363
+ const humansSince = standing && samePlanDigest(standing.planDigest, record.planDigest) ? humanQuorumSince(pending, standing) : since;
1364
+ const tally = tallyGateApprovals([...prior, record], record.gate, since, record.planDigest, approval, humansSince);
1353
1365
  const roles = approval.quorum?.roles ? ` with role ${approval.quorum.roles.join(" or ")}` : "";
1354
1366
  const who = tally.counted.map((r) => r.resolvedBy).join(", ") || "none yet";
1355
1367
  lines.push(`Quorum: ${tally.counted.length} of ${tally.need} human approval(s)${roles} for this plan (${who}).`);
@@ -0,0 +1,87 @@
1
+ /**
2
+ * #3760: `chant approve policy-override <subject> --rule <id> --reason <text>`
3
+ * records an override of the subject's recorded denial, for exactly that
4
+ * plan and those rules.
5
+ */
6
+ import { beforeEach, describe, expect, test, vi } from "vitest";
7
+ import type { ParsedArgs } from "../registry";
8
+ import { overrideDigest, overridePending, OVERRIDE_OP } from "../../override-gate";
9
+
10
+ const recordGateApprovalMock = vi.fn();
11
+ const readOverrideLedgerMock = vi.fn();
12
+ const requireLifecycleLedgerMock = vi.fn();
13
+ const originMock = vi.fn(() => "cli");
14
+
15
+ vi.mock("./operator", () => ({ recordGateApproval: (...a: unknown[]) => recordGateApprovalMock(...a) }));
16
+ vi.mock("../../lifecycle/override-ledger", () => ({ readOverrideLedger: (...a: unknown[]) => readOverrideLedgerMock(...a) }));
17
+ vi.mock("../../lifecycle/git", () => ({ requireLifecycleLedger: (...a: unknown[]) => requireLifecycleLedgerMock(...a) }));
18
+ vi.mock("../../lifecycle/gate-origin", async () => {
19
+ const actual = await vi.importActual<typeof import("../../lifecycle/gate-origin")>("../../lifecycle/gate-origin");
20
+ return { ...actual, currentGateOrigin: () => originMock() };
21
+ });
22
+
23
+ const { runOverrideApprove } = await import("./override-approve");
24
+
25
+ const PLAN = `sha256:${"a".repeat(64)}`;
26
+ const DENIAL = overridePending({ subject: "prod", planDigest: PLAN, rules: ["no-drop", "no-lock"], timestamp: "2026-10-11T10:00:00.000Z", expiresAt: "2099-01-01T00:00:00.000Z" });
27
+
28
+ function ctx(args: Partial<ParsedArgs>) {
29
+ return {
30
+ args: { command: "approve", path: OVERRIDE_OP, extraPositional: "prod", format: "", fix: false, watch: false, verbose: false, help: false, live: false, ...args } as ParsedArgs,
31
+ plugins: [],
32
+ serializers: [],
33
+ };
34
+ }
35
+
36
+ let err: ReturnType<typeof vi.spyOn>;
37
+ const printed = () => err.mock.calls.flat().join("\n");
38
+
39
+ beforeEach(() => {
40
+ vi.clearAllMocks();
41
+ err = vi.spyOn(console, "error").mockImplementation(() => undefined);
42
+ originMock.mockReturnValue("cli");
43
+ requireLifecycleLedgerMock.mockResolvedValue(undefined);
44
+ readOverrideLedgerMock.mockResolvedValue({ resolutions: [], pending: [DENIAL], applied: [] });
45
+ recordGateApprovalMock.mockResolvedValue({ ok: true, pushed: true, record: { version: 1, op: OVERRIDE_OP, gate: "prod", resolvedBy: "github:alice", timestamp: "2026-10-11T11:00:00.000Z" } });
46
+ });
47
+
48
+ describe("chant approve policy-override", () => {
49
+ test("approves the denial's override digest with the reason as its note", async () => {
50
+ const code = await runOverrideApprove(ctx({ rules: ["no-lock", "no-drop"], reason: " the table is empty ", actor: "github:alice", sign: true }));
51
+ expect(code).toBe(0);
52
+ expect(recordGateApprovalMock).toHaveBeenCalledWith(OVERRIDE_OP, "prod", expect.objectContaining({
53
+ actor: "github:alice", note: "the table is empty", plan: overrideDigest("prod", PLAN, ["no-drop", "no-lock"]), sign: true,
54
+ }));
55
+ expect(printed()).toMatch(/overrides the denial of prod by no-drop, no-lock for the plan sha256:a{64}/);
56
+ });
57
+
58
+ test("--note is the same field as --reason", async () => {
59
+ expect(await runOverrideApprove(ctx({ rules: ["no-drop", "no-lock"], note: "empty table" }))).toBe(0);
60
+ expect(recordGateApprovalMock).toHaveBeenCalledWith(OVERRIDE_OP, "prod", expect.objectContaining({ note: "empty table" }));
61
+ expect(await runOverrideApprove(ctx({ rules: ["no-drop", "no-lock"], note: "a", reason: "b" }))).toBe(1);
62
+ });
63
+
64
+ test.each<[string, Partial<ParsedArgs>, RegExp]>([
65
+ ["no rule", { reason: "why" }, /names each rule it overrides with --rule/],
66
+ ["no reason", { rules: ["no-drop", "no-lock"], reason: " " }, /needs --reason/],
67
+ ["other rules", { rules: ["no-drop"], reason: "why" }, /denied by no-drop, no-lock; an override names exactly those rules, and --rule gave no-drop/],
68
+ ["another plan", { rules: ["no-drop", "no-lock"], reason: "why", plan: `sha256:${"b".repeat(64)}` }, /is not the plan denied for prod/],
69
+ ["an agent", { rules: ["no-drop", "no-lock"], reason: "why", agent: true }, /An override is a person.s/],
70
+ ["no denial", { rules: ["x"], reason: "why", extraPositional: "staging" }, /No denial of staging is recorded on policy-override; denied: prod/],
71
+ ])("refuses %s, and records nothing", async (_name, args, why) => {
72
+ expect(await runOverrideApprove(ctx(args))).toBe(1);
73
+ expect(printed()).toMatch(why);
74
+ expect(recordGateApprovalMock).not.toHaveBeenCalled();
75
+ });
76
+
77
+ test("is refused over MCP", async () => {
78
+ originMock.mockReturnValue("mcp");
79
+ expect(await runOverrideApprove(ctx({ rules: ["no-drop", "no-lock"], reason: "why" }))).toBe(1);
80
+ expect(recordGateApprovalMock).not.toHaveBeenCalled();
81
+ });
82
+
83
+ test("--plan may name the denied plan or the override digest", async () => {
84
+ expect(await runOverrideApprove(ctx({ rules: ["no-drop", "no-lock"], reason: "why", plan: PLAN }))).toBe(0);
85
+ expect(await runOverrideApprove(ctx({ rules: ["no-drop", "no-lock"], reason: "why", plan: DENIAL.planDigest }))).toBe(0);
86
+ });
87
+ });
@@ -0,0 +1,103 @@
1
+ /**
2
+ * `chant approve policy-override <subject> --rule <id>... --reason <text>`
3
+ * (#3760): record a person's override of the denial a run recorded for
4
+ * `subject`. The override is an approval of the denial's override digest
5
+ * (`../../override-gate.ts`), with the reason as its note, written by the
6
+ * same `recordGateApproval` every `chant approve` uses, so `--sign`,
7
+ * `--actor`, `--relayed-by` and `--url` work as they do there.
8
+ *
9
+ * It names the rules it overrides, which must be exactly the rules the denial
10
+ * recorded: the approver says what they are letting through. Whether the
11
+ * override counts is decided by the run, against the overriders and signers
12
+ * at base; this command only warns when the checkout's own overriders file
13
+ * would not count it.
14
+ */
15
+
16
+ import { currentGateOrigin, isModelAuthored } from "../../lifecycle/gate-origin";
17
+ import { requireLifecycleLedger } from "../../lifecycle/git";
18
+ import { readOverrideLedger } from "../../lifecycle/override-ledger";
19
+ import { samePlanDigest } from "../../lifecycle/plan-digest";
20
+ import { OVERRIDE_OP, OVERRIDERS_PATH, overrideCommand, overridersAt, recordedDenials, sortedRules } from "../../override-gate";
21
+ import { formatError, formatInfo, formatWarning } from "../format";
22
+ import type { CommandContext } from "../registry";
23
+ import { recordGateApproval } from "./operator";
24
+
25
+ const norm = (s: string): string => s.normalize("NFKC").trim().toLowerCase();
26
+
27
+ export async function runOverrideApprove(ctx: CommandContext): Promise<number> {
28
+ const subject = ctx.args.extraPositional!;
29
+ const usage = overrideCommand(subject, ctx.args.rules?.length ? ctx.args.rules : ["<id>"]);
30
+ if (ctx.args.reason !== undefined && ctx.args.note !== undefined && ctx.args.reason.trim() !== ctx.args.note.trim()) {
31
+ console.error(formatError({ message: "Give the override's reason once: --reason <text> (--note is the same field)", hint: usage }));
32
+ return 1;
33
+ }
34
+ const reason = (ctx.args.reason ?? ctx.args.note)?.trim();
35
+ const rules = sortedRules(ctx.args.rules ?? []);
36
+ if (rules.length === 0) {
37
+ console.error(formatError({ message: `An override names each rule it overrides with --rule <id>`, hint: usage }));
38
+ return 1;
39
+ }
40
+ if (!reason) {
41
+ console.error(formatError({ message: `An override needs --reason <text>: why this plan goes out although the policy denies it`, hint: usage }));
42
+ return 1;
43
+ }
44
+ if (ctx.args.agent || isModelAuthored(currentGateOrigin())) {
45
+ console.error(formatError({ message: `An override is a person's: it is never recorded by an agent or over MCP or ACP`, hint: `${usage}, at a shell.` }));
46
+ return 1;
47
+ }
48
+
49
+ try {
50
+ await requireLifecycleLedger();
51
+ } catch (err) {
52
+ console.error(formatError({ message: `Cannot record the override: ${err instanceof Error ? err.message : String(err)}` }));
53
+ return 1;
54
+ }
55
+ const ledger = await readOverrideLedger();
56
+ const denials = recordedDenials(ledger.pending);
57
+ const denial = denials.find((d) => d.gate === subject);
58
+ if (!denial) {
59
+ console.error(formatError({
60
+ message: `No denial of ${subject} is recorded on ${OVERRIDE_OP}` + (denials.length ? `; denied: ${denials.map((d) => d.gate).join(", ")}` : ""),
61
+ hint: "A run records one when its policy denies the plan. An override answers that denial, for that plan.",
62
+ }));
63
+ return 1;
64
+ }
65
+ if (denial.rules.join("\n") !== rules.join("\n")) {
66
+ console.error(formatError({
67
+ message: `${subject} was denied by ${denial.rules.join(", ") || "no rule it named"}; an override names exactly those rules, and --rule gave ${rules.join(", ")}`,
68
+ hint: overrideCommand(subject, denial.rules),
69
+ }));
70
+ return 1;
71
+ }
72
+ if (ctx.args.plan !== undefined && !samePlanDigest(ctx.args.plan, denial.plan) && !samePlanDigest(ctx.args.plan, denial.planDigest)) {
73
+ console.error(formatError({
74
+ message: `--plan ${ctx.args.plan} is not the plan denied for ${subject}: the newest denial is of ${denial.plan || denial.planDigest}`,
75
+ hint: "Run the plan again, or override the denial that stands.",
76
+ }));
77
+ return 1;
78
+ }
79
+
80
+ const outcome = await recordGateApproval(OVERRIDE_OP, subject, {
81
+ actor: ctx.args.approver ?? ctx.args.actor,
82
+ note: reason,
83
+ url: ctx.args.url,
84
+ plan: denial.planDigest!,
85
+ allowSameOrigin: ctx.args.allowSameOrigin,
86
+ ...(ctx.args.roles ? { roles: ctx.args.roles } : {}),
87
+ ...(ctx.args.sign !== undefined ? { sign: ctx.args.sign } : {}),
88
+ ...(ctx.args.relayedBy !== undefined ? { relayedBy: ctx.args.relayedBy } : {}),
89
+ });
90
+ if (!outcome.ok) return 1;
91
+
92
+ console.error(formatInfo(
93
+ `This overrides the denial of ${subject} by ${rules.join(", ")} for the plan ${denial.plan || denial.planDigest}. ` +
94
+ `The next run that plans it applies it once; a plan that moves, or rules that change, need their own override.`,
95
+ ));
96
+ const here = overridersAt(process.cwd(), "HEAD");
97
+ if (!here.active) {
98
+ console.error(formatWarning({ message: `This checkout has no ${OVERRIDERS_PATH}: unless the run reads its overriders from elsewhere at base, no override counts` }));
99
+ } else if (!here.principals.map(norm).includes(norm(outcome.record.resolvedBy))) {
100
+ console.error(formatWarning({ message: `${outcome.record.resolvedBy} is not in ${OVERRIDERS_PATH} here (${here.principals.join(", ") || "nobody"}), so a run that reads it at base does not count this override` }));
101
+ }
102
+ return 0;
103
+ }