@intutic/gate 2.9.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/actions.d.ts +39 -0
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +139 -0
  4. package/dist/actions.js.map +1 -1
  5. package/dist/client.d.ts +10 -0
  6. package/dist/client.d.ts.map +1 -1
  7. package/dist/client.js +19 -0
  8. package/dist/client.js.map +1 -1
  9. package/dist/decide.d.ts +269 -0
  10. package/dist/decide.d.ts.map +1 -0
  11. package/dist/decide.js +757 -0
  12. package/dist/decide.js.map +1 -0
  13. package/dist/decideApi.d.ts +24 -0
  14. package/dist/decideApi.d.ts.map +1 -0
  15. package/dist/decideApi.js +32 -0
  16. package/dist/decideApi.js.map +1 -0
  17. package/dist/decideEngine.d.ts +195 -0
  18. package/dist/decideEngine.d.ts.map +1 -0
  19. package/dist/decideEngine.js +707 -0
  20. package/dist/decideEngine.js.map +1 -0
  21. package/dist/decideEvaluate.d.ts +250 -0
  22. package/dist/decideEvaluate.d.ts.map +1 -0
  23. package/dist/decideEvaluate.js +504 -0
  24. package/dist/decideEvaluate.js.map +1 -0
  25. package/dist/decideHostGuard.d.ts +56 -0
  26. package/dist/decideHostGuard.d.ts.map +1 -0
  27. package/dist/decideHostGuard.js +194 -0
  28. package/dist/decideHostGuard.js.map +1 -0
  29. package/dist/decideLog.d.ts +287 -0
  30. package/dist/decideLog.d.ts.map +1 -0
  31. package/dist/decideLog.js +521 -0
  32. package/dist/decideLog.js.map +1 -0
  33. package/dist/decideLogRedaction.d.ts +17 -0
  34. package/dist/decideLogRedaction.d.ts.map +1 -0
  35. package/dist/decideLogRedaction.js +33 -0
  36. package/dist/decideLogRedaction.js.map +1 -0
  37. package/dist/decideRecord.d.ts +128 -0
  38. package/dist/decideRecord.d.ts.map +1 -0
  39. package/dist/decideRecord.js +254 -0
  40. package/dist/decideRecord.js.map +1 -0
  41. package/dist/decideSdk.d.ts +86 -0
  42. package/dist/decideSdk.d.ts.map +1 -0
  43. package/dist/decideSdk.js +146 -0
  44. package/dist/decideSdk.js.map +1 -0
  45. package/dist/dsh.d.ts.map +1 -1
  46. package/dist/dsh.js +6 -1
  47. package/dist/dsh.js.map +1 -1
  48. package/dist/errors.d.ts +26 -2
  49. package/dist/errors.d.ts.map +1 -1
  50. package/dist/errors.js +38 -1
  51. package/dist/errors.js.map +1 -1
  52. package/dist/gate.d.ts +85 -1
  53. package/dist/gate.d.ts.map +1 -1
  54. package/dist/gate.js +314 -18
  55. package/dist/gate.js.map +1 -1
  56. package/dist/gateRuleRecord.d.ts +244 -0
  57. package/dist/gateRuleRecord.d.ts.map +1 -0
  58. package/dist/gateRuleRecord.js +459 -0
  59. package/dist/gateRuleRecord.js.map +1 -0
  60. package/dist/harness.d.ts.map +1 -1
  61. package/dist/harness.js +22 -10
  62. package/dist/harness.js.map +1 -1
  63. package/dist/index.d.ts +14 -5
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +5 -3
  66. package/dist/index.js.map +1 -1
  67. package/dist/lanes.d.ts +94 -0
  68. package/dist/lanes.d.ts.map +1 -0
  69. package/dist/lanes.js +150 -0
  70. package/dist/lanes.js.map +1 -0
  71. package/dist/limits.d.ts +6 -0
  72. package/dist/limits.d.ts.map +1 -1
  73. package/dist/limits.js +6 -0
  74. package/dist/limits.js.map +1 -1
  75. package/dist/refusalDetail.d.ts +58 -0
  76. package/dist/refusalDetail.d.ts.map +1 -0
  77. package/dist/refusalDetail.js +121 -0
  78. package/dist/refusalDetail.js.map +1 -0
  79. package/dist/scopeMatch.d.ts +156 -0
  80. package/dist/scopeMatch.d.ts.map +1 -0
  81. package/dist/scopeMatch.js +438 -0
  82. package/dist/scopeMatch.js.map +1 -0
  83. package/dist/snapshot.d.ts +51 -3
  84. package/dist/snapshot.d.ts.map +1 -1
  85. package/dist/snapshot.js +86 -13
  86. package/dist/snapshot.js.map +1 -1
  87. package/dist/testOutcome.d.ts +164 -0
  88. package/dist/testOutcome.d.ts.map +1 -0
  89. package/dist/testOutcome.js +439 -0
  90. package/dist/testOutcome.js.map +1 -0
  91. package/dist/wrapTools.d.ts +7 -1
  92. package/dist/wrapTools.d.ts.map +1 -1
  93. package/dist/wrapTools.js +30 -2
  94. package/dist/wrapTools.js.map +1 -1
  95. package/package.json +2 -2
@@ -52,6 +52,8 @@
52
52
  */
53
53
  import { type McpAllowlistRecord, type McpRegistryRecord } from './mcpRegistryRecord.js';
54
54
  import { type SsoGroupRecord } from './ssoGroups.js';
55
+ import { type DecideRecord } from './decideRecord.js';
56
+ import { type GateRuleRecord } from './gateRuleRecord.js';
55
57
  export declare const SNAPSHOT_STALE_AFTER_DAYS = 7;
56
58
  /** Severity tiers, in the order the shipped gate handles them. */
57
59
  export declare const SEV_SHADOW: "shadow";
@@ -123,6 +125,25 @@ export declare class Snapshot {
123
125
  * check, since it only ever hides text and never allows a call.
124
126
  */
125
127
  opaque: boolean;
128
+ /** The snapshot format its `@format` record names; 1 without one. */
129
+ formatVersion: number;
130
+ /**
131
+ * The decide rules whose `@decide` records decoded, rule and hash checked,
132
+ * in snapshot order. Each one's fallback line is skipped only for a caller
133
+ * that evaluates decide rules ({@link LoadSnapshotOptions}); a record that
134
+ * does not decode is not here, and its fallback line refuses. Empty on a
135
+ * snapshot that fails its integrity check.
136
+ */
137
+ decideRules: DecideRecord[];
138
+ /**
139
+ * The rule records (`@rule`) that decoded, in snapshot order:
140
+ * qualified prerequisites, enforced scopes and plan approval, which Tier R
141
+ * evaluates. Each one's fallback line is skipped only for a caller that
142
+ * evaluates rule records ({@link LoadSnapshotOptions}); a record that does
143
+ * not decode is not here, and its fallback line refuses. Empty on a
144
+ * snapshot that fails its integrity check.
145
+ */
146
+ ruleRecords: GateRuleRecord[];
126
147
  get healthMessage(): string;
127
148
  }
128
149
  export interface Decision {
@@ -131,9 +152,31 @@ export interface Decision {
131
152
  /** The rule's reason and `[id]`; for a hold, the reason alone, which the gate words as a hold. */
132
153
  reason: string;
133
154
  ruleId: string;
155
+ /**
156
+ * Every rule that matched without deciding the call (shadow, warn), in
157
+ * rule order, up to the deciding rule. The caller records each one, as the
158
+ * rendered gates do. When no rule decides, `severity` is the first of them.
159
+ */
160
+ advisories?: Decision[];
161
+ /** Index of the rule after the deciding one: where to resume after an approved hold. */
162
+ next?: number;
134
163
  }
135
164
  /** Where the policy snapshot is read from: `INTUTIC_SNAPSHOT_RULES`, else `~/.intutic/hooks/policy-snapshot.rules`. */
136
165
  export declare function snapshotPath(): string;
166
+ export interface LoadSnapshotOptions {
167
+ /**
168
+ * The caller evaluates the decide rules the records carry. Only then is a
169
+ * decoded record's fallback line skipped; otherwise the fallback line
170
+ * refuses the rule's tools, exactly as in a gate that reads no records.
171
+ */
172
+ evaluatesDecide?: boolean;
173
+ /**
174
+ * The caller evaluates the `@rule` records (Tier R). Only then is a decoded
175
+ * record's fallback line skipped; otherwise the fallback line refuses what
176
+ * the rule covers, exactly as in a gate that reads no records.
177
+ */
178
+ evaluatesRules?: boolean;
179
+ }
137
180
  /**
138
181
  * Read the policy snapshot the sync daemon compiled: from `path`, else
139
182
  * {@link snapshotPath}. A missing file gives an empty snapshot whose `state`
@@ -141,8 +184,13 @@ export declare function snapshotPath(): string;
141
184
  * was compiled for a workspace other than a non-empty `workspaceId`, is
142
185
  * `'invalid'`: its rules and MCP records are dropped.
143
186
  */
144
- export declare function loadSnapshot(workspaceId?: string, path?: string): Snapshot;
145
- /** Evaluate one tool call against the snapshot. First match wins. */
146
- export declare function evaluate(toolName: string, target: string, command: string, snap: Snapshot, guardDisabled?: boolean): Decision;
187
+ export declare function loadSnapshot(workspaceId?: string, path?: string, opts?: LoadSnapshotOptions): Snapshot;
188
+ /**
189
+ * Evaluate one tool call against the snapshot, as the rendered gates do: a
190
+ * shadow or warn match is collected and evaluation continues, so a later block
191
+ * or hold still decides the call. The first block or hold wins. With none, the
192
+ * first advisory match is returned. `from` resumes after an approved hold.
193
+ */
194
+ export declare function evaluate(toolName: string, target: string, command: string, snap: Snapshot, guardDisabled?: boolean, from?: number): Decision;
147
195
  export declare function guardDisabledFromEnv(): boolean;
148
196
  //# sourceMappingURL=snapshot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAMH,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAA8C,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAMhG,eAAO,MAAM,yBAAyB,IAAI,CAAA;AAE1C,kEAAkE;AAClE,eAAO,MAAM,UAAU,EAAG,QAAiB,CAAA;AAC3C,eAAO,MAAM,QAAQ,EAAG,MAAe,CAAA;AACvC,eAAO,MAAM,SAAS,EAAG,OAAgB,CAAA;AACzC;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAG,MAAe,CAAA;AAEvC,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,GAAG,OAAO,QAAQ,GAAG,OAAO,SAAS,GAAG,OAAO,QAAQ,CAAA;AAC/F;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAA;AACrF,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAA;AAE3E,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAA;CAC1B;AAED,qBAAa,QAAQ;IACnB,KAAK,EAAE,IAAI,EAAE,CAAK;IAClB,MAAM,SAAS;IACf,KAAK,EAAE,aAAa,CAAW;IAC/B,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,OAAO,SAAI;IACX,sCAAsC;IACtC,YAAY,SAAI;IAChB;;;;;OAKG;IACH,SAAS,EAAE,cAAc,GAAG,IAAI,CAAO;IACvC;;;;;;OAMG;IACH,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAO;IAC5C;;;;OAIG;IACH,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAO;IAC9C;;;;;OAKG;IACH,MAAM,UAAQ;IAEd,IAAI,aAAa,IAAI,MAAM,CAa1B;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,kGAAkG;IAClG,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAMD,uHAAuH;AACvH,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAYD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,WAAW,SAAK,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CA2GtE;AAED,qEAAqE;AACrE,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ,EACd,aAAa,UAAQ,GACpB,QAAQ,CAiEV;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C"}
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAMH,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAA8C,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEhG,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAyC,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAMhG,eAAO,MAAM,yBAAyB,IAAI,CAAA;AAE1C,kEAAkE;AAClE,eAAO,MAAM,UAAU,EAAG,QAAiB,CAAA;AAC3C,eAAO,MAAM,QAAQ,EAAG,MAAe,CAAA;AACvC,eAAO,MAAM,SAAS,EAAG,OAAgB,CAAA;AACzC;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAG,MAAe,CAAA;AAEvC,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,GAAG,OAAO,QAAQ,GAAG,OAAO,SAAS,GAAG,OAAO,QAAQ,CAAA;AAC/F;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAA;AACrF,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAA;AAE3E,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,WAAW,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAA;CAC1B;AAED,qBAAa,QAAQ;IACnB,KAAK,EAAE,IAAI,EAAE,CAAK;IAClB,MAAM,SAAS;IACf,KAAK,EAAE,aAAa,CAAW;IAC/B,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,OAAO,SAAI;IACX,sCAAsC;IACtC,YAAY,SAAI;IAChB;;;;;OAKG;IACH,SAAS,EAAE,cAAc,GAAG,IAAI,CAAO;IACvC;;;;;;OAMG;IACH,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAO;IAC5C;;;;OAIG;IACH,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAO;IAC9C;;;;;OAKG;IACH,MAAM,UAAQ;IACd,qEAAqE;IACrE,aAAa,SAAI;IACjB;;;;;;OAMG;IACH,WAAW,EAAE,YAAY,EAAE,CAAK;IAChC;;;;;;;OAOG;IACH,WAAW,EAAE,cAAc,EAAE,CAAK;IAElC,IAAI,aAAa,IAAI,MAAM,CAa1B;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,0BAA0B;IAC1B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,kGAAkG;IAClG,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAA;IACvB,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAYD,uHAAuH;AACvH,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAYD,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,WAAW,SAAK,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,mBAAwB,GAAG,QAAQ,CAoJtG;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ,EACd,aAAa,UAAQ,EACrB,IAAI,SAAI,GACP,QAAQ,CAiEV;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C"}
package/dist/snapshot.js CHANGED
@@ -56,6 +56,9 @@ import { homedir } from 'node:os';
56
56
  import { join } from 'node:path';
57
57
  import { decodeMcpAllowlistRecord, decodeMcpRegistryRecord, MCP_ALLOWLIST_RECORD_TAG, MCP_REGISTRY_RECORD_TAG, } from './mcpRegistryRecord.js';
58
58
  import { decodeSsoGroupRecord, SSO_GROUP_RECORD_TAG } from './ssoGroups.js';
59
+ import { decideRuleHash, validateDecideRule } from './decide.js';
60
+ import { DECIDE_FALLBACK_PREFIX, DECIDE_RECORD_TAG, decodeDecideRecord, decodeSnapshotFormatRecord, SNAPSHOT_FORMAT_RECORD_TAG, } from './decideRecord.js';
61
+ import { decodeGateRuleRecord, RULE_RECORD_TAG } from './gateRuleRecord.js';
59
62
  import { INTERVENTION_MODE_RECORD_TAG, isOpaqueInterventionModeRecord } from './opaqueRefusal.js';
60
63
  import { hasPhrase, phraseText } from './phrases.js';
61
64
  import { classify } from './actions.js';
@@ -107,6 +110,25 @@ export class Snapshot {
107
110
  * check, since it only ever hides text and never allows a call.
108
111
  */
109
112
  opaque = false;
113
+ /** The snapshot format its `@format` record names; 1 without one. */
114
+ formatVersion = 1;
115
+ /**
116
+ * The decide rules whose `@decide` records decoded, rule and hash checked,
117
+ * in snapshot order. Each one's fallback line is skipped only for a caller
118
+ * that evaluates decide rules ({@link LoadSnapshotOptions}); a record that
119
+ * does not decode is not here, and its fallback line refuses. Empty on a
120
+ * snapshot that fails its integrity check.
121
+ */
122
+ decideRules = [];
123
+ /**
124
+ * The rule records (`@rule`) that decoded, in snapshot order:
125
+ * qualified prerequisites, enforced scopes and plan approval, which Tier R
126
+ * evaluates. Each one's fallback line is skipped only for a caller that
127
+ * evaluates rule records ({@link LoadSnapshotOptions}); a record that does
128
+ * not decode is not here, and its fallback line refuses. Empty on a
129
+ * snapshot that fails its integrity check.
130
+ */
131
+ ruleRecords = [];
110
132
  get healthMessage() {
111
133
  switch (this.state) {
112
134
  case 'absent':
@@ -122,6 +144,11 @@ export class Snapshot {
122
144
  }
123
145
  }
124
146
  }
147
+ /** A decide record's rule: its hash when it is valid. */
148
+ function checkDecideRule(ir) {
149
+ const v = validateDecideRule(ir);
150
+ return v.ok ? decideRuleHash(v.rule, (t) => createHash('sha256').update(t, 'utf-8').digest('hex')) : null;
151
+ }
125
152
  function allow() {
126
153
  return { severity: null, reason: '', ruleId: '' };
127
154
  }
@@ -146,7 +173,7 @@ function normalise(value) {
146
173
  * was compiled for a workspace other than a non-empty `workspaceId`, is
147
174
  * `'invalid'`: its rules and MCP records are dropped.
148
175
  */
149
- export function loadSnapshot(workspaceId = '', path) {
176
+ export function loadSnapshot(workspaceId = '', path, opts = {}) {
150
177
  const p = path ?? snapshotPath();
151
178
  const snap = new Snapshot();
152
179
  let text;
@@ -188,6 +215,22 @@ export function loadSnapshot(workspaceId = '', path) {
188
215
  snap.opaque = isOpaqueInterventionModeRecord(line);
189
216
  continue;
190
217
  }
218
+ if (line.startsWith(`${SNAPSHOT_FORMAT_RECORD_TAG}\t`)) {
219
+ snap.formatVersion = decodeSnapshotFormatRecord(line) ?? snap.formatVersion;
220
+ continue;
221
+ }
222
+ if (line.startsWith(`${DECIDE_RECORD_TAG}\t`)) {
223
+ const record = decodeDecideRecord(line, checkDecideRule);
224
+ if (record)
225
+ snap.decideRules.push(record);
226
+ continue;
227
+ }
228
+ if (line.startsWith(`${RULE_RECORD_TAG}\t`)) {
229
+ const record = decodeGateRuleRecord(line);
230
+ if (record)
231
+ snap.ruleRecords.push(record);
232
+ continue;
233
+ }
191
234
  const f = line.split('\t');
192
235
  // Column order: id, severity, flags, subject, reason, source(regex), [argPatternB64].
193
236
  // Flags: i = case-insensitive, s = a sequence rule.
@@ -208,6 +251,28 @@ export function loadSnapshot(workspaceId = '', path) {
208
251
  snap.droppedRules += 1;
209
252
  }
210
253
  }
254
+ // A fallback line stands in for a decide rule a gate cannot evaluate. A
255
+ // caller that evaluates the rule from its record skips the line, but only
256
+ // when that record decoded: any other line with the prefix is enforced.
257
+ if (opts.evaluatesDecide === true && snap.decideRules.length > 0) {
258
+ const skip = new Set(snap.decideRules.map((r) => r.fallbackId));
259
+ snap.rules = snap.rules.filter((r) => !r.id.startsWith(DECIDE_FALLBACK_PREFIX) || !skip.has(r.id));
260
+ }
261
+ // The same for a rule record's fallback line: skipped only for a caller
262
+ // that evaluates rule records, and only when a record that decoded names it.
263
+ if (opts.evaluatesRules === true && snap.ruleRecords.length > 0) {
264
+ const skip = new Set(snap.ruleRecords.map((r) => r.fallbackId).filter((id) => id !== null));
265
+ snap.rules = snap.rules.filter((r) => !skip.has(r.id));
266
+ }
267
+ // A hold token's rules share one id (laneHoldPatterns, lanes.ts): a phrase
268
+ // rule a gate whose classifier predates the token holds by, and for
269
+ // force_push and destroy an action rule. This classifier knows every
270
+ // token, so it holds by the action rule alone: the partial phrase
271
+ // "git push --force" also matches --force-with-lease, which is no force
272
+ // push. One id, so one approval releases the call whichever gate held it.
273
+ const actionIds = new Set(snap.rules.filter((r) => r.subject === 'action').map((r) => r.id));
274
+ if (actionIds.size > 0)
275
+ snap.rules = snap.rules.filter((r) => r.subject !== 'phrase' || !actionIds.has(r.id));
211
276
  // Integrity. A digest nobody recomputes is a comment; a workspace id nobody
212
277
  // compares means workspace A's rules get enforced on B's machine and B's
213
278
  // events attribute A's policy to B.
@@ -238,6 +303,9 @@ export function loadSnapshot(workspaceId = '', path) {
238
303
  // Neither MCP record can be vouched for: the gate admits no MCP server.
239
304
  snap.mcpRegistry = null;
240
305
  snap.mcpAllowlist = null;
306
+ // The decide records go with the rest of the dynamic tier.
307
+ snap.decideRules = [];
308
+ snap.ruleRecords = [];
241
309
  }
242
310
  if (snap.state === 'ok' && snap.generatedAt) {
243
311
  const t = Date.parse(snap.generatedAt);
@@ -250,8 +318,13 @@ export function loadSnapshot(workspaceId = '', path) {
250
318
  }
251
319
  return snap;
252
320
  }
253
- /** Evaluate one tool call against the snapshot. First match wins. */
254
- export function evaluate(toolName, target, command, snap, guardDisabled = false) {
321
+ /**
322
+ * Evaluate one tool call against the snapshot, as the rendered gates do: a
323
+ * shadow or warn match is collected and evaluation continues, so a later block
324
+ * or hold still decides the call. The first block or hold wins. With none, the
325
+ * first advisory match is returned. `from` resumes after an approved hold.
326
+ */
327
+ export function evaluate(toolName, target, command, snap, guardDisabled = false, from = 0) {
255
328
  let rules = snap.rules;
256
329
  if (guardDisabled) {
257
330
  // Only the destructive family is skippable. The alternative a blocked
@@ -267,7 +340,9 @@ export function evaluate(toolName, target, command, snap, guardDisabled = false)
267
340
  // a hold on `action:deploy` matches whole tokens. Classified with the same
268
341
  // needles and phrase matcher as the hook gates and the proxy's actions.rs.
269
342
  let actions = null;
270
- for (const rule of rules) {
343
+ const advisories = [];
344
+ for (let i = from; i < rules.length; i++) {
345
+ const rule = rules[i];
271
346
  if (rule.subject === 'phrase') {
272
347
  // The source is `|`-separated phrases matched as words against the raw
273
348
  // command (phrases.ts), not a regex: a backtracking regex for "whatever
@@ -294,26 +369,24 @@ export function evaluate(toolName, target, command, snap, guardDisabled = false)
294
369
  if (rule.subject !== 'phrase' && !(rule.steps ? sequenceMatch(rule.steps, subject) : rule.pattern.test(subject)))
295
370
  continue;
296
371
  if (rule.severity === SEV_SHADOW) {
297
- return { severity: SEV_SHADOW, reason: `${rule.reason} [${rule.id}]`, ruleId: rule.id };
372
+ advisories.push({ severity: SEV_SHADOW, reason: `${rule.reason} [${rule.id}]`, ruleId: rule.id });
373
+ break;
298
374
  }
299
375
  if (rule.severity === SEV_WARN) {
300
376
  const verb = nCommand.trim().split(' ')[0] ?? '';
301
- return {
302
- severity: SEV_WARN,
303
- reason: `${rule.reason} [${rule.id}] verb=${verb}`,
304
- ruleId: rule.id,
305
- };
377
+ advisories.push({ severity: SEV_WARN, reason: `${rule.reason} [${rule.id}] verb=${verb}`, ruleId: rule.id });
378
+ break;
306
379
  }
307
380
  if (rule.severity === SEV_HOLD) {
308
- return { severity: SEV_HOLD, reason: rule.reason, ruleId: rule.id };
381
+ return { severity: SEV_HOLD, reason: rule.reason, ruleId: rule.id, advisories, next: i + 1 };
309
382
  }
310
383
  // Any other severity blocks, as an unknown one does in the shipped
311
384
  // gates: a severity this reader does not know must not allow. The
312
385
  // rule's own reason, not a generic one — resolveSeverity reads it.
313
- return { severity: SEV_BLOCK, reason: `${rule.reason} [${rule.id}]`, ruleId: rule.id };
386
+ return { severity: SEV_BLOCK, reason: `${rule.reason} [${rule.id}]`, ruleId: rule.id, advisories, next: i + 1 };
314
387
  }
315
388
  }
316
- return allow();
389
+ return advisories.length > 0 ? { ...advisories[0], advisories } : allow();
317
390
  }
318
391
  export function guardDisabledFromEnv() {
319
392
  return process.env.INTUTIC_GUARD_DISABLE === '1';
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Did the tests pass? The deciding function behind the qualified ordering
3
+ * rule `requires_before: action:run_tests[ok] -> action:deploy`, and the
4
+ * per-session state the gates keep of it.
5
+ *
6
+ * {@link decideTestOutcome} reads what a surface saw of one test run (an exit
7
+ * code, an error flag, a success flag, the output) and says `ok`, `failed` or
8
+ * `unknown`, in this order:
9
+ *
10
+ * 1. an integer exit code other than 0, `isError === true` or
11
+ * `success === false`: failed;
12
+ * 2. any runner summary in the output that reports failures or errors: failed;
13
+ * 3. a summary that says no tests ran (`no tests ran`, `0 passed`, `0 total`,
14
+ * `0 passing`, `0 examples`) while no summary counts a pass: failed
15
+ * (`no_tests`);
16
+ * 4. exit code 0: ok;
17
+ * 5. no exit code, and at least one summary counts a pass: ok;
18
+ * 6. anything else: unknown.
19
+ *
20
+ * Unknown leaves a qualified rule unmet, as a failure does: a result that
21
+ * cannot be read is not a pass.
22
+ *
23
+ * {@link extractExitCode} reads an exit code out of text, for a surface that
24
+ * reports only text (Codex's JSON shell output, Claude Code's `Exit code N`
25
+ * error results, `exit status N`, `Process exited with code N`).
26
+ *
27
+ * Runner summaries are read line by line from the last
28
+ * {@link TEST_OUTPUT_TAIL_BYTES} bytes of the output, each line cut to
29
+ * {@link TEST_OUTPUT_LINE_BYTES} bytes, carriage returns and ANSI colour
30
+ * sequences removed. Every pattern is anchored and has no nested quantifier;
31
+ * a summary's counts are read by splitting it, not by a regex, so the whole
32
+ * read is linear in the output.
33
+ *
34
+ * The outcome state ({@link OutcomeState}) is what a gate keeps per session:
35
+ * the latest outcome per outcome token, with when it was recorded, whether a
36
+ * file changed after it (a pass describes the code it ran
37
+ * against, so a later write makes it stale), and whether any other call
38
+ * completed after it (for `~>`).
39
+ *
40
+ * Self-contained (no imports, no module state the emitted source does not
41
+ * carry) so `@intutic/gate` keeps a byte-identical copy and the JavaScript
42
+ * hook gates embed {@link TEST_OUTCOME_JS_SOURCE}. The Python port is
43
+ * `intutic_clawde/gate/test_outcome.py`, the Rust one
44
+ * `packages/proxy/src/plugins/anomaly/outcome.rs`; all of them run
45
+ * `fixtures/test-outcome-vectors.json`.
46
+ *
47
+ * @module
48
+ */
49
+ /** The tokens a `[ok]` qualifier may stand on. */
50
+ export declare const OUTCOME_TOKENS: readonly ["action:run_tests"];
51
+ /** The qualifiers there are. */
52
+ export declare const OUTCOME_QUALIFIERS: readonly ["ok"];
53
+ /** The one qualified token there is. */
54
+ export declare const QUALIFIED_TOKEN_RE: RegExp;
55
+ /** How much of a run's output the summaries are read from: its last 64 KiB. */
56
+ export declare const TEST_OUTPUT_TAIL_BYTES = 65536;
57
+ /** Each line is cut to this many bytes before it is matched. */
58
+ export declare const TEST_OUTPUT_LINE_BYTES = 1024;
59
+ /** The longest output whose JSON form is parsed for an exit code. */
60
+ export declare const TEST_OUTPUT_JSON_MAX_CHARS = 1048576;
61
+ /** An outcome older than this is ignored: a day. */
62
+ export declare const OUTCOME_STATE_TTL_MS = 86400000;
63
+ export type TestOutcome = 'ok' | 'failed' | 'unknown';
64
+ /** Why {@link decideTestOutcome} said what it said, by the step that decided. */
65
+ export type TestOutcomeWhy = 'exit_code' | 'is_error' | 'success_false' | 'summary_failed' | 'no_tests' | 'exit_zero' | 'summary_passed' | 'no_signal';
66
+ export interface TestOutcomeInput {
67
+ exitCode?: number | null;
68
+ isError?: boolean | null;
69
+ success?: boolean | null;
70
+ output?: string | null;
71
+ }
72
+ export interface TestOutcomeDecision {
73
+ outcome: TestOutcome;
74
+ why: TestOutcomeWhy;
75
+ }
76
+ /** One runner's summary: its counts, and whether it said no tests ran. */
77
+ export interface TestRunnerSummary {
78
+ runner: 'pytest' | 'jest' | 'vitest' | 'go' | 'cargo' | 'mocha' | 'rspec';
79
+ passed: number;
80
+ /** Failures and errors together. */
81
+ failed: number;
82
+ noTests: boolean;
83
+ }
84
+ /**
85
+ * The exit code a run's text reports, or null. A whole-output JSON object
86
+ * with `metadata.exit_code`, else `exit_code`, else `exitCode`; otherwise the
87
+ * first line, of the first 64 KiB then the last 64 KiB, that is
88
+ * `Exit code N` / `Exit code: N` (any case), `exit status N`, or begins
89
+ * `Process exited with code N` / `Command exited with code N`.
90
+ */
91
+ export declare function extractExitCode(output: string | null | undefined): number | null;
92
+ /** The runner summaries in the last 64 KiB of `output`, in the order they appear (go and mocha folded into one each). */
93
+ export declare function parseTestSummaries(output: string | null | undefined): TestRunnerSummary[];
94
+ /** The outcome of one test run. See the module doc for the steps. */
95
+ export declare function decideTestOutcome(input: TestOutcomeInput): TestOutcomeDecision;
96
+ /**
97
+ * Why one side of an ordering rule cannot carry the qualifier it carries, or
98
+ * null when it is fine. A side carries a qualifier when it holds `[` or `]`;
99
+ * only `action:run_tests[ok]`, on the left of the arrow, is one. The error
100
+ * names the side as written, quoted as the parser quotes it.
101
+ */
102
+ export declare function orderingQualifierError(side: string, left: boolean): string | null;
103
+ /** `action:run_tests[ok]` as `{ token: 'action:run_tests', qualifier: 'ok' }`; any other token unqualified. */
104
+ export declare function splitQualifier(token: string): {
105
+ token: string;
106
+ qualifier: 'ok' | null;
107
+ };
108
+ /** The latest outcome of one token in a session. */
109
+ export interface OutcomeEntry {
110
+ o: TestOutcome;
111
+ /** Epoch milliseconds. */
112
+ at: number;
113
+ /** Why `o` is what it is ({@link TestOutcomeWhy}). */
114
+ why?: string;
115
+ /** A file changed after the run: a pass no longer counts. */
116
+ changed?: true;
117
+ /** Another call completed after the run: it is not adjacent to the next one. */
118
+ later?: true;
119
+ }
120
+ /** `~/.intutic/hooks/state/outcomes/<key>.json`, and a gate SDK's memory. */
121
+ export interface OutcomeState {
122
+ v: 1;
123
+ outcomes: Record<string, OutcomeEntry>;
124
+ }
125
+ /** A state with nothing in it. */
126
+ export declare function emptyOutcomeState(): OutcomeState;
127
+ /** The state file's name for one session: the first 32 hex of sha256(harness NUL sessionId), and `.json`. */
128
+ export declare function outcomeStateFileName(harness: string, sessionId: string, sha256Hex: (text: string) => string): string;
129
+ /** A state file's text as a state, or null when it is not one: a damaged file is no state, which leaves every rule unmet. */
130
+ export declare function parseOutcomeState(text: string): OutcomeState | null;
131
+ /** `state` with `token`'s outcome replaced by this run's. */
132
+ export declare function recordTestOutcome(state: OutcomeState, token: string, decision: TestOutcomeDecision, atMs: number): OutcomeState;
133
+ /**
134
+ * `state` after another call completed: every entry is no longer adjacent to
135
+ * what comes next, and when the call changed a file (`changedFiles`), a pass
136
+ * before it no longer counts.
137
+ */
138
+ export declare function noteCompletedCall(state: OutcomeState, changedFiles: boolean): OutcomeState;
139
+ /** Why a qualified prerequisite is unmet, or `met`. */
140
+ export type PrerequisiteCase = 'met' | 'none' | 'failed' | 'unknown' | 'changed' | 'not_adjacent' | 'not_observable' | 'no_session';
141
+ /**
142
+ * Whether `token`'s latest outcome in `state` meets a qualified rule now:
143
+ * `met` only for an `ok` younger than {@link OUTCOME_STATE_TTL_MS} that no
144
+ * file change followed (and, for `~>`, that no other call followed). A null
145
+ * state (none, or unreadable) is `none`.
146
+ */
147
+ export declare function prerequisiteCase(state: OutcomeState | null, token: string, adjacent: boolean, nowMs: number): {
148
+ case: PrerequisiteCase;
149
+ why: string | null;
150
+ };
151
+ /**
152
+ * The reason a refusal (`PREREQUISITE_UNMET`) gives, for every case but
153
+ * `met`. `harness` names the surface for `not_observable` and `no_session`.
154
+ * Byte-stable: every port answers with these exact words.
155
+ */
156
+ export declare function prerequisiteUnmetReason(first: string, then: string, c: PrerequisiteCase, why: string | null, harness: string): string;
157
+ /**
158
+ * The functions above as JavaScript source, for the hook gates to embed: the
159
+ * gates run this exact code. A CommonJS build names an exported function
160
+ * `exports.X` inside another; the source defines each as a plain `X`, so that
161
+ * prefix is dropped.
162
+ */
163
+ export declare const TEST_OUTCOME_JS_SOURCE: string;
164
+ //# sourceMappingURL=testOutcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testOutcome.d.ts","sourceRoot":"","sources":["../src/testOutcome.ts"],"names":[],"mappings":"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"}