@paybond/kit 0.9.8 → 0.11.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 (368) hide show
  1. package/completion-presets/catalog.json +1187 -0
  2. package/completion-presets/catalog.sha256 +1 -0
  3. package/dev/trace-ui/dashboard.html +617 -0
  4. package/dist/agent/adapter.d.ts +51 -0
  5. package/dist/agent/adapter.js +66 -0
  6. package/dist/agent/attach-bundle.d.ts +37 -0
  7. package/dist/agent/attach-bundle.js +118 -0
  8. package/dist/agent/authorization-cache.d.ts +22 -0
  9. package/dist/agent/authorization-cache.js +36 -0
  10. package/dist/agent/deferred-tools.d.ts +11 -0
  11. package/dist/agent/deferred-tools.js +62 -0
  12. package/dist/agent/discover.d.ts +41 -0
  13. package/dist/agent/discover.js +147 -0
  14. package/dist/agent/evidence.d.ts +9 -0
  15. package/dist/agent/evidence.js +28 -0
  16. package/dist/agent/facade.d.ts +48 -0
  17. package/dist/agent/facade.js +112 -0
  18. package/dist/agent/gateway-trace-reporter.d.ts +28 -0
  19. package/dist/agent/gateway-trace-reporter.js +49 -0
  20. package/dist/agent/generic-runner.d.ts +14 -0
  21. package/dist/agent/generic-runner.js +49 -0
  22. package/dist/agent/generic-sandbox-demo.d.ts +36 -0
  23. package/dist/agent/generic-sandbox-demo.js +82 -0
  24. package/dist/agent/guarded-agent.d.ts +49 -0
  25. package/dist/agent/guarded-agent.js +100 -0
  26. package/dist/agent/index.d.ts +13 -0
  27. package/dist/agent/index.js +13 -0
  28. package/dist/agent/instrument.d.ts +156 -0
  29. package/dist/agent/instrument.js +442 -0
  30. package/dist/agent/interceptor.d.ts +24 -0
  31. package/dist/agent/interceptor.js +440 -0
  32. package/dist/agent/lazy-context-tools.d.ts +15 -0
  33. package/dist/agent/lazy-context-tools.js +81 -0
  34. package/dist/agent/registry-file.d.ts +39 -0
  35. package/dist/agent/registry-file.js +219 -0
  36. package/dist/agent/registry.d.ts +37 -0
  37. package/dist/agent/registry.js +128 -0
  38. package/dist/agent/run.d.ts +124 -0
  39. package/dist/agent/run.js +301 -0
  40. package/dist/agent/types.d.ts +318 -0
  41. package/dist/agent/types.js +42 -0
  42. package/dist/agent-recognition.d.ts +72 -0
  43. package/dist/agent-recognition.js +165 -0
  44. package/dist/bincode-wire.d.ts +18 -0
  45. package/dist/bincode-wire.js +93 -0
  46. package/dist/claude-agents/config.d.ts +21 -0
  47. package/dist/claude-agents/config.js +145 -0
  48. package/dist/claude-agents/index.d.ts +2 -0
  49. package/dist/claude-agents/index.js +2 -0
  50. package/dist/claude-agents/sandbox-demo.d.ts +30 -0
  51. package/dist/claude-agents/sandbox-demo.js +91 -0
  52. package/dist/cli/agent/env-quote.d.ts +1 -0
  53. package/dist/cli/agent/env-quote.js +6 -0
  54. package/dist/cli/agent/env-write.d.ts +8 -0
  55. package/dist/cli/agent/env-write.js +47 -0
  56. package/dist/cli/agent/paybond.d.ts +16 -0
  57. package/dist/cli/agent/paybond.js +55 -0
  58. package/dist/cli/agent/policy-file.d.ts +29 -0
  59. package/dist/cli/agent/policy-file.js +61 -0
  60. package/dist/cli/agent/production-evidence.d.ts +24 -0
  61. package/dist/cli/agent/production-evidence.js +98 -0
  62. package/dist/cli/agent/run-store.d.ts +30 -0
  63. package/dist/cli/agent/run-store.js +42 -0
  64. package/dist/cli/agent/run-trace-store.d.ts +39 -0
  65. package/dist/cli/agent/run-trace-store.js +143 -0
  66. package/dist/cli/agent-run-trace-table.d.ts +9 -0
  67. package/dist/cli/agent-run-trace-table.js +24 -0
  68. package/dist/cli/agent-sandbox-smoke-checklist.d.ts +9 -0
  69. package/dist/cli/agent-sandbox-smoke-checklist.js +50 -0
  70. package/dist/cli/audit-export.d.ts +7 -0
  71. package/dist/cli/audit-export.js +120 -0
  72. package/dist/cli/automation.d.ts +25 -0
  73. package/dist/cli/automation.js +297 -0
  74. package/dist/cli/body.d.ts +7 -0
  75. package/dist/cli/body.js +22 -0
  76. package/dist/cli/color.d.ts +15 -0
  77. package/dist/cli/color.js +39 -0
  78. package/dist/cli/command-spec.d.ts +13 -0
  79. package/dist/cli/command-spec.js +611 -0
  80. package/dist/cli/commands/agent.d.ts +16 -0
  81. package/dist/cli/commands/agent.js +1135 -0
  82. package/dist/cli/commands/dev.d.ts +7 -0
  83. package/dist/cli/commands/dev.js +348 -0
  84. package/dist/cli/commands/discovery.d.ts +8 -0
  85. package/dist/cli/commands/discovery.js +194 -0
  86. package/dist/cli/commands/policy.d.ts +13 -0
  87. package/dist/cli/commands/policy.js +769 -0
  88. package/dist/cli/commands/setup.d.ts +18 -0
  89. package/dist/cli/commands/setup.js +513 -0
  90. package/dist/cli/commands/workflows.d.ts +7 -0
  91. package/dist/cli/commands/workflows.js +214 -0
  92. package/dist/cli/config.d.ts +16 -0
  93. package/dist/cli/config.js +98 -0
  94. package/dist/cli/context.d.ts +22 -0
  95. package/dist/cli/context.js +110 -0
  96. package/dist/cli/credentials.d.ts +21 -0
  97. package/dist/cli/credentials.js +141 -0
  98. package/dist/cli/doctor-agent-middleware.d.ts +5 -0
  99. package/dist/cli/doctor-agent-middleware.js +49 -0
  100. package/dist/cli/doctor-agent.d.ts +15 -0
  101. package/dist/cli/doctor-agent.js +311 -0
  102. package/dist/cli/envelope.d.ts +14 -0
  103. package/dist/cli/envelope.js +46 -0
  104. package/dist/cli/globals.d.ts +23 -0
  105. package/dist/cli/globals.js +248 -0
  106. package/dist/cli/help.d.ts +3 -0
  107. package/dist/cli/help.js +83 -0
  108. package/dist/cli/mcp-install.d.ts +41 -0
  109. package/dist/cli/mcp-install.js +95 -0
  110. package/dist/cli/mcp-policy.d.ts +26 -0
  111. package/dist/cli/mcp-policy.js +110 -0
  112. package/dist/cli/mcp-verify-config.d.ts +37 -0
  113. package/dist/cli/mcp-verify-config.js +172 -0
  114. package/dist/cli/redact.d.ts +4 -0
  115. package/dist/cli/redact.js +88 -0
  116. package/dist/cli/request-id.d.ts +2 -0
  117. package/dist/cli/request-id.js +5 -0
  118. package/dist/cli/router.d.ts +2 -0
  119. package/dist/cli/router.js +378 -0
  120. package/dist/cli/smoke-deep-links.d.ts +15 -0
  121. package/dist/cli/smoke-deep-links.js +63 -0
  122. package/dist/cli/suggest.d.ts +4 -0
  123. package/dist/cli/suggest.js +58 -0
  124. package/dist/cli/support-diagnostics.d.ts +19 -0
  125. package/dist/cli/support-diagnostics.js +47 -0
  126. package/dist/cli/telemetry.d.ts +17 -0
  127. package/dist/cli/telemetry.js +94 -0
  128. package/dist/cli/types.d.ts +72 -0
  129. package/dist/cli/types.js +60 -0
  130. package/dist/cli/ux.d.ts +8 -0
  131. package/dist/cli/ux.js +164 -0
  132. package/dist/cli.d.ts +2 -0
  133. package/dist/cli.js +38 -0
  134. package/dist/completion-catalog-digest.d.ts +2 -0
  135. package/dist/completion-catalog-digest.js +2 -0
  136. package/dist/completion-catalog-integrity.d.ts +2 -0
  137. package/dist/completion-catalog-integrity.js +17 -0
  138. package/dist/completion-catalog.d.ts +49 -0
  139. package/dist/completion-catalog.js +62 -0
  140. package/dist/completion-contract-digest.d.ts +37 -0
  141. package/dist/completion-contract-digest.js +73 -0
  142. package/dist/completion-forbidden-fields.d.ts +5 -0
  143. package/dist/completion-forbidden-fields.js +26 -0
  144. package/dist/completion-init.d.ts +8 -0
  145. package/dist/completion-init.js +334 -0
  146. package/dist/completion-resolve.d.ts +21 -0
  147. package/dist/completion-resolve.js +86 -0
  148. package/dist/completion-validate-evidence.d.ts +24 -0
  149. package/dist/completion-validate-evidence.js +145 -0
  150. package/dist/dev/offline-gateway.d.ts +24 -0
  151. package/dist/dev/offline-gateway.js +102 -0
  152. package/dist/dev/trace-buffer.d.ts +61 -0
  153. package/dist/dev/trace-buffer.js +330 -0
  154. package/dist/dev/trace-security-headers.d.ts +11 -0
  155. package/dist/dev/trace-security-headers.js +16 -0
  156. package/dist/dev/trace-server.d.ts +8 -0
  157. package/dist/dev/trace-server.js +38 -0
  158. package/dist/dev/trace-ui.d.ts +4 -0
  159. package/dist/dev/trace-ui.js +25 -0
  160. package/dist/dev/wiremock-up.d.ts +15 -0
  161. package/dist/dev/wiremock-up.js +118 -0
  162. package/dist/doctor-completion.d.ts +17 -0
  163. package/dist/doctor-completion.js +428 -0
  164. package/dist/gateway-url.d.ts +7 -0
  165. package/dist/gateway-url.js +69 -0
  166. package/dist/index.d.ts +119 -2
  167. package/dist/index.js +267 -6
  168. package/dist/init.js +380 -68
  169. package/dist/langgraph/awrap-tool-call.d.ts +25 -0
  170. package/dist/langgraph/awrap-tool-call.js +81 -0
  171. package/dist/langgraph/config.d.ts +13 -0
  172. package/dist/langgraph/config.js +11 -0
  173. package/dist/langgraph/index.d.ts +4 -0
  174. package/dist/langgraph/index.js +4 -0
  175. package/dist/langgraph/sandbox-demo.d.ts +40 -0
  176. package/dist/langgraph/sandbox-demo.js +96 -0
  177. package/dist/langgraph/tool-node.d.ts +10 -0
  178. package/dist/langgraph/tool-node.js +38 -0
  179. package/dist/login.d.ts +14 -1
  180. package/dist/login.js +130 -63
  181. package/dist/mcp/index.d.ts +1 -0
  182. package/dist/mcp/index.js +1 -0
  183. package/dist/mcp/tool-surface.d.ts +25 -0
  184. package/dist/mcp/tool-surface.js +17 -0
  185. package/dist/mcp-capability-token-cache.d.ts +24 -0
  186. package/dist/mcp-capability-token-cache.js +101 -0
  187. package/dist/mcp-evidence-policy.d.ts +48 -0
  188. package/dist/mcp-evidence-policy.js +117 -0
  189. package/dist/mcp-policy-reload.d.ts +79 -0
  190. package/dist/mcp-policy-reload.js +200 -0
  191. package/dist/mcp-sep2828-evidence.d.ts +36 -0
  192. package/dist/mcp-sep2828-evidence.js +65 -0
  193. package/dist/mcp-server.d.ts +10 -0
  194. package/dist/mcp-server.js +423 -115
  195. package/dist/openai-agents/index.d.ts +40 -0
  196. package/dist/openai-agents/index.js +151 -0
  197. package/dist/openai-agents/sandbox-demo.d.ts +34 -0
  198. package/dist/openai-agents/sandbox-demo.js +118 -0
  199. package/dist/payee-evidence.js +2 -29
  200. package/dist/policy/catalog.d.ts +31 -0
  201. package/dist/policy/catalog.js +48 -0
  202. package/dist/policy/compose-utils.d.ts +3 -0
  203. package/dist/policy/compose-utils.js +4 -0
  204. package/dist/policy/compose.d.ts +20 -0
  205. package/dist/policy/compose.js +240 -0
  206. package/dist/policy/digest.d.ts +7 -0
  207. package/dist/policy/digest.js +75 -0
  208. package/dist/policy/domain.d.ts +15 -0
  209. package/dist/policy/domain.js +28 -0
  210. package/dist/policy/guardrail-spec.d.ts +17 -0
  211. package/dist/policy/guardrail-spec.js +140 -0
  212. package/dist/policy/guardrails.d.ts +48 -0
  213. package/dist/policy/guardrails.js +72 -0
  214. package/dist/policy/index.d.ts +21 -0
  215. package/dist/policy/index.js +21 -0
  216. package/dist/policy/init.d.ts +102 -0
  217. package/dist/policy/init.js +351 -0
  218. package/dist/policy/intent-spec.d.ts +52 -0
  219. package/dist/policy/intent-spec.js +176 -0
  220. package/dist/policy/json-path.d.ts +4 -0
  221. package/dist/policy/json-path.js +23 -0
  222. package/dist/policy/layers-io.d.ts +7 -0
  223. package/dist/policy/layers-io.js +28 -0
  224. package/dist/policy/load-effective.d.ts +22 -0
  225. package/dist/policy/load-effective.js +77 -0
  226. package/dist/policy/load.d.ts +85 -0
  227. package/dist/policy/load.js +164 -0
  228. package/dist/policy/merge.d.ts +29 -0
  229. package/dist/policy/merge.js +297 -0
  230. package/dist/policy/parse-text.d.ts +2 -0
  231. package/dist/policy/parse-text.js +126 -0
  232. package/dist/policy/policy-api.d.ts +45 -0
  233. package/dist/policy/policy-api.js +61 -0
  234. package/dist/policy/presets.d.ts +19 -0
  235. package/dist/policy/presets.js +66 -0
  236. package/dist/policy/registry.d.ts +7 -0
  237. package/dist/policy/registry.js +33 -0
  238. package/dist/policy/reload.d.ts +86 -0
  239. package/dist/policy/reload.js +233 -0
  240. package/dist/policy/render-yaml.d.ts +3 -0
  241. package/dist/policy/render-yaml.js +69 -0
  242. package/dist/policy/sandbox-bootstrap.d.ts +19 -0
  243. package/dist/policy/sandbox-bootstrap.js +66 -0
  244. package/dist/policy/schema.d.ts +204 -0
  245. package/dist/policy/schema.js +255 -0
  246. package/dist/policy/snapshot.d.ts +33 -0
  247. package/dist/policy/snapshot.js +23 -0
  248. package/dist/policy/validate-remote.d.ts +43 -0
  249. package/dist/policy/validate-remote.js +104 -0
  250. package/dist/policy/validate.d.ts +36 -0
  251. package/dist/policy/validate.js +150 -0
  252. package/dist/policy/watcher.d.ts +29 -0
  253. package/dist/policy/watcher.js +112 -0
  254. package/dist/principal-intent.d.ts +52 -0
  255. package/dist/principal-intent.js +193 -37
  256. package/dist/project-init.d.ts +34 -0
  257. package/dist/project-init.js +898 -0
  258. package/dist/sep2828-signature.d.ts +10 -0
  259. package/dist/sep2828-signature.js +134 -0
  260. package/dist/solutions/api.d.ts +22 -0
  261. package/dist/solutions/api.js +40 -0
  262. package/dist/solutions/catalog.d.ts +34 -0
  263. package/dist/solutions/catalog.js +129 -0
  264. package/dist/solutions/index.d.ts +2 -0
  265. package/dist/solutions/index.js +2 -0
  266. package/dist/template-init.d.ts +54 -0
  267. package/dist/template-init.js +203 -0
  268. package/dist/vercel-ai/config.d.ts +15 -0
  269. package/dist/vercel-ai/config.js +13 -0
  270. package/dist/vercel-ai/index.d.ts +4 -0
  271. package/dist/vercel-ai/index.js +4 -0
  272. package/dist/vercel-ai/sandbox-demo.d.ts +44 -0
  273. package/dist/vercel-ai/sandbox-demo.js +153 -0
  274. package/dist/vercel-ai/tool-approval.d.ts +16 -0
  275. package/dist/vercel-ai/tool-approval.js +41 -0
  276. package/dist/vercel-ai/wrap-tools.d.ts +9 -0
  277. package/dist/vercel-ai/wrap-tools.js +40 -0
  278. package/dist/x402-receipt-evidence.d.ts +29 -0
  279. package/dist/x402-receipt-evidence.js +97 -0
  280. package/dist/x402-receipt-signature.d.ts +12 -0
  281. package/dist/x402-receipt-signature.js +211 -0
  282. package/package.json +79 -4
  283. package/solutions/aws.json +17 -0
  284. package/solutions/saas.json +17 -0
  285. package/solutions/shopping.json +17 -0
  286. package/solutions/travel.json +18 -0
  287. package/templates/manifest.json +169 -0
  288. package/templates/openai-shopping-agent/.env.example +3 -0
  289. package/templates/openai-shopping-agent/.github/workflows/smoke.yml +20 -0
  290. package/templates/openai-shopping-agent/LICENSE +201 -0
  291. package/templates/openai-shopping-agent/README.md +29 -0
  292. package/templates/openai-shopping-agent/package.json +22 -0
  293. package/templates/openai-shopping-agent/paybond.policy.yaml +22 -0
  294. package/templates/openai-shopping-agent/src/index.ts +22 -0
  295. package/templates/openai-shopping-agent/src/paybond.config.ts +51 -0
  296. package/templates/openai-shopping-agent/tsconfig.json +13 -0
  297. package/templates/paybond-aws-operator/.env.example +3 -0
  298. package/templates/paybond-aws-operator/.github/workflows/smoke.yml +20 -0
  299. package/templates/paybond-aws-operator/LICENSE +201 -0
  300. package/templates/paybond-aws-operator/README.md +29 -0
  301. package/templates/paybond-aws-operator/package.json +20 -0
  302. package/templates/paybond-aws-operator/paybond.policy.yaml +22 -0
  303. package/templates/paybond-aws-operator/src/index.ts +54 -0
  304. package/templates/paybond-aws-operator/src/paybond.config.ts +51 -0
  305. package/templates/paybond-aws-operator/tsconfig.json +13 -0
  306. package/templates/paybond-claude-agents-demo/.env.example +3 -0
  307. package/templates/paybond-claude-agents-demo/.github/workflows/smoke.yml +20 -0
  308. package/templates/paybond-claude-agents-demo/LICENSE +201 -0
  309. package/templates/paybond-claude-agents-demo/README.md +29 -0
  310. package/templates/paybond-claude-agents-demo/package.json +22 -0
  311. package/templates/paybond-claude-agents-demo/paybond.policy.yaml +22 -0
  312. package/templates/paybond-claude-agents-demo/src/index.ts +22 -0
  313. package/templates/paybond-claude-agents-demo/src/paybond.config.ts +51 -0
  314. package/templates/paybond-claude-agents-demo/tsconfig.json +13 -0
  315. package/templates/paybond-invoice-agent/.env.example +3 -0
  316. package/templates/paybond-invoice-agent/.github/workflows/smoke.yml +19 -0
  317. package/templates/paybond-invoice-agent/LICENSE +201 -0
  318. package/templates/paybond-invoice-agent/README.md +29 -0
  319. package/templates/paybond-invoice-agent/app.py +27 -0
  320. package/templates/paybond-invoice-agent/package.json +6 -0
  321. package/templates/paybond-invoice-agent/paybond.policy.yaml +22 -0
  322. package/templates/paybond-invoice-agent/paybond_config.py +45 -0
  323. package/templates/paybond-invoice-agent/requirements.txt +2 -0
  324. package/templates/paybond-mcp-coding-agent/.env.example +3 -0
  325. package/templates/paybond-mcp-coding-agent/.github/workflows/smoke.yml +20 -0
  326. package/templates/paybond-mcp-coding-agent/LICENSE +201 -0
  327. package/templates/paybond-mcp-coding-agent/README.md +39 -0
  328. package/templates/paybond-mcp-coding-agent/package.json +20 -0
  329. package/templates/paybond-mcp-coding-agent/paybond.policy.yaml +25 -0
  330. package/templates/paybond-mcp-coding-agent/src/index.ts +40 -0
  331. package/templates/paybond-mcp-coding-agent/src/paybond.config.ts +51 -0
  332. package/templates/paybond-mcp-coding-agent/tsconfig.json +13 -0
  333. package/templates/paybond-openai-agents-demo/.env.example +3 -0
  334. package/templates/paybond-openai-agents-demo/.github/workflows/smoke.yml +20 -0
  335. package/templates/paybond-openai-agents-demo/LICENSE +201 -0
  336. package/templates/paybond-openai-agents-demo/README.md +29 -0
  337. package/templates/paybond-openai-agents-demo/package.json +22 -0
  338. package/templates/paybond-openai-agents-demo/paybond.policy.yaml +22 -0
  339. package/templates/paybond-openai-agents-demo/src/index.ts +22 -0
  340. package/templates/paybond-openai-agents-demo/src/paybond.config.ts +51 -0
  341. package/templates/paybond-openai-agents-demo/tsconfig.json +13 -0
  342. package/templates/paybond-procurement-agent/.env.example +3 -0
  343. package/templates/paybond-procurement-agent/.github/workflows/smoke.yml +20 -0
  344. package/templates/paybond-procurement-agent/LICENSE +201 -0
  345. package/templates/paybond-procurement-agent/README.md +29 -0
  346. package/templates/paybond-procurement-agent/package.json +20 -0
  347. package/templates/paybond-procurement-agent/paybond.policy.yaml +25 -0
  348. package/templates/paybond-procurement-agent/src/index.ts +54 -0
  349. package/templates/paybond-procurement-agent/src/paybond.config.ts +51 -0
  350. package/templates/paybond-procurement-agent/tsconfig.json +13 -0
  351. package/templates/paybond-travel-agent/.env.example +3 -0
  352. package/templates/paybond-travel-agent/.github/workflows/smoke.yml +20 -0
  353. package/templates/paybond-travel-agent/LICENSE +201 -0
  354. package/templates/paybond-travel-agent/README.md +29 -0
  355. package/templates/paybond-travel-agent/package.json +23 -0
  356. package/templates/paybond-travel-agent/paybond.policy.yaml +22 -0
  357. package/templates/paybond-travel-agent/src/index.ts +22 -0
  358. package/templates/paybond-travel-agent/src/paybond.config.ts +51 -0
  359. package/templates/paybond-travel-agent/tsconfig.json +13 -0
  360. package/templates/paybond-vercel-shopping-agent/.env.example +3 -0
  361. package/templates/paybond-vercel-shopping-agent/.github/workflows/smoke.yml +20 -0
  362. package/templates/paybond-vercel-shopping-agent/LICENSE +201 -0
  363. package/templates/paybond-vercel-shopping-agent/README.md +29 -0
  364. package/templates/paybond-vercel-shopping-agent/package.json +22 -0
  365. package/templates/paybond-vercel-shopping-agent/paybond.policy.yaml +22 -0
  366. package/templates/paybond-vercel-shopping-agent/src/index.ts +22 -0
  367. package/templates/paybond-vercel-shopping-agent/src/paybond.config.ts +51 -0
  368. package/templates/paybond-vercel-shopping-agent/tsconfig.json +13 -0
@@ -0,0 +1,297 @@
1
+ import { PaybondPolicyValidationError, PAYBOND_POLICY_SCHEMA_VERSION, isPaybondPolicyDocumentV1, isPaybondPolicyOverlay, } from "./schema.js";
2
+ function cloneToolEntry(entry) {
3
+ return { ...entry };
4
+ }
5
+ function mergeStricterDefaultDeny(...values) {
6
+ return values.some((value) => value === true);
7
+ }
8
+ function mergeToolFields(base, patch, toolName, report, denied) {
9
+ const merged = cloneToolEntry(base);
10
+ if (patch.side_effecting !== undefined) {
11
+ if (base.side_effecting && patch.side_effecting === false) {
12
+ denied.push({
13
+ path: `tools.${toolName}.side_effecting`,
14
+ code: "policy.cannot_disable_org_side_effecting_tool",
15
+ message: `cannot disable org-required side-effecting tool "${toolName}"`,
16
+ });
17
+ }
18
+ else {
19
+ merged.side_effecting = patch.side_effecting;
20
+ report.overrides_applied.push(`tools.${toolName}.side_effecting`);
21
+ }
22
+ }
23
+ if (patch.max_spend_cents !== undefined) {
24
+ if (base.max_spend_cents !== undefined &&
25
+ patch.max_spend_cents > base.max_spend_cents) {
26
+ denied.push({
27
+ path: `tools.${toolName}.max_spend_cents`,
28
+ code: "policy.cannot_raise_spend_cap",
29
+ message: `tenant max_spend_cents (${patch.max_spend_cents}) exceeds org cap (${base.max_spend_cents})`,
30
+ });
31
+ }
32
+ else {
33
+ merged.max_spend_cents = patch.max_spend_cents;
34
+ report.overrides_applied.push(`tools.${toolName}.max_spend_cents`);
35
+ }
36
+ }
37
+ if (patch.spend_from_args !== undefined) {
38
+ if (base.max_spend_cents !== undefined) {
39
+ denied.push({
40
+ path: `tools.${toolName}.spend_from_args`,
41
+ code: "policy.cannot_override_org_spend_mode",
42
+ message: `cannot replace org max_spend_cents with spend_from_args on "${toolName}"`,
43
+ });
44
+ }
45
+ else {
46
+ merged.spend_from_args = patch.spend_from_args;
47
+ delete merged.max_spend_cents;
48
+ report.overrides_applied.push(`tools.${toolName}.spend_from_args`);
49
+ }
50
+ }
51
+ if (patch.evidence_preset !== undefined) {
52
+ if (patch.evidence_preset !== base.evidence_preset &&
53
+ report.org_policy_id !== null) {
54
+ // Structural check only; catalog membership is validated downstream.
55
+ report.overrides_applied.push(`tools.${toolName}.evidence_preset`);
56
+ }
57
+ merged.evidence_preset = patch.evidence_preset;
58
+ }
59
+ if (patch.vendor_pack !== undefined) {
60
+ merged.vendor_pack = patch.vendor_pack;
61
+ report.overrides_applied.push(`tools.${toolName}.vendor_pack`);
62
+ }
63
+ if (patch.operation !== undefined) {
64
+ merged.operation = patch.operation;
65
+ report.overrides_applied.push(`tools.${toolName}.operation`);
66
+ }
67
+ if (merged.side_effecting && !merged.evidence_preset) {
68
+ denied.push({
69
+ path: `tools.${toolName}.evidence_preset`,
70
+ code: "policy.missing_evidence_preset",
71
+ message: `side-effecting tool "${toolName}" must declare evidence_preset after merge`,
72
+ });
73
+ }
74
+ if (merged.max_spend_cents !== undefined &&
75
+ merged.spend_from_args !== undefined) {
76
+ denied.push({
77
+ path: `tools.${toolName}`,
78
+ code: "policy.conflicting_spend_fields",
79
+ message: "max_spend_cents and spend_from_args are mutually exclusive",
80
+ });
81
+ }
82
+ return merged;
83
+ }
84
+ function mergePolicyBinding(base, overlay, override, denied, report) {
85
+ if (!base && !overlay && !override) {
86
+ return undefined;
87
+ }
88
+ const templateId = override?.template_id ?? overlay?.template_id ?? base?.template_id;
89
+ if (!templateId) {
90
+ return undefined;
91
+ }
92
+ const merged = { template_id: templateId };
93
+ const overlayTemplate = overlay?.template_id ?? override?.template_id;
94
+ if (base?.template_id && overlayTemplate && overlayTemplate !== base.template_id) {
95
+ denied.push({
96
+ path: "intent.policy_binding.template_id",
97
+ code: "policy.cannot_change_org_template",
98
+ message: `tenant template_id "${overlayTemplate}" must match org template "${base.template_id}"`,
99
+ });
100
+ }
101
+ const versionSeq = override?.version_seq ?? overlay?.version_seq ?? base?.version_seq;
102
+ if (versionSeq !== undefined) {
103
+ if (base?.version_seq !== undefined && versionSeq < base.version_seq) {
104
+ denied.push({
105
+ path: "intent.policy_binding.version_seq",
106
+ code: "policy.cannot_downgrade_template_version",
107
+ message: `tenant version_seq (${versionSeq}) is older than org version_seq (${base.version_seq})`,
108
+ });
109
+ }
110
+ else {
111
+ merged.version_seq = versionSeq;
112
+ if (override?.version_seq !== undefined) {
113
+ report.overrides_applied.push("intent.policy_binding.version_seq");
114
+ }
115
+ }
116
+ }
117
+ const headDigest = override?.head_digest ?? overlay?.head_digest ?? base?.head_digest;
118
+ if (headDigest !== undefined) {
119
+ if (base?.head_digest && headDigest !== base.head_digest) {
120
+ denied.push({
121
+ path: "intent.policy_binding.head_digest",
122
+ code: "policy.cannot_change_org_head_digest",
123
+ message: "tenant head_digest must match the org-pinned template head",
124
+ });
125
+ }
126
+ else {
127
+ merged.head_digest = headDigest;
128
+ if (override?.head_digest !== undefined) {
129
+ report.overrides_applied.push("intent.policy_binding.head_digest");
130
+ }
131
+ }
132
+ }
133
+ return merged;
134
+ }
135
+ function mergeBudget(base, overlay, override, denied, report) {
136
+ const merged = {
137
+ ...(base ?? {}),
138
+ ...(overlay ?? {}),
139
+ ...(override ?? {}),
140
+ };
141
+ if (!merged || Object.keys(merged).length === 0) {
142
+ return undefined;
143
+ }
144
+ const orgMax = base?.max_spend_usd;
145
+ const tenantMax = override?.max_spend_usd ?? overlay?.max_spend_usd;
146
+ if (orgMax !== undefined && tenantMax !== undefined && tenantMax > orgMax) {
147
+ denied.push({
148
+ path: "intent.budget.max_spend_usd",
149
+ code: "policy.cannot_raise_budget_cap",
150
+ message: `tenant max_spend_usd (${tenantMax}) exceeds org cap (${orgMax})`,
151
+ });
152
+ }
153
+ else if (override?.max_spend_usd !== undefined) {
154
+ report.overrides_applied.push("intent.budget.max_spend_usd");
155
+ }
156
+ return merged;
157
+ }
158
+ function intersectAllowedTools(orgAllowed, tenantAllowed, denied, report) {
159
+ if (!tenantAllowed || tenantAllowed.length === 0) {
160
+ return orgAllowed;
161
+ }
162
+ if (!orgAllowed || orgAllowed.length === 0) {
163
+ return tenantAllowed;
164
+ }
165
+ const orgSet = new Set(orgAllowed);
166
+ const widened = tenantAllowed.filter((tool) => !orgSet.has(tool));
167
+ if (widened.length > 0) {
168
+ denied.push({
169
+ path: "intent.allowed_tools",
170
+ code: "policy.cannot_widen_allowed_tools",
171
+ message: `tenant allowed_tools widens org allowlist: ${widened.join(", ")}`,
172
+ });
173
+ }
174
+ const intersection = tenantAllowed.filter((tool) => orgSet.has(tool));
175
+ if (intersection.length !== tenantAllowed.length) {
176
+ report.overrides_applied.push("intent.allowed_tools");
177
+ }
178
+ return intersection;
179
+ }
180
+ function baseDocumentToEffectiveV1(document) {
181
+ return {
182
+ version: PAYBOND_POLICY_SCHEMA_VERSION,
183
+ name: document.name,
184
+ default_deny: document.default_deny,
185
+ tools: Object.fromEntries(Object.entries(document.tools).map(([toolName, entry]) => [toolName, cloneToolEntry(entry)])),
186
+ intent: document.intent ? structuredClone(document.intent) : undefined,
187
+ };
188
+ }
189
+ function assertOverlay(document) {
190
+ if (!isPaybondPolicyOverlay(document)) {
191
+ throw new PaybondPolicyValidationError("merge requires a tenant overlay document with extends", [{ path: "extends", code: "required", message: "extends is required for overlay merge" }]);
192
+ }
193
+ }
194
+ /**
195
+ * Deterministically merge an org base policy with a tenant overlay.
196
+ * Returns a v1 effective document suitable for middleware and validation.
197
+ */
198
+ export function mergePaybondPolicies(base, overlay, options = {}) {
199
+ assertOverlay(overlay);
200
+ const denied = [];
201
+ const report = {
202
+ org_policy_id: overlay.extends.org_policy_id,
203
+ org_id: overlay.extends.org_id,
204
+ base_policy_name: base.name,
205
+ overlay_policy_name: overlay.name,
206
+ overrides_applied: [],
207
+ denied_widenings: [],
208
+ };
209
+ const effective = baseDocumentToEffectiveV1(base);
210
+ effective.name = overlay.name;
211
+ effective.default_deny = mergeStricterDefaultDeny(base.default_deny, overlay.default_deny, overlay.overrides?.default_deny);
212
+ if (overlay.overrides?.default_deny !== undefined) {
213
+ report.overrides_applied.push("overrides.default_deny");
214
+ }
215
+ for (const [toolName, patch] of Object.entries(overlay.overrides?.tools ?? {})) {
216
+ const existing = effective.tools[toolName];
217
+ if (!existing) {
218
+ denied.push({
219
+ path: `overrides.tools.${toolName}`,
220
+ code: "policy.unknown_org_tool_override",
221
+ message: `cannot override unknown org tool "${toolName}"`,
222
+ });
223
+ continue;
224
+ }
225
+ effective.tools[toolName] = mergeToolFields(existing, patch, toolName, report, denied);
226
+ }
227
+ for (const [toolName, entry] of Object.entries(overlay.tools)) {
228
+ if (effective.tools[toolName]) {
229
+ denied.push({
230
+ path: `tools.${toolName}`,
231
+ code: "policy.cannot_replace_org_tool",
232
+ message: `tenant tools must append new entries; "${toolName}" already exists in org base`,
233
+ });
234
+ continue;
235
+ }
236
+ effective.tools[toolName] = cloneToolEntry(entry);
237
+ }
238
+ const orgAllowed = base.intent?.allowed_tools;
239
+ const tenantAllowed = overlay.overrides?.intent?.allowed_tools ?? overlay.intent?.allowed_tools;
240
+ const mergedAllowed = intersectAllowedTools(orgAllowed, tenantAllowed, denied, report);
241
+ if (!overlay.intent && !overlay.overrides?.intent) {
242
+ effective.intent = base.intent ? structuredClone(base.intent) : undefined;
243
+ if (mergedAllowed && effective.intent) {
244
+ effective.intent.allowed_tools = mergedAllowed;
245
+ }
246
+ }
247
+ else {
248
+ const mergedBinding = mergePolicyBinding(base.intent?.policy_binding, overlay.intent?.policy_binding, overlay.overrides?.intent?.policy_binding, denied, report);
249
+ const mergedBudget = mergeBudget(base.intent?.budget, overlay.intent?.budget, overlay.overrides?.intent?.budget, denied, report);
250
+ if (mergedBinding || mergedBudget || mergedAllowed) {
251
+ effective.intent = {
252
+ ...(mergedBinding ? { policy_binding: mergedBinding } : {}),
253
+ ...(mergedBudget ? { budget: mergedBudget } : {}),
254
+ ...(mergedAllowed ? { allowed_tools: mergedAllowed } : {}),
255
+ };
256
+ }
257
+ else if (base.intent) {
258
+ effective.intent = structuredClone(base.intent);
259
+ }
260
+ }
261
+ if (options.approvedEvidencePresets) {
262
+ const approved = new Set(options.approvedEvidencePresets);
263
+ for (const [toolName, entry] of Object.entries(effective.tools)) {
264
+ if (!entry.side_effecting || !entry.evidence_preset) {
265
+ continue;
266
+ }
267
+ const basePreset = base.tools[toolName]?.evidence_preset;
268
+ if (basePreset && entry.evidence_preset !== basePreset && !approved.has(entry.evidence_preset)) {
269
+ denied.push({
270
+ path: `tools.${toolName}.evidence_preset`,
271
+ code: "policy.evidence_preset_not_org_approved",
272
+ message: `evidence preset "${entry.evidence_preset}" is not in the org-approved catalog subset`,
273
+ });
274
+ }
275
+ }
276
+ }
277
+ report.denied_widenings = denied;
278
+ if (denied.length > 0) {
279
+ const summary = denied.map((item) => `${item.path}: ${item.message}`).join("; ");
280
+ throw new PaybondPolicyValidationError(summary, denied.map((item) => ({
281
+ path: item.path,
282
+ code: item.code,
283
+ message: item.message,
284
+ })));
285
+ }
286
+ return { effective, report };
287
+ }
288
+ /** Normalize any supported policy document to a flat v1 effective document. */
289
+ export function toEffectivePolicyDocument(document) {
290
+ if (isPaybondPolicyDocumentV1(document)) {
291
+ return baseDocumentToEffectiveV1(document);
292
+ }
293
+ if (isPaybondPolicyOverlay(document)) {
294
+ throw new PaybondPolicyValidationError("tenant overlay requires merge with an org base policy before use", [{ path: "extends", code: "merge_required", message: "resolve inheritance before producing effective policy" }]);
295
+ }
296
+ return baseDocumentToEffectiveV1(document);
297
+ }
@@ -0,0 +1,2 @@
1
+ /** Parse policy file text (JSON or YAML) into a raw document object. */
2
+ export declare function parsePolicyDocumentText(text: string, sourceLabel?: string): Record<string, unknown>;
@@ -0,0 +1,126 @@
1
+ import { PaybondPolicyValidationError } from "./schema.js";
2
+ function tokenizeYamlLines(text) {
3
+ const lines = [];
4
+ for (const raw of text.split(/\r?\n/)) {
5
+ const trimmed = raw.trim();
6
+ if (!trimmed || trimmed.startsWith("#")) {
7
+ continue;
8
+ }
9
+ const indent = raw.search(/\S/);
10
+ if (indent < 0) {
11
+ continue;
12
+ }
13
+ lines.push({ indent, trimmed, raw });
14
+ }
15
+ return lines;
16
+ }
17
+ function parseYamlScalar(value) {
18
+ if (!value) {
19
+ return "";
20
+ }
21
+ if (value === "true") {
22
+ return true;
23
+ }
24
+ if (value === "false") {
25
+ return false;
26
+ }
27
+ if (/^-?\d+$/.test(value)) {
28
+ return Number.parseInt(value, 10);
29
+ }
30
+ if (/^-?\d+\.\d+$/.test(value)) {
31
+ return Number.parseFloat(value);
32
+ }
33
+ if ((value.startsWith('"') && value.endsWith('"')) ||
34
+ (value.startsWith("'") && value.endsWith("'"))) {
35
+ return value.slice(1, -1);
36
+ }
37
+ return value;
38
+ }
39
+ function parseYamlBlock(lines, start, indent, sourceLabel) {
40
+ if (start >= lines.length || lines[start].indent < indent) {
41
+ return [{}, start];
42
+ }
43
+ if (lines[start].trimmed.startsWith("- ")) {
44
+ const items = [];
45
+ let index = start;
46
+ while (index < lines.length &&
47
+ lines[index].indent === indent &&
48
+ lines[index].trimmed.startsWith("- ")) {
49
+ const afterDash = lines[index].trimmed.slice(2).trim();
50
+ if (!afterDash) {
51
+ const [child, next] = parseYamlBlock(lines, index + 1, indent + 2, sourceLabel);
52
+ items.push(child);
53
+ index = next;
54
+ continue;
55
+ }
56
+ const inlineMap = /^([^:]+?):\s*(.*)$/.exec(afterDash);
57
+ if (inlineMap && !inlineMap[2]) {
58
+ const key = inlineMap[1].trim();
59
+ const [child, next] = parseYamlBlock(lines, index + 1, indent + 2, sourceLabel);
60
+ items.push({ [key]: child });
61
+ index = next;
62
+ continue;
63
+ }
64
+ if (inlineMap) {
65
+ items.push({
66
+ [inlineMap[1].trim()]: parseYamlScalar(inlineMap[2].trim()),
67
+ });
68
+ index += 1;
69
+ continue;
70
+ }
71
+ items.push(parseYamlScalar(afterDash));
72
+ index += 1;
73
+ }
74
+ return [items, index];
75
+ }
76
+ const objectValue = {};
77
+ let index = start;
78
+ while (index < lines.length && lines[index].indent === indent) {
79
+ const match = /^([^:]+?):\s*(.*)$/.exec(lines[index].trimmed);
80
+ if (!match) {
81
+ throw new PaybondPolicyValidationError(`${sourceLabel} has invalid YAML line: ${lines[index].raw}`);
82
+ }
83
+ const key = match[1].trim();
84
+ const rest = match[2].trim();
85
+ if (rest) {
86
+ objectValue[key] = parseYamlScalar(rest);
87
+ index += 1;
88
+ continue;
89
+ }
90
+ const [child, next] = parseYamlBlock(lines, index + 1, indent + 2, sourceLabel);
91
+ objectValue[key] = child;
92
+ index = next;
93
+ }
94
+ return [objectValue, index];
95
+ }
96
+ function parseIndentedYaml(text, sourceLabel) {
97
+ const lines = tokenizeYamlLines(text);
98
+ if (lines.length === 0) {
99
+ throw new PaybondPolicyValidationError(`${sourceLabel} is empty`);
100
+ }
101
+ const [value] = parseYamlBlock(lines, 0, lines[0].indent, sourceLabel);
102
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
103
+ throw new PaybondPolicyValidationError(`${sourceLabel} must be a YAML object`);
104
+ }
105
+ return value;
106
+ }
107
+ /** Parse policy file text (JSON or YAML) into a raw document object. */
108
+ export function parsePolicyDocumentText(text, sourceLabel = "policy file") {
109
+ const trimmed = text.trim();
110
+ if (!trimmed) {
111
+ throw new PaybondPolicyValidationError(`${sourceLabel} is empty`);
112
+ }
113
+ try {
114
+ const parsed = JSON.parse(trimmed);
115
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
116
+ throw new PaybondPolicyValidationError(`${sourceLabel} must be a JSON object`);
117
+ }
118
+ return parsed;
119
+ }
120
+ catch (err) {
121
+ if (err instanceof PaybondPolicyValidationError) {
122
+ throw err;
123
+ }
124
+ return parseIndentedYaml(trimmed, sourceLabel);
125
+ }
126
+ }
@@ -0,0 +1,45 @@
1
+ import { maxSpend, maxSpendUsd, type PolicyGuardrailLayer } from "./guardrails.js";
2
+ import { PaybondPolicy } from "./load.js";
3
+ import { isLayeredPolicyPresetId } from "./presets.js";
4
+ import type { PaybondPolicyDocumentV1 } from "./schema.js";
5
+ export type VerticalPolicyOptions = {
6
+ /** Per side-effecting tool spend cap in cents. */
7
+ maxSpend?: number;
8
+ /** Intent budget cap in USD. */
9
+ maxSpendUsd?: number;
10
+ /** Additional guardrail layers applied after bundled defaults. */
11
+ guardrails?: PolicyGuardrailLayer[];
12
+ };
13
+ declare function composeToPolicy(domainDocument: PaybondPolicyDocumentV1, ...layers: PolicyGuardrailLayer[]): PaybondPolicy;
14
+ /** Programmatic policy composition API (`paybond.policyPresets.*`). */
15
+ export declare const paybondPolicyPresets: {
16
+ readonly travel: (options?: VerticalPolicyOptions) => PaybondPolicy;
17
+ readonly shopping: (options?: VerticalPolicyOptions) => PaybondPolicy;
18
+ readonly saas: (options?: VerticalPolicyOptions) => PaybondPolicy;
19
+ readonly aws: (options?: VerticalPolicyOptions) => PaybondPolicy;
20
+ readonly readOnly: () => PaybondPolicy;
21
+ readonly strict: () => PaybondPolicy;
22
+ readonly compose: typeof composeToPolicy;
23
+ readonly domain: {
24
+ readonly travel: typeof import("./domain.js").travel;
25
+ readonly shopping: typeof import("./domain.js").shopping;
26
+ readonly saas: typeof import("./domain.js").saas;
27
+ readonly aws: typeof import("./domain.js").aws;
28
+ };
29
+ readonly guardrails: {
30
+ readonly defaultDeny: typeof import("./guardrails.js").defaultDeny;
31
+ readonly maxSpend: typeof maxSpend;
32
+ readonly maxSpendUsd: typeof maxSpendUsd;
33
+ readonly readOnly: typeof import("./guardrails.js").readOnly;
34
+ readonly readOnlySearch: typeof import("./guardrails.js").readOnlySearch;
35
+ readonly strict: typeof import("./guardrails.js").strict;
36
+ readonly requireEvidence: typeof import("./guardrails.js").requireEvidence;
37
+ readonly auditOnly: typeof import("./guardrails.js").auditOnly;
38
+ readonly allowDryRun: typeof import("./guardrails.js").allowDryRun;
39
+ readonly fromDocument: typeof import("./guardrails.js").guardrailLayerFromDocument;
40
+ };
41
+ readonly resolvePresetDocument: (presetId: string) => PaybondPolicyDocumentV1;
42
+ readonly isLayeredPreset: typeof isLayeredPolicyPresetId;
43
+ };
44
+ export type PaybondPolicyPresets = typeof paybondPolicyPresets;
45
+ export {};
@@ -0,0 +1,61 @@
1
+ import { bundledDefaultGuardrails, composeBundledPresetDefault, composePolicyLayers, } from "./compose.js";
2
+ import { domain } from "./domain.js";
3
+ import { guardrails, maxSpend, maxSpendUsd } from "./guardrails.js";
4
+ import { PaybondPolicy } from "./load.js";
5
+ import { isKnownPolicyPresetId, isLayeredPolicyPresetId, resolveComposedPresetDocument, } from "./presets.js";
6
+ function verticalPolicy(presetId, options) {
7
+ const hasCustomizations = options?.maxSpend !== undefined ||
8
+ options?.maxSpendUsd !== undefined ||
9
+ (options?.guardrails?.length ?? 0) > 0;
10
+ if (!hasCustomizations) {
11
+ return PaybondPolicy.fromDocument(composeBundledPresetDefault(presetId));
12
+ }
13
+ const layers = [...bundledDefaultGuardrails(presetId)];
14
+ if (options?.maxSpend !== undefined) {
15
+ layers.push(maxSpend(options.maxSpend));
16
+ }
17
+ if (options?.maxSpendUsd !== undefined) {
18
+ layers.push(maxSpendUsd(options.maxSpendUsd));
19
+ }
20
+ if (options?.guardrails?.length) {
21
+ layers.push(...options.guardrails);
22
+ }
23
+ return PaybondPolicy.fromDocument(composePolicyLayers(domain[presetId](), ...layers));
24
+ }
25
+ function composeToPolicy(domainDocument, ...layers) {
26
+ return PaybondPolicy.fromDocument(composePolicyLayers(domainDocument, ...layers));
27
+ }
28
+ function presetPolicy(presetId) {
29
+ return PaybondPolicy.fromDocument(resolveComposedPresetDocument(presetId));
30
+ }
31
+ /** Programmatic policy composition API (`paybond.policyPresets.*`). */
32
+ export const paybondPolicyPresets = {
33
+ travel(options) {
34
+ return verticalPolicy("travel", options);
35
+ },
36
+ shopping(options) {
37
+ return verticalPolicy("shopping", options);
38
+ },
39
+ saas(options) {
40
+ return verticalPolicy("saas", options);
41
+ },
42
+ aws(options) {
43
+ return verticalPolicy("aws", options);
44
+ },
45
+ readOnly() {
46
+ return presetPolicy("read-only");
47
+ },
48
+ strict() {
49
+ return presetPolicy("strict");
50
+ },
51
+ compose: composeToPolicy,
52
+ domain,
53
+ guardrails,
54
+ resolvePresetDocument(presetId) {
55
+ if (!isKnownPolicyPresetId(presetId)) {
56
+ throw new Error(`unknown policy preset: ${presetId}`);
57
+ }
58
+ return resolveComposedPresetDocument(presetId);
59
+ },
60
+ isLayeredPreset: isLayeredPolicyPresetId,
61
+ };
@@ -0,0 +1,19 @@
1
+ import type { LayeredPolicyPresetId } from "./compose.js";
2
+ import { type PaybondPolicyDocumentV1 } from "./schema.js";
3
+ export type { LayeredPolicyPresetId };
4
+ declare const KNOWN_POLICY_PRESET_IDS: readonly ["travel", "shopping", "saas", "aws", "read-only", "strict"];
5
+ export type PolicyPresetId = (typeof KNOWN_POLICY_PRESET_IDS)[number];
6
+ /** True when `value` is a bundled vertical policy preset id (not a file path). */
7
+ export declare function isKnownPolicyPresetId(value: string): value is PolicyPresetId;
8
+ /** True when the preset is composed from domain + guardrails layers. */
9
+ export declare function isLayeredPolicyPresetId(value: string): value is LayeredPolicyPresetId;
10
+ /** List bundled vertical policy preset ids shipped with Paybond Kit. */
11
+ export declare function listPolicyPresetIds(): PolicyPresetId[];
12
+ /** Resolve a bundled preset id to an on-disk `paybond.policy.yaml` path. */
13
+ export declare function resolvePolicyPresetPath(presetId: string): string;
14
+ /** Load a bundled vertical policy preset as YAML text (for tests and scaffolding). */
15
+ export declare function readPolicyPresetYaml(presetId: PolicyPresetId): string;
16
+ /** Resolve a bundled preset to its composed v1 policy document. */
17
+ export declare function resolveComposedPresetDocument(presetId: PolicyPresetId): PaybondPolicyDocumentV1;
18
+ /** @deprecated Internal alias used by YAML flat-file parity checks. */
19
+ export declare function readComposedPresetYamlObject(presetId: LayeredPolicyPresetId): Record<string, unknown>;
@@ -0,0 +1,66 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { composeBundledPresetDefault, composeLayeredPolicyPresetDocument, isLayeredPolicyPreset, } from "./compose.js";
5
+ import { parsePolicyDocumentText } from "./parse-text.js";
6
+ import { parsePaybondPolicyDocumentV1, } from "./schema.js";
7
+ const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
8
+ const KNOWN_POLICY_PRESET_IDS = [
9
+ "travel",
10
+ "shopping",
11
+ "saas",
12
+ "aws",
13
+ "read-only",
14
+ "strict",
15
+ ];
16
+ function presetCandidatePaths(presetId) {
17
+ const fileName = `${presetId}.yaml`;
18
+ const roots = [
19
+ join(MODULE_DIR, "../../policy/presets"),
20
+ join(MODULE_DIR, "../../../policy/presets"),
21
+ join(MODULE_DIR, "../../../../kit/policy/presets"),
22
+ ];
23
+ return roots.map((root) => join(root, fileName));
24
+ }
25
+ /** True when `value` is a bundled vertical policy preset id (not a file path). */
26
+ export function isKnownPolicyPresetId(value) {
27
+ return KNOWN_POLICY_PRESET_IDS.includes(value.trim());
28
+ }
29
+ /** True when the preset is composed from domain + guardrails layers. */
30
+ export function isLayeredPolicyPresetId(value) {
31
+ return isLayeredPolicyPreset(value);
32
+ }
33
+ /** List bundled vertical policy preset ids shipped with Paybond Kit. */
34
+ export function listPolicyPresetIds() {
35
+ return [...KNOWN_POLICY_PRESET_IDS];
36
+ }
37
+ /** Resolve a bundled preset id to an on-disk `paybond.policy.yaml` path. */
38
+ export function resolvePolicyPresetPath(presetId) {
39
+ const trimmed = presetId.trim();
40
+ if (!isKnownPolicyPresetId(trimmed)) {
41
+ throw new Error(`unknown policy preset: ${trimmed}`);
42
+ }
43
+ for (const candidate of presetCandidatePaths(trimmed)) {
44
+ if (existsSync(candidate)) {
45
+ return candidate;
46
+ }
47
+ }
48
+ throw new Error(`policy preset file not found for: ${trimmed}`);
49
+ }
50
+ /** Load a bundled vertical policy preset as YAML text (for tests and scaffolding). */
51
+ export function readPolicyPresetYaml(presetId) {
52
+ const path = resolvePolicyPresetPath(presetId);
53
+ return readFileSync(path, "utf8");
54
+ }
55
+ /** Resolve a bundled preset to its composed v1 policy document. */
56
+ export function resolveComposedPresetDocument(presetId) {
57
+ if (isLayeredPolicyPreset(presetId)) {
58
+ return composeBundledPresetDefault(presetId);
59
+ }
60
+ const flatPath = resolvePolicyPresetPath(presetId);
61
+ return parsePaybondPolicyDocumentV1(parsePolicyDocumentText(readPolicyPresetYaml(presetId), flatPath));
62
+ }
63
+ /** @deprecated Internal alias used by YAML flat-file parity checks. */
64
+ export function readComposedPresetYamlObject(presetId) {
65
+ return composeLayeredPolicyPresetDocument(presetId);
66
+ }
@@ -0,0 +1,7 @@
1
+ import { PaybondToolRegistry } from "../agent/registry.js";
2
+ import { PaybondToolRegistryConfig } from "../agent/types.js";
3
+ import type { PaybondPolicyDocumentV1 } from "./schema.js";
4
+ /** Convert a validated policy document into middleware registry config. */
5
+ export declare function policyDocumentToToolRegistryConfig(document: PaybondPolicyDocumentV1): PaybondToolRegistryConfig;
6
+ /** Build a validated {@link PaybondToolRegistry} from a policy document. */
7
+ export declare function policyToToolRegistry(document: PaybondPolicyDocumentV1): PaybondToolRegistry;
@@ -0,0 +1,33 @@
1
+ import { createPaybondToolRegistry } from "../agent/registry.js";
2
+ import { resolveSpendCentsFromJsonPath } from "./json-path.js";
3
+ /** Convert a validated policy document into middleware registry config. */
4
+ export function policyDocumentToToolRegistryConfig(document) {
5
+ const sideEffecting = {};
6
+ for (const [toolName, entry] of Object.entries(document.tools)) {
7
+ if (!entry.side_effecting) {
8
+ continue;
9
+ }
10
+ const policy = {
11
+ evidencePreset: entry.evidence_preset,
12
+ };
13
+ if (entry.operation?.trim()) {
14
+ policy.operation = entry.operation.trim();
15
+ }
16
+ if (entry.max_spend_cents !== undefined) {
17
+ policy.spendCents = entry.max_spend_cents;
18
+ }
19
+ else if (entry.spend_from_args) {
20
+ const path = entry.spend_from_args;
21
+ policy.spendCents = (args) => resolveSpendCentsFromJsonPath(args, path, toolName);
22
+ }
23
+ sideEffecting[toolName] = policy;
24
+ }
25
+ return {
26
+ defaultDeny: document.default_deny,
27
+ sideEffecting,
28
+ };
29
+ }
30
+ /** Build a validated {@link PaybondToolRegistry} from a policy document. */
31
+ export function policyToToolRegistry(document) {
32
+ return createPaybondToolRegistry(policyDocumentToToolRegistryConfig(document));
33
+ }