@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.
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/gate-decision.d.ts +36 -4
- package/dist/gate-decision.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +8 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/op/op-waves-run.d.ts +1 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/workspace/identity-gate-rule.d.ts +65 -0
- package/dist/workspace/identity-gate-rule.d.ts.map +1 -0
- package/dist/workspace/identity.d.ts +4 -2
- package/dist/workspace/identity.d.ts.map +1 -1
- package/dist/workspace/principal-classes.d.ts +3 -14
- package/dist/workspace/principal-classes.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/lint.ts +33 -6
- package/src/gate-decision-bundle.test.ts +3 -2
- package/src/gate-decision-identity.test.ts +176 -0
- package/src/gate-decision.ts +100 -22
- package/src/lifecycle/gate-ledger.ts +8 -0
- package/src/op/op-waves-point.test.ts +1 -0
- package/src/op/op-waves-run.ts +5 -4
- package/src/op/op-waves.test.ts +14 -0
- package/src/workspace/identity-gate-rule.ts +109 -0
- package/src/workspace/identity.ts +8 -18
- package/src/workspace/principal-classes.ts +4 -29
|
@@ -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;
|
|
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"}
|
package/dist/gate-decision.d.ts
CHANGED
|
@@ -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.
|
|
67
|
-
*
|
|
68
|
-
*
|
|
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":"AAAA
|
|
1
|
+
{"version":3,"file":"gate-decision.d.ts","sourceRoot":"","sources":["../src/gate-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AASH,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAQzG,OAAO,EAA+B,KAAK,UAAU,EAA0B,MAAM,gCAAgC,CAAC;AACtH,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,OAAO,EAAE,qBAAqB,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,GACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,MAAM,EACX,KAAK,SAAS,GACf,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,cAAc,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,KAAK,iBAAiB,GACvB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAcrD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY/C;AAwBD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAErE;AAED,0HAA0H;AAC1H,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAmBD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CAG1E;AAED,yEAAyE;AACzE,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,YAAY,CAAC;IAC1B,+HAA+H;IAC/H,OAAO,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAAC;CACtD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;CAAO,GAC7C,qBAAqB,GAAG,IAAI,CAiB9B;AAID,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7F;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,CAmBnH;AAID,+FAA+F;AAC/F,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,oGAAoG;IACpG,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,sIAAsI;IACtI,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,iHAAiH;IACjH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,MAAM,GAAG,IAAI,CAAC;IAC5D,oJAAoJ;IACpJ,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,uEAAuE;IACvE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,oBAAoB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,oBAAoB,CAAA;CAAE,GACvE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;CAAE,GAC1E;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,wHAAwH;IACxH,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,yGAAyG;IACzG,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,iFAAiF;IACjF,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,yDAAyD;IACzD,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IAClC,wHAAwH;IACxH,KAAK,CAAC,EAAE,oBAAoB,CAAC;CAC9B,CAAC;AAIN;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,oBAAoB,CA6CjF"}
|
|
@@ -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 {
|
|
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;
|
|
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
|
-
|
|
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
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,EAAuC,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;
|
|
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
package/src/cli/commands/lint.ts
CHANGED
|
@@ -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
|
|
669
|
-
*
|
|
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
|
|
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`,
|
|
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
|
+
});
|
package/src/gate-decision.ts
CHANGED
|
@@ -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
|
-
|
|
122
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 });
|
package/src/op/op-waves-run.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
...
|
|
1701
|
+
fields: { ...decision.pending, approvalMode: decision.approval },
|
|
1701
1702
|
...(decision.neverOverMcp ? { neverOverMcp: true } : {}),
|
|
1702
1703
|
});
|
|
1703
1704
|
if (check.satisfied) {
|
package/src/op/op-waves.test.ts
CHANGED
|
@@ -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 {
|
|
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 {
|
|
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
|
-
|
|
162
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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`. */
|