ĀML™ / AGENT BUILD
FROM A PROPOSAL TO A HOST-OWNED TOOL

The agent can ask.
Your host decides.

Give one function tool an exact policy boundary. Start with a local callback that sends nothing; then replace only the host-owned pieces with your actual policy, approval, and service.

Build the boundary ↓
ĀML / FUNCTION TOOL PATHNO LIVE DELIVERY
01

Run the local rehearsal.

This runs the checked-in experimental adapter. It simulates an approval and a host callback for a matching destination, then tries a changed destination. Record your checkout commit when sharing a result.

git clone --depth 1 https://github.com/aruintelligence/aml-core.git cd aml-core git rev-parse HEAD node pilots/action-boundary/guarded-tool-demo.mjs

EXACT ROUTE + SIMULATED APPROVALCallback returned

The result is marked dispatched; it reports would_send_to. No message is sent or person authenticated.

CHANGED DESTINATIONBlocked before callback

The exact policy rule does not match the outside resource. Inspect the plan and receipt in the printed JSON.

02

Move the boundary into your host.

The real host owns the tool identity, effect, resource mapping, policy, authenticated approval, and the service call. This sketch deliberately throws until you implement the two callbacks. It imports the project preview from your checkout.

import { createGuardedToolExecute } from "./pilots/action-boundary/guarded-tool.mjs"; const policy = { protocol: "aml-action-policy/1", rules: [{ tool: "send_message", effect: "send", resource: "team@example.test", requires_approval: true }] }; async function hostApproveExact(proposal, proposal_sha256, context) { throw new Error("Implement authenticated approval for this exact proposal"); } async function sendFromHost(args, context) { throw new Error("Implement the provider call using these exact arguments"); } export const execute = createGuardedToolExecute({ tool: "send_message", effect: "send", purpose: "Send a team update", resourceFor: args => args.to, policy, requestApproval: ({ proposal, proposal_sha256 }, context) => hostApproveExact(proposal, proposal_sha256, context), execute: (args, context) => sendFromHost(args, context) });

The approval hook must return { approved: true, proposal_sha256 } for the exact frozen proposal. For callbacks with CC/BCC or transformed provider requests, use the dedicated adapters in the full guide. Do not copy the rehearsal’s automatic approval into a real host.

03

Recheck before any real dispatch.

The host must supply its own authentication, durable one-use claims, operation idempotency, audit storage, and honest mapping to the provider request. An unknown callback result might already have caused a side effect; this wrapper does not retry it.

A digest binds the proposal bytes. It does not prove who approved them, whether the policy is trustworthy, or whether the outside service completed the action.