Your AI agent called a tool. Can you prove it followed the rules? WasmAgent released the @wasmagent/aep package, which records every tool call as an ActionEvidence object with pre/post state digests and capability decisions baked into a single record, solving the problem of proving whether a policy gate was applied before or after a tool ran. The package also emits OpenTelemetry spans for real-time observability and supports multi-agent setups with delegation chains and scope leases. Your agent just wrote a file. You have logs. But can you answer this: Was the policy gate applied beforethe tool ran — or after? Logs can't tell you that. Here's how we solved it. Most frameworks give you a log line like: 2026-07-07T09:00:01Z tool:fs write path=/tmp/report.txt status=ok That tells you the tool ran. It doesn't tell you: For a hobby project, that's fine. For anything touching real data, it's not. WasmAgent's @wasmagent/aep package records every tool call as an ActionEvidence object — Zod-validated, schema-versioned, with pre/post state digests baked in. js import { AEPEmitter } from "@wasmagent/aep"; const emitter = new AEPEmitter { run id: "run-abc123", repo commit: "5c1102f", model id: "claude-sonnet-4-6", } ; // Before tool execution: emitter.addAction { tool name: "fs write", state changing: true, capability decision: { capability: "fs write", subject: "agent:run-abc123", resource: "/tmp/report.txt", decision: "allow", reason code: "policy:default-v1", }, precondition digest: "sha256:a1b2c3...", input taint labels: "user provided" , } ; // After tool execution: emitter.addAction { tool name: "fs write", state changing: true, post state digest: "sha256:d4e5f6...", } ; emitter.setBudgetLedger { token budget: { limit: 4000, spent: 142 }, risk budget: { limit: 1.0, spent: 0.2 }, } ; const record = emitter.build ; The capability decision is part of the same record as the action — not a separate log entry that could be reordered or dropped. For real-time observability, AEP also emits named OpenTelemetry spans: js import { AEP SPAN NAMES } from "@wasmagent/otel-exporter"; // Plug into any OTel collector: AEP SPAN NAMES.TOOL CALL // "tool.call" AEP SPAN NAMES.POLICY CHECK // "policy.check" AEP SPAN NAMES.SANDBOX EXEC // "sandbox.exec" AEP SPAN NAMES.VERIFIER CHECK // "verifier.check" AEP SPAN NAMES.LLM GENERATE // "llm.generate" AEP SPAN NAMES.MCP REQUEST // "mcp.request" // + 3 more The spans go to Grafana/Jaeger/etc. The AEPRecord is what you keep for audit and training data. In a single-agent setup, this is useful. In a multi-agent setup — orchestrator delegates to a subagent — it becomes essential: run context: { agent id: "orchestrator", subagent id: "coder-agent", delegation chain: "orchestrator", "planner", "coder-agent" , scope lease id: "lease-xyz", // ← subagent can only do what parent granted } git clone https://github.com/WasmAgent/wasmagent-js bun test packages/aep/src/ Next in this series: MCP Trust Pack — the gateway layer that enforces policy before tools execute. Code: packages/aep https://github.com/WasmAgent/wasmagent-js/tree/main/packages/aep · packages/otel-exporter https://github.com/WasmAgent/wasmagent-js/tree/main/packages/otel-exporter