veto-sdk 1.17.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.md +69 -203
  2. package/dist/browser/index.d.ts +1 -1
  3. package/dist/browser/index.d.ts.map +1 -1
  4. package/dist/browser/index.js.map +1 -1
  5. package/dist/browser/types.d.ts +17 -1
  6. package/dist/browser/types.d.ts.map +1 -1
  7. package/dist/browser/veto.d.ts +10 -0
  8. package/dist/browser/veto.d.ts.map +1 -1
  9. package/dist/browser/veto.js +69 -5
  10. package/dist/browser/veto.js.map +1 -1
  11. package/dist/cli/bin.js +0 -0
  12. package/dist/cli/compile.d.ts +22 -1
  13. package/dist/cli/compile.d.ts.map +1 -1
  14. package/dist/cli/compile.js +100 -21
  15. package/dist/cli/compile.js.map +1 -1
  16. package/dist/cli/diff.d.ts +2 -25
  17. package/dist/cli/diff.d.ts.map +1 -1
  18. package/dist/cli/diff.js +5 -327
  19. package/dist/cli/diff.js.map +1 -1
  20. package/dist/cli/headless.js +1 -1
  21. package/dist/cli/headless.js.map +1 -1
  22. package/dist/cli/index.d.ts +3 -1
  23. package/dist/cli/index.d.ts.map +1 -1
  24. package/dist/cli/index.js +2 -0
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/repl-generate.d.ts.map +1 -1
  27. package/dist/cli/repl-generate.js +346 -17
  28. package/dist/cli/repl-generate.js.map +1 -1
  29. package/dist/cli/replay-engine.d.ts +77 -0
  30. package/dist/cli/replay-engine.d.ts.map +1 -0
  31. package/dist/cli/replay-engine.js +379 -0
  32. package/dist/cli/replay-engine.js.map +1 -0
  33. package/dist/cli/replay.d.ts +57 -0
  34. package/dist/cli/replay.d.ts.map +1 -0
  35. package/dist/cli/replay.js +202 -0
  36. package/dist/cli/replay.js.map +1 -0
  37. package/dist/cli/runner.d.ts.map +1 -1
  38. package/dist/cli/runner.js +20 -0
  39. package/dist/cli/runner.js.map +1 -1
  40. package/dist/cli/templates.d.ts +1 -1
  41. package/dist/cli/templates.d.ts.map +1 -1
  42. package/dist/cli/templates.js +1 -1
  43. package/dist/cloud/client.d.ts.map +1 -1
  44. package/dist/cloud/client.js +6 -1
  45. package/dist/cloud/client.js.map +1 -1
  46. package/dist/cloud/types.d.ts +33 -2
  47. package/dist/cloud/types.d.ts.map +1 -1
  48. package/dist/core/events.d.ts +11 -1
  49. package/dist/core/events.d.ts.map +1 -1
  50. package/dist/core/events.js +4 -0
  51. package/dist/core/events.js.map +1 -1
  52. package/dist/core/interceptor.d.ts +20 -1
  53. package/dist/core/interceptor.d.ts.map +1 -1
  54. package/dist/core/interceptor.js +47 -3
  55. package/dist/core/interceptor.js.map +1 -1
  56. package/dist/core/output-validator.d.ts +11 -0
  57. package/dist/core/output-validator.d.ts.map +1 -1
  58. package/dist/core/output-validator.js +88 -15
  59. package/dist/core/output-validator.js.map +1 -1
  60. package/dist/core/protect.d.ts +3 -1
  61. package/dist/core/protect.d.ts.map +1 -1
  62. package/dist/core/protect.js +14 -4
  63. package/dist/core/protect.js.map +1 -1
  64. package/dist/core/veto.d.ts +54 -1
  65. package/dist/core/veto.d.ts.map +1 -1
  66. package/dist/core/veto.js +471 -91
  67. package/dist/core/veto.js.map +1 -1
  68. package/dist/deterministic/types.d.ts +103 -0
  69. package/dist/deterministic/types.d.ts.map +1 -1
  70. package/dist/economic/budget-engine.d.ts +29 -0
  71. package/dist/economic/budget-engine.d.ts.map +1 -0
  72. package/dist/economic/budget-engine.js +146 -0
  73. package/dist/economic/budget-engine.js.map +1 -0
  74. package/dist/economic/connectors/ap2.d.ts +51 -0
  75. package/dist/economic/connectors/ap2.d.ts.map +1 -0
  76. package/dist/economic/connectors/ap2.js +133 -0
  77. package/dist/economic/connectors/ap2.js.map +1 -0
  78. package/dist/economic/connectors/index.d.ts +8 -0
  79. package/dist/economic/connectors/index.d.ts.map +1 -0
  80. package/dist/economic/connectors/index.js +8 -0
  81. package/dist/economic/connectors/index.js.map +1 -0
  82. package/dist/economic/connectors/mpp.d.ts +41 -0
  83. package/dist/economic/connectors/mpp.d.ts.map +1 -0
  84. package/dist/economic/connectors/mpp.js +97 -0
  85. package/dist/economic/connectors/mpp.js.map +1 -0
  86. package/dist/economic/connectors/x402.d.ts +20 -0
  87. package/dist/economic/connectors/x402.d.ts.map +1 -0
  88. package/dist/economic/connectors/x402.js +142 -0
  89. package/dist/economic/connectors/x402.js.map +1 -0
  90. package/dist/economic/evaluator.d.ts +77 -0
  91. package/dist/economic/evaluator.d.ts.map +1 -0
  92. package/dist/economic/evaluator.js +231 -0
  93. package/dist/economic/evaluator.js.map +1 -0
  94. package/dist/economic/index.d.ts +13 -0
  95. package/dist/economic/index.d.ts.map +1 -0
  96. package/dist/economic/index.js +15 -0
  97. package/dist/economic/index.js.map +1 -0
  98. package/dist/economic/types.d.ts +188 -0
  99. package/dist/economic/types.d.ts.map +1 -0
  100. package/dist/economic/types.js +10 -0
  101. package/dist/economic/types.js.map +1 -0
  102. package/dist/extractors/content.d.ts +42 -0
  103. package/dist/extractors/content.d.ts.map +1 -0
  104. package/dist/extractors/content.js +154 -0
  105. package/dist/extractors/content.js.map +1 -0
  106. package/dist/extractors/index.d.ts +7 -0
  107. package/dist/extractors/index.d.ts.map +1 -0
  108. package/dist/extractors/index.js +7 -0
  109. package/dist/extractors/index.js.map +1 -0
  110. package/dist/index.d.ts +10 -4
  111. package/dist/index.d.ts.map +1 -1
  112. package/dist/index.js +10 -2
  113. package/dist/index.js.map +1 -1
  114. package/dist/policy/generator.d.ts +110 -0
  115. package/dist/policy/generator.d.ts.map +1 -0
  116. package/dist/policy/generator.js +463 -0
  117. package/dist/policy/generator.js.map +1 -0
  118. package/dist/policy/index.d.ts +7 -0
  119. package/dist/policy/index.d.ts.map +1 -0
  120. package/dist/policy/index.js +7 -0
  121. package/dist/policy/index.js.map +1 -0
  122. package/dist/providers/adapters.d.ts +27 -0
  123. package/dist/providers/adapters.d.ts.map +1 -1
  124. package/dist/providers/adapters.js +58 -0
  125. package/dist/providers/adapters.js.map +1 -1
  126. package/dist/rules/condition-evaluator.d.ts +2 -1
  127. package/dist/rules/condition-evaluator.d.ts.map +1 -1
  128. package/dist/rules/condition-evaluator.js +97 -7
  129. package/dist/rules/condition-evaluator.js.map +1 -1
  130. package/dist/rules/index.d.ts +1 -0
  131. package/dist/rules/index.d.ts.map +1 -1
  132. package/dist/rules/index.js +1 -0
  133. package/dist/rules/index.js.map +1 -1
  134. package/dist/rules/local-evaluator.d.ts +69 -0
  135. package/dist/rules/local-evaluator.d.ts.map +1 -0
  136. package/dist/rules/local-evaluator.js +217 -0
  137. package/dist/rules/local-evaluator.js.map +1 -0
  138. package/dist/rules/policy-ir-schema.d.ts +132 -1
  139. package/dist/rules/policy-ir-schema.d.ts.map +1 -1
  140. package/dist/rules/policy-ir-schema.js +114 -0
  141. package/dist/rules/policy-ir-schema.js.map +1 -1
  142. package/dist/rules/policy-packs.d.ts.map +1 -1
  143. package/dist/rules/policy-packs.js +1 -0
  144. package/dist/rules/policy-packs.js.map +1 -1
  145. package/dist/rules/types.d.ts +3 -1
  146. package/dist/rules/types.d.ts.map +1 -1
  147. package/dist/rules/types.js.map +1 -1
  148. package/dist/types/config.d.ts +2 -1
  149. package/dist/types/config.d.ts.map +1 -1
  150. package/dist/types/config.js.map +1 -1
  151. package/dist/utils/logger.d.ts +38 -2
  152. package/dist/utils/logger.d.ts.map +1 -1
  153. package/dist/utils/logger.js +231 -26
  154. package/dist/utils/logger.js.map +1 -1
  155. package/package.json +9 -1
  156. package/packs/economic-agent.yaml +62 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Shared replay engine used by both `replay` and `diff` commands.
3
+ *
4
+ * Pure deterministic evaluation — no LLM calls, no cloud calls, no network.
5
+ *
6
+ * @module cli/replay-engine
7
+ */
8
+ import { type ASTNode } from '../compiler/index.js';
9
+ import { RuleLoader } from '../rules/loader.js';
10
+ import type { Rule } from '../rules/types.js';
11
+ type RuleDecision = 'allow' | 'deny' | 'require_approval';
12
+ type SnapshotKind = 'file' | 'directory' | 'git-file';
13
+ export interface PolicySnapshot {
14
+ kind: SnapshotKind;
15
+ source: string;
16
+ rules: Rule[];
17
+ rulesByTool: Map<string, Rule[]>;
18
+ globalRules: Rule[];
19
+ }
20
+ export interface ReplaySnapshot {
21
+ globalRules: Rule[];
22
+ rulesByTool: Map<string, Rule[]>;
23
+ }
24
+ export interface ReplayCall {
25
+ index: number;
26
+ line: number;
27
+ tool: string;
28
+ arguments: Record<string, unknown>;
29
+ timestamp: string;
30
+ decision?: RuleDecision;
31
+ ruleId?: string;
32
+ sessionId?: string;
33
+ agentId?: string;
34
+ userId?: string;
35
+ role?: string;
36
+ custom?: Record<string, unknown>;
37
+ }
38
+ export interface ReplayDecision {
39
+ decision: RuleDecision;
40
+ ruleId?: string;
41
+ ruleName?: string;
42
+ reason?: string;
43
+ }
44
+ export interface ReplayHistoryEntry {
45
+ toolName: string;
46
+ arguments: Record<string, unknown>;
47
+ decision: RuleDecision;
48
+ timestamp: Date;
49
+ }
50
+ export interface ParsedReplayLog {
51
+ calls: ReplayCall[];
52
+ totalLines: number;
53
+ invalidLines: number;
54
+ invalidLineNumbers: number[];
55
+ }
56
+ export interface DecisionCounts {
57
+ allow: number;
58
+ deny: number;
59
+ require_approval: number;
60
+ }
61
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
62
+ export declare function normalizeOptionalString(value: unknown): string | undefined;
63
+ export declare function normalizeTimestamp(raw: unknown): string | null;
64
+ export declare function parseReplayLog(logPath: string): ParsedReplayLog;
65
+ export declare function parseReplayLogContent(content: string, sourceName?: string): ParsedReplayLog;
66
+ export declare function evaluateExpressionSafely(expression: string, context: Record<string, unknown>, cache: Map<string, ASTNode>): boolean;
67
+ export declare function matchesReplayRule(rule: Rule, call: ReplayCall, history: readonly ReplayHistoryEntry[], expressionCache: Map<string, ASTNode>): boolean;
68
+ export declare function buildReplaySnapshot(snapshot: PolicySnapshot): ReplaySnapshot;
69
+ export declare function decideReplayCall(replaySnapshot: ReplaySnapshot, call: ReplayCall, history: readonly ReplayHistoryEntry[], expressionCache: Map<string, ASTNode>): ReplayDecision;
70
+ export declare function replayCalls(snapshot: PolicySnapshot, calls: readonly ReplayCall[]): ReplayDecision[];
71
+ export declare function countDecisions(decisions: readonly ReplayDecision[]): DecisionCounts;
72
+ export declare function createRuleLoader(): RuleLoader;
73
+ export declare function getPathType(inputPath: string): 'file' | 'directory';
74
+ export declare function createSnapshotFromLoader(kind: SnapshotKind, source: string, loader: RuleLoader): PolicySnapshot;
75
+ export declare function loadPolicySnapshot(inputPath: string): PolicySnapshot;
76
+ export {};
77
+ //# sourceMappingURL=replay-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-engine.d.ts","sourceRoot":"","sources":["../../src/cli/replay-engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAA0C,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAO9C,KAAK,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,kBAAkB,CAAC;AAC1D,KAAK,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACjC,WAAW,EAAE,IAAI,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,IAAI,EAAE,CAAC;IACpB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAYD,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAK9E;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAM1E;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAS9D;AAMD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAO/D;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,SAAW,GAAG,eAAe,CAuF7F;AAMD,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAC1B,OAAO,CAgBT;AA8GD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,OAAO,CAwBT;AAMD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,cAAc,CAe5E;AAED,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,cAAc,EAC9B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,cAAc,CAwDhB;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,cAAc,EAAE,CAmBpG;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,GAAG,cAAc,CAYnF;AAMD,wBAAgB,gBAAgB,IAAI,UAAU,CAI7C;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAUnE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,cAAc,CAe/G;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAapE"}
@@ -0,0 +1,379 @@
1
+ /**
2
+ * Shared replay engine used by both `replay` and `diff` commands.
3
+ *
4
+ * Pure deterministic evaluation — no LLM calls, no cloud calls, no network.
5
+ *
6
+ * @module cli/replay-engine
7
+ */
8
+ import { existsSync, readFileSync, statSync } from 'node:fs';
9
+ import { resolve } from 'node:path';
10
+ import { parse as parseYaml } from 'yaml';
11
+ import { compile as compileExpression, evaluate } from '../compiler/index.js';
12
+ import { RuleLoader } from '../rules/loader.js';
13
+ import { evaluateConditionCollections } from '../rules/condition-evaluator.js';
14
+ import { silentLogger } from '../utils/logger.js';
15
+ // ---------------------------------------------------------------------------
16
+ // Constants
17
+ // ---------------------------------------------------------------------------
18
+ const DEFAULT_SYNTHETIC_BASE_MS = Date.parse('2000-01-01T00:00:00.000Z');
19
+ // ---------------------------------------------------------------------------
20
+ // Helpers
21
+ // ---------------------------------------------------------------------------
22
+ export function isPlainObject(value) {
23
+ return Boolean(value)
24
+ && typeof value === 'object'
25
+ && !Array.isArray(value)
26
+ && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
27
+ }
28
+ export function normalizeOptionalString(value) {
29
+ if (typeof value !== 'string') {
30
+ return undefined;
31
+ }
32
+ const trimmed = value.trim();
33
+ return trimmed.length > 0 ? trimmed : undefined;
34
+ }
35
+ export function normalizeTimestamp(raw) {
36
+ if (raw instanceof Date) {
37
+ return Number.isNaN(raw.getTime()) ? null : raw.toISOString();
38
+ }
39
+ if (typeof raw === 'string' || typeof raw === 'number') {
40
+ const parsed = new Date(raw);
41
+ return Number.isNaN(parsed.getTime()) ? null : parsed.toISOString();
42
+ }
43
+ return null;
44
+ }
45
+ // ---------------------------------------------------------------------------
46
+ // Log parsing
47
+ // ---------------------------------------------------------------------------
48
+ export function parseReplayLog(logPath) {
49
+ if (!existsSync(logPath)) {
50
+ throw new Error(`Log file not found: ${logPath}`);
51
+ }
52
+ const content = readFileSync(logPath, 'utf-8');
53
+ return parseReplayLogContent(content, logPath);
54
+ }
55
+ export function parseReplayLogContent(content, sourceName = 'inline') {
56
+ const lines = content.split(/\r?\n/);
57
+ const calls = [];
58
+ const invalidLineNumbers = [];
59
+ let totalLines = 0;
60
+ let syntheticCounter = 0;
61
+ for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
62
+ const lineNumber = lineIndex + 1;
63
+ const rawLine = lines[lineIndex].trim();
64
+ if (!rawLine) {
65
+ continue;
66
+ }
67
+ totalLines += 1;
68
+ let parsed;
69
+ try {
70
+ parsed = JSON.parse(rawLine);
71
+ }
72
+ catch {
73
+ invalidLineNumbers.push(lineNumber);
74
+ continue;
75
+ }
76
+ if (!isPlainObject(parsed)) {
77
+ invalidLineNumbers.push(lineNumber);
78
+ continue;
79
+ }
80
+ const tool = normalizeOptionalString(parsed.toolName ?? parsed.tool_name ?? parsed.tool ?? parsed.name);
81
+ const argumentsValue = parsed.arguments ?? parsed.args;
82
+ if (!tool || !isPlainObject(argumentsValue)) {
83
+ invalidLineNumbers.push(lineNumber);
84
+ continue;
85
+ }
86
+ let timestamp = normalizeTimestamp(parsed.timestamp);
87
+ if (!timestamp) {
88
+ if (parsed.timestamp === undefined) {
89
+ timestamp = new Date(DEFAULT_SYNTHETIC_BASE_MS + (syntheticCounter * 1000)).toISOString();
90
+ syntheticCounter += 1;
91
+ }
92
+ else {
93
+ invalidLineNumbers.push(lineNumber);
94
+ continue;
95
+ }
96
+ }
97
+ // Parse optional original decision for replay comparison
98
+ const rawDecision = normalizeOptionalString(parsed.decision);
99
+ const decision = (rawDecision === 'allow' || rawDecision === 'deny' || rawDecision === 'require_approval')
100
+ ? rawDecision
101
+ : undefined;
102
+ calls.push({
103
+ index: calls.length + 1,
104
+ line: lineNumber,
105
+ tool,
106
+ arguments: argumentsValue,
107
+ timestamp,
108
+ decision,
109
+ ruleId: normalizeOptionalString(parsed.ruleId ?? parsed.rule_id),
110
+ sessionId: normalizeOptionalString(parsed.sessionId ?? parsed.session_id),
111
+ agentId: normalizeOptionalString(parsed.agentId ?? parsed.agent_id),
112
+ userId: normalizeOptionalString(parsed.userId ?? parsed.user_id),
113
+ role: normalizeOptionalString(parsed.role),
114
+ custom: isPlainObject(parsed.custom) ? parsed.custom : undefined,
115
+ });
116
+ }
117
+ if (calls.length === 0) {
118
+ const detail = invalidLineNumbers.length > 0
119
+ ? ` (${invalidLineNumbers.length} invalid line${invalidLineNumbers.length > 1 ? 's' : ''}: ${invalidLineNumbers.slice(0, 10).join(', ')}${invalidLineNumbers.length > 10 ? ', ...' : ''} — missing required 'toolName'/'tool' and 'arguments'/'args' fields)`
120
+ : '';
121
+ throw new Error(`No valid replay calls found in: ${sourceName}${detail}`);
122
+ }
123
+ return {
124
+ calls,
125
+ totalLines,
126
+ invalidLines: invalidLineNumbers.length,
127
+ invalidLineNumbers,
128
+ };
129
+ }
130
+ // ---------------------------------------------------------------------------
131
+ // Expression evaluation
132
+ // ---------------------------------------------------------------------------
133
+ export function evaluateExpressionSafely(expression, context, cache) {
134
+ let ast = cache.get(expression);
135
+ if (!ast) {
136
+ try {
137
+ ast = compileExpression(expression);
138
+ cache.set(expression, ast);
139
+ }
140
+ catch {
141
+ return false;
142
+ }
143
+ }
144
+ try {
145
+ return Boolean(evaluate(ast, context));
146
+ }
147
+ catch {
148
+ return false;
149
+ }
150
+ }
151
+ // ---------------------------------------------------------------------------
152
+ // Rule matching
153
+ // ---------------------------------------------------------------------------
154
+ function matchesRuleAgentScope(rule, agentId) {
155
+ if (!rule.agents) {
156
+ return true;
157
+ }
158
+ if (Array.isArray(rule.agents)) {
159
+ const includeOnly = rule.agents.filter((value) => typeof value === 'string');
160
+ return agentId !== undefined && includeOnly.includes(agentId);
161
+ }
162
+ const excluded = rule.agents.not.filter((value) => typeof value === 'string');
163
+ return agentId === undefined || !excluded.includes(agentId);
164
+ }
165
+ function buildReplayCallContext(call) {
166
+ return {
167
+ ...call.arguments,
168
+ tool_name: call.tool,
169
+ arguments: call.arguments,
170
+ session_id: call.sessionId,
171
+ agent_id: call.agentId,
172
+ user_id: call.userId,
173
+ role: call.role,
174
+ custom: call.custom,
175
+ };
176
+ }
177
+ function buildHistoricalContext(entry) {
178
+ return {
179
+ ...entry.arguments,
180
+ tool_name: entry.toolName,
181
+ arguments: entry.arguments,
182
+ decision: entry.decision,
183
+ timestamp: entry.timestamp.toISOString(),
184
+ };
185
+ }
186
+ function hasMatchingHistoryEntry(constraint, history, now, expressionCache) {
187
+ const nowMs = now.getTime();
188
+ const withinMs = typeof constraint.within === 'number'
189
+ ? Math.max(0, constraint.within) * 1000
190
+ : null;
191
+ return history.some((entry) => {
192
+ if (entry.toolName !== constraint.tool) {
193
+ return false;
194
+ }
195
+ if (entry.decision === 'deny') {
196
+ return false;
197
+ }
198
+ if (withinMs !== null) {
199
+ const ageMs = nowMs - entry.timestamp.getTime();
200
+ if (ageMs < 0 || ageMs > withinMs) {
201
+ return false;
202
+ }
203
+ }
204
+ return evaluateConditionCollections(constraint.conditions, constraint.condition_groups, buildHistoricalContext(entry), {
205
+ now: entry.timestamp,
206
+ evaluateExpression: (expression, context) => evaluateExpressionSafely(expression, context, expressionCache),
207
+ });
208
+ });
209
+ }
210
+ function matchesSequenceConstraints(rule, history, now, expressionCache) {
211
+ const blockedBy = rule.blocked_by ?? [];
212
+ const requires = rule.requires ?? [];
213
+ if (blockedBy.length === 0 && requires.length === 0) {
214
+ return true;
215
+ }
216
+ const blockedByMatched = blockedBy.some((constraint) => hasMatchingHistoryEntry(constraint, history, now, expressionCache));
217
+ const missingRequirement = requires.some((constraint) => !hasMatchingHistoryEntry(constraint, history, now, expressionCache));
218
+ // OR semantics: the rule fires if ANY blocking history exists OR ANY
219
+ // required prior call is missing. Each constraint type independently
220
+ // triggers the rule — they are not combined with AND.
221
+ return blockedByMatched || missingRequirement;
222
+ }
223
+ export function matchesReplayRule(rule, call, history, expressionCache) {
224
+ if (!matchesRuleAgentScope(rule, call.agentId)) {
225
+ return false;
226
+ }
227
+ const callTime = new Date(call.timestamp);
228
+ const context = buildReplayCallContext(call);
229
+ const conditionsMatch = evaluateConditionCollections(rule.conditions, rule.condition_groups, context, {
230
+ now: callTime,
231
+ evaluateExpression: (expression, evaluationContext) => evaluateExpressionSafely(expression, evaluationContext, expressionCache),
232
+ });
233
+ if (!conditionsMatch) {
234
+ return false;
235
+ }
236
+ return matchesSequenceConstraints(rule, history, callTime, expressionCache);
237
+ }
238
+ // ---------------------------------------------------------------------------
239
+ // Core replay
240
+ // ---------------------------------------------------------------------------
241
+ export function buildReplaySnapshot(snapshot) {
242
+ const globalRules = snapshot.globalRules.filter((rule) => rule.enabled !== false);
243
+ const rulesByTool = new Map();
244
+ for (const [toolName, rules] of snapshot.rulesByTool.entries()) {
245
+ const enabledRules = rules.filter((rule) => rule.enabled !== false);
246
+ if (enabledRules.length > 0) {
247
+ rulesByTool.set(toolName, enabledRules);
248
+ }
249
+ }
250
+ return {
251
+ globalRules,
252
+ rulesByTool,
253
+ };
254
+ }
255
+ export function decideReplayCall(replaySnapshot, call, history, expressionCache) {
256
+ const toolRules = replaySnapshot.rulesByTool.get(call.tool) ?? [];
257
+ const rules = [...replaySnapshot.globalRules, ...toolRules];
258
+ if (rules.length === 0) {
259
+ return { decision: 'allow' };
260
+ }
261
+ // Collect all matching rules, then return the most restrictive outcome.
262
+ // Priority: block > require_approval > allow (prevents approval from shadowing denial).
263
+ let denyRule = null;
264
+ let approvalRule = null;
265
+ let firstAllowRule = null;
266
+ for (const rule of rules) {
267
+ if (!matchesReplayRule(rule, call, history, expressionCache)) {
268
+ continue;
269
+ }
270
+ if (rule.action === 'block' && !denyRule) {
271
+ denyRule = rule;
272
+ }
273
+ else if (rule.action === 'require_approval' && !approvalRule) {
274
+ approvalRule = rule;
275
+ }
276
+ else if (rule.action === 'allow' && !firstAllowRule) {
277
+ firstAllowRule = rule;
278
+ }
279
+ }
280
+ if (denyRule) {
281
+ return {
282
+ decision: 'deny',
283
+ ruleId: denyRule.id,
284
+ ruleName: denyRule.name,
285
+ reason: denyRule.description ?? `Matched rule: ${denyRule.name}`,
286
+ };
287
+ }
288
+ if (approvalRule) {
289
+ return {
290
+ decision: 'require_approval',
291
+ ruleId: approvalRule.id,
292
+ ruleName: approvalRule.name,
293
+ reason: approvalRule.description ?? `Matched rule: ${approvalRule.name}`,
294
+ };
295
+ }
296
+ if (firstAllowRule) {
297
+ return {
298
+ decision: 'allow',
299
+ ruleId: firstAllowRule.id,
300
+ ruleName: firstAllowRule.name,
301
+ reason: firstAllowRule.description ?? `Allowed by rule: ${firstAllowRule.name}`,
302
+ };
303
+ }
304
+ return { decision: 'allow' };
305
+ }
306
+ export function replayCalls(snapshot, calls) {
307
+ const replaySnapshot = buildReplaySnapshot(snapshot);
308
+ const expressionCache = new Map();
309
+ const history = [];
310
+ const decisions = [];
311
+ for (const call of calls) {
312
+ const decision = decideReplayCall(replaySnapshot, call, history, expressionCache);
313
+ decisions.push(decision);
314
+ history.push({
315
+ toolName: call.tool,
316
+ arguments: call.arguments,
317
+ decision: decision.decision,
318
+ timestamp: new Date(call.timestamp),
319
+ });
320
+ }
321
+ return decisions;
322
+ }
323
+ export function countDecisions(decisions) {
324
+ const counts = {
325
+ allow: 0,
326
+ deny: 0,
327
+ require_approval: 0,
328
+ };
329
+ for (const decision of decisions) {
330
+ counts[decision.decision] += 1;
331
+ }
332
+ return counts;
333
+ }
334
+ // ---------------------------------------------------------------------------
335
+ // Policy loading
336
+ // ---------------------------------------------------------------------------
337
+ export function createRuleLoader() {
338
+ const loader = new RuleLoader({ logger: silentLogger });
339
+ loader.setYamlParser(parseYaml);
340
+ return loader;
341
+ }
342
+ export function getPathType(inputPath) {
343
+ if (!existsSync(inputPath)) {
344
+ throw new Error(`Path not found: ${inputPath}`);
345
+ }
346
+ const stats = statSync(inputPath);
347
+ if (stats.isFile())
348
+ return 'file';
349
+ if (stats.isDirectory())
350
+ return 'directory';
351
+ throw new Error(`Path must be a file or directory: ${inputPath}`);
352
+ }
353
+ export function createSnapshotFromLoader(kind, source, loader) {
354
+ const loaded = loader.getRules();
355
+ const rulesByTool = new Map();
356
+ for (const [toolName, rules] of loaded.rulesByTool.entries()) {
357
+ rulesByTool.set(toolName, [...rules]);
358
+ }
359
+ return {
360
+ kind,
361
+ source,
362
+ rules: [...loaded.allRules],
363
+ rulesByTool,
364
+ globalRules: [...loaded.globalRules],
365
+ };
366
+ }
367
+ export function loadPolicySnapshot(inputPath) {
368
+ const resolvedPath = resolve(inputPath);
369
+ const pathType = getPathType(resolvedPath);
370
+ const loader = createRuleLoader();
371
+ if (pathType === 'file') {
372
+ const content = readFileSync(resolvedPath, 'utf-8');
373
+ loader.loadFromString(content, resolvedPath);
374
+ return createSnapshotFromLoader('file', resolvedPath, loader);
375
+ }
376
+ loader.loadFromDirectory(resolvedPath, true);
377
+ return createSnapshotFromLoader('directory', resolvedPath, loader);
378
+ }
379
+ //# sourceMappingURL=replay-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-engine.js","sourceRoot":"","sources":["../../src/cli/replay-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * `veto replay` — replay recorded tool calls against a policy to show
3
+ * what would be allowed, denied, or require approval.
4
+ *
5
+ * Pure deterministic evaluation. No LLM calls, no cloud calls, no network.
6
+ *
7
+ * @module cli/replay
8
+ */
9
+ import { type DecisionCounts } from './replay-engine.js';
10
+ type ReportFormat = 'text' | 'json';
11
+ export interface ReplayOptions {
12
+ policy: string;
13
+ log: string;
14
+ diff?: boolean;
15
+ format?: ReportFormat;
16
+ quiet?: boolean;
17
+ }
18
+ export interface ReplayChangedCall {
19
+ index: number;
20
+ line: number;
21
+ tool: string;
22
+ arguments: Record<string, unknown>;
23
+ timestamp: string;
24
+ originalDecision: string;
25
+ replayedDecision: string;
26
+ ruleId?: string;
27
+ ruleName?: string;
28
+ reason?: string;
29
+ }
30
+ export interface ReplayDeniedGroup {
31
+ tool: string;
32
+ count: number;
33
+ reason?: string;
34
+ }
35
+ export interface ReplayReport {
36
+ timestamp: string;
37
+ policySource: string;
38
+ logSource: string;
39
+ totalCalls: number;
40
+ invalidLines: number;
41
+ decisions: DecisionCounts;
42
+ topDenied: ReplayDeniedGroup[];
43
+ topRequireApproval: ReplayDeniedGroup[];
44
+ changed: {
45
+ total: number;
46
+ calls: ReplayChangedCall[];
47
+ };
48
+ hasOriginalDecisions: boolean;
49
+ }
50
+ export interface ReplayResult {
51
+ success: boolean;
52
+ report: ReplayReport | null;
53
+ errors: string[];
54
+ }
55
+ export declare function replay(options: ReplayOptions): Promise<ReplayResult>;
56
+ export {};
57
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/cli/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAOL,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAM5B,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpC,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,iBAAiB,EAAE,CAAC;KAC5B,CAAC;IACF,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AA2LD,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAwC1E"}