open-multi-agent-kit 0.80.8 → 0.90.3

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 (208) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +21 -31
  3. package/dist/cli/args.d.ts +0 -2
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +2 -7
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/core/agent-session.d.ts +2 -0
  8. package/dist/core/agent-session.d.ts.map +1 -1
  9. package/dist/core/agent-session.js +41 -5
  10. package/dist/core/agent-session.js.map +1 -1
  11. package/dist/core/automation/index.d.ts +359 -0
  12. package/dist/core/automation/index.d.ts.map +1 -0
  13. package/dist/core/automation/index.js +665 -0
  14. package/dist/core/automation/index.js.map +1 -0
  15. package/dist/core/bang-skill-invocation.d.ts +26 -0
  16. package/dist/core/bang-skill-invocation.d.ts.map +1 -0
  17. package/dist/core/bang-skill-invocation.js +59 -0
  18. package/dist/core/bang-skill-invocation.js.map +1 -0
  19. package/dist/core/browser-use.d.ts +8 -0
  20. package/dist/core/browser-use.d.ts.map +1 -1
  21. package/dist/core/browser-use.js +61 -23
  22. package/dist/core/browser-use.js.map +1 -1
  23. package/dist/core/compactor.d.ts.map +1 -1
  24. package/dist/core/compactor.js +0 -3
  25. package/dist/core/compactor.js.map +1 -1
  26. package/dist/core/context-budget-governor-v2.d.ts +2 -1
  27. package/dist/core/context-budget-governor-v2.d.ts.map +1 -1
  28. package/dist/core/context-budget-governor-v2.js +1 -0
  29. package/dist/core/context-budget-governor-v2.js.map +1 -1
  30. package/dist/core/context-budget-headroom-types.d.ts +8 -0
  31. package/dist/core/context-budget-headroom-types.d.ts.map +1 -1
  32. package/dist/core/context-budget-headroom-types.js.map +1 -1
  33. package/dist/core/context-budget-headroom.d.ts +1 -1
  34. package/dist/core/context-budget-headroom.d.ts.map +1 -1
  35. package/dist/core/context-budget-headroom.js +17 -4
  36. package/dist/core/context-budget-headroom.js.map +1 -1
  37. package/dist/core/context-budget-system-prompt.d.ts +2 -1
  38. package/dist/core/context-budget-system-prompt.d.ts.map +1 -1
  39. package/dist/core/context-budget-system-prompt.js +6 -1
  40. package/dist/core/context-budget-system-prompt.js.map +1 -1
  41. package/dist/core/context-budget-v2-cache-hash.d.ts +3 -0
  42. package/dist/core/context-budget-v2-cache-hash.d.ts.map +1 -0
  43. package/dist/core/context-budget-v2-cache-hash.js +16 -0
  44. package/dist/core/context-budget-v2-cache-hash.js.map +1 -0
  45. package/dist/core/context-budget-v2-cache-keys.d.ts +58 -0
  46. package/dist/core/context-budget-v2-cache-keys.d.ts.map +1 -0
  47. package/dist/core/context-budget-v2-cache-keys.js +128 -0
  48. package/dist/core/context-budget-v2-cache-keys.js.map +1 -0
  49. package/dist/core/context-budget-v2-cache-provider.d.ts +23 -0
  50. package/dist/core/context-budget-v2-cache-provider.d.ts.map +1 -0
  51. package/dist/core/context-budget-v2-cache-provider.js +29 -0
  52. package/dist/core/context-budget-v2-cache-provider.js.map +1 -0
  53. package/dist/core/context-budget-v2-cache-telemetry.d.ts +36 -0
  54. package/dist/core/context-budget-v2-cache-telemetry.d.ts.map +1 -0
  55. package/dist/core/context-budget-v2-cache-telemetry.js +64 -0
  56. package/dist/core/context-budget-v2-cache-telemetry.js.map +1 -0
  57. package/dist/core/context-budget-v2-cache-validation.d.ts +36 -0
  58. package/dist/core/context-budget-v2-cache-validation.d.ts.map +1 -0
  59. package/dist/core/context-budget-v2-cache-validation.js +98 -0
  60. package/dist/core/context-budget-v2-cache-validation.js.map +1 -0
  61. package/dist/core/context-budget-v2-cache.d.ts +36 -0
  62. package/dist/core/context-budget-v2-cache.d.ts.map +1 -0
  63. package/dist/core/context-budget-v2-cache.js +50 -0
  64. package/dist/core/context-budget-v2-cache.js.map +1 -0
  65. package/dist/core/context-budget-v2-plan-cache-keys.d.ts +16 -0
  66. package/dist/core/context-budget-v2-plan-cache-keys.d.ts.map +1 -0
  67. package/dist/core/context-budget-v2-plan-cache-keys.js +49 -0
  68. package/dist/core/context-budget-v2-plan-cache-keys.js.map +1 -0
  69. package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
  70. package/dist/core/context-budget-v2-planner.js +55 -2
  71. package/dist/core/context-budget-v2-planner.js.map +1 -1
  72. package/dist/core/context-budget-v2-representation-cache.d.ts +27 -0
  73. package/dist/core/context-budget-v2-representation-cache.d.ts.map +1 -0
  74. package/dist/core/context-budget-v2-representation-cache.js +173 -0
  75. package/dist/core/context-budget-v2-representation-cache.js.map +1 -0
  76. package/dist/core/context-budget-v2-selection.d.ts +2 -0
  77. package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
  78. package/dist/core/context-budget-v2-selection.js +12 -2
  79. package/dist/core/context-budget-v2-selection.js.map +1 -1
  80. package/dist/core/context-budget-v2-types.d.ts +107 -1
  81. package/dist/core/context-budget-v2-types.d.ts.map +1 -1
  82. package/dist/core/context-budget-v2-types.js.map +1 -1
  83. package/dist/core/diagnostics.d.ts +2 -0
  84. package/dist/core/diagnostics.d.ts.map +1 -1
  85. package/dist/core/diagnostics.js.map +1 -1
  86. package/dist/core/extensions/builtin/todo-checklist.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin/todo-checklist.js +3 -0
  88. package/dist/core/extensions/builtin/todo-checklist.js.map +1 -1
  89. package/dist/core/footer-data-provider.d.ts +3 -1
  90. package/dist/core/footer-data-provider.d.ts.map +1 -1
  91. package/dist/core/footer-data-provider.js +4 -0
  92. package/dist/core/footer-data-provider.js.map +1 -1
  93. package/dist/core/headroom.d.ts.map +1 -1
  94. package/dist/core/headroom.js +0 -4
  95. package/dist/core/headroom.js.map +1 -1
  96. package/dist/core/hook-inventory.d.ts.map +1 -1
  97. package/dist/core/hook-inventory.js +6 -0
  98. package/dist/core/hook-inventory.js.map +1 -1
  99. package/dist/core/mcp-computer-use-presets.d.ts +64 -0
  100. package/dist/core/mcp-computer-use-presets.d.ts.map +1 -0
  101. package/dist/core/mcp-computer-use-presets.js +158 -0
  102. package/dist/core/mcp-computer-use-presets.js.map +1 -0
  103. package/dist/core/mcp-public-presets.d.ts +578 -0
  104. package/dist/core/mcp-public-presets.d.ts.map +1 -0
  105. package/dist/core/mcp-public-presets.js +647 -0
  106. package/dist/core/mcp-public-presets.js.map +1 -0
  107. package/dist/core/model-registry.d.ts.map +1 -1
  108. package/dist/core/model-registry.js +1 -0
  109. package/dist/core/model-registry.js.map +1 -1
  110. package/dist/core/model-resolver.d.ts.map +1 -1
  111. package/dist/core/model-resolver.js +1 -0
  112. package/dist/core/model-resolver.js.map +1 -1
  113. package/dist/core/pi-package-intake-candidates.d.ts +34 -0
  114. package/dist/core/pi-package-intake-candidates.d.ts.map +1 -0
  115. package/dist/core/pi-package-intake-candidates.js +291 -0
  116. package/dist/core/pi-package-intake-candidates.js.map +1 -0
  117. package/dist/core/pi-package-intake.d.ts +50 -0
  118. package/dist/core/pi-package-intake.d.ts.map +1 -0
  119. package/dist/core/pi-package-intake.js +132 -0
  120. package/dist/core/pi-package-intake.js.map +1 -0
  121. package/dist/core/provider-display-names.d.ts.map +1 -1
  122. package/dist/core/provider-display-names.js +1 -0
  123. package/dist/core/provider-display-names.js.map +1 -1
  124. package/dist/core/resource-loader.d.ts.map +1 -1
  125. package/dist/core/resource-loader.js +1 -0
  126. package/dist/core/resource-loader.js.map +1 -1
  127. package/dist/core/reverse-skill.d.ts +2 -0
  128. package/dist/core/reverse-skill.d.ts.map +1 -0
  129. package/dist/core/reverse-skill.js +7 -0
  130. package/dist/core/reverse-skill.js.map +1 -0
  131. package/dist/core/settings-manager.d.ts +3 -3
  132. package/dist/core/settings-manager.d.ts.map +1 -1
  133. package/dist/core/settings-manager.js.map +1 -1
  134. package/dist/core/skills.d.ts +4 -0
  135. package/dist/core/skills.d.ts.map +1 -1
  136. package/dist/core/skills.js +115 -43
  137. package/dist/core/skills.js.map +1 -1
  138. package/dist/core/system-prompt.d.ts +2 -0
  139. package/dist/core/system-prompt.d.ts.map +1 -1
  140. package/dist/core/system-prompt.js +58 -5
  141. package/dist/core/system-prompt.js.map +1 -1
  142. package/dist/core/todo-runtime-state.d.ts +5 -0
  143. package/dist/core/todo-runtime-state.d.ts.map +1 -0
  144. package/dist/core/todo-runtime-state.js +12 -0
  145. package/dist/core/todo-runtime-state.js.map +1 -0
  146. package/dist/index.d.ts +2 -0
  147. package/dist/index.d.ts.map +1 -1
  148. package/dist/index.js +2 -0
  149. package/dist/index.js.map +1 -1
  150. package/dist/migrations.d.ts +19 -0
  151. package/dist/migrations.d.ts.map +1 -1
  152. package/dist/migrations.js +39 -15
  153. package/dist/migrations.js.map +1 -1
  154. package/dist/modes/interactive/components/control-panel-box.d.ts +3 -3
  155. package/dist/modes/interactive/components/control-panel-box.d.ts.map +1 -1
  156. package/dist/modes/interactive/components/control-panel-box.js +10 -10
  157. package/dist/modes/interactive/components/control-panel-box.js.map +1 -1
  158. package/dist/modes/interactive/components/control-panel-gradient-motion.d.ts.map +1 -1
  159. package/dist/modes/interactive/components/control-panel-gradient-motion.js +2 -1
  160. package/dist/modes/interactive/components/control-panel-gradient-motion.js.map +1 -1
  161. package/dist/modes/interactive/components/control-panel-layout.d.ts +22 -1
  162. package/dist/modes/interactive/components/control-panel-layout.d.ts.map +1 -1
  163. package/dist/modes/interactive/components/control-panel-layout.js +244 -68
  164. package/dist/modes/interactive/components/control-panel-layout.js.map +1 -1
  165. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts +2 -1
  166. package/dist/modes/interactive/components/control-panel-runtime-status.d.ts.map +1 -1
  167. package/dist/modes/interactive/components/control-panel-runtime-status.js +20 -1
  168. package/dist/modes/interactive/components/control-panel-runtime-status.js.map +1 -1
  169. package/dist/modes/interactive/components/control-panel-sparkles.d.ts +27 -0
  170. package/dist/modes/interactive/components/control-panel-sparkles.d.ts.map +1 -0
  171. package/dist/modes/interactive/components/control-panel-sparkles.js +42 -0
  172. package/dist/modes/interactive/components/control-panel-sparkles.js.map +1 -0
  173. package/dist/modes/interactive/components/control-panel.d.ts +9 -0
  174. package/dist/modes/interactive/components/control-panel.d.ts.map +1 -1
  175. package/dist/modes/interactive/components/control-panel.js +50 -6
  176. package/dist/modes/interactive/components/control-panel.js.map +1 -1
  177. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  178. package/dist/modes/interactive/components/footer.js +6 -0
  179. package/dist/modes/interactive/components/footer.js.map +1 -1
  180. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  181. package/dist/modes/interactive/components/settings-selector.js +2 -1
  182. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  183. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  184. package/dist/modes/interactive/components/thinking-selector.js +2 -1
  185. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  186. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  187. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  188. package/dist/modes/interactive/interactive-mode.js +70 -15
  189. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  190. package/dist/modes/interactive/theme/theme.d.ts +1 -1
  191. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  192. package/dist/modes/interactive/theme/theme.js +5 -0
  193. package/dist/modes/interactive/theme/theme.js.map +1 -1
  194. package/docs/providers.md +12 -0
  195. package/docs/skills.md +8 -4
  196. package/docs/usage.md +4 -3
  197. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  198. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  199. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  200. package/examples/extensions/gondolin/package-lock.json +2 -2
  201. package/examples/extensions/gondolin/package.json +1 -1
  202. package/examples/extensions/preset.ts +2 -2
  203. package/examples/extensions/sandbox/package-lock.json +2 -2
  204. package/examples/extensions/sandbox/package.json +1 -1
  205. package/examples/extensions/with-deps/package-lock.json +2 -2
  206. package/examples/extensions/with-deps/package.json +1 -1
  207. package/npm-shrinkwrap.json +27 -34
  208. package/package.json +5 -5
@@ -0,0 +1,359 @@
1
+ export type RiskLevel = "R0" | "R1" | "R2" | "R3";
2
+ export type Capability = "fs.read" | "fs.write" | "process.exec" | "network.read" | "network.write" | "browser.observe" | "browser.mutate" | "browser.credentialed" | "mcp.call" | "extension.run" | "api.call" | "secrets.resolve" | "subagent.spawn";
3
+ export type EnvMode = "secret-ref-only" | "passthrough-audited" | "passthrough-full";
4
+ export type Sensitivity = "public" | "internal" | "credential" | "payment" | "session" | "admin";
5
+ export type ApiMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
6
+ export interface AutonomyProfile {
7
+ id: "autopilot-max" | "trusted-dev" | "ci-agent" | "public-safe";
8
+ humanPromptBudget: {
9
+ maxPromptsPerTask: number;
10
+ maxPromptRate: number;
11
+ };
12
+ capabilities: Capability[];
13
+ env: {
14
+ mode: EnvMode;
15
+ allowPatterns: string[];
16
+ denyPatterns: string[];
17
+ redactPatterns: string[];
18
+ exposeToModel: false;
19
+ };
20
+ api: {
21
+ allowOrigins: string[];
22
+ allowMethods: ApiMethod[];
23
+ mutationDefault: "auto";
24
+ requireIdempotencyForMethods: ApiMethod[];
25
+ };
26
+ browser: {
27
+ persistentProfile: boolean;
28
+ credentialedSessions: boolean;
29
+ autoSubmit: boolean;
30
+ autoDownload: boolean;
31
+ maxUnknownOutcomeReconciliations: number;
32
+ };
33
+ verification: {
34
+ minVerifiabilityByRisk: Record<RiskLevel, number>;
35
+ requireEvidenceByRisk: Record<RiskLevel, boolean>;
36
+ requirePostconditionsByRisk: Record<RiskLevel, boolean>;
37
+ };
38
+ recovery: {
39
+ autoRetry: boolean;
40
+ autoRollback: boolean;
41
+ autoCompensate: boolean;
42
+ duplicateMutationSuppression: boolean;
43
+ };
44
+ budgets: {
45
+ maxWallClockMs: number;
46
+ maxToolCalls: number;
47
+ maxBrowserActions: number;
48
+ maxNetworkCalls: number;
49
+ maxCostUsd: number;
50
+ riskBudget: Record<RiskLevel, number>;
51
+ };
52
+ }
53
+ export declare const AUTOPILOT_MAX: AutonomyProfile;
54
+ export interface EnvRecord {
55
+ key: string;
56
+ value: string;
57
+ sensitivity: Sensitivity;
58
+ source: "process" | "profile" | "workspace" | "task" | "tool";
59
+ fingerprint: string;
60
+ }
61
+ export interface EnvUseEvent {
62
+ actionId: string;
63
+ toolId: string;
64
+ key: string;
65
+ sensitivity: Sensitivity;
66
+ fingerprint: string;
67
+ purpose: string;
68
+ passedToProcess: boolean;
69
+ exposedToModel: false;
70
+ timestamp: string;
71
+ }
72
+ export interface EnvResolutionRequest {
73
+ actionId: string;
74
+ toolId: string;
75
+ purpose: string;
76
+ profile: AutonomyProfile;
77
+ requestedKeys?: string[];
78
+ requestedPatterns?: string[];
79
+ extraEnv?: Record<string, string>;
80
+ }
81
+ export interface EnvBrokerLedger {
82
+ append(event: EnvUseEvent): Promise<unknown>;
83
+ }
84
+ export declare class EnvBroker {
85
+ private readonly processEnv;
86
+ private readonly ledger;
87
+ constructor(args: {
88
+ processEnv: Record<string, string | undefined>;
89
+ ledger: EnvBrokerLedger;
90
+ });
91
+ createChildEnv(req: EnvResolutionRequest): Promise<Record<string, string>>;
92
+ redactEnvForModel(env: Record<string, string>): Record<string, string>;
93
+ private collect;
94
+ private isAllowed;
95
+ }
96
+ export type EvidenceActor = "agent" | "tool" | "browser" | "extension-host" | "mcp" | "api" | "verifier" | "recovery";
97
+ export type EvidenceOutcome = "planned" | "executed" | "verified" | "failed_before_commit" | "unknown_after_dispatch" | "reconciled" | "compensated";
98
+ export interface EvidenceEvent {
99
+ sequence: number;
100
+ previousHash: string;
101
+ eventHash: string;
102
+ timestamp: string;
103
+ sessionId: string;
104
+ taskId: string;
105
+ actionId?: string;
106
+ actor: EvidenceActor;
107
+ kind: string;
108
+ inputHash?: string;
109
+ outputHash?: string;
110
+ redactedOutputHash?: string;
111
+ envUseHash?: string;
112
+ policyHash?: string;
113
+ profileHash?: string;
114
+ schemaHash?: string;
115
+ outcome?: EvidenceOutcome;
116
+ }
117
+ export type EvidenceEventInput = Omit<EvidenceEvent, "sequence" | "previousHash" | "eventHash" | "timestamp" | "sessionId" | "taskId">;
118
+ export declare class EvidenceLedger {
119
+ private readonly sessionId;
120
+ private readonly taskId;
121
+ private readonly events;
122
+ private previousHash;
123
+ constructor(args: {
124
+ sessionId: string;
125
+ taskId: string;
126
+ });
127
+ append(event: EvidenceEventInput): Promise<EvidenceEvent>;
128
+ snapshot(): EvidenceEvent[];
129
+ }
130
+ export type Postcondition = {
131
+ kind: "url";
132
+ origin?: string;
133
+ path?: string;
134
+ pattern?: string;
135
+ } | {
136
+ kind: "text";
137
+ exact?: string;
138
+ pattern?: string;
139
+ } | {
140
+ kind: "element-visible";
141
+ ref?: string;
142
+ role?: string;
143
+ name?: string;
144
+ } | {
145
+ kind: "element-value";
146
+ ref: string;
147
+ expected: string;
148
+ } | {
149
+ kind: "api-status";
150
+ status: number;
151
+ } | {
152
+ kind: "api-json";
153
+ jsonPath: string;
154
+ expected: unknown;
155
+ } | {
156
+ kind: "file-exists";
157
+ path: string;
158
+ sha256?: string;
159
+ } | {
160
+ kind: "download";
161
+ path: string;
162
+ sha256?: string;
163
+ mimeType?: string;
164
+ } | {
165
+ kind: "receipt";
166
+ idPattern: string;
167
+ } | {
168
+ kind: "database";
169
+ queryId: string;
170
+ expectedHash: string;
171
+ };
172
+ export interface VerificationContext {
173
+ currentUrl?: string;
174
+ text?: string;
175
+ elements?: Array<{
176
+ ref?: string;
177
+ role?: string;
178
+ name?: string;
179
+ value?: string;
180
+ visible?: boolean;
181
+ }>;
182
+ apiStatus?: number;
183
+ apiBody?: unknown;
184
+ receiptId?: string;
185
+ databaseHashes?: Record<string, string>;
186
+ }
187
+ export interface EvidencePointer {
188
+ kind: string;
189
+ description: string;
190
+ sha256?: string;
191
+ }
192
+ export interface VerificationResult {
193
+ pass: boolean;
194
+ confidence: number;
195
+ evidencePointers: EvidencePointer[];
196
+ failures: string[];
197
+ receiptId?: string;
198
+ }
199
+ export declare class PostconditionVerifier {
200
+ verify(conditions: Postcondition[], ctx: VerificationContext): Promise<VerificationResult>;
201
+ private verifyOne;
202
+ }
203
+ export interface ApiAction {
204
+ actionId: string;
205
+ method: ApiMethod;
206
+ url: string;
207
+ headers: Record<string, string>;
208
+ body?: unknown;
209
+ credentialRefs: string[];
210
+ expectedPostconditions: Postcondition[];
211
+ idempotencyKey?: string;
212
+ }
213
+ export interface ApiOutcome {
214
+ kind: "succeeded" | "failed_before_commit" | "succeeded_unverified" | "unknown_after_dispatch";
215
+ status?: number;
216
+ bodyHash?: string;
217
+ receiptId?: string;
218
+ redactedBody?: unknown;
219
+ }
220
+ export interface BrokerFetchRequest {
221
+ method: ApiMethod;
222
+ headers: Record<string, string>;
223
+ body?: string;
224
+ signal?: AbortSignal;
225
+ }
226
+ export interface BrokerFetchResponse {
227
+ status: number;
228
+ json(): Promise<unknown>;
229
+ text(): Promise<string>;
230
+ }
231
+ export type BrokerFetcher = (url: string, init: BrokerFetchRequest) => Promise<BrokerFetchResponse>;
232
+ export declare class ApiBroker {
233
+ private readonly ledger;
234
+ private readonly verifier;
235
+ private readonly fetcher;
236
+ constructor(args: {
237
+ ledger: EvidenceLedger;
238
+ verifier: PostconditionVerifier;
239
+ fetcher?: BrokerFetcher;
240
+ });
241
+ execute(action: ApiAction, ctx?: {
242
+ signal?: AbortSignal;
243
+ profile?: AutonomyProfile;
244
+ }): Promise<ApiOutcome>;
245
+ private reconcileUnknown;
246
+ }
247
+ export interface ExecutionStrategy {
248
+ execute: boolean;
249
+ requirePostcondition: boolean;
250
+ requireIdempotency: boolean;
251
+ recovery: "retry" | "repair" | "reconcile-and-compensate";
252
+ evidenceDepth: "minimal" | "normal" | "deep" | "forensic";
253
+ }
254
+ export declare function strategyForRisk(risk: RiskLevel): ExecutionStrategy;
255
+ export interface ToolExecutionNeed {
256
+ actionId: string;
257
+ requiredCapability: Capability;
258
+ risk: RiskLevel;
259
+ requiredPostconditions: Postcondition[];
260
+ contextFingerprint?: string;
261
+ }
262
+ export interface ToolExecutionCandidate {
263
+ toolId: string;
264
+ capability: Capability;
265
+ schemaHash: string;
266
+ reliability: number;
267
+ verificationStrength: number;
268
+ avgLatencyMs: number;
269
+ costUsd: number;
270
+ supportsIdempotency: boolean;
271
+ enabled: boolean;
272
+ contextFingerprint?: string;
273
+ }
274
+ export interface ToolExecutionChoice {
275
+ candidate: ToolExecutionCandidate;
276
+ score: number;
277
+ strategy: ExecutionStrategy;
278
+ reasons: string[];
279
+ }
280
+ export declare class DynamicToolPortfolioOptimizer {
281
+ rank(candidates: ToolExecutionCandidate[], need: ToolExecutionNeed): ToolExecutionChoice[];
282
+ scoreCandidate(candidate: ToolExecutionCandidate, need: ToolExecutionNeed): ToolExecutionChoice;
283
+ }
284
+ export declare class ToolExecutionBroker {
285
+ private readonly ledger;
286
+ private readonly profile;
287
+ private readonly optimizer;
288
+ constructor(args: {
289
+ ledger: EvidenceLedger;
290
+ profile?: AutonomyProfile;
291
+ optimizer?: DynamicToolPortfolioOptimizer;
292
+ });
293
+ select(need: ToolExecutionNeed, candidates: ToolExecutionCandidate[]): Promise<ToolExecutionChoice>;
294
+ recordResult(choice: ToolExecutionChoice, result: VerificationResult): Promise<EvidenceEvent>;
295
+ }
296
+ export interface AutomationTraceAction {
297
+ kind: "tool" | "browser" | "api" | "mcp" | "extension";
298
+ verificationPass: boolean;
299
+ schemaHashMatched?: boolean;
300
+ envUseLedgered?: boolean;
301
+ targetFingerprintMatched?: boolean;
302
+ outcome?: "unknown_after_dispatch" | "succeeded" | "failed";
303
+ reconciled?: boolean;
304
+ }
305
+ export interface AutomationTraceEnvApiUse {
306
+ ledgered: boolean;
307
+ exposedToModel: boolean;
308
+ exposedToLogs: boolean;
309
+ }
310
+ export interface AutomationTraceContextPlan {
311
+ renderedTokens: number;
312
+ resourceBudget: number;
313
+ planHash: string;
314
+ renderedHashLinkedPlanHash: string;
315
+ outputReserveCountedOnce: boolean;
316
+ }
317
+ export interface AutomationTrace {
318
+ actions: AutomationTraceAction[];
319
+ verifications: Array<{
320
+ conditionHash: string;
321
+ pass: boolean;
322
+ }>;
323
+ humanPrompts: number;
324
+ envApiUses: AutomationTraceEnvApiUse[];
325
+ failures: number;
326
+ unknownOutcomes: number;
327
+ recoveredFailures: number;
328
+ reconciledUnknowns: number;
329
+ secretLeaks: number;
330
+ duplicateIrreversibleMutations: number;
331
+ unledgeredEnvUses: number;
332
+ replayMatches: boolean;
333
+ contextPlans: AutomationTraceContextPlan[];
334
+ }
335
+ export interface AutomationHarnessScoreInput {
336
+ requiredPostconditions: Postcondition[];
337
+ trace: AutomationTrace;
338
+ }
339
+ export interface AutomationScoreBreakdown {
340
+ score: number;
341
+ verifiedSuccess: boolean;
342
+ envApiUseCorrectness: number;
343
+ duplicateMutations: number;
344
+ secretLeaks: number;
345
+ critical: boolean;
346
+ }
347
+ export declare class AutomationHarnessScorer {
348
+ score(input: AutomationHarnessScoreInput): AutomationScoreBreakdown;
349
+ private verifiedSuccess;
350
+ private toolUseScore;
351
+ private browserUseScore;
352
+ private envApiScore;
353
+ private recoveryScore;
354
+ private contextScore;
355
+ }
356
+ export declare function classifyEnvKey(key: string, value: string): Sensitivity;
357
+ export declare function canonicalHash(value: unknown): string;
358
+ export declare function redactForModel(value: unknown): unknown;
359
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/automation/index.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD,MAAM,MAAM,UAAU,GACnB,SAAS,GACT,UAAU,GACV,cAAc,GACd,cAAc,GACd,eAAe,GACf,iBAAiB,GACjB,gBAAgB,GAChB,sBAAsB,GACtB,UAAU,GACV,eAAe,GACf,UAAU,GACV,iBAAiB,GACjB,gBAAgB,CAAC;AAEpB,MAAM,MAAM,OAAO,GAAG,iBAAiB,GAAG,qBAAqB,GAAG,kBAAkB,CAAC;AACrF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AACjG,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,eAAe,GAAG,aAAa,GAAG,UAAU,GAAG,aAAa,CAAC;IACjE,iBAAiB,EAAE;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACxE,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,GAAG,EAAE;QACJ,IAAI,EAAE,OAAO,CAAC;QACd,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,aAAa,EAAE,KAAK,CAAC;KACrB,CAAC;IACF,GAAG,EAAE;QACJ,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,YAAY,EAAE,SAAS,EAAE,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;QACxB,4BAA4B,EAAE,SAAS,EAAE,CAAC;KAC1C,CAAC;IACF,OAAO,EAAE;QACR,iBAAiB,EAAE,OAAO,CAAC;QAC3B,oBAAoB,EAAE,OAAO,CAAC;QAC9B,UAAU,EAAE,OAAO,CAAC;QACpB,YAAY,EAAE,OAAO,CAAC;QACtB,gCAAgC,EAAE,MAAM,CAAC;KACzC,CAAC;IACF,YAAY,EAAE;QACb,sBAAsB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAClD,qBAAqB,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAClD,2BAA2B,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;KACxD,CAAC;IACF,QAAQ,EAAE;QACT,SAAS,EAAE,OAAO,CAAC;QACnB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,4BAA4B,EAAE,OAAO,CAAC;KACtC,CAAC;IACF,OAAO,EAAE;QACR,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;KACtC,CAAC;CACF;AAED,eAAO,MAAM,aAAa,EAAE,eAqE3B,CAAC;AAEF,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9D,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,KAAK,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC/B,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7C;AAED,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqC;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IAEzC,YAAY,IAAI,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,EAG5F;IAEK,cAAc,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAkB/E;IAED,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOrE;IAED,OAAO,CAAC,OAAO;IAwBf,OAAO,CAAC,SAAS;CAUjB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,KAAK,GAAG,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;AACtH,MAAM,MAAM,eAAe,GACxB,SAAS,GACT,UAAU,GACV,UAAU,GACV,sBAAsB,GACtB,wBAAwB,GACxB,YAAY,GACZ,aAAa,CAAC;AAEjB,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACpC,aAAa,EACb,UAAU,GAAG,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,CAChF,CAAC;AAEF,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,YAAY,CAAa;IAEjC,YAAY,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAGtD;IAEK,MAAM,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAc9D;IAED,QAAQ,IAAI,aAAa,EAAE,CAE1B;CACD;AAED,MAAM,MAAM,aAAa,GACtB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACpG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,qBAAqB;IAC3B,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAe/F;YAEa,SAAS;CA2DvB;AAED,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,sBAAsB,EAAE,aAAa,EAAE,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,WAAW,GAAG,sBAAsB,GAAG,sBAAsB,GAAG,wBAAwB,CAAC;IAC/F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CACxB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEpG,qBAAa,SAAS;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC,YAAY,IAAI,EAAE;QAAE,MAAM,EAAE,cAAc,CAAC;QAAC,QAAQ,EAAE,qBAAqB,CAAC;QAAC,OAAO,CAAC,EAAE,aAAa,CAAA;KAAE,EAIrG;IAEK,OAAO,CACZ,MAAM,EAAE,SAAS,EACjB,GAAG,GAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,OAAO,CAAC,EAAE,eAAe,CAAA;KAAO,GAC3D,OAAO,CAAC,UAAU,CAAC,CAqDrB;YAEa,gBAAgB;CAyB9B;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,OAAO,GAAG,QAAQ,GAAG,0BAA0B,CAAC;IAC1D,aAAa,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;CAC1D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,iBAAiB,CAmClE;AAED,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,UAAU,CAAC;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,sBAAsB,EAAE,aAAa,EAAE,CAAC;IACxC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IACnC,SAAS,EAAE,sBAAsB,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,6BAA6B;IACzC,IAAI,CAAC,UAAU,EAAE,sBAAsB,EAAE,EAAE,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,EAAE,CAKzF;IAED,cAAc,CAAC,SAAS,EAAE,sBAAsB,EAAE,IAAI,EAAE,iBAAiB,GAAG,mBAAmB,CA0B9F;CACD;AAED,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAE1D,YAAY,IAAI,EAAE;QACjB,MAAM,EAAE,cAAc,CAAC;QACvB,OAAO,CAAC,EAAE,eAAe,CAAC;QAC1B,SAAS,CAAC,EAAE,6BAA6B,CAAC;KAC1C,EAIA;IAEK,MAAM,CAAC,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,sBAAsB,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgBxG;IAEK,YAAY,CAAC,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CASlG;CACD;AAED,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,WAAW,CAAC;IACvD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,OAAO,CAAC,EAAE,wBAAwB,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC5D,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACxC,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B,EAAE,MAAM,CAAC;IACnC,wBAAwB,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,aAAa,EAAE,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B,EAAE,MAAM,CAAC;IACvC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,0BAA0B,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,2BAA2B;IAC3C,sBAAsB,EAAE,aAAa,EAAE,CAAC;IACxC,KAAK,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,uBAAuB;IACnC,KAAK,CAAC,KAAK,EAAE,2BAA2B,GAAG,wBAAwB,CAsClE;IAED,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,YAAY;CAUpB;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAqBtE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CActD","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { readFile, stat } from \"node:fs/promises\";\n\nexport type RiskLevel = \"R0\" | \"R1\" | \"R2\" | \"R3\";\n\nexport type Capability =\n\t| \"fs.read\"\n\t| \"fs.write\"\n\t| \"process.exec\"\n\t| \"network.read\"\n\t| \"network.write\"\n\t| \"browser.observe\"\n\t| \"browser.mutate\"\n\t| \"browser.credentialed\"\n\t| \"mcp.call\"\n\t| \"extension.run\"\n\t| \"api.call\"\n\t| \"secrets.resolve\"\n\t| \"subagent.spawn\";\n\nexport type EnvMode = \"secret-ref-only\" | \"passthrough-audited\" | \"passthrough-full\";\nexport type Sensitivity = \"public\" | \"internal\" | \"credential\" | \"payment\" | \"session\" | \"admin\";\nexport type ApiMethod = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n\nexport interface AutonomyProfile {\n\tid: \"autopilot-max\" | \"trusted-dev\" | \"ci-agent\" | \"public-safe\";\n\thumanPromptBudget: { maxPromptsPerTask: number; maxPromptRate: number };\n\tcapabilities: Capability[];\n\tenv: {\n\t\tmode: EnvMode;\n\t\tallowPatterns: string[];\n\t\tdenyPatterns: string[];\n\t\tredactPatterns: string[];\n\t\texposeToModel: false;\n\t};\n\tapi: {\n\t\tallowOrigins: string[];\n\t\tallowMethods: ApiMethod[];\n\t\tmutationDefault: \"auto\";\n\t\trequireIdempotencyForMethods: ApiMethod[];\n\t};\n\tbrowser: {\n\t\tpersistentProfile: boolean;\n\t\tcredentialedSessions: boolean;\n\t\tautoSubmit: boolean;\n\t\tautoDownload: boolean;\n\t\tmaxUnknownOutcomeReconciliations: number;\n\t};\n\tverification: {\n\t\tminVerifiabilityByRisk: Record<RiskLevel, number>;\n\t\trequireEvidenceByRisk: Record<RiskLevel, boolean>;\n\t\trequirePostconditionsByRisk: Record<RiskLevel, boolean>;\n\t};\n\trecovery: {\n\t\tautoRetry: boolean;\n\t\tautoRollback: boolean;\n\t\tautoCompensate: boolean;\n\t\tduplicateMutationSuppression: boolean;\n\t};\n\tbudgets: {\n\t\tmaxWallClockMs: number;\n\t\tmaxToolCalls: number;\n\t\tmaxBrowserActions: number;\n\t\tmaxNetworkCalls: number;\n\t\tmaxCostUsd: number;\n\t\triskBudget: Record<RiskLevel, number>;\n\t};\n}\n\nexport const AUTOPILOT_MAX: AutonomyProfile = {\n\tid: \"autopilot-max\",\n\thumanPromptBudget: { maxPromptsPerTask: 0, maxPromptRate: 0 },\n\tcapabilities: [\n\t\t\"fs.read\",\n\t\t\"fs.write\",\n\t\t\"process.exec\",\n\t\t\"network.read\",\n\t\t\"network.write\",\n\t\t\"browser.observe\",\n\t\t\"browser.mutate\",\n\t\t\"browser.credentialed\",\n\t\t\"mcp.call\",\n\t\t\"extension.run\",\n\t\t\"api.call\",\n\t\t\"secrets.resolve\",\n\t\t\"subagent.spawn\",\n\t],\n\tenv: {\n\t\tmode: \"passthrough-audited\",\n\t\tallowPatterns: [\"*\"],\n\t\tdenyPatterns: [],\n\t\tredactPatterns: [\n\t\t\t\"*KEY*\",\n\t\t\t\"*TOKEN*\",\n\t\t\t\"*SECRET*\",\n\t\t\t\"*PASSWORD*\",\n\t\t\t\"AWS_*\",\n\t\t\t\"GCP_*\",\n\t\t\t\"AZURE_*\",\n\t\t\t\"OPENAI_*\",\n\t\t\t\"ANTHROPIC_*\",\n\t\t\t\"GITHUB_*\",\n\t\t\t\"NPM_*\",\n\t\t],\n\t\texposeToModel: false,\n\t},\n\tapi: {\n\t\tallowOrigins: [\"*\"],\n\t\tallowMethods: [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n\t\tmutationDefault: \"auto\",\n\t\trequireIdempotencyForMethods: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n\t},\n\tbrowser: {\n\t\tpersistentProfile: true,\n\t\tcredentialedSessions: true,\n\t\tautoSubmit: true,\n\t\tautoDownload: true,\n\t\tmaxUnknownOutcomeReconciliations: 5,\n\t},\n\tverification: {\n\t\tminVerifiabilityByRisk: { R0: 0.1, R1: 0.25, R2: 0.45, R3: 0.65 },\n\t\trequireEvidenceByRisk: { R0: false, R1: true, R2: true, R3: true },\n\t\trequirePostconditionsByRisk: { R0: false, R1: true, R2: true, R3: true },\n\t},\n\trecovery: {\n\t\tautoRetry: true,\n\t\tautoRollback: true,\n\t\tautoCompensate: true,\n\t\tduplicateMutationSuppression: true,\n\t},\n\tbudgets: {\n\t\tmaxWallClockMs: 30 * 60 * 1000,\n\t\tmaxToolCalls: 500,\n\t\tmaxBrowserActions: 250,\n\t\tmaxNetworkCalls: 1000,\n\t\tmaxCostUsd: 10,\n\t\triskBudget: { R0: 10000, R1: 2000, R2: 500, R3: 100 },\n\t},\n};\n\nexport interface EnvRecord {\n\tkey: string;\n\tvalue: string;\n\tsensitivity: Sensitivity;\n\tsource: \"process\" | \"profile\" | \"workspace\" | \"task\" | \"tool\";\n\tfingerprint: string;\n}\n\nexport interface EnvUseEvent {\n\tactionId: string;\n\ttoolId: string;\n\tkey: string;\n\tsensitivity: Sensitivity;\n\tfingerprint: string;\n\tpurpose: string;\n\tpassedToProcess: boolean;\n\texposedToModel: false;\n\ttimestamp: string;\n}\n\nexport interface EnvResolutionRequest {\n\tactionId: string;\n\ttoolId: string;\n\tpurpose: string;\n\tprofile: AutonomyProfile;\n\trequestedKeys?: string[];\n\trequestedPatterns?: string[];\n\textraEnv?: Record<string, string>;\n}\n\nexport interface EnvBrokerLedger {\n\tappend(event: EnvUseEvent): Promise<unknown>;\n}\n\nexport class EnvBroker {\n\tprivate readonly processEnv: Record<string, string | undefined>;\n\tprivate readonly ledger: EnvBrokerLedger;\n\n\tconstructor(args: { processEnv: Record<string, string | undefined>; ledger: EnvBrokerLedger }) {\n\t\tthis.processEnv = args.processEnv;\n\t\tthis.ledger = args.ledger;\n\t}\n\n\tasync createChildEnv(req: EnvResolutionRequest): Promise<Record<string, string>> {\n\t\tconst selected = this.collect(req).filter((record) => this.isAllowed(record, req));\n\t\tconst childEnv: Record<string, string> = {};\n\t\tfor (const record of selected) {\n\t\t\tchildEnv[record.key] = record.value;\n\t\t\tawait this.ledger.append({\n\t\t\t\tactionId: req.actionId,\n\t\t\t\ttoolId: req.toolId,\n\t\t\t\tkey: record.key,\n\t\t\t\tsensitivity: record.sensitivity,\n\t\t\t\tfingerprint: record.fingerprint,\n\t\t\t\tpurpose: req.purpose,\n\t\t\t\tpassedToProcess: true,\n\t\t\t\texposedToModel: false,\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t});\n\t\t}\n\t\treturn childEnv;\n\t}\n\n\tredactEnvForModel(env: Record<string, string>): Record<string, string> {\n\t\tconst out: Record<string, string> = {};\n\t\tfor (const [key, value] of Object.entries(env)) {\n\t\t\tconst sensitivity = classifyEnvKey(key, value);\n\t\t\tout[key] = sensitivity === \"public\" ? value : `[REDACTED:${sha256(value).slice(0, 12)}]`;\n\t\t}\n\t\treturn out;\n\t}\n\n\tprivate collect(req: EnvResolutionRequest): EnvRecord[] {\n\t\tconst records: EnvRecord[] = [];\n\t\tfor (const [key, value] of Object.entries(this.processEnv)) {\n\t\t\tif (typeof value !== \"string\") continue;\n\t\t\trecords.push({\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\tsensitivity: classifyEnvKey(key, value),\n\t\t\t\tsource: \"process\",\n\t\t\t\tfingerprint: sha256(value),\n\t\t\t});\n\t\t}\n\t\tfor (const [key, value] of Object.entries(req.extraEnv ?? {})) {\n\t\t\trecords.push({\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\tsensitivity: classifyEnvKey(key, value),\n\t\t\t\tsource: \"tool\",\n\t\t\t\tfingerprint: sha256(value),\n\t\t\t});\n\t\t}\n\t\treturn records;\n\t}\n\n\tprivate isAllowed(record: EnvRecord, req: EnvResolutionRequest): boolean {\n\t\tif (req.profile.env.mode === \"passthrough-full\") return true;\n\t\tif (req.profile.env.mode === \"secret-ref-only\" && record.sensitivity !== \"public\") return false;\n\t\tconst allowedByPattern = matchesAny(record.key, req.profile.env.allowPatterns);\n\t\tconst deniedByPattern = matchesAny(record.key, req.profile.env.denyPatterns);\n\t\tif (deniedByPattern || !allowedByPattern) return false;\n\t\tif (req.requestedKeys?.includes(record.key)) return true;\n\t\tif (req.requestedPatterns?.some((pattern) => globMatch(record.key, pattern))) return true;\n\t\treturn req.profile.env.allowPatterns.includes(\"*\");\n\t}\n}\n\nexport type EvidenceActor = \"agent\" | \"tool\" | \"browser\" | \"extension-host\" | \"mcp\" | \"api\" | \"verifier\" | \"recovery\";\nexport type EvidenceOutcome =\n\t| \"planned\"\n\t| \"executed\"\n\t| \"verified\"\n\t| \"failed_before_commit\"\n\t| \"unknown_after_dispatch\"\n\t| \"reconciled\"\n\t| \"compensated\";\n\nexport interface EvidenceEvent {\n\tsequence: number;\n\tpreviousHash: string;\n\teventHash: string;\n\ttimestamp: string;\n\tsessionId: string;\n\ttaskId: string;\n\tactionId?: string;\n\tactor: EvidenceActor;\n\tkind: string;\n\tinputHash?: string;\n\toutputHash?: string;\n\tredactedOutputHash?: string;\n\tenvUseHash?: string;\n\tpolicyHash?: string;\n\tprofileHash?: string;\n\tschemaHash?: string;\n\toutcome?: EvidenceOutcome;\n}\n\nexport type EvidenceEventInput = Omit<\n\tEvidenceEvent,\n\t\"sequence\" | \"previousHash\" | \"eventHash\" | \"timestamp\" | \"sessionId\" | \"taskId\"\n>;\n\nexport class EvidenceLedger {\n\tprivate readonly sessionId: string;\n\tprivate readonly taskId: string;\n\tprivate readonly events: EvidenceEvent[] = [];\n\tprivate previousHash = \"genesis\";\n\n\tconstructor(args: { sessionId: string; taskId: string }) {\n\t\tthis.sessionId = args.sessionId;\n\t\tthis.taskId = args.taskId;\n\t}\n\n\tasync append(event: EvidenceEventInput): Promise<EvidenceEvent> {\n\t\tconst fullWithoutHash = {\n\t\t\t...event,\n\t\t\tsequence: this.events.length + 1,\n\t\t\tpreviousHash: this.previousHash,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsessionId: this.sessionId,\n\t\t\ttaskId: this.taskId,\n\t\t};\n\t\tconst eventHash = canonicalHash(fullWithoutHash);\n\t\tconst full: EvidenceEvent = { ...fullWithoutHash, eventHash };\n\t\tthis.events.push(full);\n\t\tthis.previousHash = eventHash;\n\t\treturn full;\n\t}\n\n\tsnapshot(): EvidenceEvent[] {\n\t\treturn this.events.map((event) => ({ ...event }));\n\t}\n}\n\nexport type Postcondition =\n\t| { kind: \"url\"; origin?: string; path?: string; pattern?: string }\n\t| { kind: \"text\"; exact?: string; pattern?: string }\n\t| { kind: \"element-visible\"; ref?: string; role?: string; name?: string }\n\t| { kind: \"element-value\"; ref: string; expected: string }\n\t| { kind: \"api-status\"; status: number }\n\t| { kind: \"api-json\"; jsonPath: string; expected: unknown }\n\t| { kind: \"file-exists\"; path: string; sha256?: string }\n\t| { kind: \"download\"; path: string; sha256?: string; mimeType?: string }\n\t| { kind: \"receipt\"; idPattern: string }\n\t| { kind: \"database\"; queryId: string; expectedHash: string };\n\nexport interface VerificationContext {\n\tcurrentUrl?: string;\n\ttext?: string;\n\telements?: Array<{ ref?: string; role?: string; name?: string; value?: string; visible?: boolean }>;\n\tapiStatus?: number;\n\tapiBody?: unknown;\n\treceiptId?: string;\n\tdatabaseHashes?: Record<string, string>;\n}\n\nexport interface EvidencePointer {\n\tkind: string;\n\tdescription: string;\n\tsha256?: string;\n}\n\nexport interface VerificationResult {\n\tpass: boolean;\n\tconfidence: number;\n\tevidencePointers: EvidencePointer[];\n\tfailures: string[];\n\treceiptId?: string;\n}\n\nexport class PostconditionVerifier {\n\tasync verify(conditions: Postcondition[], ctx: VerificationContext): Promise<VerificationResult> {\n\t\tif (conditions.length === 0) {\n\t\t\treturn { pass: false, confidence: 0, evidencePointers: [], failures: [\"no postconditions\"] };\n\t\t}\n\t\tconst results: VerificationResult[] = [];\n\t\tfor (const condition of conditions) {\n\t\t\tresults.push(await this.verifyOne(condition, ctx));\n\t\t}\n\t\treturn {\n\t\t\tpass: results.every((result) => result.pass),\n\t\t\tconfidence: Math.min(...results.map((result) => result.confidence)),\n\t\t\tevidencePointers: results.flatMap((result) => result.evidencePointers),\n\t\t\tfailures: results.flatMap((result) => result.failures),\n\t\t\treceiptId: results.find((result) => result.receiptId)?.receiptId,\n\t\t};\n\t}\n\n\tprivate async verifyOne(condition: Postcondition, ctx: VerificationContext): Promise<VerificationResult> {\n\t\tswitch (condition.kind) {\n\t\t\tcase \"api-status\":\n\t\t\t\treturn booleanResult(ctx.apiStatus === condition.status, \"api-status\", `status ${condition.status}`);\n\t\t\tcase \"api-json\": {\n\t\t\t\tconst actual = readJsonPath(ctx.apiBody, condition.jsonPath);\n\t\t\t\treturn booleanResult(deepEqual(actual, condition.expected), \"api-json\", condition.jsonPath);\n\t\t\t}\n\t\t\tcase \"text\": {\n\t\t\t\tconst text = ctx.text ?? \"\";\n\t\t\t\tconst pass =\n\t\t\t\t\tcondition.exact !== undefined\n\t\t\t\t\t\t? text.includes(condition.exact)\n\t\t\t\t\t\t: condition.pattern !== undefined && new RegExp(condition.pattern).test(text);\n\t\t\t\treturn booleanResult(pass, \"text\", condition.exact ?? condition.pattern ?? \"<missing>\");\n\t\t\t}\n\t\t\tcase \"url\": {\n\t\t\t\tconst currentUrl = ctx.currentUrl;\n\t\t\t\tif (typeof currentUrl !== \"string\") {\n\t\t\t\t\treturn booleanResult(false, \"url\", \"<missing>\");\n\t\t\t\t}\n\t\t\t\tconst parsedUrl = new URL(currentUrl);\n\t\t\t\tlet pass = true;\n\t\t\t\tif (condition.origin) pass = parsedUrl.origin === condition.origin;\n\t\t\t\tif (pass && condition.path) pass = parsedUrl.pathname === condition.path;\n\t\t\t\tif (pass && condition.pattern) pass = new RegExp(condition.pattern).test(currentUrl);\n\t\t\t\treturn booleanResult(pass, \"url\", currentUrl ?? \"<missing>\");\n\t\t\t}\n\t\t\tcase \"file-exists\":\n\t\t\t\treturn verifyFile(condition.path, condition.sha256, \"file-exists\");\n\t\t\tcase \"download\":\n\t\t\t\treturn verifyFile(condition.path, condition.sha256, \"download\");\n\t\t\tcase \"receipt\": {\n\t\t\t\tconst receiptId = ctx.receiptId;\n\t\t\t\tconst pass = typeof receiptId === \"string\" && new RegExp(condition.idPattern).test(receiptId);\n\t\t\t\treturn { ...booleanResult(pass, \"receipt\", receiptId ?? \"<missing>\"), receiptId };\n\t\t\t}\n\t\t\tcase \"database\": {\n\t\t\t\tconst actualHash = ctx.databaseHashes?.[condition.queryId];\n\t\t\t\treturn booleanResult(actualHash === condition.expectedHash, \"database\", condition.queryId);\n\t\t\t}\n\t\t\tcase \"element-visible\": {\n\t\t\t\tconst pass = (ctx.elements ?? []).some(\n\t\t\t\t\t(element) =>\n\t\t\t\t\t\telement.visible === true &&\n\t\t\t\t\t\t(condition.ref === undefined || element.ref === condition.ref) &&\n\t\t\t\t\t\t(condition.role === undefined || element.role === condition.role) &&\n\t\t\t\t\t\t(condition.name === undefined || element.name === condition.name),\n\t\t\t\t);\n\t\t\t\treturn booleanResult(pass, \"element-visible\", condition.ref ?? condition.role ?? condition.name ?? \"<any>\");\n\t\t\t}\n\t\t\tcase \"element-value\": {\n\t\t\t\tconst pass = (ctx.elements ?? []).some(\n\t\t\t\t\t(element) => element.ref === condition.ref && element.value === condition.expected,\n\t\t\t\t);\n\t\t\t\treturn booleanResult(pass, \"element-value\", condition.ref);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport interface ApiAction {\n\tactionId: string;\n\tmethod: ApiMethod;\n\turl: string;\n\theaders: Record<string, string>;\n\tbody?: unknown;\n\tcredentialRefs: string[];\n\texpectedPostconditions: Postcondition[];\n\tidempotencyKey?: string;\n}\n\nexport interface ApiOutcome {\n\tkind: \"succeeded\" | \"failed_before_commit\" | \"succeeded_unverified\" | \"unknown_after_dispatch\";\n\tstatus?: number;\n\tbodyHash?: string;\n\treceiptId?: string;\n\tredactedBody?: unknown;\n}\n\nexport interface BrokerFetchRequest {\n\tmethod: ApiMethod;\n\theaders: Record<string, string>;\n\tbody?: string;\n\tsignal?: AbortSignal;\n}\n\nexport interface BrokerFetchResponse {\n\tstatus: number;\n\tjson(): Promise<unknown>;\n\ttext(): Promise<string>;\n}\n\nexport type BrokerFetcher = (url: string, init: BrokerFetchRequest) => Promise<BrokerFetchResponse>;\n\nexport class ApiBroker {\n\tprivate readonly ledger: EvidenceLedger;\n\tprivate readonly verifier: PostconditionVerifier;\n\tprivate readonly fetcher: BrokerFetcher;\n\n\tconstructor(args: { ledger: EvidenceLedger; verifier: PostconditionVerifier; fetcher?: BrokerFetcher }) {\n\t\tthis.ledger = args.ledger;\n\t\tthis.verifier = args.verifier;\n\t\tthis.fetcher = args.fetcher ?? defaultFetcher;\n\t}\n\n\tasync execute(\n\t\taction: ApiAction,\n\t\tctx: { signal?: AbortSignal; profile?: AutonomyProfile } = {},\n\t): Promise<ApiOutcome> {\n\t\tconst idempotencyKey = action.idempotencyKey ?? deriveIdempotencyKey(action);\n\t\tconst headers = { ...action.headers, \"Idempotency-Key\": idempotencyKey, \"X-OMK-Action-Id\": action.actionId };\n\t\tawait this.ledger.append({\n\t\t\tactor: \"api\",\n\t\t\tkind: \"api.dispatch.planned\",\n\t\t\tactionId: action.actionId,\n\t\t\tinputHash: canonicalHash({ method: action.method, url: action.url, headers, body: action.body }),\n\t\t\toutcome: \"planned\",\n\t\t});\n\n\t\tlet response: BrokerFetchResponse;\n\t\ttry {\n\t\t\tresponse = await this.fetcher(action.url, {\n\t\t\t\tmethod: action.method,\n\t\t\t\theaders,\n\t\t\t\tbody: action.body === undefined ? undefined : JSON.stringify(action.body),\n\t\t\t\tsignal: ctx.signal,\n\t\t\t});\n\t\t} catch {\n\t\t\treturn this.reconcileUnknown(action, idempotencyKey, ctx.profile ?? AUTOPILOT_MAX);\n\t\t}\n\n\t\tconst rawBody = await safeReadJsonOrText(response);\n\t\tconst redactedBody = redactForModel(rawBody);\n\t\tawait this.ledger.append({\n\t\t\tactor: \"api\",\n\t\t\tkind: \"api.response\",\n\t\t\tactionId: action.actionId,\n\t\t\toutputHash: canonicalHash(rawBody),\n\t\t\tredactedOutputHash: canonicalHash(redactedBody),\n\t\t\toutcome: \"executed\",\n\t\t});\n\t\tconst verification = await this.verifier.verify(action.expectedPostconditions, {\n\t\t\tapiStatus: response.status,\n\t\t\tapiBody: rawBody,\n\t\t\treceiptId: readReceiptId(rawBody),\n\t\t});\n\t\tif (!verification.pass) {\n\t\t\treturn {\n\t\t\t\tkind: \"succeeded_unverified\",\n\t\t\t\tstatus: response.status,\n\t\t\t\tbodyHash: canonicalHash(rawBody),\n\t\t\t\tredactedBody,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"succeeded\",\n\t\t\tstatus: response.status,\n\t\t\tbodyHash: canonicalHash(rawBody),\n\t\t\treceiptId: verification.receiptId,\n\t\t\tredactedBody,\n\t\t};\n\t}\n\n\tprivate async reconcileUnknown(\n\t\taction: ApiAction,\n\t\tidempotencyKey: string,\n\t\tprofile: AutonomyProfile,\n\t): Promise<ApiOutcome> {\n\t\tfor (let attempt = 0; attempt < profile.browser.maxUnknownOutcomeReconciliations; attempt++) {\n\t\t\tconst verification = await this.verifier.verify(action.expectedPostconditions, { receiptId: idempotencyKey });\n\t\t\tif (verification.pass) {\n\t\t\t\tawait this.ledger.append({\n\t\t\t\t\tactor: \"recovery\",\n\t\t\t\t\tkind: \"api.unknown.reconciled\",\n\t\t\t\t\tactionId: action.actionId,\n\t\t\t\t\toutcome: \"reconciled\",\n\t\t\t\t});\n\t\t\t\treturn { kind: \"succeeded\", receiptId: verification.receiptId };\n\t\t\t}\n\t\t}\n\t\tawait this.ledger.append({\n\t\t\tactor: \"recovery\",\n\t\t\tkind: \"api.unknown.unresolved\",\n\t\t\tactionId: action.actionId,\n\t\t\toutcome: \"unknown_after_dispatch\",\n\t\t});\n\t\treturn { kind: \"unknown_after_dispatch\" };\n\t}\n}\n\nexport interface ExecutionStrategy {\n\texecute: boolean;\n\trequirePostcondition: boolean;\n\trequireIdempotency: boolean;\n\trecovery: \"retry\" | \"repair\" | \"reconcile-and-compensate\";\n\tevidenceDepth: \"minimal\" | \"normal\" | \"deep\" | \"forensic\";\n}\n\nexport function strategyForRisk(risk: RiskLevel): ExecutionStrategy {\n\tif (risk === \"R0\") {\n\t\treturn {\n\t\t\texecute: true,\n\t\t\trequirePostcondition: false,\n\t\t\trequireIdempotency: false,\n\t\t\trecovery: \"retry\",\n\t\t\tevidenceDepth: \"minimal\",\n\t\t};\n\t}\n\tif (risk === \"R1\") {\n\t\treturn {\n\t\t\texecute: true,\n\t\t\trequirePostcondition: true,\n\t\t\trequireIdempotency: false,\n\t\t\trecovery: \"retry\",\n\t\t\tevidenceDepth: \"normal\",\n\t\t};\n\t}\n\tif (risk === \"R2\") {\n\t\treturn {\n\t\t\texecute: true,\n\t\t\trequirePostcondition: true,\n\t\t\trequireIdempotency: true,\n\t\t\trecovery: \"repair\",\n\t\t\tevidenceDepth: \"deep\",\n\t\t};\n\t}\n\treturn {\n\t\texecute: true,\n\t\trequirePostcondition: true,\n\t\trequireIdempotency: true,\n\t\trecovery: \"reconcile-and-compensate\",\n\t\tevidenceDepth: \"forensic\",\n\t};\n}\n\nexport interface ToolExecutionNeed {\n\tactionId: string;\n\trequiredCapability: Capability;\n\trisk: RiskLevel;\n\trequiredPostconditions: Postcondition[];\n\tcontextFingerprint?: string;\n}\n\nexport interface ToolExecutionCandidate {\n\ttoolId: string;\n\tcapability: Capability;\n\tschemaHash: string;\n\treliability: number;\n\tverificationStrength: number;\n\tavgLatencyMs: number;\n\tcostUsd: number;\n\tsupportsIdempotency: boolean;\n\tenabled: boolean;\n\tcontextFingerprint?: string;\n}\n\nexport interface ToolExecutionChoice {\n\tcandidate: ToolExecutionCandidate;\n\tscore: number;\n\tstrategy: ExecutionStrategy;\n\treasons: string[];\n}\n\nexport class DynamicToolPortfolioOptimizer {\n\trank(candidates: ToolExecutionCandidate[], need: ToolExecutionNeed): ToolExecutionChoice[] {\n\t\treturn candidates\n\t\t\t.filter((candidate) => candidate.enabled && candidate.capability === need.requiredCapability)\n\t\t\t.map((candidate) => this.scoreCandidate(candidate, need))\n\t\t\t.sort((left, right) => right.score - left.score);\n\t}\n\n\tscoreCandidate(candidate: ToolExecutionCandidate, need: ToolExecutionNeed): ToolExecutionChoice {\n\t\tconst strategy = strategyForRisk(need.risk);\n\t\tconst contextMatch =\n\t\t\tneed.contextFingerprint === undefined || candidate.contextFingerprint === need.contextFingerprint ? 1 : 0;\n\t\tconst idempotency = !strategy.requireIdempotency || candidate.supportsIdempotency ? 1 : 0;\n\t\tconst latency = Math.max(0, 1 - candidate.avgLatencyMs / 30000);\n\t\tconst cost = Math.max(0, 1 - candidate.costUsd / Math.max(1, AUTOPILOT_MAX.budgets.maxCostUsd));\n\t\tconst postconditionCoverage = need.requiredPostconditions.length > 0 ? candidate.verificationStrength : 1;\n\t\tconst score =\n\t\t\t0.32 * candidate.reliability +\n\t\t\t0.26 * postconditionCoverage +\n\t\t\t0.16 * idempotency +\n\t\t\t0.12 * contextMatch +\n\t\t\t0.08 * latency +\n\t\t\t0.06 * cost;\n\t\treturn {\n\t\t\tcandidate,\n\t\t\tscore: Number(score.toFixed(4)),\n\t\t\tstrategy,\n\t\t\treasons: [\n\t\t\t\t`reliability=${candidate.reliability}`,\n\t\t\t\t`verification=${postconditionCoverage}`,\n\t\t\t\t`idempotency=${idempotency}`,\n\t\t\t\t`context=${contextMatch}`,\n\t\t\t],\n\t\t};\n\t}\n}\n\nexport class ToolExecutionBroker {\n\tprivate readonly ledger: EvidenceLedger;\n\tprivate readonly profile: AutonomyProfile;\n\tprivate readonly optimizer: DynamicToolPortfolioOptimizer;\n\n\tconstructor(args: {\n\t\tledger: EvidenceLedger;\n\t\tprofile?: AutonomyProfile;\n\t\toptimizer?: DynamicToolPortfolioOptimizer;\n\t}) {\n\t\tthis.ledger = args.ledger;\n\t\tthis.profile = args.profile ?? AUTOPILOT_MAX;\n\t\tthis.optimizer = args.optimizer ?? new DynamicToolPortfolioOptimizer();\n\t}\n\n\tasync select(need: ToolExecutionNeed, candidates: ToolExecutionCandidate[]): Promise<ToolExecutionChoice> {\n\t\tconst choices = this.optimizer.rank(candidates, need);\n\t\tconst choice = choices[0];\n\t\tif (choice === undefined) {\n\t\t\tthrow new Error(`No enabled tool candidate for ${need.requiredCapability}`);\n\t\t}\n\t\tawait this.ledger.append({\n\t\t\tactor: \"tool\",\n\t\t\tkind: \"tool.execution.planned\",\n\t\t\tactionId: need.actionId,\n\t\t\tinputHash: canonicalHash(need),\n\t\t\tpolicyHash: canonicalHash(this.profile),\n\t\t\tschemaHash: choice.candidate.schemaHash,\n\t\t\toutcome: \"planned\",\n\t\t});\n\t\treturn choice;\n\t}\n\n\tasync recordResult(choice: ToolExecutionChoice, result: VerificationResult): Promise<EvidenceEvent> {\n\t\treturn this.ledger.append({\n\t\t\tactor: \"tool\",\n\t\t\tkind: \"tool.execution.result\",\n\t\t\tactionId: choice.candidate.toolId,\n\t\t\toutputHash: canonicalHash(result),\n\t\t\tschemaHash: choice.candidate.schemaHash,\n\t\t\toutcome: result.pass ? \"verified\" : \"unknown_after_dispatch\",\n\t\t});\n\t}\n}\n\nexport interface AutomationTraceAction {\n\tkind: \"tool\" | \"browser\" | \"api\" | \"mcp\" | \"extension\";\n\tverificationPass: boolean;\n\tschemaHashMatched?: boolean;\n\tenvUseLedgered?: boolean;\n\ttargetFingerprintMatched?: boolean;\n\toutcome?: \"unknown_after_dispatch\" | \"succeeded\" | \"failed\";\n\treconciled?: boolean;\n}\n\nexport interface AutomationTraceEnvApiUse {\n\tledgered: boolean;\n\texposedToModel: boolean;\n\texposedToLogs: boolean;\n}\n\nexport interface AutomationTraceContextPlan {\n\trenderedTokens: number;\n\tresourceBudget: number;\n\tplanHash: string;\n\trenderedHashLinkedPlanHash: string;\n\toutputReserveCountedOnce: boolean;\n}\n\nexport interface AutomationTrace {\n\tactions: AutomationTraceAction[];\n\tverifications: Array<{ conditionHash: string; pass: boolean }>;\n\thumanPrompts: number;\n\tenvApiUses: AutomationTraceEnvApiUse[];\n\tfailures: number;\n\tunknownOutcomes: number;\n\trecoveredFailures: number;\n\treconciledUnknowns: number;\n\tsecretLeaks: number;\n\tduplicateIrreversibleMutations: number;\n\tunledgeredEnvUses: number;\n\treplayMatches: boolean;\n\tcontextPlans: AutomationTraceContextPlan[];\n}\n\nexport interface AutomationHarnessScoreInput {\n\trequiredPostconditions: Postcondition[];\n\ttrace: AutomationTrace;\n}\n\nexport interface AutomationScoreBreakdown {\n\tscore: number;\n\tverifiedSuccess: boolean;\n\tenvApiUseCorrectness: number;\n\tduplicateMutations: number;\n\tsecretLeaks: number;\n\tcritical: boolean;\n}\n\nexport class AutomationHarnessScorer {\n\tscore(input: AutomationHarnessScoreInput): AutomationScoreBreakdown {\n\t\tconst verifiedSuccess = this.verifiedSuccess(input);\n\t\tconst autonomy = 1 - input.trace.humanPrompts / Math.max(1, input.trace.actions.length);\n\t\tconst toolUse = this.toolUseScore(input.trace);\n\t\tconst browserUse = this.browserUseScore(input.trace);\n\t\tconst envApi = this.envApiScore(input.trace);\n\t\tconst recovery = this.recoveryScore(input.trace);\n\t\tconst determinism = input.trace.replayMatches ? 1 : 0;\n\t\tconst context = this.contextScore(input.trace);\n\t\tconst critical =\n\t\t\tinput.trace.secretLeaks > 0 ||\n\t\t\tinput.trace.duplicateIrreversibleMutations > 0 ||\n\t\t\t(input.requiredPostconditions.length > 0 && verifiedSuccess < 1) ||\n\t\t\t!input.trace.replayMatches ||\n\t\t\tinput.trace.unledgeredEnvUses > 0 ||\n\t\t\tinput.trace.envApiUses.some((use) => !use.ledgered) ||\n\t\t\tinput.trace.actions.some(\n\t\t\t\t(action) =>\n\t\t\t\t\taction.schemaHashMatched === false ||\n\t\t\t\t\t(action.kind === \"browser\" && action.targetFingerprintMatched === false),\n\t\t\t);\n\t\tconst raw =\n\t\t\t20 * verifiedSuccess +\n\t\t\t15 * autonomy +\n\t\t\t15 * toolUse +\n\t\t\t15 * browserUse +\n\t\t\t10 * envApi +\n\t\t\t10 * recovery +\n\t\t\t10 * determinism +\n\t\t\t5 * context;\n\t\treturn {\n\t\t\tscore: critical ? Math.min(79, raw) : raw,\n\t\t\tverifiedSuccess: verifiedSuccess >= 0.93,\n\t\t\tenvApiUseCorrectness: envApi,\n\t\t\tduplicateMutations: input.trace.duplicateIrreversibleMutations,\n\t\t\tsecretLeaks: input.trace.secretLeaks,\n\t\t\tcritical,\n\t\t};\n\t}\n\n\tprivate verifiedSuccess(input: AutomationHarnessScoreInput): number {\n\t\tconst passed = input.requiredPostconditions.filter((condition) =>\n\t\t\tinput.trace.verifications.some(\n\t\t\t\t(verification) => verification.conditionHash === canonicalHash(condition) && verification.pass,\n\t\t\t),\n\t\t);\n\t\treturn passed.length / Math.max(1, input.requiredPostconditions.length);\n\t}\n\n\tprivate toolUseScore(trace: AutomationTrace): number {\n\t\tconst calls = trace.actions.filter((action) => action.kind === \"tool\");\n\t\tif (calls.length === 0) return 1;\n\t\tconst verified = calls.filter((action) => action.verificationPass).length;\n\t\tconst schemaStable = calls.filter((action) => action.schemaHashMatched === true).length;\n\t\tconst envLedgered = calls.filter((action) => action.envUseLedgered === true).length;\n\t\treturn (verified + schemaStable + envLedgered) / (3 * calls.length);\n\t}\n\n\tprivate browserUseScore(trace: AutomationTrace): number {\n\t\tconst actions = trace.actions.filter((action) => action.kind === \"browser\");\n\t\tif (actions.length === 0) return 1;\n\t\tconst verified = actions.filter((action) => action.verificationPass).length;\n\t\tconst targetStable = actions.filter((action) => action.targetFingerprintMatched === true).length;\n\t\tconst unknownResolved = actions.filter(\n\t\t\t(action) => action.outcome !== \"unknown_after_dispatch\" || action.reconciled === true,\n\t\t).length;\n\t\treturn (verified + targetStable + unknownResolved) / (3 * actions.length);\n\t}\n\n\tprivate envApiScore(trace: AutomationTrace): number {\n\t\tif (trace.envApiUses.length === 0) return 1;\n\t\tconst ledgered = trace.envApiUses.filter((use) => use.ledgered).length;\n\t\tconst notLeaked = trace.envApiUses.filter((use) => !use.exposedToModel && !use.exposedToLogs).length;\n\t\treturn (ledgered + notLeaked) / (2 * trace.envApiUses.length);\n\t}\n\n\tprivate recoveryScore(trace: AutomationTrace): number {\n\t\tconst failures = trace.failures + trace.unknownOutcomes;\n\t\tif (failures === 0) return 1;\n\t\treturn (trace.recoveredFailures + trace.reconciledUnknowns) / failures;\n\t}\n\n\tprivate contextScore(trace: AutomationTrace): number {\n\t\tif (trace.contextPlans.length === 0) return 1;\n\t\tconst valid = trace.contextPlans.filter(\n\t\t\t(plan) =>\n\t\t\t\tplan.renderedTokens <= plan.resourceBudget &&\n\t\t\t\tplan.planHash === plan.renderedHashLinkedPlanHash &&\n\t\t\t\tplan.outputReserveCountedOnce,\n\t\t).length;\n\t\treturn valid / trace.contextPlans.length;\n\t}\n}\n\nexport function classifyEnvKey(key: string, value: string): Sensitivity {\n\tconst normalizedKey = key.toUpperCase();\n\tif (\n\t\tnormalizedKey.includes(\"TOKEN\") ||\n\t\tnormalizedKey.includes(\"SECRET\") ||\n\t\tnormalizedKey.includes(\"PASSWORD\") ||\n\t\tnormalizedKey.includes(\"API_KEY\") ||\n\t\tnormalizedKey.endsWith(\"_KEY\") ||\n\t\tnormalizedKey.startsWith(\"AWS_\") ||\n\t\tnormalizedKey.startsWith(\"GCP_\") ||\n\t\tnormalizedKey.startsWith(\"AZURE_\") ||\n\t\tnormalizedKey.startsWith(\"OPENAI_\") ||\n\t\tnormalizedKey.startsWith(\"ANTHROPIC_\") ||\n\t\tnormalizedKey.startsWith(\"GITHUB_\") ||\n\t\tnormalizedKey.startsWith(\"NPM_\")\n\t) {\n\t\treturn \"credential\";\n\t}\n\tif (looksLikePaymentCredential(value)) return \"payment\";\n\tif (looksLikeSessionCookie(value)) return \"session\";\n\treturn \"public\";\n}\n\nexport function canonicalHash(value: unknown): string {\n\treturn sha256(stableStringify(value));\n}\n\nexport function redactForModel(value: unknown): unknown {\n\tif (typeof value === \"string\") return redactString(value);\n\tif (Array.isArray(value)) return value.map((item) => redactForModel(item));\n\tif (isRecord(value)) {\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [key, child] of Object.entries(value)) {\n\t\t\tout[key] =\n\t\t\t\tclassifyEnvKey(key, typeof child === \"string\" ? child : \"\") === \"public\"\n\t\t\t\t\t? redactForModel(child)\n\t\t\t\t\t: \"[REDACTED]\";\n\t\t}\n\t\treturn out;\n\t}\n\treturn value;\n}\n\nfunction booleanResult(pass: boolean, kind: string, description: string): VerificationResult {\n\treturn {\n\t\tpass,\n\t\tconfidence: pass ? 1 : 0,\n\t\tevidencePointers: pass ? [{ kind, description }] : [],\n\t\tfailures: pass ? [] : [`${kind} postcondition failed: ${description}`],\n\t};\n}\n\nasync function verifyFile(path: string, expectedHash: string | undefined, kind: string): Promise<VerificationResult> {\n\ttry {\n\t\tawait stat(path);\n\t\tconst content = await readFile(path);\n\t\tconst actualHash = createHash(\"sha256\").update(content).digest(\"hex\");\n\t\tconst pass = expectedHash === undefined || expectedHash === actualHash;\n\t\treturn {\n\t\t\tpass,\n\t\t\tconfidence: pass ? 1 : 0,\n\t\t\tevidencePointers: pass ? [{ kind, description: path, sha256: actualHash }] : [],\n\t\t\tfailures: pass ? [] : [`${kind} hash mismatch for ${path}`],\n\t\t};\n\t} catch {\n\t\treturn { pass: false, confidence: 0, evidencePointers: [], failures: [`${kind} missing: ${path}`] };\n\t}\n}\n\nfunction readJsonPath(value: unknown, path: string): unknown {\n\tif (path === \"$\") return value;\n\tif (!path.startsWith(\"$.\")) return undefined;\n\tlet current = value;\n\tfor (const segment of path.slice(2).split(\".\")) {\n\t\tif (!isRecord(current)) return undefined;\n\t\tcurrent = current[segment];\n\t}\n\treturn current;\n}\n\nfunction readReceiptId(value: unknown): string | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst receipt = value.receiptId ?? value.id;\n\treturn typeof receipt === \"string\" ? receipt : undefined;\n}\n\nasync function safeReadJsonOrText(response: BrokerFetchResponse): Promise<unknown> {\n\ttry {\n\t\treturn await response.json();\n\t} catch {\n\t\treturn response.text();\n\t}\n}\n\nfunction deriveIdempotencyKey(action: ApiAction): string {\n\treturn `omk-${canonicalHash({ method: action.method, url: action.url, body: action.body, actionId: action.actionId }).slice(0, 24)}`;\n}\n\nasync function defaultFetcher(url: string, init: BrokerFetchRequest): Promise<BrokerFetchResponse> {\n\tconst response = await fetch(url, init);\n\treturn {\n\t\tstatus: response.status,\n\t\tjson: () => response.json() as Promise<unknown>,\n\t\ttext: () => response.text(),\n\t};\n}\n\nfunction redactString(value: string): string {\n\treturn value\n\t\t.replace(/Bearer\\s+[A-Za-z0-9._~+/=-]{8,}/g, \"Bearer [REDACTED]\")\n\t\t.replace(/([?&]?(?:access_)?token=)[^&\\s]+/gi, \"$1[REDACTED]\")\n\t\t.replace(/((?:api[_-]?key|password|secret)=)[^&\\s]+/gi, \"$1[REDACTED]\");\n}\n\nfunction deepEqual(left: unknown, right: unknown): boolean {\n\treturn stableStringify(left) === stableStringify(right);\n}\n\nfunction stableStringify(value: unknown): string {\n\tif (value === null || typeof value !== \"object\") return JSON.stringify(value);\n\tif (Array.isArray(value)) return `[${value.map((item) => stableStringify(item)).join(\",\")}]`;\n\tconst record = value as Record<string, unknown>;\n\treturn `{${Object.keys(record)\n\t\t.sort()\n\t\t.map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`)\n\t\t.join(\",\")}}`;\n}\n\nfunction matchesAny(value: string, patterns: string[]): boolean {\n\treturn patterns.some((pattern) => pattern === \"*\" || globMatch(value, pattern));\n}\n\nfunction globMatch(value: string, pattern: string): boolean {\n\tconst escaped = pattern\n\t\t.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\t\t.replace(/\\*/g, \".*\")\n\t\t.replace(/\\?/g, \".\");\n\treturn new RegExp(`^${escaped}$`, \"i\").test(value);\n}\n\nfunction sha256(value: string): string {\n\treturn createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction looksLikePaymentCredential(value: string): boolean {\n\treturn /\\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})\\b/.test(value);\n}\n\nfunction looksLikeSessionCookie(value: string): boolean {\n\treturn value.length >= 32 && /[A-Za-z0-9+/=_-]{32,}/.test(value);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"]}