@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.
- package/completion-presets/catalog.json +1187 -0
- package/completion-presets/catalog.sha256 +1 -0
- package/dev/trace-ui/dashboard.html +617 -0
- package/dist/agent/adapter.d.ts +51 -0
- package/dist/agent/adapter.js +66 -0
- package/dist/agent/attach-bundle.d.ts +37 -0
- package/dist/agent/attach-bundle.js +118 -0
- package/dist/agent/authorization-cache.d.ts +22 -0
- package/dist/agent/authorization-cache.js +36 -0
- package/dist/agent/deferred-tools.d.ts +11 -0
- package/dist/agent/deferred-tools.js +62 -0
- package/dist/agent/discover.d.ts +41 -0
- package/dist/agent/discover.js +147 -0
- package/dist/agent/evidence.d.ts +9 -0
- package/dist/agent/evidence.js +28 -0
- package/dist/agent/facade.d.ts +48 -0
- package/dist/agent/facade.js +112 -0
- package/dist/agent/gateway-trace-reporter.d.ts +28 -0
- package/dist/agent/gateway-trace-reporter.js +49 -0
- package/dist/agent/generic-runner.d.ts +14 -0
- package/dist/agent/generic-runner.js +49 -0
- package/dist/agent/generic-sandbox-demo.d.ts +36 -0
- package/dist/agent/generic-sandbox-demo.js +82 -0
- package/dist/agent/guarded-agent.d.ts +49 -0
- package/dist/agent/guarded-agent.js +100 -0
- package/dist/agent/index.d.ts +13 -0
- package/dist/agent/index.js +13 -0
- package/dist/agent/instrument.d.ts +156 -0
- package/dist/agent/instrument.js +442 -0
- package/dist/agent/interceptor.d.ts +24 -0
- package/dist/agent/interceptor.js +440 -0
- package/dist/agent/lazy-context-tools.d.ts +15 -0
- package/dist/agent/lazy-context-tools.js +81 -0
- package/dist/agent/registry-file.d.ts +39 -0
- package/dist/agent/registry-file.js +219 -0
- package/dist/agent/registry.d.ts +37 -0
- package/dist/agent/registry.js +128 -0
- package/dist/agent/run.d.ts +124 -0
- package/dist/agent/run.js +301 -0
- package/dist/agent/types.d.ts +318 -0
- package/dist/agent/types.js +42 -0
- package/dist/agent-recognition.d.ts +72 -0
- package/dist/agent-recognition.js +165 -0
- package/dist/bincode-wire.d.ts +18 -0
- package/dist/bincode-wire.js +93 -0
- package/dist/claude-agents/config.d.ts +21 -0
- package/dist/claude-agents/config.js +145 -0
- package/dist/claude-agents/index.d.ts +2 -0
- package/dist/claude-agents/index.js +2 -0
- package/dist/claude-agents/sandbox-demo.d.ts +30 -0
- package/dist/claude-agents/sandbox-demo.js +91 -0
- package/dist/cli/agent/env-quote.d.ts +1 -0
- package/dist/cli/agent/env-quote.js +6 -0
- package/dist/cli/agent/env-write.d.ts +8 -0
- package/dist/cli/agent/env-write.js +47 -0
- package/dist/cli/agent/paybond.d.ts +16 -0
- package/dist/cli/agent/paybond.js +55 -0
- package/dist/cli/agent/policy-file.d.ts +29 -0
- package/dist/cli/agent/policy-file.js +61 -0
- package/dist/cli/agent/production-evidence.d.ts +24 -0
- package/dist/cli/agent/production-evidence.js +98 -0
- package/dist/cli/agent/run-store.d.ts +30 -0
- package/dist/cli/agent/run-store.js +42 -0
- package/dist/cli/agent/run-trace-store.d.ts +39 -0
- package/dist/cli/agent/run-trace-store.js +143 -0
- package/dist/cli/agent-run-trace-table.d.ts +9 -0
- package/dist/cli/agent-run-trace-table.js +24 -0
- package/dist/cli/agent-sandbox-smoke-checklist.d.ts +9 -0
- package/dist/cli/agent-sandbox-smoke-checklist.js +50 -0
- package/dist/cli/audit-export.d.ts +7 -0
- package/dist/cli/audit-export.js +120 -0
- package/dist/cli/automation.d.ts +25 -0
- package/dist/cli/automation.js +297 -0
- package/dist/cli/body.d.ts +7 -0
- package/dist/cli/body.js +22 -0
- package/dist/cli/color.d.ts +15 -0
- package/dist/cli/color.js +39 -0
- package/dist/cli/command-spec.d.ts +13 -0
- package/dist/cli/command-spec.js +611 -0
- package/dist/cli/commands/agent.d.ts +16 -0
- package/dist/cli/commands/agent.js +1135 -0
- package/dist/cli/commands/dev.d.ts +7 -0
- package/dist/cli/commands/dev.js +348 -0
- package/dist/cli/commands/discovery.d.ts +8 -0
- package/dist/cli/commands/discovery.js +194 -0
- package/dist/cli/commands/policy.d.ts +13 -0
- package/dist/cli/commands/policy.js +769 -0
- package/dist/cli/commands/setup.d.ts +18 -0
- package/dist/cli/commands/setup.js +513 -0
- package/dist/cli/commands/workflows.d.ts +7 -0
- package/dist/cli/commands/workflows.js +214 -0
- package/dist/cli/config.d.ts +16 -0
- package/dist/cli/config.js +98 -0
- package/dist/cli/context.d.ts +22 -0
- package/dist/cli/context.js +110 -0
- package/dist/cli/credentials.d.ts +21 -0
- package/dist/cli/credentials.js +141 -0
- package/dist/cli/doctor-agent-middleware.d.ts +5 -0
- package/dist/cli/doctor-agent-middleware.js +49 -0
- package/dist/cli/doctor-agent.d.ts +15 -0
- package/dist/cli/doctor-agent.js +311 -0
- package/dist/cli/envelope.d.ts +14 -0
- package/dist/cli/envelope.js +46 -0
- package/dist/cli/globals.d.ts +23 -0
- package/dist/cli/globals.js +248 -0
- package/dist/cli/help.d.ts +3 -0
- package/dist/cli/help.js +83 -0
- package/dist/cli/mcp-install.d.ts +41 -0
- package/dist/cli/mcp-install.js +95 -0
- package/dist/cli/mcp-policy.d.ts +26 -0
- package/dist/cli/mcp-policy.js +110 -0
- package/dist/cli/mcp-verify-config.d.ts +37 -0
- package/dist/cli/mcp-verify-config.js +172 -0
- package/dist/cli/redact.d.ts +4 -0
- package/dist/cli/redact.js +88 -0
- package/dist/cli/request-id.d.ts +2 -0
- package/dist/cli/request-id.js +5 -0
- package/dist/cli/router.d.ts +2 -0
- package/dist/cli/router.js +378 -0
- package/dist/cli/smoke-deep-links.d.ts +15 -0
- package/dist/cli/smoke-deep-links.js +63 -0
- package/dist/cli/suggest.d.ts +4 -0
- package/dist/cli/suggest.js +58 -0
- package/dist/cli/support-diagnostics.d.ts +19 -0
- package/dist/cli/support-diagnostics.js +47 -0
- package/dist/cli/telemetry.d.ts +17 -0
- package/dist/cli/telemetry.js +94 -0
- package/dist/cli/types.d.ts +72 -0
- package/dist/cli/types.js +60 -0
- package/dist/cli/ux.d.ts +8 -0
- package/dist/cli/ux.js +164 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +38 -0
- package/dist/completion-catalog-digest.d.ts +2 -0
- package/dist/completion-catalog-digest.js +2 -0
- package/dist/completion-catalog-integrity.d.ts +2 -0
- package/dist/completion-catalog-integrity.js +17 -0
- package/dist/completion-catalog.d.ts +49 -0
- package/dist/completion-catalog.js +62 -0
- package/dist/completion-contract-digest.d.ts +37 -0
- package/dist/completion-contract-digest.js +73 -0
- package/dist/completion-forbidden-fields.d.ts +5 -0
- package/dist/completion-forbidden-fields.js +26 -0
- package/dist/completion-init.d.ts +8 -0
- package/dist/completion-init.js +334 -0
- package/dist/completion-resolve.d.ts +21 -0
- package/dist/completion-resolve.js +86 -0
- package/dist/completion-validate-evidence.d.ts +24 -0
- package/dist/completion-validate-evidence.js +145 -0
- package/dist/dev/offline-gateway.d.ts +24 -0
- package/dist/dev/offline-gateway.js +102 -0
- package/dist/dev/trace-buffer.d.ts +61 -0
- package/dist/dev/trace-buffer.js +330 -0
- package/dist/dev/trace-security-headers.d.ts +11 -0
- package/dist/dev/trace-security-headers.js +16 -0
- package/dist/dev/trace-server.d.ts +8 -0
- package/dist/dev/trace-server.js +38 -0
- package/dist/dev/trace-ui.d.ts +4 -0
- package/dist/dev/trace-ui.js +25 -0
- package/dist/dev/wiremock-up.d.ts +15 -0
- package/dist/dev/wiremock-up.js +118 -0
- package/dist/doctor-completion.d.ts +17 -0
- package/dist/doctor-completion.js +428 -0
- package/dist/gateway-url.d.ts +7 -0
- package/dist/gateway-url.js +69 -0
- package/dist/index.d.ts +119 -2
- package/dist/index.js +267 -6
- package/dist/init.js +380 -68
- package/dist/langgraph/awrap-tool-call.d.ts +25 -0
- package/dist/langgraph/awrap-tool-call.js +81 -0
- package/dist/langgraph/config.d.ts +13 -0
- package/dist/langgraph/config.js +11 -0
- package/dist/langgraph/index.d.ts +4 -0
- package/dist/langgraph/index.js +4 -0
- package/dist/langgraph/sandbox-demo.d.ts +40 -0
- package/dist/langgraph/sandbox-demo.js +96 -0
- package/dist/langgraph/tool-node.d.ts +10 -0
- package/dist/langgraph/tool-node.js +38 -0
- package/dist/login.d.ts +14 -1
- package/dist/login.js +130 -63
- package/dist/mcp/index.d.ts +1 -0
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/tool-surface.d.ts +25 -0
- package/dist/mcp/tool-surface.js +17 -0
- package/dist/mcp-capability-token-cache.d.ts +24 -0
- package/dist/mcp-capability-token-cache.js +101 -0
- package/dist/mcp-evidence-policy.d.ts +48 -0
- package/dist/mcp-evidence-policy.js +117 -0
- package/dist/mcp-policy-reload.d.ts +79 -0
- package/dist/mcp-policy-reload.js +200 -0
- package/dist/mcp-sep2828-evidence.d.ts +36 -0
- package/dist/mcp-sep2828-evidence.js +65 -0
- package/dist/mcp-server.d.ts +10 -0
- package/dist/mcp-server.js +423 -115
- package/dist/openai-agents/index.d.ts +40 -0
- package/dist/openai-agents/index.js +151 -0
- package/dist/openai-agents/sandbox-demo.d.ts +34 -0
- package/dist/openai-agents/sandbox-demo.js +118 -0
- package/dist/payee-evidence.js +2 -29
- package/dist/policy/catalog.d.ts +31 -0
- package/dist/policy/catalog.js +48 -0
- package/dist/policy/compose-utils.d.ts +3 -0
- package/dist/policy/compose-utils.js +4 -0
- package/dist/policy/compose.d.ts +20 -0
- package/dist/policy/compose.js +240 -0
- package/dist/policy/digest.d.ts +7 -0
- package/dist/policy/digest.js +75 -0
- package/dist/policy/domain.d.ts +15 -0
- package/dist/policy/domain.js +28 -0
- package/dist/policy/guardrail-spec.d.ts +17 -0
- package/dist/policy/guardrail-spec.js +140 -0
- package/dist/policy/guardrails.d.ts +48 -0
- package/dist/policy/guardrails.js +72 -0
- package/dist/policy/index.d.ts +21 -0
- package/dist/policy/index.js +21 -0
- package/dist/policy/init.d.ts +102 -0
- package/dist/policy/init.js +351 -0
- package/dist/policy/intent-spec.d.ts +52 -0
- package/dist/policy/intent-spec.js +176 -0
- package/dist/policy/json-path.d.ts +4 -0
- package/dist/policy/json-path.js +23 -0
- package/dist/policy/layers-io.d.ts +7 -0
- package/dist/policy/layers-io.js +28 -0
- package/dist/policy/load-effective.d.ts +22 -0
- package/dist/policy/load-effective.js +77 -0
- package/dist/policy/load.d.ts +85 -0
- package/dist/policy/load.js +164 -0
- package/dist/policy/merge.d.ts +29 -0
- package/dist/policy/merge.js +297 -0
- package/dist/policy/parse-text.d.ts +2 -0
- package/dist/policy/parse-text.js +126 -0
- package/dist/policy/policy-api.d.ts +45 -0
- package/dist/policy/policy-api.js +61 -0
- package/dist/policy/presets.d.ts +19 -0
- package/dist/policy/presets.js +66 -0
- package/dist/policy/registry.d.ts +7 -0
- package/dist/policy/registry.js +33 -0
- package/dist/policy/reload.d.ts +86 -0
- package/dist/policy/reload.js +233 -0
- package/dist/policy/render-yaml.d.ts +3 -0
- package/dist/policy/render-yaml.js +69 -0
- package/dist/policy/sandbox-bootstrap.d.ts +19 -0
- package/dist/policy/sandbox-bootstrap.js +66 -0
- package/dist/policy/schema.d.ts +204 -0
- package/dist/policy/schema.js +255 -0
- package/dist/policy/snapshot.d.ts +33 -0
- package/dist/policy/snapshot.js +23 -0
- package/dist/policy/validate-remote.d.ts +43 -0
- package/dist/policy/validate-remote.js +104 -0
- package/dist/policy/validate.d.ts +36 -0
- package/dist/policy/validate.js +150 -0
- package/dist/policy/watcher.d.ts +29 -0
- package/dist/policy/watcher.js +112 -0
- package/dist/principal-intent.d.ts +52 -0
- package/dist/principal-intent.js +193 -37
- package/dist/project-init.d.ts +34 -0
- package/dist/project-init.js +898 -0
- package/dist/sep2828-signature.d.ts +10 -0
- package/dist/sep2828-signature.js +134 -0
- package/dist/solutions/api.d.ts +22 -0
- package/dist/solutions/api.js +40 -0
- package/dist/solutions/catalog.d.ts +34 -0
- package/dist/solutions/catalog.js +129 -0
- package/dist/solutions/index.d.ts +2 -0
- package/dist/solutions/index.js +2 -0
- package/dist/template-init.d.ts +54 -0
- package/dist/template-init.js +203 -0
- package/dist/vercel-ai/config.d.ts +15 -0
- package/dist/vercel-ai/config.js +13 -0
- package/dist/vercel-ai/index.d.ts +4 -0
- package/dist/vercel-ai/index.js +4 -0
- package/dist/vercel-ai/sandbox-demo.d.ts +44 -0
- package/dist/vercel-ai/sandbox-demo.js +153 -0
- package/dist/vercel-ai/tool-approval.d.ts +16 -0
- package/dist/vercel-ai/tool-approval.js +41 -0
- package/dist/vercel-ai/wrap-tools.d.ts +9 -0
- package/dist/vercel-ai/wrap-tools.js +40 -0
- package/dist/x402-receipt-evidence.d.ts +29 -0
- package/dist/x402-receipt-evidence.js +97 -0
- package/dist/x402-receipt-signature.d.ts +12 -0
- package/dist/x402-receipt-signature.js +211 -0
- package/package.json +79 -4
- package/solutions/aws.json +17 -0
- package/solutions/saas.json +17 -0
- package/solutions/shopping.json +17 -0
- package/solutions/travel.json +18 -0
- package/templates/manifest.json +169 -0
- package/templates/openai-shopping-agent/.env.example +3 -0
- package/templates/openai-shopping-agent/.github/workflows/smoke.yml +20 -0
- package/templates/openai-shopping-agent/LICENSE +201 -0
- package/templates/openai-shopping-agent/README.md +29 -0
- package/templates/openai-shopping-agent/package.json +22 -0
- package/templates/openai-shopping-agent/paybond.policy.yaml +22 -0
- package/templates/openai-shopping-agent/src/index.ts +22 -0
- package/templates/openai-shopping-agent/src/paybond.config.ts +51 -0
- package/templates/openai-shopping-agent/tsconfig.json +13 -0
- package/templates/paybond-aws-operator/.env.example +3 -0
- package/templates/paybond-aws-operator/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-aws-operator/LICENSE +201 -0
- package/templates/paybond-aws-operator/README.md +29 -0
- package/templates/paybond-aws-operator/package.json +20 -0
- package/templates/paybond-aws-operator/paybond.policy.yaml +22 -0
- package/templates/paybond-aws-operator/src/index.ts +54 -0
- package/templates/paybond-aws-operator/src/paybond.config.ts +51 -0
- package/templates/paybond-aws-operator/tsconfig.json +13 -0
- package/templates/paybond-claude-agents-demo/.env.example +3 -0
- package/templates/paybond-claude-agents-demo/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-claude-agents-demo/LICENSE +201 -0
- package/templates/paybond-claude-agents-demo/README.md +29 -0
- package/templates/paybond-claude-agents-demo/package.json +22 -0
- package/templates/paybond-claude-agents-demo/paybond.policy.yaml +22 -0
- package/templates/paybond-claude-agents-demo/src/index.ts +22 -0
- package/templates/paybond-claude-agents-demo/src/paybond.config.ts +51 -0
- package/templates/paybond-claude-agents-demo/tsconfig.json +13 -0
- package/templates/paybond-invoice-agent/.env.example +3 -0
- package/templates/paybond-invoice-agent/.github/workflows/smoke.yml +19 -0
- package/templates/paybond-invoice-agent/LICENSE +201 -0
- package/templates/paybond-invoice-agent/README.md +29 -0
- package/templates/paybond-invoice-agent/app.py +27 -0
- package/templates/paybond-invoice-agent/package.json +6 -0
- package/templates/paybond-invoice-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-invoice-agent/paybond_config.py +45 -0
- package/templates/paybond-invoice-agent/requirements.txt +2 -0
- package/templates/paybond-mcp-coding-agent/.env.example +3 -0
- package/templates/paybond-mcp-coding-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-mcp-coding-agent/LICENSE +201 -0
- package/templates/paybond-mcp-coding-agent/README.md +39 -0
- package/templates/paybond-mcp-coding-agent/package.json +20 -0
- package/templates/paybond-mcp-coding-agent/paybond.policy.yaml +25 -0
- package/templates/paybond-mcp-coding-agent/src/index.ts +40 -0
- package/templates/paybond-mcp-coding-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-mcp-coding-agent/tsconfig.json +13 -0
- package/templates/paybond-openai-agents-demo/.env.example +3 -0
- package/templates/paybond-openai-agents-demo/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-openai-agents-demo/LICENSE +201 -0
- package/templates/paybond-openai-agents-demo/README.md +29 -0
- package/templates/paybond-openai-agents-demo/package.json +22 -0
- package/templates/paybond-openai-agents-demo/paybond.policy.yaml +22 -0
- package/templates/paybond-openai-agents-demo/src/index.ts +22 -0
- package/templates/paybond-openai-agents-demo/src/paybond.config.ts +51 -0
- package/templates/paybond-openai-agents-demo/tsconfig.json +13 -0
- package/templates/paybond-procurement-agent/.env.example +3 -0
- package/templates/paybond-procurement-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-procurement-agent/LICENSE +201 -0
- package/templates/paybond-procurement-agent/README.md +29 -0
- package/templates/paybond-procurement-agent/package.json +20 -0
- package/templates/paybond-procurement-agent/paybond.policy.yaml +25 -0
- package/templates/paybond-procurement-agent/src/index.ts +54 -0
- package/templates/paybond-procurement-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-procurement-agent/tsconfig.json +13 -0
- package/templates/paybond-travel-agent/.env.example +3 -0
- package/templates/paybond-travel-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-travel-agent/LICENSE +201 -0
- package/templates/paybond-travel-agent/README.md +29 -0
- package/templates/paybond-travel-agent/package.json +23 -0
- package/templates/paybond-travel-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-travel-agent/src/index.ts +22 -0
- package/templates/paybond-travel-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-travel-agent/tsconfig.json +13 -0
- package/templates/paybond-vercel-shopping-agent/.env.example +3 -0
- package/templates/paybond-vercel-shopping-agent/.github/workflows/smoke.yml +20 -0
- package/templates/paybond-vercel-shopping-agent/LICENSE +201 -0
- package/templates/paybond-vercel-shopping-agent/README.md +29 -0
- package/templates/paybond-vercel-shopping-agent/package.json +22 -0
- package/templates/paybond-vercel-shopping-agent/paybond.policy.yaml +22 -0
- package/templates/paybond-vercel-shopping-agent/src/index.ts +22 -0
- package/templates/paybond-vercel-shopping-agent/src/paybond.config.ts +51 -0
- package/templates/paybond-vercel-shopping-agent/tsconfig.json +13 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { PaybondToolRegistryValidationError } from "../agent/types.js";
|
|
2
|
+
import { resolveCompletionPreset, contractSnapshotForPreset } from "../completion-resolve.js";
|
|
3
|
+
import { policyToToolRegistry } from "./registry.js";
|
|
4
|
+
/** Raised when policy intent fields cannot be aligned to a Harbor create payload. */
|
|
5
|
+
export class PaybondPolicyIntentSpecError extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "PaybondPolicyIntentSpecError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function normalizeDigestHex(digest) {
|
|
12
|
+
const trimmed = digest.trim().toLowerCase();
|
|
13
|
+
if (trimmed.startsWith("sha256:")) {
|
|
14
|
+
return trimmed.slice("sha256:".length);
|
|
15
|
+
}
|
|
16
|
+
return trimmed.replace(/^0x/, "");
|
|
17
|
+
}
|
|
18
|
+
function resolveAllowedHarborOperations(document, registry, override) {
|
|
19
|
+
const raw = override ?? document.intent?.allowed_tools;
|
|
20
|
+
if (!raw || raw.length === 0) {
|
|
21
|
+
throw new PaybondPolicyIntentSpecError("policy intent.allowed_tools is required for toIntentCreateInput");
|
|
22
|
+
}
|
|
23
|
+
const operations = registry.sideEffectingOperations();
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
const resolved = [];
|
|
26
|
+
for (const name of raw) {
|
|
27
|
+
let operation;
|
|
28
|
+
if (registry.isSideEffecting(name)) {
|
|
29
|
+
operation = registry.resolveOperation(name);
|
|
30
|
+
}
|
|
31
|
+
else if (operations.includes(name)) {
|
|
32
|
+
operation = name;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
throw new PaybondPolicyIntentSpecError(`allowed_tools entry "${name}" is not a registered side-effecting tool or Harbor operation`);
|
|
36
|
+
}
|
|
37
|
+
if (!seen.has(operation)) {
|
|
38
|
+
seen.add(operation);
|
|
39
|
+
resolved.push(operation);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (resolved.length === 0) {
|
|
43
|
+
throw new PaybondPolicyIntentSpecError("allowed_tools must resolve to at least one Harbor operation");
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
registry.validateForBind(resolved);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (err instanceof PaybondToolRegistryValidationError) {
|
|
50
|
+
throw new PaybondPolicyIntentSpecError(err.message);
|
|
51
|
+
}
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
return resolved;
|
|
55
|
+
}
|
|
56
|
+
function resolveEvidencePresetForOperations(registry, allowedOperations) {
|
|
57
|
+
const presets = new Set();
|
|
58
|
+
for (const operation of allowedOperations) {
|
|
59
|
+
for (const toolName of registry.sideEffectingToolNames()) {
|
|
60
|
+
if (registry.resolveOperation(toolName) !== operation) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const preset = registry.getSideEffectingEntry(toolName)?.evidencePreset;
|
|
64
|
+
if (preset) {
|
|
65
|
+
presets.add(preset);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (presets.size === 0) {
|
|
70
|
+
throw new PaybondPolicyIntentSpecError("could not resolve evidence_preset from policy allowed_tools");
|
|
71
|
+
}
|
|
72
|
+
if (presets.size > 1) {
|
|
73
|
+
throw new PaybondPolicyIntentSpecError(`allowed_tools reference multiple evidence_preset values: ${[...presets].join(", ")}`);
|
|
74
|
+
}
|
|
75
|
+
return [...presets][0];
|
|
76
|
+
}
|
|
77
|
+
function resolvePolicyBindingRef(document, publishedHead, override) {
|
|
78
|
+
const policyBinding = document.intent?.policy_binding;
|
|
79
|
+
if (!override && !policyBinding) {
|
|
80
|
+
throw new PaybondPolicyIntentSpecError("policy intent.policy_binding is required for toIntentCreateInput");
|
|
81
|
+
}
|
|
82
|
+
const binding = override ?? {
|
|
83
|
+
templateId: policyBinding.template_id,
|
|
84
|
+
versionSeq: policyBinding.version_seq ?? publishedHead.versionSeq,
|
|
85
|
+
};
|
|
86
|
+
if (binding.templateId !== publishedHead.templateId) {
|
|
87
|
+
throw new PaybondPolicyIntentSpecError("publishedPolicyHead.templateId must match policy intent.policy_binding.template_id");
|
|
88
|
+
}
|
|
89
|
+
if (binding.versionSeq !== publishedHead.versionSeq) {
|
|
90
|
+
throw new PaybondPolicyIntentSpecError("publishedPolicyHead.versionSeq must match policy intent.policy_binding.version_seq");
|
|
91
|
+
}
|
|
92
|
+
if (policyBinding?.version_seq !== undefined &&
|
|
93
|
+
policyBinding.version_seq !== publishedHead.versionSeq) {
|
|
94
|
+
throw new PaybondPolicyIntentSpecError("policy intent.policy_binding.version_seq does not match publishedPolicyHead.versionSeq");
|
|
95
|
+
}
|
|
96
|
+
const headDigest = policyBinding?.head_digest;
|
|
97
|
+
if (headDigest) {
|
|
98
|
+
const expected = normalizeDigestHex(headDigest);
|
|
99
|
+
const actual = normalizeDigestHex(publishedHead.policyContentDigestHex);
|
|
100
|
+
if (expected !== actual) {
|
|
101
|
+
throw new PaybondPolicyIntentSpecError("policy intent.policy_binding.head_digest does not match publishedPolicyHead.policyContentDigestHex");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return binding;
|
|
105
|
+
}
|
|
106
|
+
function resolveBudgetFields(document, overrides) {
|
|
107
|
+
if (overrides.budget !== undefined &&
|
|
108
|
+
overrides.currency !== undefined &&
|
|
109
|
+
overrides.amountCents !== undefined) {
|
|
110
|
+
return {
|
|
111
|
+
budget: overrides.budget,
|
|
112
|
+
currency: overrides.currency,
|
|
113
|
+
amountCents: overrides.amountCents,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const intentBudget = document.intent?.budget;
|
|
117
|
+
const currency = overrides.currency ??
|
|
118
|
+
(typeof intentBudget?.currency === "string" ? intentBudget.currency : undefined) ??
|
|
119
|
+
"usd";
|
|
120
|
+
let amountCents = overrides.amountCents;
|
|
121
|
+
if (amountCents === undefined && intentBudget && typeof intentBudget.max_spend_usd === "number") {
|
|
122
|
+
amountCents = Math.round(intentBudget.max_spend_usd * 100);
|
|
123
|
+
}
|
|
124
|
+
if (amountCents === undefined) {
|
|
125
|
+
throw new PaybondPolicyIntentSpecError("amountCents is required when policy intent.budget.max_spend_usd is not set");
|
|
126
|
+
}
|
|
127
|
+
const budget = overrides.budget ?? {
|
|
128
|
+
...(intentBudget ?? {}),
|
|
129
|
+
max: amountCents,
|
|
130
|
+
};
|
|
131
|
+
if (!("max" in budget)) {
|
|
132
|
+
budget.max = amountCents;
|
|
133
|
+
}
|
|
134
|
+
return { budget, currency, amountCents };
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Build {@link PaybondIntents.createWithPolicyBinding} input from a validated policy document.
|
|
138
|
+
* Merges policy intent alignment (`allowed_tools`, `budget`, `policy_binding`) with caller signing context.
|
|
139
|
+
*/
|
|
140
|
+
export function policyToIntentCreateInput(document, overrides) {
|
|
141
|
+
const registry = policyToToolRegistry(document);
|
|
142
|
+
const allowedTools = resolveAllowedHarborOperations(document, registry, overrides.allowedTools);
|
|
143
|
+
const policyBinding = resolvePolicyBindingRef(document, overrides.publishedPolicyHead, overrides.policyBinding);
|
|
144
|
+
const { budget, currency, amountCents } = resolveBudgetFields(document, overrides);
|
|
145
|
+
const completionPresetId = overrides.completionPresetId ??
|
|
146
|
+
resolveEvidencePresetForOperations(registry, allowedTools);
|
|
147
|
+
const resolvedPreset = resolveCompletionPreset(completionPresetId);
|
|
148
|
+
const evidenceSchema = overrides.evidenceSchema ?? resolvedPreset.evidenceSchema;
|
|
149
|
+
let completionContract;
|
|
150
|
+
try {
|
|
151
|
+
completionContract = contractSnapshotForPreset(completionPresetId);
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
throw new PaybondPolicyIntentSpecError(err instanceof Error ? err.message : "failed to build completion contract snapshot");
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
principalDid: overrides.principalDid,
|
|
158
|
+
principalSigningSeed: overrides.principalSigningSeed,
|
|
159
|
+
payeeDid: overrides.payeeDid,
|
|
160
|
+
payeeSigningSeed: overrides.payeeSigningSeed,
|
|
161
|
+
budget,
|
|
162
|
+
currency,
|
|
163
|
+
amountCents,
|
|
164
|
+
evidenceSchema,
|
|
165
|
+
deadlineRfc3339: overrides.deadlineRfc3339,
|
|
166
|
+
allowedTools,
|
|
167
|
+
settlementRail: overrides.settlementRail,
|
|
168
|
+
policyBinding,
|
|
169
|
+
publishedPolicyHead: overrides.publishedPolicyHead,
|
|
170
|
+
recognitionProof: overrides.recognitionProof,
|
|
171
|
+
intentId: overrides.intentId,
|
|
172
|
+
predicateRef: overrides.predicateRef,
|
|
173
|
+
completionPresetId,
|
|
174
|
+
completionContract,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Read a dot-separated JSON path from tool call arguments. */
|
|
2
|
+
export declare function resolveJsonPath(args: unknown, path: string): unknown;
|
|
3
|
+
/** Resolve non-negative integer spend cents from a JSON path at intercept time. */
|
|
4
|
+
export declare function resolveSpendCentsFromJsonPath(args: unknown, path: string, toolName: string): number | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PaybondPolicyValidationError } from "./schema.js";
|
|
2
|
+
/** Read a dot-separated JSON path from tool call arguments. */
|
|
3
|
+
export function resolveJsonPath(args, path) {
|
|
4
|
+
let current = args;
|
|
5
|
+
for (const segment of path.split(".")) {
|
|
6
|
+
if (current === null || typeof current !== "object" || Array.isArray(current)) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
current = current[segment];
|
|
10
|
+
}
|
|
11
|
+
return current;
|
|
12
|
+
}
|
|
13
|
+
/** Resolve non-negative integer spend cents from a JSON path at intercept time. */
|
|
14
|
+
export function resolveSpendCentsFromJsonPath(args, path, toolName) {
|
|
15
|
+
const value = resolveJsonPath(args, path);
|
|
16
|
+
if (value === undefined) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 0) {
|
|
20
|
+
throw new PaybondPolicyValidationError(`tool "${toolName}" spend_from_args path "${path}" must resolve to a non-negative integer`);
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LayeredPolicyPresetId } from "./compose.js";
|
|
2
|
+
export declare function presetLayerCandidatePaths(subdir: string, fileName: string): string[];
|
|
3
|
+
export declare function readPresetLayerYaml(subdir: string, fileName: string): string;
|
|
4
|
+
/** Load a bundled domain layer YAML document. */
|
|
5
|
+
export declare function loadBundledDomainDocument(presetId: LayeredPolicyPresetId): Record<string, unknown>;
|
|
6
|
+
/** Load a bundled default guardrails layer YAML document. */
|
|
7
|
+
export declare function loadBundledDefaultGuardrailsDocument(presetId: LayeredPolicyPresetId): Record<string, unknown>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { parsePolicyDocumentText } from "./parse-text.js";
|
|
5
|
+
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
export function presetLayerCandidatePaths(subdir, fileName) {
|
|
7
|
+
return [
|
|
8
|
+
join(MODULE_DIR, "../../policy/presets", subdir, fileName),
|
|
9
|
+
join(MODULE_DIR, "../../../policy/presets", subdir, fileName),
|
|
10
|
+
join(MODULE_DIR, "../../../../kit/policy/presets", subdir, fileName),
|
|
11
|
+
];
|
|
12
|
+
}
|
|
13
|
+
export function readPresetLayerYaml(subdir, fileName) {
|
|
14
|
+
for (const candidate of presetLayerCandidatePaths(subdir, fileName)) {
|
|
15
|
+
if (existsSync(candidate)) {
|
|
16
|
+
return readFileSync(candidate, "utf8");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`policy preset layer not found: ${subdir}/${fileName}`);
|
|
20
|
+
}
|
|
21
|
+
/** Load a bundled domain layer YAML document. */
|
|
22
|
+
export function loadBundledDomainDocument(presetId) {
|
|
23
|
+
return parsePolicyDocumentText(readPresetLayerYaml("domain", `${presetId}.yaml`), `domain/${presetId}.yaml`);
|
|
24
|
+
}
|
|
25
|
+
/** Load a bundled default guardrails layer YAML document. */
|
|
26
|
+
export function loadBundledDefaultGuardrailsDocument(presetId) {
|
|
27
|
+
return parsePolicyDocumentText(readPresetLayerYaml("guardrails", `default-${presetId}.yaml`), `guardrails/default-${presetId}.yaml`);
|
|
28
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PaybondPolicyDocumentV2 } from "./schema.js";
|
|
2
|
+
import type { PolicyMergeReport } from "./merge.js";
|
|
3
|
+
export type PolicyEffectiveResolveResult = {
|
|
4
|
+
effective_policy: Record<string, unknown>;
|
|
5
|
+
effective_policy_digest: string;
|
|
6
|
+
effective_policy_version: string;
|
|
7
|
+
merge_report: PolicyMergeReport;
|
|
8
|
+
org_base_version_seq: number;
|
|
9
|
+
org_base_content_digest: string;
|
|
10
|
+
unchanged?: boolean;
|
|
11
|
+
};
|
|
12
|
+
/** Gateway client surface used by {@link resolvePolicyEffectiveRemote}. */
|
|
13
|
+
export type PolicyEffectiveResolveClient = {
|
|
14
|
+
resolvePolicyEffective(orgPolicyId: string, overlay: Record<string, unknown>, options?: {
|
|
15
|
+
currentDigest?: string;
|
|
16
|
+
}): Promise<PolicyEffectiveResolveResult>;
|
|
17
|
+
};
|
|
18
|
+
export declare function parseMergeReport(value: unknown): PolicyMergeReport;
|
|
19
|
+
/** Parse a Gateway org-policy effective resolution JSON body. */
|
|
20
|
+
export declare function parsePolicyEffectiveResolveResponse(body: unknown): PolicyEffectiveResolveResult;
|
|
21
|
+
/** Resolve merged effective policy via Gateway org-policy inheritance endpoint. */
|
|
22
|
+
export declare function resolvePolicyEffectiveRemote(overlay: PaybondPolicyDocumentV2, client: PolicyEffectiveResolveClient): Promise<PolicyEffectiveResolveResult>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export function parseMergeReport(value) {
|
|
2
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3
|
+
throw new Error("merge_report must be an object");
|
|
4
|
+
}
|
|
5
|
+
const row = value;
|
|
6
|
+
return {
|
|
7
|
+
org_policy_id: row.org_policy_id == null ? null : String(row.org_policy_id),
|
|
8
|
+
org_id: row.org_id == null ? null : String(row.org_id),
|
|
9
|
+
base_policy_name: String(row.base_policy_name ?? ""),
|
|
10
|
+
overlay_policy_name: row.overlay_policy_name == null ? null : String(row.overlay_policy_name),
|
|
11
|
+
overrides_applied: Array.isArray(row.overrides_applied)
|
|
12
|
+
? row.overrides_applied.map((item) => String(item))
|
|
13
|
+
: [],
|
|
14
|
+
denied_widenings: Array.isArray(row.denied_widenings)
|
|
15
|
+
? row.denied_widenings
|
|
16
|
+
.map((item) => {
|
|
17
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const denied = item;
|
|
21
|
+
const path = String(denied.path ?? "");
|
|
22
|
+
const code = String(denied.code ?? "");
|
|
23
|
+
const message = String(denied.message ?? "");
|
|
24
|
+
if (!path || !code || !message) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return { path, code, message };
|
|
28
|
+
})
|
|
29
|
+
.filter((item) => item !== null)
|
|
30
|
+
: [],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Parse a Gateway org-policy effective resolution JSON body. */
|
|
34
|
+
export function parsePolicyEffectiveResolveResponse(body) {
|
|
35
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
36
|
+
throw new Error("policy effective response must be a JSON object");
|
|
37
|
+
}
|
|
38
|
+
const row = body;
|
|
39
|
+
const digest = String(row.effective_policy_digest ?? "");
|
|
40
|
+
if (!digest) {
|
|
41
|
+
throw new Error("effective_policy_digest is required");
|
|
42
|
+
}
|
|
43
|
+
const version = String(row.effective_policy_version ?? "");
|
|
44
|
+
if (!version) {
|
|
45
|
+
throw new Error("effective_policy_version is required");
|
|
46
|
+
}
|
|
47
|
+
if (row.unchanged === true) {
|
|
48
|
+
return {
|
|
49
|
+
effective_policy: {},
|
|
50
|
+
effective_policy_digest: digest,
|
|
51
|
+
effective_policy_version: version,
|
|
52
|
+
merge_report: parseMergeReport(row.merge_report ?? {}),
|
|
53
|
+
org_base_version_seq: Number(row.org_base_version_seq ?? 0),
|
|
54
|
+
org_base_content_digest: String(row.org_base_content_digest ?? ""),
|
|
55
|
+
unchanged: true,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const effective = row.effective_policy;
|
|
59
|
+
if (!effective || typeof effective !== "object" || Array.isArray(effective)) {
|
|
60
|
+
throw new Error("effective_policy must be an object");
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
effective_policy: effective,
|
|
64
|
+
effective_policy_digest: digest,
|
|
65
|
+
effective_policy_version: version,
|
|
66
|
+
merge_report: parseMergeReport(row.merge_report),
|
|
67
|
+
org_base_version_seq: Number(row.org_base_version_seq ?? 0),
|
|
68
|
+
org_base_content_digest: String(row.org_base_content_digest ?? ""),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Resolve merged effective policy via Gateway org-policy inheritance endpoint. */
|
|
72
|
+
export async function resolvePolicyEffectiveRemote(overlay, client) {
|
|
73
|
+
if (!overlay.extends?.org_policy_id) {
|
|
74
|
+
throw new Error("overlay must declare extends.org_policy_id");
|
|
75
|
+
}
|
|
76
|
+
return client.resolvePolicyEffective(overlay.extends.org_policy_id, overlay);
|
|
77
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { PaybondToolRegistry } from "../agent/registry.js";
|
|
2
|
+
import { type PaybondPolicyIntentCreateInput, type PaybondPolicyIntentCreateOverrides } from "./intent-spec.js";
|
|
3
|
+
import { type PolicyMergeOptions, type PolicyMergeResult } from "./merge.js";
|
|
4
|
+
import { type PaybondPolicyDocument, type PaybondPolicyDocumentV1 } from "./schema.js";
|
|
5
|
+
import { type PaybondPolicySandboxBootstrapOptions } from "./sandbox-bootstrap.js";
|
|
6
|
+
import { type PolicyValidatorOptions, type PolicyValidatorResult } from "./validate.js";
|
|
7
|
+
import { type PolicyRemoteValidateClient, type PolicyRemoteValidateOptions, type PolicyRemoteValidateResult } from "./validate-remote.js";
|
|
8
|
+
import { type PolicyEffectiveResolveClient } from "./load-effective.js";
|
|
9
|
+
import type { PaybondRunBindingSandboxBootstrapInput } from "../agent/types.js";
|
|
10
|
+
export type PaybondPolicyLoadEffectiveResult = {
|
|
11
|
+
policy: PaybondPolicy;
|
|
12
|
+
report: PolicyMergeResult["report"];
|
|
13
|
+
effectivePolicyDigest: string;
|
|
14
|
+
effectivePolicyVersion: string;
|
|
15
|
+
orgBaseVersionSeq: number;
|
|
16
|
+
orgBaseContentDigest: string;
|
|
17
|
+
unchanged?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type PaybondPolicyLoadSource = string | PaybondPolicyDocumentV1 | PaybondPolicyDocument | Record<string, unknown>;
|
|
20
|
+
/**
|
|
21
|
+
* Portable policy-as-code document loaded from `paybond.policy.yaml` or an in-memory object.
|
|
22
|
+
* Drives tool registry construction and production intent create alignment.
|
|
23
|
+
*/
|
|
24
|
+
export declare class PaybondPolicy {
|
|
25
|
+
readonly document: PaybondPolicyDocumentV1;
|
|
26
|
+
readonly source?: string;
|
|
27
|
+
private constructor();
|
|
28
|
+
/** Policy name from the document (`name` field). */
|
|
29
|
+
get name(): string;
|
|
30
|
+
/** Whether unregistered side-effecting tools should fail closed at intercept time. */
|
|
31
|
+
get defaultDeny(): boolean;
|
|
32
|
+
/** Optional intent section from the policy file. */
|
|
33
|
+
get intent(): PaybondPolicyDocumentV1["intent"];
|
|
34
|
+
/**
|
|
35
|
+
* Load and validate a policy from a file path or pre-parsed document object.
|
|
36
|
+
* File paths accept JSON (`.json`) or YAML (`.yaml` / `.yml`).
|
|
37
|
+
*/
|
|
38
|
+
static load(source: PaybondPolicyLoadSource): Promise<PaybondPolicy>;
|
|
39
|
+
private static resolveEffectiveDocument;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve merged effective policy via Gateway org-policy inheritance.
|
|
42
|
+
* Production tenants should prefer this over {@link mergeLocal}.
|
|
43
|
+
*/
|
|
44
|
+
static loadEffective(options: {
|
|
45
|
+
overlay: PaybondPolicyLoadSource;
|
|
46
|
+
gateway: PolicyEffectiveResolveClient;
|
|
47
|
+
}): Promise<PaybondPolicyLoadEffectiveResult>;
|
|
48
|
+
/** Synchronous variant for pre-parsed effective (v1) document objects only. */
|
|
49
|
+
static fromDocument(document: PaybondPolicyDocumentV1): PaybondPolicy;
|
|
50
|
+
/**
|
|
51
|
+
* Offline merge of org base + tenant overlay into an effective v1 policy.
|
|
52
|
+
* Best-effort for CI; production should use Gateway effective resolution.
|
|
53
|
+
*/
|
|
54
|
+
static mergeLocal(options: {
|
|
55
|
+
base: PaybondPolicyLoadSource;
|
|
56
|
+
overlay: PaybondPolicyLoadSource;
|
|
57
|
+
merge?: PolicyMergeOptions;
|
|
58
|
+
}): Promise<PolicyMergeResult & {
|
|
59
|
+
policy: PaybondPolicy;
|
|
60
|
+
}>;
|
|
61
|
+
private static loadDocument;
|
|
62
|
+
/** Load a raw overlay document payload for server-side inheritance validation. */
|
|
63
|
+
static loadOverlayPayload(source: PaybondPolicyLoadSource): Promise<Record<string, unknown>>;
|
|
64
|
+
/**
|
|
65
|
+
* Validate a tenant overlay with server-side org-base merge
|
|
66
|
+
* (`POST /v1/policy/validate?resolve_inheritance=1`).
|
|
67
|
+
*/
|
|
68
|
+
static validateOverlayRemote(overlay: PaybondPolicyLoadSource, gateway: PolicyRemoteValidateClient, options?: PolicyRemoteValidateOptions): Promise<PolicyRemoteValidateResult>;
|
|
69
|
+
/** Build the tool registry consumed by agent middleware. */
|
|
70
|
+
toToolRegistry(): PaybondToolRegistry;
|
|
71
|
+
/**
|
|
72
|
+
* Build params for {@link PaybondIntents.createWithPolicyBinding} from policy intent alignment
|
|
73
|
+
* plus caller signing context and a published managed-policy head.
|
|
74
|
+
*/
|
|
75
|
+
toIntentCreateInput(overrides: PaybondPolicyIntentCreateOverrides): PaybondPolicyIntentCreateInput;
|
|
76
|
+
/** Run client-side alignment checks (registry, presets, optional gateway template lookup). */
|
|
77
|
+
validate(options?: PolicyValidatorOptions): Promise<PolicyValidatorResult>;
|
|
78
|
+
/**
|
|
79
|
+
* Validate this policy against the tenant-scoped Gateway registry (`POST /v1/policy/validate`).
|
|
80
|
+
* Requires a logged-in Gateway Harbor client from `paybond.open()`.
|
|
81
|
+
*/
|
|
82
|
+
validateRemote(gateway: PolicyRemoteValidateClient, options?: PolicyRemoteValidateOptions): Promise<PolicyRemoteValidateResult>;
|
|
83
|
+
/** Build sandbox bootstrap input for {@link PaybondAgentRun.bind} from this policy. */
|
|
84
|
+
sandboxBootstrap(options?: PaybondPolicySandboxBootstrapOptions): PaybondRunBindingSandboxBootstrapInput;
|
|
85
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { policyToIntentCreateInput, } from "./intent-spec.js";
|
|
4
|
+
import { mergePaybondPolicies, toEffectivePolicyDocument, } from "./merge.js";
|
|
5
|
+
import { parsePolicyDocumentText } from "./parse-text.js";
|
|
6
|
+
import { policyToToolRegistry } from "./registry.js";
|
|
7
|
+
import { isPaybondPolicyDocumentV2, isPaybondPolicyOverlay, parsePaybondPolicyDocument, parsePaybondPolicyDocumentV1, } from "./schema.js";
|
|
8
|
+
import { policySandboxBootstrap, } from "./sandbox-bootstrap.js";
|
|
9
|
+
import { PolicyValidator } from "./validate.js";
|
|
10
|
+
import { validatePolicyRemote, validatePolicyPayloadRemote, } from "./validate-remote.js";
|
|
11
|
+
import { resolvePolicyEffectiveRemote, } from "./load-effective.js";
|
|
12
|
+
/**
|
|
13
|
+
* Portable policy-as-code document loaded from `paybond.policy.yaml` or an in-memory object.
|
|
14
|
+
* Drives tool registry construction and production intent create alignment.
|
|
15
|
+
*/
|
|
16
|
+
export class PaybondPolicy {
|
|
17
|
+
document;
|
|
18
|
+
source;
|
|
19
|
+
constructor(document, source) {
|
|
20
|
+
this.document = document;
|
|
21
|
+
this.source = source;
|
|
22
|
+
}
|
|
23
|
+
/** Policy name from the document (`name` field). */
|
|
24
|
+
get name() {
|
|
25
|
+
return this.document.name;
|
|
26
|
+
}
|
|
27
|
+
/** Whether unregistered side-effecting tools should fail closed at intercept time. */
|
|
28
|
+
get defaultDeny() {
|
|
29
|
+
return this.document.default_deny;
|
|
30
|
+
}
|
|
31
|
+
/** Optional intent section from the policy file. */
|
|
32
|
+
get intent() {
|
|
33
|
+
return this.document.intent;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load and validate a policy from a file path or pre-parsed document object.
|
|
37
|
+
* File paths accept JSON (`.json`) or YAML (`.yaml` / `.yml`).
|
|
38
|
+
*/
|
|
39
|
+
static async load(source) {
|
|
40
|
+
if (typeof source === "string") {
|
|
41
|
+
const document = await PaybondPolicy.loadDocument(source);
|
|
42
|
+
const effective = await PaybondPolicy.resolveEffectiveDocument(document, source);
|
|
43
|
+
return new PaybondPolicy(effective, source);
|
|
44
|
+
}
|
|
45
|
+
const document = parsePaybondPolicyDocument(source);
|
|
46
|
+
const effective = await PaybondPolicy.resolveEffectiveDocument(document);
|
|
47
|
+
return new PaybondPolicy(effective);
|
|
48
|
+
}
|
|
49
|
+
static async resolveEffectiveDocument(document, sourcePath) {
|
|
50
|
+
if (isPaybondPolicyDocumentV2(document) && isPaybondPolicyOverlay(document)) {
|
|
51
|
+
const basePath = document.extends?.base_policy;
|
|
52
|
+
if (!basePath) {
|
|
53
|
+
return toEffectivePolicyDocument(document);
|
|
54
|
+
}
|
|
55
|
+
const resolvedBase = sourcePath
|
|
56
|
+
? resolve(dirname(sourcePath), basePath)
|
|
57
|
+
: basePath;
|
|
58
|
+
const baseDoc = await PaybondPolicy.loadDocument(resolvedBase);
|
|
59
|
+
return mergePaybondPolicies(baseDoc, document).effective;
|
|
60
|
+
}
|
|
61
|
+
return toEffectivePolicyDocument(document);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve merged effective policy via Gateway org-policy inheritance.
|
|
65
|
+
* Production tenants should prefer this over {@link mergeLocal}.
|
|
66
|
+
*/
|
|
67
|
+
static async loadEffective(options) {
|
|
68
|
+
const overlayDoc = await PaybondPolicy.loadDocument(options.overlay);
|
|
69
|
+
if (!isPaybondPolicyDocumentV2(overlayDoc) || !isPaybondPolicyOverlay(overlayDoc)) {
|
|
70
|
+
throw new Error("overlay must be a v2 tenant policy with extends");
|
|
71
|
+
}
|
|
72
|
+
const resolved = await resolvePolicyEffectiveRemote(overlayDoc, options.gateway);
|
|
73
|
+
const effective = parsePaybondPolicyDocumentV1(resolved.effective_policy);
|
|
74
|
+
return {
|
|
75
|
+
policy: PaybondPolicy.fromDocument(effective),
|
|
76
|
+
report: resolved.merge_report,
|
|
77
|
+
effectivePolicyDigest: resolved.effective_policy_digest,
|
|
78
|
+
effectivePolicyVersion: resolved.effective_policy_version,
|
|
79
|
+
orgBaseVersionSeq: resolved.org_base_version_seq,
|
|
80
|
+
orgBaseContentDigest: resolved.org_base_content_digest,
|
|
81
|
+
...(resolved.unchanged ? { unchanged: true } : {}),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** Synchronous variant for pre-parsed effective (v1) document objects only. */
|
|
85
|
+
static fromDocument(document) {
|
|
86
|
+
return new PaybondPolicy(document);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Offline merge of org base + tenant overlay into an effective v1 policy.
|
|
90
|
+
* Best-effort for CI; production should use Gateway effective resolution.
|
|
91
|
+
*/
|
|
92
|
+
static async mergeLocal(options) {
|
|
93
|
+
const baseDoc = await PaybondPolicy.loadDocument(options.base);
|
|
94
|
+
const overlayDoc = await PaybondPolicy.loadDocument(options.overlay);
|
|
95
|
+
if (!isPaybondPolicyDocumentV2(overlayDoc) || !isPaybondPolicyOverlay(overlayDoc)) {
|
|
96
|
+
throw new Error("overlay must be a v2 tenant policy with extends");
|
|
97
|
+
}
|
|
98
|
+
const merged = mergePaybondPolicies(baseDoc, overlayDoc, options.merge);
|
|
99
|
+
return {
|
|
100
|
+
...merged,
|
|
101
|
+
policy: PaybondPolicy.fromDocument(merged.effective),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
static async loadDocument(source) {
|
|
105
|
+
if (typeof source === "string") {
|
|
106
|
+
const text = await readFile(source, "utf8");
|
|
107
|
+
const raw = parsePolicyDocumentText(text, source);
|
|
108
|
+
return parsePaybondPolicyDocument(raw);
|
|
109
|
+
}
|
|
110
|
+
return parsePaybondPolicyDocument(source);
|
|
111
|
+
}
|
|
112
|
+
/** Load a raw overlay document payload for server-side inheritance validation. */
|
|
113
|
+
static async loadOverlayPayload(source) {
|
|
114
|
+
if (typeof source === "string") {
|
|
115
|
+
const text = await readFile(source, "utf8");
|
|
116
|
+
const raw = parsePolicyDocumentText(text, source);
|
|
117
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
118
|
+
throw new Error("overlay must be a JSON or YAML object");
|
|
119
|
+
}
|
|
120
|
+
return raw;
|
|
121
|
+
}
|
|
122
|
+
if (typeof source === "object" && source !== null && !Array.isArray(source)) {
|
|
123
|
+
return source;
|
|
124
|
+
}
|
|
125
|
+
throw new Error("overlay must be a file path or raw overlay object");
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Validate a tenant overlay with server-side org-base merge
|
|
129
|
+
* (`POST /v1/policy/validate?resolve_inheritance=1`).
|
|
130
|
+
*/
|
|
131
|
+
static async validateOverlayRemote(overlay, gateway, options) {
|
|
132
|
+
const payload = await PaybondPolicy.loadOverlayPayload(overlay);
|
|
133
|
+
return validatePolicyPayloadRemote(payload, gateway, {
|
|
134
|
+
...options,
|
|
135
|
+
resolveInheritance: true,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/** Build the tool registry consumed by agent middleware. */
|
|
139
|
+
toToolRegistry() {
|
|
140
|
+
return policyToToolRegistry(this.document);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Build params for {@link PaybondIntents.createWithPolicyBinding} from policy intent alignment
|
|
144
|
+
* plus caller signing context and a published managed-policy head.
|
|
145
|
+
*/
|
|
146
|
+
toIntentCreateInput(overrides) {
|
|
147
|
+
return policyToIntentCreateInput(this.document, overrides);
|
|
148
|
+
}
|
|
149
|
+
/** Run client-side alignment checks (registry, presets, optional gateway template lookup). */
|
|
150
|
+
validate(options) {
|
|
151
|
+
return PolicyValidator.validateDocument(this.document, options);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Validate this policy against the tenant-scoped Gateway registry (`POST /v1/policy/validate`).
|
|
155
|
+
* Requires a logged-in Gateway Harbor client from `paybond.open()`.
|
|
156
|
+
*/
|
|
157
|
+
validateRemote(gateway, options) {
|
|
158
|
+
return validatePolicyRemote(this.document, gateway, options);
|
|
159
|
+
}
|
|
160
|
+
/** Build sandbox bootstrap input for {@link PaybondAgentRun.bind} from this policy. */
|
|
161
|
+
sandboxBootstrap(options = {}) {
|
|
162
|
+
return policySandboxBootstrap(this.document, options);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type PaybondPolicyDocument, type PaybondPolicyDocumentV1, type PaybondPolicyDocumentV2 } from "./schema.js";
|
|
2
|
+
export type PolicyMergeDeniedWidening = {
|
|
3
|
+
path: string;
|
|
4
|
+
code: string;
|
|
5
|
+
message: string;
|
|
6
|
+
};
|
|
7
|
+
export type PolicyMergeReport = {
|
|
8
|
+
org_policy_id: string | null;
|
|
9
|
+
org_id: string | null;
|
|
10
|
+
base_policy_name: string;
|
|
11
|
+
overlay_policy_name: string | null;
|
|
12
|
+
overrides_applied: string[];
|
|
13
|
+
denied_widenings: PolicyMergeDeniedWidening[];
|
|
14
|
+
};
|
|
15
|
+
export type PolicyMergeResult = {
|
|
16
|
+
effective: PaybondPolicyDocumentV1;
|
|
17
|
+
report: PolicyMergeReport;
|
|
18
|
+
};
|
|
19
|
+
export type PolicyMergeOptions = {
|
|
20
|
+
/** When set, tenant evidence_preset swaps must stay within this catalog subset. */
|
|
21
|
+
approvedEvidencePresets?: readonly string[];
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Deterministically merge an org base policy with a tenant overlay.
|
|
25
|
+
* Returns a v1 effective document suitable for middleware and validation.
|
|
26
|
+
*/
|
|
27
|
+
export declare function mergePaybondPolicies(base: PaybondPolicyDocumentV1 | PaybondPolicyDocumentV2, overlay: PaybondPolicyDocumentV2, options?: PolicyMergeOptions): PolicyMergeResult;
|
|
28
|
+
/** Normalize any supported policy document to a flat v1 effective document. */
|
|
29
|
+
export declare function toEffectivePolicyDocument(document: PaybondPolicyDocument): PaybondPolicyDocumentV1;
|