From acb9802d11024a8fbf729a63f8e30d974127193f Mon Sep 17 00:00:00 2001 From: telleroutlook Date: Mon, 27 Jul 2026 19:47:47 +0800 Subject: [PATCH] feat(schema): add Critical Extension Gate + LockedArtifact to agentbom & aep-record MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Absorbs two proven designs from the ASF (Autonomous Software Factory) protocol spec into wasmagent-protocol, grounded in WasmAgent's provability-first positioning. ## Changes ### agentbom v0.2 - block: CRD-like mechanism where extensions MUST cause consumers to abort if the namespace is unrecognised. Prevents silent security downgrades (e.g. Trust Passport requirements being silently dropped when an older runtime processes the BOM). - items now enforce the namespace pattern (e.g. ), making permission grants machine-parseable and auditable. ### aep-record (aep/v0.3, additive) - : reusable definition requiring + . - array: DAG artifact tracking with nine lifecycle states (pending → completed/failed/cancelled). The conditional enforces LockedArtifact only when state == completed — completed artifacts are always cryptographically pinned, in-progress ones are not constrained. ## Test fixtures added - valid: , - invalid: , , All 18 JS tests and full Python conformance (with jsonschema) pass. Note: jq reformatted the two modified schema files to expanded style; semantics are unchanged. biome 1.9.4 (lineWidth: 100) is not installed on this host. --- schemas/aep/aep-record.schema.json | 518 +++++++++++++++--- schemas/agentbom/agentbom.schema.json | 57 +- schemas/index.json | 16 +- .../completed-artifact-missing-lock.json | 12 + .../agentbom/bad-permission-scope.json | 16 + .../agentbom/extension-missing-critical.json | 18 + .../aep-record/with-locked-artifacts.json | 29 + .../valid/agentbom/with-extension-gate.json | 32 ++ 8 files changed, 595 insertions(+), 103 deletions(-) create mode 100644 tests/fixtures/invalid/aep-record/completed-artifact-missing-lock.json create mode 100644 tests/fixtures/invalid/agentbom/bad-permission-scope.json create mode 100644 tests/fixtures/invalid/agentbom/extension-missing-critical.json create mode 100644 tests/fixtures/valid/aep-record/with-locked-artifacts.json create mode 100644 tests/fixtures/valid/agentbom/with-extension-gate.json diff --git a/schemas/aep/aep-record.schema.json b/schemas/aep/aep-record.schema.json index 99f458d..1ad1dd1 100644 --- a/schemas/aep/aep-record.schema.json +++ b/schemas/aep/aep-record.schema.json @@ -4,28 +4,76 @@ "title": "AEPRecord", "description": "Agent Evidence Protocol record — runtime action evidence and run provenance. Canonical source for wasmagent-js, wasmagent-proxy, trace-pipeline, wasmagent-train-replay, and open-agent-audit.", "type": "object", - "required": ["schema_version", "run_id", "created_at_ms"], + "required": [ + "schema_version", + "run_id", + "created_at_ms" + ], "properties": { - "schema_version": { "type": "string", "enum": ["aep/v0.1", "aep/v0.2", "aep/v0.3"] }, - "run_id": { "type": "string" }, - "trace_id": { "type": "string" }, - "parent_trace_id": { "type": ["string", "null"] }, - "repo_commit": { "type": "string" }, - "runtime_version": { "type": "string" }, - "model_provider": { "type": "string" }, - "model_id": { "type": "string" }, - "policy_bundle_digest": { "type": "string" }, - "tool_manifest_digest": { "type": "string" }, - "mcp_server_card_digest": { "type": ["string", "null"] }, + "schema_version": { + "type": "string", + "enum": [ + "aep/v0.1", + "aep/v0.2", + "aep/v0.3" + ] + }, + "run_id": { + "type": "string" + }, + "trace_id": { + "type": "string" + }, + "parent_trace_id": { + "type": [ + "string", + "null" + ] + }, + "repo_commit": { + "type": "string" + }, + "runtime_version": { + "type": "string" + }, + "model_provider": { + "type": "string" + }, + "model_id": { + "type": "string" + }, + "policy_bundle_digest": { + "type": "string" + }, + "tool_manifest_digest": { + "type": "string" + }, + "mcp_server_card_digest": { + "type": [ + "string", + "null" + ] + }, "input_refs": { "type": "array", "items": { "type": "object", - "required": ["uri"], + "required": [ + "uri" + ], "properties": { - "uri": { "type": "string" }, - "digest": { "type": "string" }, - "taint_labels": { "type": "array", "items": { "type": "string" } } + "uri": { + "type": "string" + }, + "digest": { + "type": "string" + }, + "taint_labels": { + "type": "array", + "items": { + "type": "string" + } + } } } }, @@ -33,11 +81,19 @@ "type": "array", "items": { "type": "object", - "required": ["uri"], + "required": [ + "uri" + ], "properties": { - "uri": { "type": "string" }, - "digest": { "type": "string" }, - "redaction_profile": { "type": "string" } + "uri": { + "type": "string" + }, + "digest": { + "type": "string" + }, + "redaction_profile": { + "type": "string" + } } } }, @@ -45,13 +101,34 @@ "type": "array", "items": { "type": "object", - "required": ["capability", "subject", "resource", "decision"], + "required": [ + "capability", + "subject", + "resource", + "decision" + ], "properties": { - "capability": { "type": "string" }, - "subject": { "type": "string" }, - "resource": { "type": "string" }, - "decision": { "type": "string", "enum": ["allow", "deny", "ask_user", "dry_run"] }, - "reason_code": { "type": "string" } + "capability": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "resource": { + "type": "string" + }, + "decision": { + "type": "string", + "enum": [ + "allow", + "deny", + "ask_user", + "dry_run" + ] + }, + "reason_code": { + "type": "string" + } } } }, @@ -59,27 +136,85 @@ "type": "array", "items": { "type": "object", - "required": ["action_id", "tool_name", "state_changing", "timestamp_ms"], + "required": [ + "action_id", + "tool_name", + "state_changing", + "timestamp_ms" + ], "properties": { - "action_id": { "type": "string" }, - "tool_name": { "type": "string" }, - "state_changing": { "type": "boolean" }, - "precondition_digest": { "type": "string" }, - "result_digest": { "type": "string" }, - "evidence_refs": { "type": "array", "items": { "type": "string" } }, - "timestamp_ms": { "type": "number" }, - "parent_action_id": { "type": "string" }, - "causal_chain_id": { "type": "string" }, - "tool_descriptor_digest": { "type": "string" }, - "server_card_digest": { "type": "string" }, - "scope_lease_id": { "type": "string" }, - "approval_context_hash": { "type": "string" }, - "input_taint_labels": { "type": "array", "items": { "type": "string" } }, - "output_taint_labels": { "type": "array", "items": { "type": "string" } }, - "memory_read_refs": { "type": "array", "items": { "type": "string" } }, - "memory_write_refs": { "type": "array", "items": { "type": "string" } }, - "pre_state_digest": { "type": "string" }, - "post_state_digest": { "type": "string" } + "action_id": { + "type": "string" + }, + "tool_name": { + "type": "string" + }, + "state_changing": { + "type": "boolean" + }, + "precondition_digest": { + "type": "string" + }, + "result_digest": { + "type": "string" + }, + "evidence_refs": { + "type": "array", + "items": { + "type": "string" + } + }, + "timestamp_ms": { + "type": "number" + }, + "parent_action_id": { + "type": "string" + }, + "causal_chain_id": { + "type": "string" + }, + "tool_descriptor_digest": { + "type": "string" + }, + "server_card_digest": { + "type": "string" + }, + "scope_lease_id": { + "type": "string" + }, + "approval_context_hash": { + "type": "string" + }, + "input_taint_labels": { + "type": "array", + "items": { + "type": "string" + } + }, + "output_taint_labels": { + "type": "array", + "items": { + "type": "string" + } + }, + "memory_read_refs": { + "type": "array", + "items": { + "type": "string" + } + }, + "memory_write_refs": { + "type": "array", + "items": { + "type": "string" + } + }, + "pre_state_digest": { + "type": "string" + }, + "post_state_digest": { + "type": "string" + } } } }, @@ -87,12 +222,26 @@ "type": "array", "items": { "type": "object", - "required": ["verifier_id", "passed"], + "required": [ + "verifier_id", + "passed" + ], "properties": { - "verifier_id": { "type": "string" }, - "passed": { "type": "boolean" }, - "score": { "type": "number" }, - "claim_ids": { "type": "array", "items": { "type": "string" } } + "verifier_id": { + "type": "string" + }, + "passed": { + "type": "boolean" + }, + "score": { + "type": "number" + }, + "claim_ids": { + "type": "array", + "items": { + "type": "string" + } + } } } }, @@ -102,64 +251,117 @@ "properties": { "token_budget": { "type": "object", - "required": ["spent"], + "required": [ + "spent" + ], "properties": { - "limit": { "type": "number" }, - "spent": { "type": "number" } + "limit": { + "type": "number" + }, + "spent": { + "type": "number" + } } }, "latency_budget": { "type": "object", - "required": ["actual_ms"], + "required": [ + "actual_ms" + ], "properties": { - "limit_ms": { "type": "number" }, - "actual_ms": { "type": "number" } + "limit_ms": { + "type": "number" + }, + "actual_ms": { + "type": "number" + } } }, "tool_budget": { "type": "object", - "required": ["spent"], + "required": [ + "spent" + ], "properties": { - "limit": { "type": "number" }, - "spent": { "type": "number" } + "limit": { + "type": "number" + }, + "spent": { + "type": "number" + } } }, "risk_budget": { "type": "object", - "required": ["spent"], + "required": [ + "spent" + ], "properties": { - "limit": { "type": "number" }, - "spent": { "type": "number" } + "limit": { + "type": "number" + }, + "spent": { + "type": "number" + } } }, "retry_budget": { "type": "object", - "required": ["spent"], + "required": [ + "spent" + ], "properties": { - "limit": { "type": "number" }, - "spent": { "type": "number" } + "limit": { + "type": "number" + }, + "spent": { + "type": "number" + } } }, "human_approval_budget": { "type": "object", - "required": ["spent"], + "required": [ + "spent" + ], "properties": { - "limit": { "type": "number" }, - "spent": { "type": "number" } + "limit": { + "type": "number" + }, + "spent": { + "type": "number" + } } } } }, - "created_at_ms": { "type": "number" }, + "created_at_ms": { + "type": "number" + }, "run_context": { "type": "object", "properties": { - "agent_id": { "type": "string" }, - "agent_version": { "type": "string" }, - "subagent_id": { "type": "string" }, - "delegation_chain": { "type": "array", "items": { "type": "string" } }, - "environment_digest": { "type": "string" }, - "dependency_lock_digest": { "type": "string" } + "agent_id": { + "type": "string" + }, + "agent_version": { + "type": "string" + }, + "subagent_id": { + "type": "string" + }, + "delegation_chain": { + "type": "array", + "items": { + "type": "string" + } + }, + "environment_digest": { + "type": "string" + }, + "dependency_lock_digest": { + "type": "string" + } } }, "user_id": { @@ -172,41 +374,177 @@ }, "side_effect_class": { "type": "string", - "enum": ["read", "mutate-local", "mutate-external", "network-egress", "unknown"], + "enum": [ + "read", + "mutate-local", + "mutate-external", + "network-egress", + "unknown" + ], "description": "Per-record side-effect classification (additive, aep/v0.3+). Shares one vocabulary with run_side_effect_class_max; reconciles wasmagent-js and trace-pipeline forks." }, "run_side_effect_class_max": { "type": "string", - "enum": ["read", "mutate-local", "mutate-external", "network-egress", "unknown"], + "enum": [ + "read", + "mutate-local", + "mutate-external", + "network-egress", + "unknown" + ], "description": "Per-run aggregate: the highest side-effect class observed across the whole run (additive, aep/v0.3+). Shares the side_effect_class vocabulary." }, "recording_mode": { "type": "string", - "enum": ["full", "delta", "validation"], + "enum": [ + "full", + "delta", + "validation" + ], "description": "How this run's evidence was captured (additive, aep/v0.3+)." }, "argument_drift": { "type": "object", "description": "Detected drift between an action's declared arguments and the arguments used at runtime (additive, aep/v0.3+).", "properties": { - "tool_name": { "type": "string" }, - "declared_digest": { "type": "string" }, - "actual_digest": { "type": "string" }, - "diff_summary": { "type": "string" }, - "drifted_args": { "type": "array", "items": { "type": "string" } } + "tool_name": { + "type": "string" + }, + "declared_digest": { + "type": "string" + }, + "actual_digest": { + "type": "string" + }, + "diff_summary": { + "type": "string" + }, + "drifted_args": { + "type": "array", + "items": { + "type": "string" + } + } }, "additionalProperties": true }, "signature": { "type": "object", "description": "Optional tamper-evident signature. Stays OPTIONAL in aep/v0.3; tightening it to required is a breaking change (CONTRACT-CHANGE-PROCESS.md section 3) that needs an org RFC before it can land - do not silently add it to the 'required' array.", - "required": ["alg", "key_id", "sig"], + "required": [ + "alg", + "key_id", + "sig" + ], "properties": { - "alg": { "type": "string" }, - "key_id": { "type": "string" }, - "sig": { "type": "string" }, - "bundle": { "type": "object" }, - "transparency_log_ref": { "type": "string" } + "alg": { + "type": "string" + }, + "key_id": { + "type": "string" + }, + "sig": { + "type": "string" + }, + "bundle": { + "type": "object" + }, + "transparency_log_ref": { + "type": "string" + } + } + }, + "run_artifacts": { + "type": "array", + "description": "Artifacts produced or consumed during this run. Completed artifacts are cryptographically locked via LockedArtifact constraints.", + "items": { + "type": "object", + "required": [ + "artifact_id", + "class", + "state" + ], + "properties": { + "artifact_id": { + "type": "string", + "description": "Unique artifact identifier within this run." + }, + "class": { + "type": "string", + "description": "Artifact class (e.g. file, pr, issue, test-report, model-output)." + }, + "state": { + "type": "string", + "enum": [ + "pending", + "generating", + "generated", + "building", + "testing", + "completed", + "failed", + "skipped", + "cancelled" + ], + "description": "Lifecycle state of the artifact." + }, + "depends_on": { + "type": "array", + "items": { + "type": "string" + }, + "description": "artifact_ids this artifact depends on (DAG edges)." + }, + "output_hash": { + "type": "string" + }, + "output_uri": { + "type": "string", + "format": "uri" + }, + "size_bytes": { + "type": "integer", + "minimum": 0 + } + }, + "allOf": [ + { + "if": { + "properties": { + "state": { + "const": "completed" + } + }, + "required": [ + "state" + ] + }, + "then": { + "$ref": "#/$defs/LockedArtifact" + } + } + ] + } + } + }, + "$defs": { + "LockedArtifact": { + "type": "object", + "required": [ + "output_hash", + "output_uri" + ], + "description": "Enforced only when an artifact state transitions to completed. Provides cryptographic pinning of the produced artifact.", + "properties": { + "output_hash": { + "type": "string", + "description": "SHA-256 or other digest of the artifact content." + }, + "output_uri": { + "type": "string", + "format": "uri", + "description": "Canonical URI where the artifact can be retrieved." + } } } } diff --git a/schemas/agentbom/agentbom.schema.json b/schemas/agentbom/agentbom.schema.json index 5b4e5a4..a8a7b25 100644 --- a/schemas/agentbom/agentbom.schema.json +++ b/schemas/agentbom/agentbom.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://wasmagent.dev/schemas/agentbom/v0.1.schema.json", "title": "AgentBOM", - "description": "Agent Bill of Materials v0.1 \u2014 shipped specification schema", + "description": "Agent Bill of Materials v0.1 — shipped specification schema", "type": "object", "required": [ "agentbom_version", @@ -198,7 +198,14 @@ "granted_scopes": { "type": "array", "items": { - "type": "string" + "type": "string", + "pattern": "^[a-z0-9.-]+:[a-zA-Z0-9.*_/-]+$", + "examples": [ + "network.egress:registry.npmjs.org", + "network.egress:*.github.com", + "filesystem.write:/tmp/workspace", + "tool.call:bash" + ] }, "description": "All granted permission scopes" }, @@ -398,7 +405,7 @@ }, "workflow_layer": { "type": "array", - "description": "Action pathway definitions \u2014 workflows, pipelines, and decision sequences that define how the agent executes tasks", + "description": "Action pathway definitions — workflows, pipelines, and decision sequences that define how the agent executes tasks", "items": { "type": "object", "required": [ @@ -478,7 +485,7 @@ "agent_collaboration": { "type": "object", "additionalProperties": false, - "description": "Multi-agent collaboration topology \u2014 peer agents, delegation boundaries, and shared resource access patterns", + "description": "Multi-agent collaboration topology — peer agents, delegation boundaries, and shared resource access patterns", "properties": { "peer_agents": { "type": "array", @@ -639,7 +646,7 @@ "distribution": { "type": "object", "additionalProperties": false, - "description": "Artifact lifecycle management \u2014 registry location, publication metadata, deprecation, and supersession", + "description": "Artifact lifecycle management — registry location, publication metadata, deprecation, and supersession", "properties": { "registry_uri": { "type": "string", @@ -700,6 +707,46 @@ "description": "Attestation timestamp in ISO 8601 format" } } + }, + "extensions": { + "type": "object", + "description": "CRD-like extension mechanism. An extension with critical=true MUST cause the consumer to abort if the namespace is unrecognised, preventing silent security downgrades.", + "patternProperties": { + "^[a-z0-9.-]+$": { + "type": "object", + "required": [ + "critical" + ], + "properties": { + "critical": { + "type": "boolean", + "default": false, + "description": "If true and the namespace is unrecognised, the consumer MUST abort execution." + }, + "config": { + "type": "object", + "description": "Extension-specific configuration payload." + } + }, + "additionalProperties": false + } + }, + "examples": [ + { + "wasmagent.audit": { + "critical": true, + "config": { + "require_trust_passport": true + } + }, + "ui.theme.hint": { + "critical": false, + "config": { + "primary_color": "#3b82f6" + } + } + } + ] } } } diff --git a/schemas/index.json b/schemas/index.json index 2bc43b1..1cf0a83 100644 --- a/schemas/index.json +++ b/schemas/index.json @@ -1,7 +1,7 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", "protocol": "AEP", - "description": "Registry of canonical WasmAgent protocol schemas \u2014 the single source of truth for every cross-repository contract. Downstream repos consume via @wasmagent/protocol (npm) and wasmagent-protocol (PyPI). Covers: AEP, compliance, AgentBOM, MCP Posture, Trust Passport.", + "description": "Registry of canonical WasmAgent protocol schemas — the single source of truth for every cross-repository contract. Downstream repos consume via @wasmagent/protocol (npm) and wasmagent-protocol (PyPI). Covers: AEP, compliance, AgentBOM, MCP Posture, Trust Passport.", "canonical_host": "https://wasmagent.dev/schemas/", "schemas": [ { @@ -21,7 +21,7 @@ "wasmagent-train-replay", "open-agent-audit" ], - "summary": "Runtime action evidence and run provenance record \u2014 the core Agent Evidence Protocol contract." + "summary": "Runtime action evidence and run provenance record — the core Agent Evidence Protocol contract. Includes LockedArtifact DAG artifact tracking (run_artifacts)." }, { "id": "evidence-envelope", @@ -39,7 +39,7 @@ "trace-pipeline", "open-agent-audit" ], - "summary": "Shared envelope base for all AEP evidence records \u2014 schema_version, trace_id, created_at_ms, and optional signature." + "summary": "Shared envelope base for all AEP evidence records — schema_version, trace_id, created_at_ms, and optional signature." }, { "id": "constraint-ir", @@ -55,7 +55,7 @@ "wasmagent-js", "trace-pipeline" ], - "summary": "Typed, repairable, prioritised constraint \u2014 superset of @wasmagent/core Criterion." + "summary": "Typed, repairable, prioritised constraint — superset of @wasmagent/core Criterion." }, { "id": "constraint-violation", @@ -142,7 +142,7 @@ "title": "AgentBOM", "path": "schemas/agentbom/agentbom.schema.json", "canonical_id": "https://wasmagent.dev/schemas/agentbom/v0.1.schema.json", - "version": "agentbom/v0.1", + "version": "agentbom/v0.2", "stability": "evolving", "owners": [ "agent-trust-infra" @@ -151,7 +151,7 @@ "agent-trust-infra", "open-agent-audit" ], - "summary": "Agent Bill of Materials \u2014 machine-readable agent identity, capabilities, and trust metadata." + "summary": "Agent Bill of Materials — machine-readable agent identity, capabilities, trust metadata, critical extension gate, and permission namespace scopes." }, { "id": "mcp-posture", @@ -167,7 +167,7 @@ "agent-trust-infra", "open-agent-audit" ], - "summary": "MCP Posture \u2014 tool surface, permission grants, and risk signals for MCP servers." + "summary": "MCP Posture — tool surface, permission grants, and risk signals for MCP servers." }, { "id": "trust-passport", @@ -183,7 +183,7 @@ "agent-trust-infra", "open-agent-audit" ], - "summary": "Trust Passport \u2014 signed, expiring, verifiable trust-state artifact for AI agents." + "summary": "Trust Passport — signed, expiring, verifiable trust-state artifact for AI agents." } ] } diff --git a/tests/fixtures/invalid/aep-record/completed-artifact-missing-lock.json b/tests/fixtures/invalid/aep-record/completed-artifact-missing-lock.json new file mode 100644 index 0000000..c3b09b3 --- /dev/null +++ b/tests/fixtures/invalid/aep-record/completed-artifact-missing-lock.json @@ -0,0 +1,12 @@ +{ + "schema_version": "aep/v0.3", + "run_id": "run-002", + "created_at_ms": 1700000000000, + "run_artifacts": [ + { + "artifact_id": "art-pr-99", + "class": "pr", + "state": "completed" + } + ] +} diff --git a/tests/fixtures/invalid/agentbom/bad-permission-scope.json b/tests/fixtures/invalid/agentbom/bad-permission-scope.json new file mode 100644 index 0000000..8c935b6 --- /dev/null +++ b/tests/fixtures/invalid/agentbom/bad-permission-scope.json @@ -0,0 +1,16 @@ +{ + "agentbom_version": "0.1", + "identity": { + "agent_id": "a1", + "agent_name": "Test", + "generated_at": "2026-01-01T00:00:00Z" + }, + "attestation": { + "generator": "test-tool" + }, + "permission_layer": { + "granted_scopes": [ + "*" + ] + } +} diff --git a/tests/fixtures/invalid/agentbom/extension-missing-critical.json b/tests/fixtures/invalid/agentbom/extension-missing-critical.json new file mode 100644 index 0000000..a28a88e --- /dev/null +++ b/tests/fixtures/invalid/agentbom/extension-missing-critical.json @@ -0,0 +1,18 @@ +{ + "agentbom_version": "0.1", + "identity": { + "agent_id": "a1", + "agent_name": "Test", + "generated_at": "2026-01-01T00:00:00Z" + }, + "attestation": { + "generator": "test-tool" + }, + "extensions": { + "wasmagent.audit": { + "config": { + "require_trust_passport": true + } + } + } +} diff --git a/tests/fixtures/valid/aep-record/with-locked-artifacts.json b/tests/fixtures/valid/aep-record/with-locked-artifacts.json new file mode 100644 index 0000000..838e93b --- /dev/null +++ b/tests/fixtures/valid/aep-record/with-locked-artifacts.json @@ -0,0 +1,29 @@ +{ + "schema_version": "aep/v0.3", + "run_id": "run-001", + "created_at_ms": 1700000000000, + "run_artifacts": [ + { + "artifact_id": "art-pr-42", + "class": "pr", + "state": "completed", + "output_hash": "sha256:abc123", + "output_uri": "https://github.com/WasmAgent/wasmagent/pull/42" + }, + { + "artifact_id": "art-test-report", + "class": "test-report", + "state": "completed", + "depends_on": [ + "art-pr-42" + ], + "output_hash": "sha256:def456", + "output_uri": "https://ci.example.com/reports/run-001" + }, + { + "artifact_id": "art-draft", + "class": "file", + "state": "generating" + } + ] +} diff --git a/tests/fixtures/valid/agentbom/with-extension-gate.json b/tests/fixtures/valid/agentbom/with-extension-gate.json new file mode 100644 index 0000000..d72dc81 --- /dev/null +++ b/tests/fixtures/valid/agentbom/with-extension-gate.json @@ -0,0 +1,32 @@ +{ + "agentbom_version": "0.1", + "identity": { + "agent_id": "a1", + "agent_name": "Test", + "generated_at": "2026-01-01T00:00:00Z" + }, + "attestation": { + "generator": "test-tool" + }, + "extensions": { + "wasmagent.audit": { + "critical": true, + "config": { + "require_trust_passport": true + } + }, + "ui.theme.hint": { + "critical": false, + "config": { + "primary_color": "#3b82f6" + } + } + }, + "permission_layer": { + "granted_scopes": [ + "network.egress:registry.npmjs.org", + "filesystem.write:/tmp/workspace", + "tool.call:bash" + ] + } +}