@intentius/chant 0.124.12 → 0.124.13

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.
@@ -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;AAsCzE;;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,CAmBhC;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;AAkdD;;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;AAuCzE;;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,CAmBhC;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;AA4eD;;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"}
@@ -16,6 +16,12 @@
16
16
  * approving review, when its head planned this digest
17
17
  * ({@link reviewApproval}).
18
18
  *
19
+ * A gate the declaration at base names under `identity.gates` counts only a
20
+ * sealed approval from its class: {@link identityGateAdmissionAt} reads that
21
+ * rule from a bare clone at base and judges by `admitApprover`, the function
22
+ * chant's `gateAdmission` judges by (#3862); pass its `refuses` to
23
+ * {@link decideGateApproval}.
24
+ *
19
25
  * With `spend` (#3784), an approval a wave already applied under is spent and
20
26
  * counts for nothing, as terragucci's wave gate has it: the caller hands in
21
27
  * the lines of `_gates/<op>/applied.jsonl` ({@link parseAppliedGateLines}).
@@ -28,7 +34,8 @@
28
34
  * `gate-decision.test.ts` decides the same ledgers both ways.
29
35
  */
30
36
  import { type AppliedGateRecord } from "./lifecycle/gate-applied.js";
31
- import { type GateSigners } from "./workspace/trust/gate-seal.js";
37
+ import { type GateSigners, type SealedGateApproval } from "./workspace/trust/gate-seal.js";
38
+ import { type ClassGrant } from "./workspace/identity-gate-rule.js";
32
39
  import type { GateResolutionRecord, PendingGateRecord } from "./lifecycle/gate-ledger.js";
33
40
  import type { MergedReview } from "./op/gate-review.js";
34
41
  import type { GateApprovalSource } from "./op/op-waves.js";
@@ -37,6 +44,7 @@ export { isPendingGateExpired, latestPendingGate, latestResolutionForPlan, lates
37
44
  export { GATE_SEAL_NAMESPACE, gateSealPayload, gateSealRefusal, sshKeyFingerprint, verifySshSignatureWith, type GateSigners, type SealedGateApproval, type SshSignatureCheck, } from "./workspace/trust/gate-seal.js";
38
45
  export { DEFAULT_SIGNERS_PATH, TRUST_CONFIG_PATH, parseAllowedSigners, trustConfigProblems, type Signer, type SignerSet, } from "./workspace/trust/trust-files.js";
39
46
  export type { GateResolutionRecord, PendingGateRecord } from "./lifecycle/gate-ledger.js";
47
+ export { CORE_CLASSES, admitApprover, grantedClasses, type ClassGrant, type GateAdmissionRule, type PrincipalClass, } from "./workspace/identity-gate-rule.js";
40
48
  export { appliedGateApplies, appliedGatePath, isApprovalSpent, parseAppliedGateLines, type AppliedGateRecord, } from "./lifecycle/gate-applied.js";
41
49
  export type { MergedReview } from "./op/gate-review.js";
42
50
  /**
@@ -63,11 +71,35 @@ export interface IdentityGate {
63
71
  /**
64
72
  * The gates `chant.workspace.json` (or `.jsonc`) at `base` names under
65
73
  * `identity.gates`: each counts only a sealed approval, from its class when
66
- * it names one. chant checks the class against the role grants at base; this
67
- * reads the names. Empty when there is no declaration at base. Throws when
68
- * the declaration there cannot be parsed, since the gate cannot be decided.
74
+ * it names one. {@link identityGateAdmissionAt} judges an approval by one.
75
+ * Empty when there is no declaration at base. Throws when the declaration
76
+ * there cannot be parsed, since the gate cannot be decided.
69
77
  */
70
78
  export declare function identityGatesAt(repo: string, base: string): IdentityGate[];
79
+ /** An `identity.gates` gate at base, and the judge for its approvals. */
80
+ export interface IdentityGateAdmission {
81
+ requirement: IdentityGate;
82
+ /** Why `approval` does not count toward the gate, or null when it does. Pass it to {@link decideGateApproval} as `refuses`. */
83
+ refuses(approval: SealedGateApproval): string | null;
84
+ }
85
+ /**
86
+ * The `identity.gates` rule for `gate` at `base`, or null when the
87
+ * declaration there names none: what chant's `gateAdmission(cwd, gate, base)`
88
+ * answers, read from a bare clone. An approval counts when its seal verifies
89
+ * for its approver against the signers at base and, when the gate names a
90
+ * class, the role grants in `.chant/trust.json` at base put the approver in
91
+ * it. Both judge with the same function ({@link admitApprover}).
92
+ *
93
+ * The classes are the four core ones, then `classes`, the domain classes the
94
+ * caller read from the pinned packages (`./workspace-principals`), in pin
95
+ * order. This reader loads no package. A gate whose class is in neither
96
+ * refuses every approval, and when the declaration at base pins anything the
97
+ * reason says the pins were not read, since one of them may supply it.
98
+ * Throws when the declaration at base cannot be parsed.
99
+ */
100
+ export declare function identityGateAdmissionAt(repo: string, base: string, gate: string, opts?: {
101
+ classes?: readonly ClassGrant[];
102
+ }): IdentityGateAdmission | null;
71
103
  /** What a pull request's review says about a wave, under `pr-review`. */
72
104
  export interface ReviewApproval {
73
105
  approved: boolean;
@@ -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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"}
@@ -1,5 +1,6 @@
1
1
  import { type GateOrigin } from "./gate-origin.js";
2
2
  import type { GateApprover, GatePolicyDecision, ResolvedGateApproval } from "../op/gate-approval.js";
3
+ import type { GateApprovalSource } from "../op/op-waves.js";
3
4
  import type { GateRunLocator } from "../op/gate-run-locator.js";
4
5
  export { DEFAULT_GATE_EXPIRY, isApprovalUrl, resolveApprovalUrl } from "./gate-pending.js";
5
6
  export { isPendingGateExpired, latestPendingGate, latestResolutionForPlan, latestResolutionSince, type PlanBoundResolution, } from "./gate-ledger-select.js";
@@ -226,6 +227,13 @@ export interface PendingGateRecord {
226
227
  * the run produced, and `chant operator status` to show quorum progress.
227
228
  */
228
229
  approval?: ResolvedGateApproval;
230
+ /**
231
+ * The approval mode an Op wave asked under (#3861): `ledger`, `pr-review` or
232
+ * `sealed`, as read at base. It says which approvals count for the gate, so a
233
+ * reader (behold, gate-audit) decides under the mode the wave used rather
234
+ * than inferring it from config. Not the quorum block in `approval`.
235
+ */
236
+ approvalMode?: GateApprovalSource;
229
237
  /**
230
238
  * The open question this gate waits on, on a gate that asks a decision
231
239
  * point (#3170). It is answered with `chant workspace points answer <id>`,
@@ -1 +1 @@
1
- {"version":3,"file":"gate-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/gate-ledger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gate-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/gate-ledger.ts"],"names":[],"mappings":"AA6CA,OAAO,EAAqB,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI7D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGxF,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,sBAAsB,CAAC;AAI9B,sHAAsH;AACtH,eAAO,MAAM,SAAS,WAAM,CAAC;AAI7B;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;CAChC;AAED,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC,wFAAwF;IACxF,OAAO,EAAE,CAAC,CAAC;IACX,8KAA8K;IAC9K,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,0HAA0H;IAC1H,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,SAAS,EAAE,MAAM,CAAC;IAClB,oLAAoL;IACpL,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB;;;OAGG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB;;;;;OAKG;IACH,MAAM,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC3D;;;;;OAKG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,8HAA8H;AAC9H,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,oBAAoB,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC;AAEjF;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAiB;IAChC,wFAAwF;IACxF,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,8IAA8I;IAC9I,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8FAA8F;IAC9F,SAAS,EAAE,MAAM,CAAC;IAClB,4IAA4I;IAC5I,SAAS,EAAE,MAAM,CAAC;IAClB,+FAA+F;IAC/F,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC;AAE3E,kDAAkD;AAClD,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,GAAG,iBAAiB,CAAC;AAOxE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,SAAK,GAAG,MAAM,CAEpE;AAED,+mBAA+mB;AAC/mB,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,mBAAmB,EAC1B,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC,CAI3D;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,gBAAgB,EACvB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAiBxD;AA2BD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;IAAC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAInG;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,GACd;IAAE,WAAW,EAAE,oBAAoB,EAAE,CAAC;IAAC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAmD1F;AAED,oNAAoN;AACpN,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAGjE"}
@@ -101,7 +101,7 @@ export interface OpWavePlansFile {
101
101
  waves?: number;
102
102
  }
103
103
  /** Pending-fact keys chant writes itself, which a plans file's `pending` may not set (#3821). */
104
- export declare const OP_WAVE_PENDING_RESERVED: readonly ["version", "kind", "op", "gate", "timestamp", "expiresAt", "planDigest", "runId", "url", "resume", "environment", "origin", "neverOverMcp", "approval", "answer"];
104
+ export declare const OP_WAVE_PENDING_RESERVED: readonly ["version", "kind", "op", "gate", "timestamp", "expiresAt", "planDigest", "runId", "url", "resume", "environment", "origin", "neverOverMcp", "approval", "approvalMode", "answer"];
105
105
  /** What chant writes to `{runs}` for a wave-level command or a hook (#3762). */
106
106
  export interface OpWaveRunsFile {
107
107
  /** The wave's name. */
@@ -1 +1 @@
1
- {"version":3,"file":"op-waves-run.d.ts","sourceRoot":"","sources":["../../src/op/op-waves-run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"op-waves-run.d.ts","sourceRoot":"","sources":["../../src/op/op-waves-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The `identity.gates` rule as data and one pure function (#3862).
3
+ *
4
+ * A gate the declaration names under `identity.gates` passes only on an
5
+ * approval sealed by a signer at base, from the class the gate names when it
6
+ * names one (#3163, ws-080). chant's `gateAdmissionFrom` (`./identity.ts`)
7
+ * builds a {@link GateAdmissionRule} from what `scopeSource` reads and judges
8
+ * every approval with {@link admitApprover}. `@intentius/chant/gate-decision`
9
+ * builds the same rule from a bare clone at a base commit
10
+ * (`identityGateAdmissionAt`) and judges with the same function, so a tool
11
+ * counts approvals as chant's wave gate does.
12
+ *
13
+ * The module imports node:crypto through `./trust/gate-seal.ts` and nothing
14
+ * else: no zod, no ajv, no package loading, so it bundles small.
15
+ */
16
+ import { type SealedGateApproval } from "./trust/gate-seal.js";
17
+ import type { Signer } from "./trust/trust-files.js";
18
+ /** The core classes, in the order a principal's roles are tried; `human` holds no role and is the rest. */
19
+ export declare const CORE_PRINCIPAL_CLASSES: readonly ["human", "agent", "runner", "service"];
20
+ export type CorePrincipalClass = (typeof CORE_PRINCIPAL_CLASSES)[number];
21
+ export interface PrincipalClass {
22
+ name: string;
23
+ /** One line saying who is in the class. */
24
+ description: string;
25
+ /** The role whose grant at base puts a principal in the class, or null for `human`, the rest. */
26
+ role: string | null;
27
+ /** `core`, or the pin (package name or path) that supplies the class. */
28
+ source: string;
29
+ }
30
+ export declare const CORE_CLASSES: readonly PrincipalClass[];
31
+ /** A class as the rule reads it: its name, and the role whose grant puts a principal in it (null for `human`). */
32
+ export type ClassGrant = Pick<PrincipalClass, "name" | "role">;
33
+ /** What an `identity.gates` gate is judged by, all read at base. */
34
+ export interface GateAdmissionRule {
35
+ gate: string;
36
+ /** The class the approver must be in, or null for any signer. */
37
+ class: string | null;
38
+ /** The signers file at base: its path, whether it exists, and its signers. */
39
+ signers: {
40
+ signersPath: string;
41
+ active: boolean;
42
+ signers: readonly Signer[];
43
+ };
44
+ /** The role grants at base (`.chant/trust.json` `roles`). */
45
+ roles: Readonly<Record<string, readonly string[]>>;
46
+ /** Every class the rule knows, core first, then domain classes in pin order. */
47
+ classes: readonly ClassGrant[];
48
+ /**
49
+ * Why a class the rule does not know is unknown, for the refusal. Default
50
+ * "no pinned package supplies", which is what chant says once it has read
51
+ * every pin.
52
+ */
53
+ unknownClass?: string;
54
+ }
55
+ /** Every class `principal`'s role grants put it in, in `classes` order: what `classesOf` in `./principal-classes.ts` answers. */
56
+ export declare function grantedClasses(classes: readonly ClassGrant[], roles: Readonly<Record<string, readonly string[]>>, principal: string | null): string[];
57
+ /**
58
+ * Why `a` does not count toward the gate, or null when it does. An approval
59
+ * counts only when its seal verifies for its approver against the signers at
60
+ * base and, when the rule names a class, the role grants at base put the
61
+ * approver in it (`human`: in no other class). A class the rule does not
62
+ * know lets nothing through.
63
+ */
64
+ export declare function admitApprover(rule: GateAdmissionRule, a: SealedGateApproval): string | null;
65
+ //# sourceMappingURL=identity-gate-rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-gate-rule.d.ts","sourceRoot":"","sources":["../../src/workspace/identity-gate-rule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAkF,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5I,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,2GAA2G;AAC3G,eAAO,MAAM,sBAAsB,YAAI,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAC;AACvF,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,iGAAiG;IACjG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,YAAY,EAAE,SAAS,cAAc,EAKjD,CAAC;AAEF,kHAAkH;AAClH,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAE/D,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,8EAA8E;IAC9E,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IAC9E,6DAA6D;IAC7D,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;IACnD,gFAAgF;IAChF,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,iIAAiI;AACjI,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAIrJ;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAa3F"}
@@ -27,7 +27,7 @@
27
27
  import type { Declaration, SignedGate } from "./declaration.js";
28
28
  import { type ClassRegistry } from "./principal-classes.js";
29
29
  import type { TrustPolicy } from "./trust/policy.js";
30
- import { type SealedGateApproval } from "./trust/seal.js";
30
+ import type { SealedGateApproval } from "./trust/gate-seal.js";
31
31
  /** The forges a forge identity can name. */
32
32
  export declare const FORGES: readonly ["github", "gitlab", "forgejo", "gitea"];
33
33
  export type Forge = (typeof FORGES)[number];
@@ -98,7 +98,9 @@ export interface GateRuleSource extends IdentitySource {
98
98
  * approval counts only when its seal verifies for its approver against the
99
99
  * signers at base and, when the rule names a class, the approver's role
100
100
  * grants at base put it in that class. A class no pinned package supplies
101
- * lets nothing through.
101
+ * lets nothing through. The judge is {@link admitApprover}, which
102
+ * `@intentius/chant/gate-decision` also judges with (#3862). The policy is
103
+ * the one at base, never a returned work's copy.
102
104
  */
103
105
  export declare function gateAdmissionFrom(source: GateRuleSource, gate: string): GateAdmission | null;
104
106
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/workspace/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAgD,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGvG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGtE,4CAA4C;AAC5C,eAAO,MAAM,MAAM,YAAI,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAU,CAAC;AACxE,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAK5C,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf;AAKD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAO1E;AAED,8HAA8H;AAC9H,wBAAgB,cAAc,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAExD;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,+EAA+E;IAC/E,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;CAC7B;AAID;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAE,WAAW,GAAG,IAAW,GAAG,UAAU,CAQnH;AAED,uDAAuD;AACvD,eAAO,MAAM,cAAc,qCAAsE,CAAC;AAClG,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAA4B;IACvD,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,8GAA8G;AAC9G,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAAG,IAAI,CAS7I;AAED,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAElD,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,UAAU,CAAC;IACxB,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAAC;CACpD;AAED,sHAAsH;AACtH,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAmB5F;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAE5F"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/workspace/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE7D,OAAO,EAA4C,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGnG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,4CAA4C;AAC5C,eAAO,MAAM,MAAM,YAAI,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAU,CAAC;AACxE,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAK5C,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;CACf;AAKD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAO1E;AAED,8HAA8H;AAC9H,wBAAgB,cAAc,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAExD;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,+EAA+E;IAC/E,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;CAC7B;AAID;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAE,WAAW,GAAG,IAAW,GAAG,UAAU,CAQnH;AAED,uDAAuD;AACvD,eAAO,MAAM,cAAc,qCAAsE,CAAC;AAClG,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAA4B;IACvD,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,8GAA8G;AAC9G,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAAG,IAAI,CAS7I;AAED,+EAA+E;AAC/E,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAElD,yFAAyF;AACzF,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,UAAU,CAAC;IACxB,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAAC;CACpD;AAED,sHAAsH;AACtH,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAM5F;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAE5F"}
@@ -24,26 +24,15 @@
24
24
  import { type KindLoadProblem, type PinLike } from "./kinds.js";
25
25
  import type { TrustPolicy } from "./trust/policy.js";
26
26
  import { type WorkspaceTree } from "./tree.js";
27
+ import { type PrincipalClass } from "./identity-gate-rule.js";
27
28
  export declare const PRINCIPALS_SCHEMA_ID: string;
28
29
  /** The subpath a package publishes its principal classes at. */
29
30
  export declare const PRINCIPALS_SUBPATH = "./workspace-principals";
30
- /** The core classes, in the order a principal's roles are tried; `human` holds no role and is the rest. */
31
- export declare const CORE_PRINCIPAL_CLASSES: readonly ["human", "agent", "runner", "service"];
32
- export type CorePrincipalClass = (typeof CORE_PRINCIPAL_CLASSES)[number];
31
+ export { CORE_CLASSES, CORE_PRINCIPAL_CLASSES, type CorePrincipalClass, type PrincipalClass } from "./identity-gate-rule.js";
33
32
  /** A class name: a core class, or a domain class a pinned package supplies. */
34
33
  export type PrincipalClassName = string;
35
34
  /** The grammar of a class name, as `workspace-principals.schema.json` and the declaration's writeScope keys say it. */
36
35
  export declare const CLASS_NAME: RegExp;
37
- export interface PrincipalClass {
38
- name: string;
39
- /** One line saying who is in the class. */
40
- description: string;
41
- /** The role whose grant at base puts a principal in the class, or null for `human`, the rest. */
42
- role: string | null;
43
- /** `core`, or the pin (package name or path) that supplies the class. */
44
- source: string;
45
- }
46
- export declare const CORE_CLASSES: readonly PrincipalClass[];
47
36
  export interface ClassRegistry {
48
37
  get(name: string): PrincipalClass | undefined;
49
38
  /** Every class name, core first, for "unknown class" messages. */
@@ -63,7 +52,7 @@ export declare function roleGrants(policy: TrustPolicy): Record<string, string[]
63
52
  /**
64
53
  * Every class `principal`'s role grants at base put it in, in registry order
65
54
  * (core first). Empty for a principal in no class but `human`, and for null.
66
- * Names compare as {@link normalisePrincipal} folds them.
55
+ * Names compare as `normalisePrincipal` (`./records.ts`) folds them.
67
56
  */
68
57
  export declare function classesOf(classes: ClassRegistry, policy: TrustPolicy, principal: string | null): string[];
69
58
  /** The class write scope judges `principal` as: the first class its grants put it in, or `human`. */
@@ -1 +1 @@
1
- {"version":3,"file":"principal-classes.d.ts","sourceRoot":"","sources":["../../src/workspace/principal-classes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"principal-classes.d.ts","sourceRoot":"","sources":["../../src/workspace/principal-classes.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.124.12",
3
+ "version": "0.124.13",
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",
@@ -32,6 +32,7 @@ import { applyConfiguredPreset, applyConfiguredSeverity, resolvePresetIds } from
32
32
  import { applyInlineSuppressions } from "../../lint/suppressions";
33
33
  import { getProvenance } from "../../provenance";
34
34
  import { runLexiconPostSynthChecks } from "./build";
35
+ import { armSandboxPolicyExecution, runProjectPolicies } from "../../lint/policy-sandbox";
35
36
 
36
37
  // Import config loader
37
38
  import { loadConfig, resolveRulesForFile, resolveConfiguredSeverity, findProjectRoot } from "../../lint/config";
@@ -665,9 +666,15 @@ async function runOpCheckDiagnostics(
665
666
  * builds `infraPath`, the target the caller asked to lint, never the project
666
667
  * root above it, so `chant lint <dir>` costs a build of `<dir>` and nothing
667
668
  * more (the same scoping {@link runOpCheckDiagnostics} documents). It is
668
- * skipped outright when no loaded lexicon ships post-synth checks, which keeps
669
- * a project with no lexicon, and every core-only fixture, from building at
670
- * all.
669
+ * skipped outright when no loaded lexicon ships post-synth checks and the
670
+ * project declares no `lint.policies`, which keeps a project with no lexicon,
671
+ * and every core-only fixture, from building at all.
672
+ *
673
+ * The project's `lint.policies` run over the same build after the lexicons'
674
+ * checks (#3870), with every lexicon's output and the env, as `chant build`
675
+ * runs them, and sandboxed when the build is. `lint.rules` applies to their
676
+ * ids; a policy that does not load is reported under
677
+ * {@link BUILD_FAILURE_RULE_ID}.
671
678
  *
672
679
  * A target that does not build reports each build error under
673
680
  * {@link BUILD_FAILURE_RULE_ID} and skips the checks. Findings go through
@@ -686,10 +693,10 @@ async function runLexiconPostSynthDiagnostics(
686
693
  const diagnostics: LintDiagnostic[] = [];
687
694
  const suppressed: Array<LintDiagnostic & { reason?: string }> = [];
688
695
  const withChecks = plugins.filter((plugin) => (plugin.postSynthChecks?.() ?? []).length > 0);
689
- if (withChecks.length === 0) return { diagnostics, suppressed };
690
-
691
696
  const projectRoot = findProjectRoot(infraPath);
692
697
  const lintConfig = loadConfig(projectRoot);
698
+ if (withChecks.length === 0 && (lintConfig.policies ?? []).length === 0) return { diagnostics, suppressed };
699
+
693
700
  // Where a finding that names no declared entity is reported: the config the
694
701
  // build loads once it is known (past a lint-only fragment), else the nearest.
695
702
  let fallbackFile = findProjectConfig(projectRoot).configPath ?? projectRoot;
@@ -707,6 +714,7 @@ async function runLexiconPostSynthDiagnostics(
707
714
  let telemetry: Awaited<ReturnType<typeof resolveTelemetryAttribution>>;
708
715
  let configDir = infraPath;
709
716
  let loadedConfig: Record<string, unknown> | undefined;
717
+ let policies: readonly string[] = [];
710
718
  try {
711
719
  const loaded = await loadChantConfigUpward(infraPath);
712
720
  const config = loaded.config;
@@ -720,6 +728,10 @@ async function runLexiconPostSynthDiagnostics(
720
728
  // fragment with no `buildParams` (a `src/chant.config.json`).
721
729
  const params = buildParams ?? resolveBuildParams(config.buildParams, { env: process.env }).provenance;
722
730
  env = resolveOwnershipEnv(config, params);
731
+ policies = config.lint?.policies ?? [];
732
+ // #3870: a sandboxed build sandboxes the policies too, as `chant build` arms it.
733
+ const modes = resolveBuildModes(config, { sandbox });
734
+ if (modes.sandbox && policies.length > 0) armSandboxPolicyExecution();
723
735
  telemetry = await resolveTelemetryAttribution(configDir, config as unknown as Record<string, unknown>, env);
724
736
  // Every lexicon the lint loaded, as `chant build` serializes with every
725
737
  // lexicon it loaded: a check may read another lexicon's entities, and the
@@ -732,7 +744,7 @@ async function runLexiconPostSynthDiagnostics(
732
744
  config,
733
745
  configDir,
734
746
  plugins,
735
- modes: resolveBuildModes(config, { sandbox }),
747
+ modes,
736
748
  ownership: resolveOwnershipMarker(config, params),
737
749
  buildParams: params,
738
750
  telemetry,
@@ -781,6 +793,21 @@ async function runLexiconPostSynthDiagnostics(
781
793
  }
782
794
  }
783
795
 
796
+ // #3870: the project's `lint.policies`, over the same build, as `chant
797
+ // build` runs them: every lexicon's output at once, with the env, and
798
+ // `lint.rules` applied to their ids.
799
+ if (policies.length > 0) {
800
+ let raw: Awaited<ReturnType<typeof runProjectPolicies>>;
801
+ try {
802
+ raw = await runProjectPolicies({ policies, configDir, buildResult: result, env });
803
+ } catch (err) {
804
+ diagnostics.push(buildFailure(err instanceof Error ? err.message : String(err)));
805
+ return { diagnostics, suppressed };
806
+ }
807
+ const configured = applyConfiguredSeverity(raw, lintConfig.rules);
808
+ for (const d of configured.diagnostics) diagnostics.push(toLint(d));
809
+ }
810
+
784
811
  return { diagnostics, suppressed };
785
812
  }
786
813
 
@@ -5,8 +5,8 @@
5
5
  * toolchain, and checked sealed approvals with its own copy of chant's seal
6
6
  * rule because `@intentius/chant/op/gate` pulls in zod and the git ledger
7
7
  * code. `@intentius/chant/gate-decision` holds the decision for a plan digest
8
- * under `ledger`, `pr-review` and `sealed`, and the seal check over
9
- * node:crypto. This bundles it the way terragucci would and reads esbuild's
8
+ * under `ledger`, `pr-review` and `sealed`, the seal check over
9
+ * node:crypto, and the `identity.gates` rule with its class check (#3862). This bundles it the way terragucci would and reads esbuild's
10
10
  * own list of what went in.
11
11
  */
12
12
 
@@ -46,6 +46,7 @@ describe("the gate-decision bundle", () => {
46
46
  "packages/core/src/notify.ts",
47
47
  "packages/core/src/op/gate-point.ts",
48
48
  "packages/core/src/op/op-waves.ts",
49
+ "packages/core/src/workspace/identity-gate-rule.ts",
49
50
  "packages/core/src/workspace/jsonc.ts",
50
51
  "packages/core/src/workspace/trust/gate-seal.ts",
51
52
  "packages/core/src/workspace/trust/trust-files.ts",
@@ -0,0 +1,176 @@
1
+ /**
2
+ * #3862: `identityGateAdmissionAt` judges an `identity.gates` approval from a
3
+ * bare clone at a base commit as chant's `gateAdmission(cwd, gate, base)`
4
+ * does: the seal against the signers at base, and the class against the role
5
+ * grants at base. Each fixture is judged both ways and the answers compared,
6
+ * reasons included.
7
+ */
8
+
9
+ import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
10
+ import {
11
+ admitApprover,
12
+ CORE_CLASSES,
13
+ decideGateApproval,
14
+ GATE_SEAL_NAMESPACE,
15
+ gateSealPayload,
16
+ identityGateAdmissionAt,
17
+ type GateResolutionRecord,
18
+ } from "./gate-decision";
19
+ import { gateAdmission } from "./workspace/identity";
20
+ import { hasSshKeygen, TestRepo, type Key } from "./workspace/trust/test-repo";
21
+ import { evaluateGate, memoryGateLedgerPort } from "./op/gate";
22
+
23
+ const D1 = "sha256:" + "a".repeat(64);
24
+ const GATES = { ship: {}, deploy: { class: "human" }, release: { class: "runner" }, ops: { class: "operator" } };
25
+ const NAMES = [...Object.keys(GATES), "undeclared"];
26
+
27
+ describe.skipIf(!hasSshKeygen)("identity.gates read at base, as chant reads it", () => {
28
+ const repos: TestRepo[] = [];
29
+ afterEach(() => {
30
+ while (repos.length) repos.pop()!.cleanup();
31
+ });
32
+ // Keys and seals are made once, by ssh-keygen, and shared by every fixture.
33
+ let signer: TestRepo;
34
+ let k: Record<"alice" | "bob" | "carol" | "mallory", Key>;
35
+ const sigs = new Map<string, string>();
36
+ beforeAll(() => {
37
+ signer = new TestRepo("3862-keys");
38
+ k = { alice: signer.key("alice"), bob: signer.key("bob"), carol: signer.key("carol"), mallory: signer.key("mallory") };
39
+ });
40
+ afterAll(() => signer.cleanup());
41
+ const sign = (key: Key, payload: Buffer): string => {
42
+ const id = `${key.name}\n${payload.toString("utf-8")}`;
43
+ if (!sigs.has(id)) sigs.set(id, signer.sshSign(key, payload, GATE_SEAL_NAMESPACE));
44
+ return sigs.get(id)!;
45
+ };
46
+
47
+ function setup(files: (k: Record<string, Key>) => Record<string, string>, declaration: Record<string, unknown> = {}) {
48
+ const r = new TestRepo("3862-identity");
49
+ repos.push(r);
50
+ r.write("chant.workspace.json", JSON.stringify({ name: "acme", schema: 1, members: [], identity: { gates: GATES }, ...declaration }));
51
+ for (const [path, text] of Object.entries(files(k))) r.write(path, text);
52
+ const base = r.commit("base");
53
+ // The change being applied lists mallory and makes alice a runner; neither counts at base.
54
+ r.write(".chant/allowed_signers", `alice ${k.alice.pub}\nbob ${k.bob.pub}\nmallory ${k.mallory.pub}\n`);
55
+ r.write(".chant/trust.json", JSON.stringify({ schema: 1, roles: { runner: ["alice", "bob"] } }));
56
+ r.commit("widens the policy");
57
+ const approval = (gate: string, resolvedBy: string, extra: Partial<GateResolutionRecord> = {}): GateResolutionRecord => ({
58
+ version: 1, op: "web", gate, resolvedBy, timestamp: "2026-10-11T11:00:00.000Z", planDigest: D1, ...extra,
59
+ });
60
+ const seal = (a: GateResolutionRecord, key: Key, signer = a.resolvedBy): GateResolutionRecord => ({
61
+ ...a,
62
+ seal: { signer, key: "k", signature: sign(key, gateSealPayload(a)) },
63
+ });
64
+ const made = new Map<string, GateResolutionRecord[]>();
65
+ const approvals = (gate: string): GateResolutionRecord[] => made.get(gate) ?? (made.set(gate, approvalsOf(gate)), made.get(gate)!);
66
+ const approvalsOf = (gate: string): GateResolutionRecord[] => [
67
+ approval(gate, "alice"),
68
+ seal(approval(gate, "alice"), k.alice),
69
+ seal(approval(gate, "BOB "), k.bob, "bob"),
70
+ seal(approval(gate, "mallory"), k.mallory),
71
+ seal(approval(gate, "carol"), k.carol),
72
+ seal(approval(gate, "alice"), k.bob),
73
+ seal(approval(gate, "alice"), k.alice, "bob"),
74
+ { ...approval(gate, "alice"), seal: { signer: "alice" } as unknown as GateResolutionRecord["seal"] },
75
+ { ...seal(approval(gate, "alice"), k.alice), planDigest: "sha256:" + "b".repeat(64) },
76
+ ];
77
+ return { r, base, approvals };
78
+ }
79
+
80
+ /** Every approval of every gate, judged by both readers: the pairs, and the reasons gate-decision gave. */
81
+ function judgeBoth(r: TestRepo, base: string, approvals: (gate: string) => GateResolutionRecord[]) {
82
+ const ours: Record<string, (string | null)[] | null> = {};
83
+ for (const gate of NAMES) {
84
+ const here = identityGateAdmissionAt(r.dir, base, gate);
85
+ const chant = gateAdmission(r.dir, gate, base);
86
+ expect(here === null, gate).toBe(chant === null);
87
+ if (here === null || chant === null) {
88
+ ours[gate] = null;
89
+ continue;
90
+ }
91
+ expect(here.requirement).toEqual({ gate, class: chant.requirement.class });
92
+ const reasons = approvals(gate).map((a) => here.refuses(a));
93
+ expect(reasons, gate).toEqual(approvals(gate).map((a) => chant.refuses(a)));
94
+ ours[gate] = reasons;
95
+ }
96
+ return ours;
97
+ }
98
+
99
+ test("signers, role grants and classes at base, approval by approval", () => {
100
+ const { r, base, approvals } = setup((k) => ({
101
+ ".chant/allowed_signers": `alice ${k.alice.pub}\nbob ${k.bob.pub}\ncarol namespaces="git" ${k.carol.pub}\n`,
102
+ ".chant/trust.json": JSON.stringify({ schema: 1, roles: { runner: ["Bob"] } }),
103
+ }));
104
+ const ours = judgeBoth(r, base, approvals);
105
+ expect(ours.undeclared).toBeNull();
106
+ const passed = (gate: string) => ours[gate]!.flatMap((reason, i) => (reason === null ? [i] : []));
107
+ // Any signer: alice and bob, each with their own key. Not mallory (listed after base), not carol (no chant-gate namespace).
108
+ expect(passed("ship")).toEqual([1, 2]);
109
+ // human: alice; bob holds the runner role at base.
110
+ expect(passed("deploy")).toEqual([1]);
111
+ expect(ours.deploy![2]).toMatch(/^BOB is not in the class human that gate deploy needs/);
112
+ // runner: bob, by the grant at base; alice's grant comes after base.
113
+ expect(passed("release")).toEqual([2]);
114
+ expect(ours.release![1]).toBe("alice is not in the class runner that gate release needs: no role grant at base puts them there");
115
+ // operator: no pinned package supplies it.
116
+ expect(passed("ops")).toEqual([]);
117
+ expect(ours.ops![1]).toMatch(/names the class operator, which no pinned package supplies, .*known classes: human, agent, runner, service/);
118
+ expect(ours.ship![0]).toBe("the approval by alice is not signed; gate ship needs chant approve --sign");
119
+ expect(ours.ship![3]).toBe("mallory has no key in .chant/allowed_signers at base, so the seal can't count");
120
+ expect(ours.ship![4]).toMatch(/^the seal does not verify for carol against \.chant\/allowed_signers at base/);
121
+ });
122
+
123
+ test("a signers path trust.json names", () => {
124
+ const named = setup((k) => ({
125
+ ".chant/trust.json": JSON.stringify({ schema: 1, signers: "ops/signers", roles: { runner: ["alice"] } }),
126
+ "ops/signers": `alice ${k.alice.pub}\n`,
127
+ }));
128
+ expect(judgeBoth(named.r, named.base, named.approvals).release![1]).toBeNull();
129
+ });
130
+
131
+ test("no signers file at base, and a trust.json chant refuses", () => {
132
+ const none = setup(() => ({ "README.md": "x\n" }));
133
+ expect(judgeBoth(none.r, none.base, none.approvals).ship![1]).toBe("gate ship needs a signed approval, and there is no signers file (.chant/allowed_signers) at base to check one against");
134
+
135
+ const invalid = setup((k) => ({
136
+ ".chant/trust.json": JSON.stringify({ schema: 1, roles: { Admin: ["alice"] } }),
137
+ ".chant/allowed_signers": `alice ${k.alice.pub}\n`,
138
+ }));
139
+ expect(judgeBoth(invalid.r, invalid.base, invalid.approvals).ship![1]).toMatch(/no signers file/);
140
+ });
141
+
142
+ test("a domain class the caller read from a pin, and a pin this reader does not load", () => {
143
+ const { r, base, approvals } = setup(
144
+ (k) => ({ ".chant/allowed_signers": `alice ${k.alice.pub}\n`, ".chant/trust.json": JSON.stringify({ schema: 1, roles: { operator: ["alice"] } }) }),
145
+ { pins: [{ package: "@acme/ops-classes", version: "1.0.0" }] },
146
+ );
147
+ const unread = identityGateAdmissionAt(r.dir, base, "ops")!;
148
+ expect(unread.refuses(approvals("ops")[1])).toMatch(/is not a core class, and this reader does not load the classes the pinned packages in chant\.workspace\.json at base supply/);
149
+ const read = identityGateAdmissionAt(r.dir, base, "ops", { classes: [{ name: "operator", role: "operator" }] })!;
150
+ expect(read.refuses(approvals("ops")[1])).toBeNull();
151
+ expect(read.refuses(approvals("ops")[0])).toMatch(/not signed/);
152
+ });
153
+
154
+ test("passed to decideGateApproval as refuses, it counts what chant's wave gate counts", async () => {
155
+ const { r, base, approvals } = setup((k) => ({
156
+ ".chant/allowed_signers": `alice ${k.alice.pub}\nbob ${k.bob.pub}\n`,
157
+ ".chant/trust.json": JSON.stringify({ schema: 1, roles: { runner: ["bob"] } }),
158
+ }));
159
+ const here = identityGateAdmissionAt(r.dir, base, "release")!;
160
+ const chant = gateAdmission(r.dir, "release", base)!;
161
+ for (const resolutions of [approvals("release").slice(0, 2), approvals("release")]) {
162
+ const decided = decideGateApproval({ ledger: { pending: [], resolutions }, gate: "release", planDigest: D1, refuses: here.refuses, now: "2026-10-11T12:00:00.000Z" });
163
+ const port = { ...memoryGateLedgerPort({ pending: [], resolutions }), approvalRule: async () => chant };
164
+ const check = await evaluateGate(port, { op: "web", gate: "release", planDigest: D1, now: "2026-10-11T12:00:00.000Z" });
165
+ expect(decided.status === "approved" && decided.via === "ledger" ? decided.resolution : null).toEqual(check.satisfied ? check.resolution : null);
166
+ }
167
+ });
168
+ });
169
+
170
+ describe("admitApprover", () => {
171
+ test("is the rule gateAdmission judges by: a class it does not know refuses before the seal is read", () => {
172
+ const rule = { gate: "ship", class: "operator", signers: { signersPath: ".chant/allowed_signers", active: false, signers: [] }, roles: {}, classes: CORE_CLASSES };
173
+ expect(admitApprover(rule, { op: "web", gate: "ship", resolvedBy: "alice", timestamp: "t" })).toMatch(/no pinned package supplies/);
174
+ expect(admitApprover({ ...rule, class: null }, { op: "web", gate: "ship", resolvedBy: "alice", timestamp: "t" })).toMatch(/no signers file/);
175
+ });
176
+ });
@@ -16,6 +16,12 @@
16
16
  * approving review, when its head planned this digest
17
17
  * ({@link reviewApproval}).
18
18
  *
19
+ * A gate the declaration at base names under `identity.gates` counts only a
20
+ * sealed approval from its class: {@link identityGateAdmissionAt} reads that
21
+ * rule from a bare clone at base and judges by `admitApprover`, the function
22
+ * chant's `gateAdmission` judges by (#3862); pass its `refuses` to
23
+ * {@link decideGateApproval}.
24
+ *
19
25
  * With `spend` (#3784), an approval a wave already applied under is spent and
20
26
  * counts for nothing, as terragucci's wave gate has it: the caller hands in
21
27
  * the lines of `_gates/<op>/applied.jsonl` ({@link parseAppliedGateLines}).
@@ -36,7 +42,7 @@ import {
36
42
  } from "./lifecycle/gate-ledger-select";
37
43
  import { samePlanDigest } from "./lifecycle/plan-digest";
38
44
  import { isApprovalSpent, type AppliedGateRecord } from "./lifecycle/gate-applied";
39
- import { gateSealRefusal, type GateSigners } from "./workspace/trust/gate-seal";
45
+ import { gateSealRefusal, type GateSigners, type SealedGateApproval } from "./workspace/trust/gate-seal";
40
46
  import {
41
47
  DEFAULT_SIGNERS_PATH,
42
48
  TRUST_CONFIG_PATH,
@@ -44,6 +50,7 @@ import {
44
50
  trustConfigProblems,
45
51
  } from "./workspace/trust/trust-files";
46
52
  import { parseJsonText } from "./workspace/jsonc";
53
+ import { CORE_CLASSES, admitApprover, type ClassGrant, type GateAdmissionRule } from "./workspace/identity-gate-rule";
47
54
  import type { GateResolutionRecord, PendingGateRecord } from "./lifecycle/gate-ledger";
48
55
  import type { MergedReview } from "./op/gate-review";
49
56
  import type { GateApprovalSource } from "./op/op-waves";
@@ -75,6 +82,14 @@ export {
75
82
  type SignerSet,
76
83
  } from "./workspace/trust/trust-files";
77
84
  export type { GateResolutionRecord, PendingGateRecord } from "./lifecycle/gate-ledger";
85
+ export {
86
+ CORE_CLASSES,
87
+ admitApprover,
88
+ grantedClasses,
89
+ type ClassGrant,
90
+ type GateAdmissionRule,
91
+ type PrincipalClass,
92
+ } from "./workspace/identity-gate-rule";
78
93
  export {
79
94
  appliedGateApplies,
80
95
  appliedGatePath,
@@ -117,17 +132,12 @@ export function baseCommit(repo: string): string {
117
132
  return parent;
118
133
  }
119
134
 
120
- /**
121
- * The signers at `base`: the file `.chant/trust.json` names there, else
122
- * `.chant/allowed_signers`, read as chant's trust policy reads it. A
123
- * trust.json that is not valid (`trustConfigProblems`) turns attestation
124
- * off, as it does in chant, so a sealed gate passes nothing. `base` is a
125
- * commit the repository holds, such as {@link baseCommit}'s answer.
126
- */
127
- export function gateSignersAt(repo: string, base: string): GateSigners {
128
- const off = (problems: string[]): GateSigners => ({ base, signersPath: DEFAULT_SIGNERS_PATH, active: false, signers: [], problems });
135
+ /** The signers and role grants at `base`, as chant's trust policy reads them. */
136
+ function trustAt(repo: string, base: string): { signers: GateSigners; roles: Record<string, string[]> } {
137
+ const off = (problems: string[]) => ({ signers: { base, signersPath: DEFAULT_SIGNERS_PATH, active: false, signers: [], problems }, roles: {} });
129
138
  const configText = showAt(repo, base, TRUST_CONFIG_PATH);
130
139
  let signersPath = DEFAULT_SIGNERS_PATH;
140
+ let roles: Record<string, string[]> = {};
131
141
  if (configText !== undefined) {
132
142
  let raw: unknown;
133
143
  try {
@@ -138,9 +148,21 @@ export function gateSignersAt(repo: string, base: string): GateSigners {
138
148
  const problems = trustConfigProblems(raw);
139
149
  if (problems.length > 0) return off([`${TRUST_CONFIG_PATH} is invalid: ${problems.join("; ")}`]);
140
150
  signersPath = (raw as { signers?: string }).signers ?? DEFAULT_SIGNERS_PATH;
151
+ roles = (raw as { roles?: Record<string, string[]> }).roles ?? {};
141
152
  }
142
153
  const text = showAt(repo, base, signersPath);
143
- return { base, signersPath, active: text !== undefined, signers: text === undefined ? [] : parseAllowedSigners(text).signers, problems: [] };
154
+ return { signers: { base, signersPath, active: text !== undefined, signers: text === undefined ? [] : parseAllowedSigners(text).signers, problems: [] }, roles };
155
+ }
156
+
157
+ /**
158
+ * The signers at `base`: the file `.chant/trust.json` names there, else
159
+ * `.chant/allowed_signers`, read as chant's trust policy reads it. A
160
+ * trust.json that is not valid (`trustConfigProblems`) turns attestation
161
+ * off, as it does in chant, so a sealed gate passes nothing. `base` is a
162
+ * commit the repository holds, such as {@link baseCommit}'s answer.
163
+ */
164
+ export function gateSignersAt(repo: string, base: string): GateSigners {
165
+ return trustAt(repo, base).signers;
144
166
  }
145
167
 
146
168
  /** A gate the declaration at base names under `identity.gates`, and the principal class its signer must be in, if any. */
@@ -149,23 +171,79 @@ export interface IdentityGate {
149
171
  class: string | null;
150
172
  }
151
173
 
152
- /**
153
- * The gates `chant.workspace.json` (or `.jsonc`) at `base` names under
154
- * `identity.gates`: each counts only a sealed approval, from its class when
155
- * it names one. chant checks the class against the role grants at base; this
156
- * reads the names. Empty when there is no declaration at base. Throws when
157
- * the declaration there cannot be parsed, since the gate cannot be decided.
158
- */
159
- export function identityGatesAt(repo: string, base: string): IdentityGate[] {
174
+ /** The declaration at `base`, parsed, or null when there is none. Throws when it cannot be parsed. */
175
+ function declarationAt(repo: string, base: string): { file: string; value: unknown } | null {
160
176
  for (const file of ["chant.workspace.json", "chant.workspace.jsonc"]) {
161
177
  const text = showAt(repo, base, file);
162
178
  if (text === undefined) continue;
163
179
  const parsed = parseJsonText(text, { jsonc: file.endsWith(".jsonc") });
164
180
  if (!parsed.ok) throw new Error(`${file} at base is not valid JSON (${parsed.message}), so the gate cannot be decided`);
165
- const gates = (parsed.value as { identity?: { gates?: Record<string, { class?: unknown } | null> } } | null)?.identity?.gates ?? {};
166
- return Object.entries(gates).map(([gate, entry]) => ({ gate, class: typeof entry?.class === "string" ? entry.class : null }));
181
+ return { file, value: parsed.value };
167
182
  }
168
- return [];
183
+ return null;
184
+ }
185
+
186
+ function identityGatesOf(declaration: unknown): IdentityGate[] {
187
+ const gates = (declaration as { identity?: { gates?: Record<string, { class?: unknown } | null> } } | null)?.identity?.gates ?? {};
188
+ return Object.entries(gates).map(([gate, entry]) => ({ gate, class: typeof entry?.class === "string" ? entry.class : null }));
189
+ }
190
+
191
+ /**
192
+ * The gates `chant.workspace.json` (or `.jsonc`) at `base` names under
193
+ * `identity.gates`: each counts only a sealed approval, from its class when
194
+ * it names one. {@link identityGateAdmissionAt} judges an approval by one.
195
+ * Empty when there is no declaration at base. Throws when the declaration
196
+ * there cannot be parsed, since the gate cannot be decided.
197
+ */
198
+ export function identityGatesAt(repo: string, base: string): IdentityGate[] {
199
+ const declaration = declarationAt(repo, base);
200
+ return declaration === null ? [] : identityGatesOf(declaration.value);
201
+ }
202
+
203
+ /** An `identity.gates` gate at base, and the judge for its approvals. */
204
+ export interface IdentityGateAdmission {
205
+ requirement: IdentityGate;
206
+ /** Why `approval` does not count toward the gate, or null when it does. Pass it to {@link decideGateApproval} as `refuses`. */
207
+ refuses(approval: SealedGateApproval): string | null;
208
+ }
209
+
210
+ /**
211
+ * The `identity.gates` rule for `gate` at `base`, or null when the
212
+ * declaration there names none: what chant's `gateAdmission(cwd, gate, base)`
213
+ * answers, read from a bare clone. An approval counts when its seal verifies
214
+ * for its approver against the signers at base and, when the gate names a
215
+ * class, the role grants in `.chant/trust.json` at base put the approver in
216
+ * it. Both judge with the same function ({@link admitApprover}).
217
+ *
218
+ * The classes are the four core ones, then `classes`, the domain classes the
219
+ * caller read from the pinned packages (`./workspace-principals`), in pin
220
+ * order. This reader loads no package. A gate whose class is in neither
221
+ * refuses every approval, and when the declaration at base pins anything the
222
+ * reason says the pins were not read, since one of them may supply it.
223
+ * Throws when the declaration at base cannot be parsed.
224
+ */
225
+ export function identityGateAdmissionAt(
226
+ repo: string,
227
+ base: string,
228
+ gate: string,
229
+ opts: { classes?: readonly ClassGrant[] } = {},
230
+ ): IdentityGateAdmission | null {
231
+ const declaration = declarationAt(repo, base);
232
+ const requirement = declaration === null ? undefined : identityGatesOf(declaration.value).find((g) => g.gate === gate);
233
+ if (!requirement) return null;
234
+ const { signers, roles } = trustAt(repo, base);
235
+ const pins = (declaration!.value as { pins?: unknown }).pins;
236
+ const rule: GateAdmissionRule = {
237
+ gate,
238
+ class: requirement.class,
239
+ signers,
240
+ roles,
241
+ classes: [...CORE_CLASSES, ...(opts.classes ?? [])],
242
+ ...(Array.isArray(pins) && pins.length > 0
243
+ ? { unknownClass: `is not a core class, and this reader does not load the classes the pinned packages in ${declaration!.file} at base supply` }
244
+ : {}),
245
+ };
246
+ return { requirement, refuses: (a) => admitApprover(rule, a) };
169
247
  }
170
248
 
171
249
  // ── pr-review ────────────────────────────────────────────────────────────
@@ -45,6 +45,7 @@ import { isNeverOverMcpGateOp } from "../op/gate-name";
45
45
  import { sortedJsonReplacer } from "../utils";
46
46
  import { currentGateOrigin, type GateOrigin } from "./gate-origin";
47
47
  import type { GateApprover, GatePolicyDecision, ResolvedGateApproval } from "../op/gate-approval";
48
+ import type { GateApprovalSource } from "../op/op-waves";
48
49
  import type { GateRunLocator } from "../op/gate-run-locator";
49
50
  import { readBlobFromPath, readPathSha, readBlobBySha, writeBlobToPath, RefCASConflictError } from "./git";
50
51
 
@@ -288,6 +289,13 @@ export interface PendingGateRecord {
288
289
  * the run produced, and `chant operator status` to show quorum progress.
289
290
  */
290
291
  approval?: ResolvedGateApproval;
292
+ /**
293
+ * The approval mode an Op wave asked under (#3861): `ledger`, `pr-review` or
294
+ * `sealed`, as read at base. It says which approvals count for the gate, so a
295
+ * reader (behold, gate-audit) decides under the mode the wave used rather
296
+ * than inferring it from config. Not the quorum block in `approval`.
297
+ */
298
+ approvalMode?: GateApprovalSource;
291
299
  /**
292
300
  * The open question this gate waits on, on a gate that asks a decision
293
301
  * point (#3170). It is answered with `chant workspace points answer <id>`,
@@ -254,6 +254,7 @@ describe("a wave gate that asks a decision point (#3836)", () => {
254
254
  members,
255
255
  description: "wave 1 of 1: vpc, nat",
256
256
  neverOverMcp: true,
257
+ approvalMode: "ledger",
257
258
  answer: { point: "prod-apply" },
258
259
  });
259
260
  expect(waiting.decision?.pendingFact).toMatchObject({ commit: "c".repeat(40), neverOverMcp: true });
@@ -130,7 +130,7 @@ export interface OpWavePlansFile {
130
130
  /** Pending-fact keys chant writes itself, which a plans file's `pending` may not set (#3821). */
131
131
  export const OP_WAVE_PENDING_RESERVED = [
132
132
  "version", "kind", "op", "gate", "timestamp", "expiresAt", "planDigest", "runId", "url", "resume",
133
- "environment", "origin", "neverOverMcp", "approval", "answer",
133
+ "environment", "origin", "neverOverMcp", "approval", "approvalMode", "answer",
134
134
  ] as const;
135
135
 
136
136
  /** What chant writes to `{runs}` for a wave-level command or a hook (#3762). */
@@ -1068,7 +1068,7 @@ async function settleOtherGate(ctx: WaveContext, hold: OtherGateHold): Promise<O
1068
1068
  description: hold.request.description ?? `wave ${k} (${wave.name}) of ${spec.name} is held on it by ${hold.label}`,
1069
1069
  now,
1070
1070
  // #3839: the wave a hold belongs to, as a field, whatever the hook's own description says.
1071
- fields: { ...hold.request.pending, wave: { number: k, name: wave.name, op: spec.name } },
1071
+ fields: { ...hold.request.pending, approvalMode: rules.approval, wave: { number: k, name: wave.name, op: spec.name } },
1072
1072
  ...(neverOverMcp ? { neverOverMcp: true } : {}),
1073
1073
  });
1074
1074
  const base = { op, gate: hold.request.gate, digest: hold.request.digest, hook: hold.label };
@@ -1633,7 +1633,8 @@ async function settleGate(options: RunOpWaveOptions, ctx: WaveContext, decision:
1633
1633
  description: (typeof decision.pending?.description === "string" ? decision.pending.description : undefined) ?? `wave ${k} (${wave.name}): ${members.length} run${members.length === 1 ? "" : "s"}, gate ${policy}, approval ${approval}${held}`,
1634
1634
  now,
1635
1635
  ...(spent ? { spent } : {}),
1636
- ...(decision.pending ? { fields: decision.pending } : {}),
1636
+ // #3861: the approval mode the wave asked under, for readers deciding which approvals count.
1637
+ fields: { ...decision.pending, approvalMode: approval },
1637
1638
  ...(decision.neverOverMcp ? { neverOverMcp: true } : {}),
1638
1639
  });
1639
1640
  if (check.satisfied) {
@@ -1697,7 +1698,7 @@ async function settlePointGate(options: RunOpWaveOptions, ctx: WaveContext, deci
1697
1698
  planDigest: digest,
1698
1699
  ...(options.now ? { now: options.now } : {}),
1699
1700
  // #3863: the plans file's pending fields and the spec's neverOverMcp, as settleGate passes them.
1700
- ...(decision.pending ? { fields: decision.pending } : {}),
1701
+ fields: { ...decision.pending, approvalMode: decision.approval },
1701
1702
  ...(decision.neverOverMcp ? { neverOverMcp: true } : {}),
1702
1703
  });
1703
1704
  if (check.satisfied) {
@@ -739,8 +739,22 @@ describe("a product's wave gate moved onto the waves (#3821)", () => {
739
739
  const result = await runOpWave({ spec: tg, specFile: "waves.json", wave: 1, cwd: h.cwd, exec: h.exec, show: () => ({ sha: "b".repeat(40), text: JSON.stringify({ ...tg, neverOverMcp: true }) }), gates });
740
740
  expect(result.exitCode).toBe(3);
741
741
  expect(gates.appended[0]).toMatchObject({ commit: "c".repeat(40), members, description: "wave 1 of 3: vpc, dns, nat", neverOverMcp: true, gate: "wave-1", op: "tf-apply" });
742
+ // #3861: the approval mode the wave asked under, and a plans file may not set it.
743
+ expect(gates.appended[0]).toMatchObject({ approvalMode: "ledger" });
742
744
  h.done();
743
745
 
746
+ const mode = harness(plans, { pending: { approvalMode: "sealed" } });
747
+ await expect(runOpWave({ spec: tg, specFile: "waves.json", wave: 1, cwd: mode.cwd, exec: mode.exec, show: mode.show, gates: memoryGateLedgerPort() })).rejects.toThrow(/sets approvalMode, which chant writes itself/);
748
+ mode.done();
749
+
750
+ // A sealed spec at base records "sealed".
751
+ const sealedSpec: OpWavesSpec = { ...tg, waves: [{ ...tg.waves[0]!, approval: "sealed" }] };
752
+ const sh = harness(plans, {}, sealedSpec);
753
+ const sealedGates = memoryGateLedgerPort();
754
+ await runOpWave({ spec: sealedSpec, specFile: "waves.json", wave: 1, cwd: sh.cwd, exec: sh.exec, show: () => ({ sha: "b".repeat(40), text: JSON.stringify(sealedSpec) }), gates: sealedGates });
755
+ expect(sealedGates.appended[0]).toMatchObject({ approvalMode: "sealed" });
756
+ sh.done();
757
+
744
758
  const bad = harness(plans, { pending: { gate: "other" } });
745
759
  await expect(runOpWave({ spec: tg, specFile: "waves.json", wave: 1, cwd: bad.cwd, exec: bad.exec, show: bad.show, gates: memoryGateLedgerPort() })).rejects.toThrow(/sets gate, which chant writes itself/);
746
760
  bad.done();
@@ -0,0 +1,109 @@
1
+ /**
2
+ * The `identity.gates` rule as data and one pure function (#3862).
3
+ *
4
+ * A gate the declaration names under `identity.gates` passes only on an
5
+ * approval sealed by a signer at base, from the class the gate names when it
6
+ * names one (#3163, ws-080). chant's `gateAdmissionFrom` (`./identity.ts`)
7
+ * builds a {@link GateAdmissionRule} from what `scopeSource` reads and judges
8
+ * every approval with {@link admitApprover}. `@intentius/chant/gate-decision`
9
+ * builds the same rule from a bare clone at a base commit
10
+ * (`identityGateAdmissionAt`) and judges with the same function, so a tool
11
+ * counts approvals as chant's wave gate does.
12
+ *
13
+ * The module imports node:crypto through `./trust/gate-seal.ts` and nothing
14
+ * else: no zod, no ajv, no package loading, so it bundles small.
15
+ */
16
+
17
+ import { GATE_SEAL_NAMESPACE, gateSealPayload, namespaceAllowed, verifySshSignatureWith, type SealedGateApproval } from "./trust/gate-seal";
18
+ import type { Signer } from "./trust/trust-files";
19
+
20
+ /** The core classes, in the order a principal's roles are tried; `human` holds no role and is the rest. */
21
+ export const CORE_PRINCIPAL_CLASSES = ["human", "agent", "runner", "service"] as const;
22
+ export type CorePrincipalClass = (typeof CORE_PRINCIPAL_CLASSES)[number];
23
+
24
+ export interface PrincipalClass {
25
+ name: string;
26
+ /** One line saying who is in the class. */
27
+ description: string;
28
+ /** The role whose grant at base puts a principal in the class, or null for `human`, the rest. */
29
+ role: string | null;
30
+ /** `core`, or the pin (package name or path) that supplies the class. */
31
+ source: string;
32
+ }
33
+
34
+ export const CORE_CLASSES: readonly PrincipalClass[] = [
35
+ { name: "human", description: "a principal holding none of the roles of another class", role: null, source: "core" },
36
+ { name: "agent", description: "a principal holding the agent role, or a write naming an agent session", role: "agent", source: "core" },
37
+ { name: "runner", description: "a principal holding the runner role, such as a CI job's signing identity", role: "runner", source: "core" },
38
+ { name: "service", description: "a principal holding the service role", role: "service", source: "core" },
39
+ ];
40
+
41
+ /** A class as the rule reads it: its name, and the role whose grant puts a principal in it (null for `human`). */
42
+ export type ClassGrant = Pick<PrincipalClass, "name" | "role">;
43
+
44
+ /** What an `identity.gates` gate is judged by, all read at base. */
45
+ export interface GateAdmissionRule {
46
+ gate: string;
47
+ /** The class the approver must be in, or null for any signer. */
48
+ class: string | null;
49
+ /** The signers file at base: its path, whether it exists, and its signers. */
50
+ signers: { signersPath: string; active: boolean; signers: readonly Signer[] };
51
+ /** The role grants at base (`.chant/trust.json` `roles`). */
52
+ roles: Readonly<Record<string, readonly string[]>>;
53
+ /** Every class the rule knows, core first, then domain classes in pin order. */
54
+ classes: readonly ClassGrant[];
55
+ /**
56
+ * Why a class the rule does not know is unknown, for the refusal. Default
57
+ * "no pinned package supplies", which is what chant says once it has read
58
+ * every pin.
59
+ */
60
+ unknownClass?: string;
61
+ }
62
+
63
+ const normalise = (name: string): string => name.normalize("NFKC").trim().toLowerCase();
64
+
65
+ /** Every class `principal`'s role grants put it in, in `classes` order: what `classesOf` in `./principal-classes.ts` answers. */
66
+ export function grantedClasses(classes: readonly ClassGrant[], roles: Readonly<Record<string, readonly string[]>>, principal: string | null): string[] {
67
+ if (principal === null) return [];
68
+ const name = normalise(principal);
69
+ return classes.filter((c) => c.role !== null && (roles[c.role] ?? []).some((p) => normalise(p) === name)).map((c) => c.name);
70
+ }
71
+
72
+ /**
73
+ * Why `a` does not count toward the gate, or null when it does. An approval
74
+ * counts only when its seal verifies for its approver against the signers at
75
+ * base and, when the rule names a class, the role grants at base put the
76
+ * approver in it (`human`: in no other class). A class the rule does not
77
+ * know lets nothing through.
78
+ */
79
+ export function admitApprover(rule: GateAdmissionRule, a: SealedGateApproval): string | null {
80
+ const { gate, signers } = rule;
81
+ const want = rule.class;
82
+ if (want !== null && !rule.classes.some((c) => c.name === want)) {
83
+ return `identity.gates.${gate} names the class ${want}, which ${rule.unknownClass ?? "no pinned package supplies"}, so no approval can show it is in that class (known classes: ${rule.classes.map((c) => c.name).join(", ")})`;
84
+ }
85
+ if (!signers.active) return `gate ${gate} needs a signed approval, and there is no signers file (${signers.signersPath}) at base to check one against`;
86
+ const seal = sealRefusal(gate, signers, a);
87
+ if (seal !== null) return seal;
88
+ if (want === null) return null;
89
+ const granted = grantedClasses(rule.classes, rule.roles, a.resolvedBy);
90
+ const inClass = want === "human" ? granted.length === 0 : granted.includes(want);
91
+ return inClass ? null : `${a.resolvedBy} is not in the class ${want} that gate ${gate} needs: no role grant at base puts them there`;
92
+ }
93
+
94
+ /** The seal step, worded as `checkGateSeal` (`./trust/seal.ts`) words it against an active signers file at base. */
95
+ function sealRefusal(gate: string, signers: GateAdmissionRule["signers"], a: SealedGateApproval): string | null {
96
+ const what = `the approval of gate ${a.gate} by ${a.resolvedBy}`;
97
+ if (a.seal === undefined || a.seal === null) return `the approval by ${a.resolvedBy} is not signed; gate ${gate} needs chant approve --sign`;
98
+ const seal = a.seal as { signer?: unknown; signature?: unknown };
99
+ if (typeof seal !== "object" || Array.isArray(seal) || typeof seal.signer !== "string" || typeof seal.signature !== "string") {
100
+ return `the seal on ${what} is malformed: it needs signer and signature`;
101
+ }
102
+ if (normalise(seal.signer) !== normalise(a.resolvedBy)) return `the seal on ${what} is by ${seal.signer}, and its approver is ${a.resolvedBy || "empty"}`;
103
+ const where = `${signers.signersPath} at base`;
104
+ const listed = signers.signers.filter((s) => normalise(s.principal) === normalise(a.resolvedBy));
105
+ if (listed.length === 0) return `${a.resolvedBy} has no key in ${where}, so the seal can't count`;
106
+ const keys = listed.filter((s) => namespaceAllowed(s.namespaces, GATE_SEAL_NAMESPACE)).map((s) => Buffer.from(s.key.split(" ")[1] ?? "", "base64"));
107
+ const r = verifySshSignatureWith(seal.signature, gateSealPayload(a), GATE_SEAL_NAMESPACE, keys);
108
+ return r.ok ? null : `the seal does not verify for ${a.resolvedBy} against ${where}: ${r.reason}`;
109
+ }
@@ -26,11 +26,12 @@
26
26
  */
27
27
 
28
28
  import type { Declaration, SignedGate } from "./declaration";
29
- import { classesOf, coreClassRegistry, principalClass, type ClassRegistry } from "./principal-classes";
29
+ import { admitApprover } from "./identity-gate-rule";
30
+ import { classesOf, coreClassRegistry, roleGrants, type ClassRegistry } from "./principal-classes";
30
31
  import type { ReasonCode } from "./reason-codes";
31
32
  import { normalisePrincipal } from "./records";
32
33
  import type { TrustPolicy } from "./trust/policy";
33
- import { checkGateSeal, type SealedGateApproval } from "./trust/seal";
34
+ import type { SealedGateApproval } from "./trust/gate-seal";
34
35
  import { scopeSource } from "./write-scope";
35
36
 
36
37
  /** The forges a forge identity can name. */
@@ -152,27 +153,16 @@ export interface GateRuleSource extends IdentitySource {
152
153
  * approval counts only when its seal verifies for its approver against the
153
154
  * signers at base and, when the rule names a class, the approver's role
154
155
  * grants at base put it in that class. A class no pinned package supplies
155
- * lets nothing through.
156
+ * lets nothing through. The judge is {@link admitApprover}, which
157
+ * `@intentius/chant/gate-decision` also judges with (#3862). The policy is
158
+ * the one at base, never a returned work's copy.
156
159
  */
157
160
  export function gateAdmissionFrom(source: GateRuleSource, gate: string): GateAdmission | null {
158
161
  const requirement = source.declaration?.identity?.gates[gate];
159
162
  if (!requirement) return null;
160
163
  const { policy, classes } = source;
161
- return {
162
- requirement,
163
- refuses(a) {
164
- const want = requirement.class;
165
- if (want !== null && classes.get(want) === undefined) {
166
- return `identity.gates.${gate} names the class ${want}, which no pinned package supplies, so no approval can show it is in that class (known classes: ${classes.names().join(", ")})`;
167
- }
168
- if (!policy.active) return `gate ${gate} needs a signed approval, and there is no signers file (${policy.signersPath}) at base to check one against`;
169
- const seal = checkGateSeal(policy, a);
170
- if (seal.attested !== true) return a.seal === undefined || a.seal === null ? `the approval by ${a.resolvedBy} is not signed; gate ${gate} needs chant approve --sign` : seal.message;
171
- if (want === null) return null;
172
- const inClass = want === "human" ? principalClass(policy, a.resolvedBy, classes) === "human" : classesOf(classes, policy, a.resolvedBy).includes(want);
173
- return inClass ? null : `${a.resolvedBy} is not in the class ${want} that gate ${gate} needs: no role grant at base puts them there`;
174
- },
175
- };
164
+ const rule = { gate, class: requirement.class, signers: policy, roles: roleGrants(policy), classes: classes.all() };
165
+ return { requirement, refuses: (a) => admitApprover(rule, a) };
176
166
  }
177
167
 
178
168
  /**
@@ -26,19 +26,17 @@ import { readFileSync } from "node:fs";
26
26
  import { createRequire } from "node:module";
27
27
  import { join, posix } from "node:path";
28
28
  import { kindsExportTarget, pinnedPackageDir, type KindLoadProblem, type PinLike } from "./kinds";
29
- import { normalisePrincipal } from "./records";
30
29
  import schema from "./workspace-principals.schema.json";
31
30
  import type { TrustPolicy } from "./trust/policy";
32
31
  import { joinPath, type WorkspaceTree } from "./tree";
32
+ import { CORE_CLASSES, CORE_PRINCIPAL_CLASSES, grantedClasses, type PrincipalClass } from "./identity-gate-rule";
33
33
 
34
34
  export const PRINCIPALS_SCHEMA_ID = schema.$id;
35
35
 
36
36
  /** The subpath a package publishes its principal classes at. */
37
37
  export const PRINCIPALS_SUBPATH = "./workspace-principals";
38
38
 
39
- /** The core classes, in the order a principal's roles are tried; `human` holds no role and is the rest. */
40
- export const CORE_PRINCIPAL_CLASSES = ["human", "agent", "runner", "service"] as const;
41
- export type CorePrincipalClass = (typeof CORE_PRINCIPAL_CLASSES)[number];
39
+ export { CORE_CLASSES, CORE_PRINCIPAL_CLASSES, type CorePrincipalClass, type PrincipalClass } from "./identity-gate-rule";
42
40
 
43
41
  /** A class name: a core class, or a domain class a pinned package supplies. */
44
42
  export type PrincipalClassName = string;
@@ -46,23 +44,6 @@ export type PrincipalClassName = string;
46
44
  /** The grammar of a class name, as `workspace-principals.schema.json` and the declaration's writeScope keys say it. */
47
45
  export const CLASS_NAME = /^(?!x-)[a-z][a-z0-9-]{0,39}$/;
48
46
 
49
- export interface PrincipalClass {
50
- name: string;
51
- /** One line saying who is in the class. */
52
- description: string;
53
- /** The role whose grant at base puts a principal in the class, or null for `human`, the rest. */
54
- role: string | null;
55
- /** `core`, or the pin (package name or path) that supplies the class. */
56
- source: string;
57
- }
58
-
59
- export const CORE_CLASSES: readonly PrincipalClass[] = [
60
- { name: "human", description: "a principal holding none of the roles of another class", role: null, source: "core" },
61
- { name: "agent", description: "a principal holding the agent role, or a write naming an agent session", role: "agent", source: "core" },
62
- { name: "runner", description: "a principal holding the runner role, such as a CI job's signing identity", role: "runner", source: "core" },
63
- { name: "service", description: "a principal holding the service role", role: "service", source: "core" },
64
- ];
65
-
66
47
  const CORE_ROLES = new Set(CORE_CLASSES.map((c) => c.role).filter((r): r is string => r !== null));
67
48
 
68
49
  export interface ClassRegistry {
@@ -100,16 +81,10 @@ export function roleGrants(policy: TrustPolicy): Record<string, string[]> {
100
81
  /**
101
82
  * Every class `principal`'s role grants at base put it in, in registry order
102
83
  * (core first). Empty for a principal in no class but `human`, and for null.
103
- * Names compare as {@link normalisePrincipal} folds them.
84
+ * Names compare as `normalisePrincipal` (`./records.ts`) folds them.
104
85
  */
105
86
  export function classesOf(classes: ClassRegistry, policy: TrustPolicy, principal: string | null): string[] {
106
- if (principal === null) return [];
107
- const name = normalisePrincipal(principal);
108
- const grants = roleGrants(policy);
109
- return classes
110
- .all()
111
- .filter((c) => c.role !== null && (grants[c.role] ?? []).some((p) => normalisePrincipal(p) === name))
112
- .map((c) => c.name);
87
+ return grantedClasses(classes.all(), roleGrants(policy), principal);
113
88
  }
114
89
 
115
90
  /** The class write scope judges `principal` as: the first class its grants put it in, or `human`. */