{"slug": "your-ai-agent-called-a-tool-can-you-prove-it-followed-the-rules", "title": "Your AI agent called a tool. Can you prove it followed the rules?", "summary": "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.", "body_md": "Your agent just wrote a file. You have logs. But can you answer this:\n\nWas the policy gate applied\n\nbeforethe tool ran — or after?\n\nLogs can't tell you that. Here's how we solved it.\n\nMost frameworks give you a log line like:\n\n```\n[2026-07-07T09:00:01Z] tool:fs_write path=/tmp/report.txt status=ok\n```\n\nThat tells you the tool ran. It doesn't tell you:\n\nFor a hobby project, that's fine. For anything touching real data, it's not.\n\nWasmAgent's `@wasmagent/aep`\n\npackage records every tool call as an `ActionEvidence`\n\nobject — Zod-validated, schema-versioned, with pre/post state digests baked in.\n\n``` js\nimport { AEPEmitter } from \"@wasmagent/aep\";\n\nconst emitter = new AEPEmitter({\n  run_id: \"run-abc123\",\n  repo_commit: \"5c1102f\",\n  model_id: \"claude-sonnet-4-6\",\n});\n\n// Before tool execution:\nemitter.addAction({\n  tool_name: \"fs_write\",\n  state_changing: true,\n  capability_decision: {\n    capability: \"fs_write\",\n    subject: \"agent:run-abc123\",\n    resource: \"/tmp/report.txt\",\n    decision: \"allow\",\n    reason_code: \"policy:default-v1\",\n  },\n  precondition_digest: \"sha256:a1b2c3...\",\n  input_taint_labels: [\"user_provided\"],\n});\n\n// After tool execution:\nemitter.addAction({\n  tool_name: \"fs_write\",\n  state_changing: true,\n  post_state_digest: \"sha256:d4e5f6...\",\n});\n\nemitter.setBudgetLedger({\n  token_budget: { limit: 4000, spent: 142 },\n  risk_budget:  { limit: 1.0,  spent: 0.2 },\n});\n\nconst record = emitter.build();\n```\n\nThe `capability_decision`\n\nis part of the same record as the action — not a separate log entry that could be reordered or dropped.\n\nFor real-time observability, AEP also emits named OpenTelemetry spans:\n\n``` js\nimport { AEP_SPAN_NAMES } from \"@wasmagent/otel-exporter\";\n\n// Plug into any OTel collector:\nAEP_SPAN_NAMES.TOOL_CALL       // \"tool.call\"\nAEP_SPAN_NAMES.POLICY_CHECK    // \"policy.check\"\nAEP_SPAN_NAMES.SANDBOX_EXEC    // \"sandbox.exec\"\nAEP_SPAN_NAMES.VERIFIER_CHECK  // \"verifier.check\"\nAEP_SPAN_NAMES.LLM_GENERATE    // \"llm.generate\"\nAEP_SPAN_NAMES.MCP_REQUEST     // \"mcp.request\"\n// + 3 more\n```\n\nThe spans go to Grafana/Jaeger/etc. The `AEPRecord`\n\nis what you keep for audit and training data.\n\nIn a single-agent setup, this is useful. In a multi-agent setup — orchestrator delegates to a subagent — it becomes essential:\n\n```\nrun_context: {\n  agent_id: \"orchestrator\",\n  subagent_id: \"coder-agent\",\n  delegation_chain: [\"orchestrator\", \"planner\", \"coder-agent\"],\n  scope_lease_id: \"lease-xyz\",  // ← subagent can only do what parent granted\n}\ngit clone https://github.com/WasmAgent/wasmagent-js\nbun test packages/aep/src/\n```\n\n**Next in this series:** MCP Trust Pack — the gateway layer that enforces policy before tools execute.\n\n**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)", "url": "https://wpnews.pro/news/your-ai-agent-called-a-tool-can-you-prove-it-followed-the-rules", "canonical_source": "https://dev.to/telleroutlook/your-ai-agent-called-a-tool-can-you-prove-it-followed-the-rules-2bgn", "published_at": "2026-06-26 01:26:57+00:00", "updated_at": "2026-06-26 01:33:42.108910+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-safety", "ai-infrastructure"], "entities": ["WasmAgent", "@wasmagent/aep", "OpenTelemetry", "Grafana", "Jaeger", "MCP"], "alternates": {"html": "https://wpnews.pro/news/your-ai-agent-called-a-tool-can-you-prove-it-followed-the-rules", "markdown": "https://wpnews.pro/news/your-ai-agent-called-a-tool-can-you-prove-it-followed-the-rules.md", "text": "https://wpnews.pro/news/your-ai-agent-called-a-tool-can-you-prove-it-followed-the-rules.txt", "jsonld": "https://wpnews.pro/news/your-ai-agent-called-a-tool-can-you-prove-it-followed-the-rules.jsonld"}}