usertrust 0.1.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 (149) hide show
  1. package/dist/audit/canonical.d.ts +7 -0
  2. package/dist/audit/canonical.d.ts.map +1 -0
  3. package/dist/audit/canonical.js +24 -0
  4. package/dist/audit/canonical.js.map +1 -0
  5. package/dist/audit/chain.d.ts +33 -0
  6. package/dist/audit/chain.d.ts.map +1 -0
  7. package/dist/audit/chain.js +285 -0
  8. package/dist/audit/chain.js.map +1 -0
  9. package/dist/audit/entropy.d.ts +95 -0
  10. package/dist/audit/entropy.d.ts.map +1 -0
  11. package/dist/audit/entropy.js +229 -0
  12. package/dist/audit/entropy.js.map +1 -0
  13. package/dist/audit/merkle.d.ts +87 -0
  14. package/dist/audit/merkle.d.ts.map +1 -0
  15. package/dist/audit/merkle.js +315 -0
  16. package/dist/audit/merkle.js.map +1 -0
  17. package/dist/audit/rotation.d.ts +61 -0
  18. package/dist/audit/rotation.d.ts.map +1 -0
  19. package/dist/audit/rotation.js +160 -0
  20. package/dist/audit/rotation.js.map +1 -0
  21. package/dist/audit/verify.d.ts +20 -0
  22. package/dist/audit/verify.d.ts.map +1 -0
  23. package/dist/audit/verify.js +73 -0
  24. package/dist/audit/verify.js.map +1 -0
  25. package/dist/board/board.d.ts +67 -0
  26. package/dist/board/board.d.ts.map +1 -0
  27. package/dist/board/board.js +191 -0
  28. package/dist/board/board.js.map +1 -0
  29. package/dist/board/concerns.d.ts +59 -0
  30. package/dist/board/concerns.d.ts.map +1 -0
  31. package/dist/board/concerns.js +149 -0
  32. package/dist/board/concerns.js.map +1 -0
  33. package/dist/board/director.d.ts +49 -0
  34. package/dist/board/director.d.ts.map +1 -0
  35. package/dist/board/director.js +127 -0
  36. package/dist/board/director.js.map +1 -0
  37. package/dist/cli/health.d.ts +8 -0
  38. package/dist/cli/health.d.ts.map +1 -0
  39. package/dist/cli/health.js +119 -0
  40. package/dist/cli/health.js.map +1 -0
  41. package/dist/cli/init.d.ts +8 -0
  42. package/dist/cli/init.d.ts.map +1 -0
  43. package/dist/cli/init.js +67 -0
  44. package/dist/cli/init.js.map +1 -0
  45. package/dist/cli/inspect.d.ts +8 -0
  46. package/dist/cli/inspect.d.ts.map +1 -0
  47. package/dist/cli/inspect.js +114 -0
  48. package/dist/cli/inspect.js.map +1 -0
  49. package/dist/cli/main.d.ts +3 -0
  50. package/dist/cli/main.d.ts.map +1 -0
  51. package/dist/cli/main.js +35 -0
  52. package/dist/cli/main.js.map +1 -0
  53. package/dist/cli/snapshot.d.ts +10 -0
  54. package/dist/cli/snapshot.d.ts.map +1 -0
  55. package/dist/cli/snapshot.js +61 -0
  56. package/dist/cli/snapshot.js.map +1 -0
  57. package/dist/cli/tb.d.ts +8 -0
  58. package/dist/cli/tb.d.ts.map +1 -0
  59. package/dist/cli/tb.js +43 -0
  60. package/dist/cli/tb.js.map +1 -0
  61. package/dist/cli/verify.d.ts +7 -0
  62. package/dist/cli/verify.d.ts.map +1 -0
  63. package/dist/cli/verify.js +32 -0
  64. package/dist/cli/verify.js.map +1 -0
  65. package/dist/config.d.ts +12 -0
  66. package/dist/config.d.ts.map +1 -0
  67. package/dist/config.js +34 -0
  68. package/dist/config.js.map +1 -0
  69. package/dist/detect.d.ts +18 -0
  70. package/dist/detect.d.ts.map +1 -0
  71. package/dist/detect.js +49 -0
  72. package/dist/detect.js.map +1 -0
  73. package/dist/govern.d.ts +75 -0
  74. package/dist/govern.d.ts.map +1 -0
  75. package/dist/govern.js +581 -0
  76. package/dist/govern.js.map +1 -0
  77. package/dist/index.d.ts +6 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +8 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/ledger/client.d.ts +89 -0
  82. package/dist/ledger/client.d.ts.map +1 -0
  83. package/dist/ledger/client.js +417 -0
  84. package/dist/ledger/client.js.map +1 -0
  85. package/dist/ledger/engine.d.ts +68 -0
  86. package/dist/ledger/engine.d.ts.map +1 -0
  87. package/dist/ledger/engine.js +142 -0
  88. package/dist/ledger/engine.js.map +1 -0
  89. package/dist/ledger/pricing.d.ts +35 -0
  90. package/dist/ledger/pricing.d.ts.map +1 -0
  91. package/dist/ledger/pricing.js +142 -0
  92. package/dist/ledger/pricing.js.map +1 -0
  93. package/dist/memory/patterns.d.ts +35 -0
  94. package/dist/memory/patterns.d.ts.map +1 -0
  95. package/dist/memory/patterns.js +152 -0
  96. package/dist/memory/patterns.js.map +1 -0
  97. package/dist/policy/decay.d.ts +95 -0
  98. package/dist/policy/decay.d.ts.map +1 -0
  99. package/dist/policy/decay.js +133 -0
  100. package/dist/policy/decay.js.map +1 -0
  101. package/dist/policy/default-rules.d.ts +21 -0
  102. package/dist/policy/default-rules.d.ts.map +1 -0
  103. package/dist/policy/default-rules.js +60 -0
  104. package/dist/policy/default-rules.js.map +1 -0
  105. package/dist/policy/gate.d.ts +116 -0
  106. package/dist/policy/gate.d.ts.map +1 -0
  107. package/dist/policy/gate.js +227 -0
  108. package/dist/policy/gate.js.map +1 -0
  109. package/dist/policy/pii.d.ts +28 -0
  110. package/dist/policy/pii.d.ts.map +1 -0
  111. package/dist/policy/pii.js +124 -0
  112. package/dist/policy/pii.js.map +1 -0
  113. package/dist/proxy.d.ts +33 -0
  114. package/dist/proxy.d.ts.map +1 -0
  115. package/dist/proxy.js +36 -0
  116. package/dist/proxy.js.map +1 -0
  117. package/dist/resilience/circuit.d.ts +87 -0
  118. package/dist/resilience/circuit.d.ts.map +1 -0
  119. package/dist/resilience/circuit.js +167 -0
  120. package/dist/resilience/circuit.js.map +1 -0
  121. package/dist/resilience/scope.d.ts +97 -0
  122. package/dist/resilience/scope.d.ts.map +1 -0
  123. package/dist/resilience/scope.js +244 -0
  124. package/dist/resilience/scope.js.map +1 -0
  125. package/dist/shared/constants.d.ts +7 -0
  126. package/dist/shared/constants.d.ts.map +1 -0
  127. package/dist/shared/constants.js +7 -0
  128. package/dist/shared/constants.js.map +1 -0
  129. package/dist/shared/errors.d.ts +31 -0
  130. package/dist/shared/errors.d.ts.map +1 -0
  131. package/dist/shared/errors.js +61 -0
  132. package/dist/shared/errors.js.map +1 -0
  133. package/dist/shared/ids.d.ts +7 -0
  134. package/dist/shared/ids.d.ts.map +1 -0
  135. package/dist/shared/ids.js +31 -0
  136. package/dist/shared/ids.js.map +1 -0
  137. package/dist/shared/types.d.ts +162 -0
  138. package/dist/shared/types.d.ts.map +1 -0
  139. package/dist/shared/types.js +41 -0
  140. package/dist/shared/types.js.map +1 -0
  141. package/dist/snapshot/checkpoint.d.ts +22 -0
  142. package/dist/snapshot/checkpoint.d.ts.map +1 -0
  143. package/dist/snapshot/checkpoint.js +172 -0
  144. package/dist/snapshot/checkpoint.js.map +1 -0
  145. package/dist/streaming.d.ts +44 -0
  146. package/dist/streaming.d.ts.map +1 -0
  147. package/dist/streaming.js +123 -0
  148. package/dist/streaming.js.map +1 -0
  149. package/package.json +54 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * PII Detector
3
+ *
4
+ * Pattern-based PII detection for event payloads.
5
+ * Recursively scans strings in objects/arrays and returns
6
+ * which PII types were found and at which paths.
7
+ *
8
+ * Pure module — no side effects, no network calls.
9
+ *
10
+ * Detects: email, phone, SSN, credit card (Luhn-validated), IPv4.
11
+ *
12
+ * Adapted from Field Project fermion/src/higgs/pii-detector.ts.
13
+ */
14
+ /** RFC 5322 simplified — local@domain.tld */
15
+ function isEmail(value) {
16
+ return /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/.test(value);
17
+ }
18
+ /** US/international phone: +1-234-567-8901, (234) 567-8901, 234.567.8901, etc. */
19
+ function isPhoneNumber(value) {
20
+ const stripped = value.replace(/\s+/g, "");
21
+ return /(?:\+?\d{1,3}[-.\s()]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}/.test(stripped);
22
+ }
23
+ /** US SSN: XXX-XX-XXXX (with dashes required to avoid false positives) */
24
+ function isSSN(value) {
25
+ return /\b\d{3}-\d{2}-\d{4}\b/.test(value);
26
+ }
27
+ /** IPv4 address: 0-255.0-255.0-255.0-255 */
28
+ function isIPv4(value) {
29
+ const match = value.match(/\b(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\b/);
30
+ if (!match)
31
+ return false;
32
+ return [match[1], match[2], match[3], match[4]].every((octet) => {
33
+ const n = Number(octet);
34
+ return n >= 0 && n <= 255;
35
+ });
36
+ }
37
+ /**
38
+ * Credit card number detection.
39
+ * Finds 13-19 digit sequences (with optional dashes/spaces) and
40
+ * validates them using the Luhn algorithm.
41
+ */
42
+ function isCreditCard(value) {
43
+ const candidates = value.match(/\b[\d][\d\s-]{11,22}[\d]\b/g);
44
+ if (!candidates)
45
+ return false;
46
+ return candidates.some((candidate) => {
47
+ const digits = candidate.replace(/[\s-]/g, "");
48
+ if (digits.length < 13 || digits.length > 19)
49
+ return false;
50
+ if (!/^\d+$/.test(digits))
51
+ return false;
52
+ return luhnCheck(digits);
53
+ });
54
+ }
55
+ /** Luhn algorithm for credit card validation. */
56
+ function luhnCheck(digits) {
57
+ let sum = 0;
58
+ let alternate = false;
59
+ for (let i = digits.length - 1; i >= 0; i--) {
60
+ let n = Number(digits[i]);
61
+ if (alternate) {
62
+ n *= 2;
63
+ if (n > 9)
64
+ n -= 9;
65
+ }
66
+ sum += n;
67
+ alternate = !alternate;
68
+ }
69
+ return sum % 10 === 0;
70
+ }
71
+ const PII_PATTERNS = [
72
+ { type: "email", test: isEmail },
73
+ { type: "phone", test: isPhoneNumber },
74
+ { type: "ssn", test: isSSN },
75
+ { type: "credit_card", test: isCreditCard },
76
+ { type: "ipv4", test: isIPv4 },
77
+ ];
78
+ // ---------------------------------------------------------------------------
79
+ // Recursive scanner
80
+ // ---------------------------------------------------------------------------
81
+ /**
82
+ * Detect PII in any value by recursively scanning strings in objects/arrays.
83
+ *
84
+ * Returns which PII types were found and at which dot-paths.
85
+ */
86
+ export function detectPII(data) {
87
+ const types = new Set();
88
+ const paths = [];
89
+ scanValue(data, "", types, paths);
90
+ return {
91
+ found: types.size > 0,
92
+ types: [...types],
93
+ paths,
94
+ };
95
+ }
96
+ function scanValue(value, currentPath, types, paths) {
97
+ if (typeof value === "string") {
98
+ scanString(value, currentPath, types, paths);
99
+ return;
100
+ }
101
+ if (Array.isArray(value)) {
102
+ for (let i = 0; i < value.length; i++) {
103
+ const itemPath = currentPath ? `${currentPath}[${i}]` : `[${i}]`;
104
+ scanValue(value[i], itemPath, types, paths);
105
+ }
106
+ return;
107
+ }
108
+ if (value !== null && typeof value === "object") {
109
+ const record = value;
110
+ for (const key of Object.keys(record)) {
111
+ const fieldPath = currentPath ? `${currentPath}.${key}` : key;
112
+ scanValue(record[key], fieldPath, types, paths);
113
+ }
114
+ }
115
+ }
116
+ function scanString(value, currentPath, types, paths) {
117
+ for (const pattern of PII_PATTERNS) {
118
+ if (pattern.test(value)) {
119
+ types.add(pattern.type);
120
+ paths.push(currentPath ? `${currentPath}(${pattern.type})` : `(${pattern.type})`);
121
+ }
122
+ }
123
+ }
124
+ //# sourceMappingURL=pii.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pii.js","sourceRoot":"","sources":["../../src/policy/pii.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Proxy Mode — Remote Governance Connection
3
+ *
4
+ * When `opts.proxy` is set, governance flows through the remote proxy
5
+ * instead of a local TigerBeetle instance. This is a stub for v1 —
6
+ * the real implementation will HTTP POST to proxy.usertools.ai.
7
+ */
8
+ export interface ProxySpendParams {
9
+ model: string;
10
+ estimatedCost: number;
11
+ actor: string;
12
+ }
13
+ export interface ProxySpendResult {
14
+ transferId: string;
15
+ estimatedCost: number;
16
+ }
17
+ export interface ProxyConnection {
18
+ spend(params: ProxySpendParams): Promise<ProxySpendResult>;
19
+ settle(transferId: string, actualCost: number): Promise<void>;
20
+ void(transferId: string): Promise<void>;
21
+ destroy(): void;
22
+ readonly url: string;
23
+ readonly key: string | undefined;
24
+ }
25
+ /**
26
+ * Connect to a remote governance proxy.
27
+ *
28
+ * Stub implementation for v1 — all operations succeed immediately
29
+ * with synthetic data. Real implementation will HTTP POST to the
30
+ * proxy URL with the provided API key.
31
+ */
32
+ export declare function connectProxy(url: string, key?: string): ProxyConnection;
33
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC/B,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3D,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,eAAe,CAoBvE"}
package/dist/proxy.js ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Proxy Mode — Remote Governance Connection
3
+ *
4
+ * When `opts.proxy` is set, governance flows through the remote proxy
5
+ * instead of a local TigerBeetle instance. This is a stub for v1 —
6
+ * the real implementation will HTTP POST to proxy.usertools.ai.
7
+ */
8
+ /**
9
+ * Connect to a remote governance proxy.
10
+ *
11
+ * Stub implementation for v1 — all operations succeed immediately
12
+ * with synthetic data. Real implementation will HTTP POST to the
13
+ * proxy URL with the provided API key.
14
+ */
15
+ export function connectProxy(url, key) {
16
+ return {
17
+ url,
18
+ key,
19
+ async spend(params) {
20
+ return {
21
+ transferId: `proxy_${Date.now().toString(36)}`,
22
+ estimatedCost: params.estimatedCost,
23
+ };
24
+ },
25
+ async settle(_transferId, _actualCost) {
26
+ // Stub: no-op — real implementation will POST settlement
27
+ },
28
+ async void(_transferId) {
29
+ // Stub: no-op — real implementation will POST void
30
+ },
31
+ destroy() {
32
+ // Stub: no-op — real implementation will close HTTP connection pool
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,GAAY;IACrD,OAAO;QACN,GAAG;QACH,GAAG;QACH,KAAK,CAAC,KAAK,CAAC,MAAwB;YACnC,OAAO;gBACN,UAAU,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;gBAC9C,aAAa,EAAE,MAAM,CAAC,aAAa;aACnC,CAAC;QACH,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,WAAmB,EAAE,WAAmB;YACpD,yDAAyD;QAC1D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,WAAmB;YAC7B,mDAAmD;QACpD,CAAC;QACD,OAAO;YACN,oEAAoE;QACrE,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Circuit Breaker — per-provider failure isolation
3
+ *
4
+ * Prevents cascading failures by tracking consecutive errors per key
5
+ * and short-circuiting execution when a failure threshold is exceeded.
6
+ *
7
+ * State machine: closed → open → half-open → closed
8
+ * - closed: all requests pass through normally
9
+ * - open: requests are rejected immediately (fail-fast)
10
+ * - half-open: a limited number of requests test recovery
11
+ */
12
+ /** Circuit breaker state. */
13
+ export type CircuitState = "closed" | "open" | "half-open";
14
+ /** Configuration for a circuit breaker. */
15
+ export interface CircuitBreakerConfig {
16
+ /** Number of consecutive failures before opening the circuit (default: 5). */
17
+ failureThreshold: number;
18
+ /** Milliseconds to wait before transitioning from open to half-open (default: 60 000). */
19
+ resetTimeoutMs: number;
20
+ /** Number of successful requests in half-open to close the circuit (default: 2). */
21
+ halfOpenSuccessThreshold: number;
22
+ }
23
+ /** Snapshot of breaker state for observability. */
24
+ export interface CircuitBreakerSnapshot {
25
+ readonly state: CircuitState;
26
+ readonly consecutiveFailures: number;
27
+ readonly halfOpenSuccesses: number;
28
+ readonly lastFailureTime: number | null;
29
+ readonly lastStateChange: number;
30
+ }
31
+ /** Error thrown when the circuit is open. */
32
+ export declare class CircuitOpenError extends Error {
33
+ readonly breakerKey: string;
34
+ constructor(key: string);
35
+ }
36
+ /**
37
+ * A single circuit breaker instance tracking failure state for one key.
38
+ */
39
+ export declare class CircuitBreaker {
40
+ readonly key: string;
41
+ private readonly config;
42
+ private state;
43
+ private consecutiveFailures;
44
+ private halfOpenSuccesses;
45
+ private lastFailureTime;
46
+ private lastStateChange;
47
+ private readonly now;
48
+ constructor(key: string, config?: Partial<CircuitBreakerConfig>, clock?: () => number);
49
+ /** Get a read-only snapshot of the breaker state. */
50
+ snapshot(): CircuitBreakerSnapshot;
51
+ /**
52
+ * Get the current state, applying automatic open → half-open transition
53
+ * when the reset timeout has elapsed.
54
+ */
55
+ getState(): CircuitState;
56
+ /**
57
+ * Check whether a request should be allowed through.
58
+ * Throws CircuitOpenError if the circuit is open.
59
+ */
60
+ allowRequest(): void;
61
+ /** Record a successful request. */
62
+ recordSuccess(): void;
63
+ /** Record a failed request. */
64
+ recordFailure(): void;
65
+ /** Force-reset the breaker to closed state (for admin/testing). */
66
+ reset(): void;
67
+ private transitionTo;
68
+ }
69
+ /**
70
+ * Registry of circuit breakers keyed by string (e.g. provider, action).
71
+ * Lazily creates breakers on first access.
72
+ */
73
+ export declare class CircuitBreakerRegistry {
74
+ private readonly breakers;
75
+ private readonly config;
76
+ private readonly clock;
77
+ constructor(config?: Partial<CircuitBreakerConfig>, clock?: () => number);
78
+ /** Get or create a breaker for the given key. */
79
+ get(key: string): CircuitBreaker;
80
+ /** Get a snapshot of all breakers. */
81
+ allSnapshots(): Record<string, CircuitBreakerSnapshot>;
82
+ /** Reset all breakers to closed state. */
83
+ resetAll(): void;
84
+ /** Get the number of tracked breakers. */
85
+ get size(): number;
86
+ }
87
+ //# sourceMappingURL=circuit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit.d.ts","sourceRoot":"","sources":["../../src/resilience/circuit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,6BAA6B;AAC7B,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE3D,2CAA2C;AAC3C,MAAM,WAAW,oBAAoB;IACpC,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,CAAC;IACzB,0FAA0F;IAC1F,cAAc,EAAE,MAAM,CAAC;IACvB,oFAAoF;IACpF,wBAAwB,EAAE,MAAM,CAAC;CACjC;AAED,mDAAmD;AACnD,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACjC;AAED,6CAA6C;AAC7C,qBAAa,gBAAiB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,GAAG,EAAE,MAAM;CAKvB;AAgBD;;GAEG;AACH,qBAAa,cAAc;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,MAAM;IAOrF,qDAAqD;IACrD,QAAQ,IAAI,sBAAsB;IAUlC;;;OAGG;IACH,QAAQ,IAAI,YAAY;IAWxB;;;OAGG;IACH,YAAY,IAAI,IAAI;IAQpB,mCAAmC;IACnC,aAAa,IAAI,IAAI;IAYrB,+BAA+B;IAC/B,aAAa,IAAI,IAAI;IAYrB,mEAAmE;IACnE,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,YAAY;CAUpB;AAMD;;;GAGG;AACH,qBAAa,sBAAsB;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;gBAEvC,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,MAAM;IAKxE,iDAAiD;IACjD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc;IAShC,sCAAsC;IACtC,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC;IAQtD,0CAA0C;IAC1C,QAAQ,IAAI,IAAI;IAMhB,0CAA0C;IAC1C,IAAI,IAAI,IAAI,MAAM,CAEjB;CACD"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Circuit Breaker — per-provider failure isolation
3
+ *
4
+ * Prevents cascading failures by tracking consecutive errors per key
5
+ * and short-circuiting execution when a failure threshold is exceeded.
6
+ *
7
+ * State machine: closed → open → half-open → closed
8
+ * - closed: all requests pass through normally
9
+ * - open: requests are rejected immediately (fail-fast)
10
+ * - half-open: a limited number of requests test recovery
11
+ */
12
+ /** Error thrown when the circuit is open. */
13
+ export class CircuitOpenError extends Error {
14
+ breakerKey;
15
+ constructor(key) {
16
+ super(`Circuit breaker "${key}" is open — request rejected`);
17
+ this.name = "CircuitOpenError";
18
+ this.breakerKey = key;
19
+ }
20
+ }
21
+ // ---------------------------------------------------------------------------
22
+ // Default config
23
+ // ---------------------------------------------------------------------------
24
+ const DEFAULT_CONFIG = {
25
+ failureThreshold: 5,
26
+ resetTimeoutMs: 60_000,
27
+ halfOpenSuccessThreshold: 2,
28
+ };
29
+ // ---------------------------------------------------------------------------
30
+ // CircuitBreaker
31
+ // ---------------------------------------------------------------------------
32
+ /**
33
+ * A single circuit breaker instance tracking failure state for one key.
34
+ */
35
+ export class CircuitBreaker {
36
+ key;
37
+ config;
38
+ state = "closed";
39
+ consecutiveFailures = 0;
40
+ halfOpenSuccesses = 0;
41
+ lastFailureTime = null;
42
+ lastStateChange;
43
+ now;
44
+ constructor(key, config, clock) {
45
+ this.key = key;
46
+ this.config = { ...DEFAULT_CONFIG, ...config };
47
+ this.now = clock ?? Date.now;
48
+ this.lastStateChange = this.now();
49
+ }
50
+ /** Get a read-only snapshot of the breaker state. */
51
+ snapshot() {
52
+ return {
53
+ state: this.getState(),
54
+ consecutiveFailures: this.consecutiveFailures,
55
+ halfOpenSuccesses: this.halfOpenSuccesses,
56
+ lastFailureTime: this.lastFailureTime,
57
+ lastStateChange: this.lastStateChange,
58
+ };
59
+ }
60
+ /**
61
+ * Get the current state, applying automatic open → half-open transition
62
+ * when the reset timeout has elapsed.
63
+ */
64
+ getState() {
65
+ if (this.state === "open" &&
66
+ this.lastFailureTime !== null &&
67
+ this.now() - this.lastFailureTime >= this.config.resetTimeoutMs) {
68
+ this.transitionTo("half-open");
69
+ }
70
+ return this.state;
71
+ }
72
+ /**
73
+ * Check whether a request should be allowed through.
74
+ * Throws CircuitOpenError if the circuit is open.
75
+ */
76
+ allowRequest() {
77
+ const current = this.getState();
78
+ if (current === "open") {
79
+ throw new CircuitOpenError(this.key);
80
+ }
81
+ // closed and half-open both allow requests
82
+ }
83
+ /** Record a successful request. */
84
+ recordSuccess() {
85
+ if (this.state === "half-open") {
86
+ this.halfOpenSuccesses++;
87
+ if (this.halfOpenSuccesses >= this.config.halfOpenSuccessThreshold) {
88
+ this.transitionTo("closed");
89
+ }
90
+ }
91
+ else {
92
+ // Reset failure count on success in closed state
93
+ this.consecutiveFailures = 0;
94
+ }
95
+ }
96
+ /** Record a failed request. */
97
+ recordFailure() {
98
+ this.consecutiveFailures++;
99
+ this.lastFailureTime = this.now();
100
+ if (this.state === "half-open") {
101
+ // Any failure in half-open reopens the circuit
102
+ this.transitionTo("open");
103
+ }
104
+ else if (this.consecutiveFailures >= this.config.failureThreshold) {
105
+ this.transitionTo("open");
106
+ }
107
+ }
108
+ /** Force-reset the breaker to closed state (for admin/testing). */
109
+ reset() {
110
+ this.transitionTo("closed");
111
+ }
112
+ transitionTo(newState) {
113
+ this.state = newState;
114
+ this.lastStateChange = this.now();
115
+ if (newState === "closed") {
116
+ this.consecutiveFailures = 0;
117
+ this.halfOpenSuccesses = 0;
118
+ }
119
+ else if (newState === "half-open") {
120
+ this.halfOpenSuccesses = 0;
121
+ }
122
+ }
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Registry
126
+ // ---------------------------------------------------------------------------
127
+ /**
128
+ * Registry of circuit breakers keyed by string (e.g. provider, action).
129
+ * Lazily creates breakers on first access.
130
+ */
131
+ export class CircuitBreakerRegistry {
132
+ breakers = new Map();
133
+ config;
134
+ clock;
135
+ constructor(config, clock) {
136
+ this.config = config ?? {};
137
+ this.clock = clock;
138
+ }
139
+ /** Get or create a breaker for the given key. */
140
+ get(key) {
141
+ let breaker = this.breakers.get(key);
142
+ if (breaker === undefined) {
143
+ breaker = new CircuitBreaker(key, this.config, this.clock);
144
+ this.breakers.set(key, breaker);
145
+ }
146
+ return breaker;
147
+ }
148
+ /** Get a snapshot of all breakers. */
149
+ allSnapshots() {
150
+ const result = {};
151
+ for (const [key, breaker] of this.breakers) {
152
+ result[key] = breaker.snapshot();
153
+ }
154
+ return result;
155
+ }
156
+ /** Reset all breakers to closed state. */
157
+ resetAll() {
158
+ for (const breaker of this.breakers.values()) {
159
+ breaker.reset();
160
+ }
161
+ }
162
+ /** Get the number of tracked breakers. */
163
+ get size() {
164
+ return this.breakers.size;
165
+ }
166
+ }
167
+ //# sourceMappingURL=circuit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit.js","sourceRoot":"","sources":["../../src/resilience/circuit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA4BH,6CAA6C;AAC7C,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACjC,UAAU,CAAS;IAE5B,YAAY,GAAW;QACtB,KAAK,CAAC,oBAAoB,GAAG,8BAA8B,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;IACvB,CAAC;CACD;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,cAAc,GAAyB;IAC5C,gBAAgB,EAAE,CAAC;IACnB,cAAc,EAAE,MAAM;IACtB,wBAAwB,EAAE,CAAC;CAC3B,CAAC;AAEF,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;GAEG;AACH,MAAM,OAAO,cAAc;IACjB,GAAG,CAAS;IACJ,MAAM,CAAuB;IACtC,KAAK,GAAiB,QAAQ,CAAC;IAC/B,mBAAmB,GAAG,CAAC,CAAC;IACxB,iBAAiB,GAAG,CAAC,CAAC;IACtB,eAAe,GAAkB,IAAI,CAAC;IACtC,eAAe,CAAS;IACf,GAAG,CAAe;IAEnC,YAAY,GAAW,EAAE,MAAsC,EAAE,KAAoB;QACpF,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;QAC/C,IAAI,CAAC,GAAG,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC;QAC7B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACnC,CAAC;IAED,qDAAqD;IACrD,QAAQ;QACP,OAAO;YACN,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE;YACtB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,eAAe,EAAE,IAAI,CAAC,eAAe;SACrC,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,QAAQ;QACP,IACC,IAAI,CAAC,KAAK,KAAK,MAAM;YACrB,IAAI,CAAC,eAAe,KAAK,IAAI;YAC7B,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAC9D,CAAC;YACF,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;;OAGG;IACH,YAAY;QACX,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;QACD,2CAA2C;IAC5C,CAAC;IAED,mCAAmC;IACnC,aAAa;QACZ,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,wBAAwB,EAAE,CAAC;gBACpE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC;QACF,CAAC;aAAM,CAAC;YACP,iDAAiD;YACjD,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC9B,CAAC;IACF,CAAC;IAED,+BAA+B;IAC/B,aAAa;QACZ,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAElC,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAChC,+CAA+C;YAC/C,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACrE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;IAED,mEAAmE;IACnE,KAAK;QACJ,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAEO,YAAY,CAAC,QAAsB;QAC1C,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;QACtB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC5B,CAAC;IACF,CAAC;CACD;AAED,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IACjB,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC7C,MAAM,CAAgC;IACtC,KAAK,CAA6B;IAEnD,YAAY,MAAsC,EAAE,KAAoB;QACvE,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,iDAAiD;IACjD,GAAG,CAAC,GAAW;QACd,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,sCAAsC;IACtC,YAAY;QACX,MAAM,MAAM,GAA2C,EAAE,CAAC;QAC1D,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5C,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QAClC,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAED,0CAA0C;IAC1C,QAAQ;QACP,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9C,OAAO,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;IACF,CAAC;IAED,0CAA0C;IAC1C,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC3B,CAAC;CACD"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Scope Locking — minimatch-based overlap detection & lease management
3
+ *
4
+ * Prevents conflicts between parallel workers by tracking scope-based leases.
5
+ * Each lease locks a set of glob patterns; overlapping patterns from different
6
+ * actors are rejected.
7
+ *
8
+ * Store path: `.usertools/leases.json`
9
+ */
10
+ export type LeaseStatus = "active" | "released" | "expired" | "revoked";
11
+ export interface Lease {
12
+ lease_id: string;
13
+ actor: string;
14
+ scope: string[];
15
+ intent: string;
16
+ issued_at: string;
17
+ expires_at: string;
18
+ status: LeaseStatus;
19
+ last_renewed_at?: string;
20
+ }
21
+ export interface LeaseStore {
22
+ [lease_id: string]: Lease;
23
+ }
24
+ export interface AcquireLeaseOptions {
25
+ actor: string;
26
+ scope: string[];
27
+ intent: string;
28
+ /** Lease time-to-live in minutes (default: 60). */
29
+ ttlMin?: number;
30
+ }
31
+ export interface LeaseConflict {
32
+ lease: Lease;
33
+ overlappingPatterns: string[];
34
+ }
35
+ /**
36
+ * Set the store directory path (for testing).
37
+ */
38
+ export declare function setStoreDir(dir: string): void;
39
+ /**
40
+ * Get the current store directory.
41
+ */
42
+ export declare function getStoreDir(): string;
43
+ /**
44
+ * Check if two scope patterns overlap.
45
+ *
46
+ * Two patterns overlap when:
47
+ * 1. Either literally matches the other via minimatch, OR
48
+ * 2. They share a common base prefix (e.g. `src/**` and `src/foo/**`)
49
+ */
50
+ export declare function scopesOverlap(scopeA: string[], scopeB: string[]): boolean;
51
+ /**
52
+ * Check if a file matches any of the scope patterns.
53
+ */
54
+ export declare function fileMatchesScope(file: string, scope: string[]): boolean;
55
+ /**
56
+ * Scope-based lease manager.
57
+ *
58
+ * Provides `acquireLease`, `releaseLease`, `findConflicts`, and `expireStale`
59
+ * for coordinating parallel workers operating on overlapping file scopes.
60
+ */
61
+ export declare class ScopeManager {
62
+ private readonly clock;
63
+ constructor(clock?: () => number);
64
+ /**
65
+ * Acquire a lease for the given scope.
66
+ * Throws if scope overlaps with another actor's active lease.
67
+ */
68
+ acquireLease(options: AcquireLeaseOptions): Lease;
69
+ /**
70
+ * Renew an existing lease, extending its TTL.
71
+ */
72
+ renewLease(leaseId: string, ttlMin?: number): Lease;
73
+ /**
74
+ * Release a lease, marking it as released.
75
+ */
76
+ releaseLease(leaseId: string): Lease;
77
+ /**
78
+ * Find conflicts for a proposed scope against active leases.
79
+ */
80
+ findConflicts(scope: string[], excludeActor?: string): LeaseConflict[];
81
+ /**
82
+ * Expire stale leases and persist the result.
83
+ * Returns the number of leases expired.
84
+ */
85
+ expireStale(): number;
86
+ /**
87
+ * Get all active leases.
88
+ */
89
+ getActiveLeases(): Lease[];
90
+ /**
91
+ * Get a lease by ID.
92
+ */
93
+ getLease(leaseId: string): Lease | undefined;
94
+ private findConflictsInStore;
95
+ private expireStaleInStore;
96
+ }
97
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/resilience/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAWH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,CAAC;AAExE,MAAM,WAAW,KAAK;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IAC1B,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,KAAK,CAAC;IACb,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAQD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE7C;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAgDD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAgBzE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAOvE;AAMD;;;;;GAKG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;gBAEzB,KAAK,CAAC,EAAE,MAAM,MAAM;IAIhC;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,KAAK;IAsCjD;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,KAAK;IAkB/C;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK;IAcpC;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAMtE;;;OAGG;IACH,WAAW,IAAI,MAAM;IASrB;;OAEG;IACH,eAAe,IAAI,KAAK,EAAE;IAK1B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAO5C,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,kBAAkB;CAa1B"}