From c2ac08cd302309ad4cc1fc6aa820a028f32573a3 Mon Sep 17 00:00:00 2001 From: Imran Siddique Date: Mon, 7 Sep 2026 12:36:59 -0700 Subject: [PATCH] release: 0.1.0-alpha.3 Release preparation for 0.1.0-alpha.3, following steps 1 and 2 of RELEASING.md. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_015QRxFm1Z1kE9iraPspwr7j --- CHANGELOG.md | 27 +++++++++++++++---- LIMITATIONS.md | 2 +- README.md | 2 +- SECURITY.md | 2 +- VERSIONING.md | 6 ++--- compatibility/golden/event-factory.json | 2 +- compatibility/golden/evidence-chain.json | 6 ++--- .../invalid/action-without-digest.json | 2 +- .../aggregate-cost-without-rollup.json | 2 +- .../invalid/model-call-with-rollup.json | 2 +- .../fixtures/invalid/numeric-timestamp.json | 2 +- conformance/fixtures/invalid/raw-content.json | 2 +- .../invalid/usage-without-measurement.json | 2 +- .../fixtures/invalid/zero-trace-id.json | 2 +- conformance/fixtures/valid/action.json | 2 +- conformance/fixtures/valid/approval.json | 2 +- conformance/fixtures/valid/data-flow.json | 2 +- conformance/fixtures/valid/evidence.json | 2 +- .../fixtures/valid/policy-decision.json | 2 +- conformance/fixtures/valid/usage.json | 2 +- docs/evidence-chain.md | 2 +- docs/otel-genai-compatibility.md | 2 +- docs/otel-projection.md | 2 +- examples/manual_governance.py | 2 +- packages/typescript/README.md | 2 +- packages/typescript/package-lock.json | 4 +-- packages/typescript/package.json | 2 +- .../typescript/schemas/envelope.schema.json | 2 +- packages/typescript/src/factory.ts | 2 +- packages/typescript/src/types.ts | 2 +- .../typescript/test/trace-finalizer.test.ts | 2 +- pyproject.toml | 2 +- spec/VERSION | 2 +- spec/schema/envelope.schema.json | 2 +- src/agentrust_telemetry/__init__.py | 2 +- src/agentrust_telemetry/adapters/base.py | 2 +- .../schemas/envelope.schema.json | 2 +- tests/test_repository_gates.py | 5 ++-- tests/test_trace_adapter.py | 2 +- 39 files changed, 67 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb84fe7..c66ad5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,27 @@ ## Unreleased +## 0.1.0-alpha.3 - 2026-09-07 + +### Fixed + +- The Python `EvidenceAccumulator` deadlocked forever if `append` or `seal` was + called reentrantly on the same thread, for example from inside a + `durable_append` callback. Both now raise `EvidenceError`, matching the + TypeScript SDK's existing protection. `snapshot` remains safely callable + reentrantly. +- Patch four `fast-uri` advisories in the TypeScript lockfile and stop tag + interpolation in `release.yml`. +- `test_trace_adapter_refusals` used a duck-typed signer double, which + `agentrust-trace` 0.10.0 rejects. It now builds a real `Ed25519PrivateKey`, so + a clean install of this release runs the full suite against either 0.9 or + 0.10. + +### Changed + +- Install CI dependencies from hash-pinned lock files, and add `actionlint` + plus a test-environment guard to the workflow gates. + ## 0.1.0-alpha.2 - 2026-09-02 - Align the wire `spec_version` with `spec/VERSION`; the schema previously @@ -32,9 +53,5 @@ cross-language JSON behavior. - Add the pre-alpha TypeScript reference SDK and shared conformance gates. -- Initial `0.1.0-alpha.2` event contract and conformance fixtures. +- Initial `0.1.0-alpha.1` event contract and conformance fixtures. - Initial Python reference SDK with schema/privacy validation and OTel span-event projection. - -### Fixed - -- the Python `EvidenceAccumulator` deadlocked forever if `append` or`seal` was called reentrantly on the same thread (for example, from inside a `durable_append` callback). It now raises `EvidenceError` instead, matching the TypeScript SDK's existing reentrancy protection. `snapshot` remains safely callable reentrantly. diff --git a/LIMITATIONS.md b/LIMITATIONS.md index 99e06fe..fcab652 100644 --- a/LIMITATIONS.md +++ b/LIMITATIONS.md @@ -1,6 +1,6 @@ # Limitations -Current `0.1.0-alpha.2` limitations: +Current `0.1.0-alpha.3` limitations: - The contract and SDK are experimental and may change incompatibly. - A Python reference SDK and a TypeScript reference SDK (`packages/typescript/`) diff --git a/README.md b/README.md index dd53d38..7f71f92 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Portable governance telemetry and verifiable evidence for AI-agent runtimes. This repository defines a backend-neutral contract for policy decisions, approval lifecycles, usage, classified data flows, and evidence lifecycle events. It composes with OpenTelemetry; it is not a tracing backend, policy engine, agent framework, or dashboard. -> **Status:** alpha contract `0.1.0-alpha.2`. No stable SDK API or compatibility guarantee exists yet. +> **Status:** alpha contract `0.1.0-alpha.3`. No stable SDK API or compatibility guarantee exists yet. ## Why diff --git a/SECURITY.md b/SECURITY.md index cf7cf1f..4a07f2a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -26,7 +26,7 @@ Include the affected contract/SDK version, an executable reproducer where safe, ## Supported versions -No stable release exists. Only the latest `0.1.0-alpha.2` revision will receive fixes until the first published release. +No stable release exists. Only the latest `0.1.0-alpha.3` revision will receive fixes until the first published release. ## Runtime boundary diff --git a/VERSIONING.md b/VERSIONING.md index 8aec827..d201d90 100644 --- a/VERSIONING.md +++ b/VERSIONING.md @@ -6,9 +6,9 @@ The telemetry contract uses semantic versioning independently from SDK versions, - Minor: backward-compatible optional field, event, or enum addition with defined older-consumer behavior. - Major: removal, changed meaning, new required field, or incompatible canonicalization. -The current contract version is `0.1.0-alpha.2`. Python publishes the equivalent -PEP 440 version `0.1.0a2`; npm and the Git tag use `0.1.0-alpha.2` and -`v0.1.0-alpha.2`. Pre-1.0 changes may be incompatible and must be called out +The current contract version is `0.1.0-alpha.3`. Python publishes the equivalent +PEP 440 version `0.1.0a3`; npm and the Git tag use `0.1.0-alpha.3` and +`v0.1.0-alpha.3`. Pre-1.0 changes may be incompatible and must be called out explicitly. Published GitHub releases are the sole release trigger. The release tag must diff --git a/compatibility/golden/event-factory.json b/compatibility/golden/event-factory.json index 6cdde1e..b7c77f0 100644 --- a/compatibility/golden/event-factory.json +++ b/compatibility/golden/event-factory.json @@ -1 +1 @@ -{"agent_id":"agent-1","event_id":"018f0f7d-7a13-7cc2-8000-000000000042","event_type":"usage.recorded","input_tokens":7,"operation":"chat","producer":{"name":"parity-test","version":"1.0.0"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.2","time_unix_nano":"1787079000000000000","workflow_id":"workflow-1"} +{"agent_id":"agent-1","event_id":"018f0f7d-7a13-7cc2-8000-000000000042","event_type":"usage.recorded","input_tokens":7,"operation":"chat","producer":{"name":"parity-test","version":"1.0.0"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.3","time_unix_nano":"1787079000000000000","workflow_id":"workflow-1"} diff --git a/compatibility/golden/evidence-chain.json b/compatibility/golden/evidence-chain.json index b830d85..6f9d7e4 100644 --- a/compatibility/golden/evidence-chain.json +++ b/compatibility/golden/evidence-chain.json @@ -6,13 +6,13 @@ "fixture": "policy-decision.json", "sequence": 0, "previous_digest": null, - "digest": "0945b180ca030d80fdb4d2b9079705da41aa374335e8b9de87bcd754ef5344a4" + "digest": "9d93daf8fcfb51b24a68dc108afb474fc4c89a9c3f3716bd13172e2799f099a2" }, { "fixture": "usage.json", "sequence": 1, - "previous_digest": "0945b180ca030d80fdb4d2b9079705da41aa374335e8b9de87bcd754ef5344a4", - "digest": "f5e87ab1b72a6b677dd91870bb15cc9248f7a8a3bc95d8c7867abc9df32c030f" + "previous_digest": "9d93daf8fcfb51b24a68dc108afb474fc4c89a9c3f3716bd13172e2799f099a2", + "digest": "62bdbda86c79281c0cae240abf2fa901b70d9bb407da9021e713e80358d6c7b5" } ] } diff --git a/conformance/fixtures/invalid/action-without-digest.json b/conformance/fixtures/invalid/action-without-digest.json index feb22f6..ecdd04d 100644 --- a/conformance/fixtures/invalid/action-without-digest.json +++ b/conformance/fixtures/invalid/action-without-digest.json @@ -1,5 +1,5 @@ { - "spec_version": "0.1.0-alpha.2", + "spec_version": "0.1.0-alpha.3", "event_id": "018f0f7d-7a13-7cc2-8000-000000000096", "event_type": "action.executed", "time_unix_nano": "1787079650000000000", diff --git a/conformance/fixtures/invalid/aggregate-cost-without-rollup.json b/conformance/fixtures/invalid/aggregate-cost-without-rollup.json index 0b260ff..9a6eeef 100644 --- a/conformance/fixtures/invalid/aggregate-cost-without-rollup.json +++ b/conformance/fixtures/invalid/aggregate-cost-without-rollup.json @@ -1 +1 @@ -{"agent_id":"agent-1","cost":{"amount":1,"currency":"USD","source":"aggregate"},"event_id":"018f0f7d-7a13-7cc2-8000-000000000009","event_type":"usage.recorded","operation":"chat","producer":{"name":"test","version":"1"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.2","time_unix_nano":"1"} +{"agent_id":"agent-1","cost":{"amount":1,"currency":"USD","source":"aggregate"},"event_id":"018f0f7d-7a13-7cc2-8000-000000000009","event_type":"usage.recorded","operation":"chat","producer":{"name":"test","version":"1"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.3","time_unix_nano":"1"} diff --git a/conformance/fixtures/invalid/model-call-with-rollup.json b/conformance/fixtures/invalid/model-call-with-rollup.json index a4b7d49..3e2b5eb 100644 --- a/conformance/fixtures/invalid/model-call-with-rollup.json +++ b/conformance/fixtures/invalid/model-call-with-rollup.json @@ -1 +1 @@ -{"agent_id":"agent-1","aggregation":{"cost_coverage":0,"cost_sources":[],"event_count":1,"method":"sum","token_coverage":{"input_tokens":1}},"event_id":"018f0f7d-7a13-7cc2-8000-000000000010","event_type":"usage.recorded","input_tokens":1,"operation":"chat","producer":{"name":"test","version":"1"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.2","time_unix_nano":"1"} +{"agent_id":"agent-1","aggregation":{"cost_coverage":0,"cost_sources":[],"event_count":1,"method":"sum","token_coverage":{"input_tokens":1}},"event_id":"018f0f7d-7a13-7cc2-8000-000000000010","event_type":"usage.recorded","input_tokens":1,"operation":"chat","producer":{"name":"test","version":"1"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.3","time_unix_nano":"1"} diff --git a/conformance/fixtures/invalid/numeric-timestamp.json b/conformance/fixtures/invalid/numeric-timestamp.json index cf16c6e..3bd52b5 100644 --- a/conformance/fixtures/invalid/numeric-timestamp.json +++ b/conformance/fixtures/invalid/numeric-timestamp.json @@ -1 +1 @@ -{"agent_id":"agent-1","event_id":"018f0f7d-7a13-7cc2-8000-000000000011","event_type":"usage.recorded","input_tokens":1,"operation":"chat","producer":{"name":"test","version":"1"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.2","time_unix_nano":1787079700000000000} +{"agent_id":"agent-1","event_id":"018f0f7d-7a13-7cc2-8000-000000000011","event_type":"usage.recorded","input_tokens":1,"operation":"chat","producer":{"name":"test","version":"1"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.3","time_unix_nano":1787079700000000000} diff --git a/conformance/fixtures/invalid/raw-content.json b/conformance/fixtures/invalid/raw-content.json index 9ef76c9..0dfea1e 100644 --- a/conformance/fixtures/invalid/raw-content.json +++ b/conformance/fixtures/invalid/raw-content.json @@ -1 +1 @@ -{"agent_id":"spiffe://example.test/agent/coder","event_id":"018f0f7d-7a13-7cc2-8000-000000000006","event_type":"usage.recorded","input_tokens":10,"operation":"chat","producer":{"name":"bad-adapter","version":"0.1.0"},"prompt":"copy the production credential","run_id":"run-unsafe","scope":"model_call","spec_version":"0.1.0-alpha.2","time_unix_nano":"1787079700000000000"} +{"agent_id":"spiffe://example.test/agent/coder","event_id":"018f0f7d-7a13-7cc2-8000-000000000006","event_type":"usage.recorded","input_tokens":10,"operation":"chat","producer":{"name":"bad-adapter","version":"0.1.0"},"prompt":"copy the production credential","run_id":"run-unsafe","scope":"model_call","spec_version":"0.1.0-alpha.3","time_unix_nano":"1787079700000000000"} diff --git a/conformance/fixtures/invalid/usage-without-measurement.json b/conformance/fixtures/invalid/usage-without-measurement.json index df21425..7f8e39a 100644 --- a/conformance/fixtures/invalid/usage-without-measurement.json +++ b/conformance/fixtures/invalid/usage-without-measurement.json @@ -1 +1 @@ -{"agent_id":"agent-1","event_id":"018f0f7d-7a13-7cc2-8000-000000000008","event_type":"usage.recorded","operation":"chat","producer":{"name":"test","version":"1"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.2","time_unix_nano":"1"} +{"agent_id":"agent-1","event_id":"018f0f7d-7a13-7cc2-8000-000000000008","event_type":"usage.recorded","operation":"chat","producer":{"name":"test","version":"1"},"run_id":"run-1","scope":"model_call","spec_version":"0.1.0-alpha.3","time_unix_nano":"1"} diff --git a/conformance/fixtures/invalid/zero-trace-id.json b/conformance/fixtures/invalid/zero-trace-id.json index 5b732bf..aa68bde 100644 --- a/conformance/fixtures/invalid/zero-trace-id.json +++ b/conformance/fixtures/invalid/zero-trace-id.json @@ -1 +1 @@ -{"action_type":"repository.read","agent_id":"agent-1","decision":"allow","enforcement_mode":"enforce","evaluation_duration_ns":1,"event_id":"018f0f7d-7a13-7cc2-8000-000000000007","event_type":"policy.decision","policy":{"engine":"opa","engine_version":"1.0"},"producer":{"name":"test","version":"1"},"resource_type":"repository","run_id":"run-1","spec_version":"0.1.0-alpha.2","time_unix_nano":"1","trace_id":"00000000000000000000000000000000"} +{"action_type":"repository.read","agent_id":"agent-1","decision":"allow","enforcement_mode":"enforce","evaluation_duration_ns":1,"event_id":"018f0f7d-7a13-7cc2-8000-000000000007","event_type":"policy.decision","policy":{"engine":"opa","engine_version":"1.0"},"producer":{"name":"test","version":"1"},"resource_type":"repository","run_id":"run-1","spec_version":"0.1.0-alpha.3","time_unix_nano":"1","trace_id":"00000000000000000000000000000000"} diff --git a/conformance/fixtures/valid/action.json b/conformance/fixtures/valid/action.json index 07bb87e..115ae0b 100644 --- a/conformance/fixtures/valid/action.json +++ b/conformance/fixtures/valid/action.json @@ -1,5 +1,5 @@ { - "spec_version": "0.1.0-alpha.2", + "spec_version": "0.1.0-alpha.3", "event_id": "018f0f7d-7a13-7cc2-8000-000000000006", "event_type": "action.executed", "time_unix_nano": "1787079650000000000", diff --git a/conformance/fixtures/valid/approval.json b/conformance/fixtures/valid/approval.json index a4df686..a50e030 100644 --- a/conformance/fixtures/valid/approval.json +++ b/conformance/fixtures/valid/approval.json @@ -1 +1 @@ -{"action_digest":{"algorithm":"sha256","value":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},"actor_id":"reviewer-7d91","actor_type":"human","agent_id":"spiffe://example.test/agent/coder","approval_id":"approval-001","event_id":"018f0f7d-7a13-7cc2-8000-000000000002","event_type":"approval.approved","producer":{"name":"example-approval-adapter","version":"0.1.0"},"requested_at_unix_nano":"1787079500000000000","run_id":"run-governed-sdlc-001","span_id":"00f067aa0ba902b7","spec_version":"0.1.0-alpha.2","time_unix_nano":"1787079580000000000","trace_id":"4bf92f3577b34da6a3ce929d0e0e4736"} +{"action_digest":{"algorithm":"sha256","value":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},"actor_id":"reviewer-7d91","actor_type":"human","agent_id":"spiffe://example.test/agent/coder","approval_id":"approval-001","event_id":"018f0f7d-7a13-7cc2-8000-000000000002","event_type":"approval.approved","producer":{"name":"example-approval-adapter","version":"0.1.0"},"requested_at_unix_nano":"1787079500000000000","run_id":"run-governed-sdlc-001","span_id":"00f067aa0ba902b7","spec_version":"0.1.0-alpha.3","time_unix_nano":"1787079580000000000","trace_id":"4bf92f3577b34da6a3ce929d0e0e4736"} diff --git a/conformance/fixtures/valid/data-flow.json b/conformance/fixtures/valid/data-flow.json index 6a9ef1b..acb66dc 100644 --- a/conformance/fixtures/valid/data-flow.json +++ b/conformance/fixtures/valid/data-flow.json @@ -1 +1 @@ -{"agent_id":"spiffe://example.test/agent/architect","classification":{"producer":"example-dlp","taxonomy":"example.enterprise.v1","value":"confidential"},"content_digest":{"algorithm":"sha256","value":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"destination":{"id":"architecture-agent","kind":"agent"},"direction":"read","event_id":"018f0f7d-7a13-7cc2-8000-000000000004","event_type":"data_flow.observed","policy_decision":"allow","producer":{"name":"example-dataflow-adapter","version":"0.1.0"},"purpose":"generate_architecture","run_id":"run-governed-sdlc-001","size_bytes":18342,"source":{"id":"requirements-graph","kind":"knowledge_graph"},"spec_version":"0.1.0-alpha.2","time_unix_nano":"1787079400000000000","transformation":"metadata_only"} +{"agent_id":"spiffe://example.test/agent/architect","classification":{"producer":"example-dlp","taxonomy":"example.enterprise.v1","value":"confidential"},"content_digest":{"algorithm":"sha256","value":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"},"destination":{"id":"architecture-agent","kind":"agent"},"direction":"read","event_id":"018f0f7d-7a13-7cc2-8000-000000000004","event_type":"data_flow.observed","policy_decision":"allow","producer":{"name":"example-dataflow-adapter","version":"0.1.0"},"purpose":"generate_architecture","run_id":"run-governed-sdlc-001","size_bytes":18342,"source":{"id":"requirements-graph","kind":"knowledge_graph"},"spec_version":"0.1.0-alpha.3","time_unix_nano":"1787079400000000000","transformation":"metadata_only"} diff --git a/conformance/fixtures/valid/evidence.json b/conformance/fixtures/valid/evidence.json index 53d1eb1..41cee77 100644 --- a/conformance/fixtures/valid/evidence.json +++ b/conformance/fixtures/valid/evidence.json @@ -1 +1 @@ -{"capture_profile":"metadata_only","chain_digest":{"algorithm":"sha256","value":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"},"completeness":"complete","event_id":"018f0f7d-7a13-7cc2-8000-000000000005","event_type":"evidence.run_closed","producer":{"name":"agentrust-telemetry","version":"0.1.0-alpha.2"},"run_id":"run-governed-sdlc-001","sequence":14,"spec_version":"0.1.0-alpha.2","time_unix_nano":"1787079700000000000"} +{"capture_profile":"metadata_only","chain_digest":{"algorithm":"sha256","value":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"},"completeness":"complete","event_id":"018f0f7d-7a13-7cc2-8000-000000000005","event_type":"evidence.run_closed","producer":{"name":"agentrust-telemetry","version":"0.1.0-alpha.3"},"run_id":"run-governed-sdlc-001","sequence":14,"spec_version":"0.1.0-alpha.3","time_unix_nano":"1787079700000000000"} diff --git a/conformance/fixtures/valid/policy-decision.json b/conformance/fixtures/valid/policy-decision.json index 124addf..f8c922a 100644 --- a/conformance/fixtures/valid/policy-decision.json +++ b/conformance/fixtures/valid/policy-decision.json @@ -1 +1 @@ -{"action_type":"repository.write","agent_id":"spiffe://example.test/agent/coder","decision":"deny","enforcement_mode":"enforce","evaluation_duration_ns":182000,"event_id":"018f0f7d-7a13-7cc2-8000-000000000001","event_type":"policy.decision","policy":{"bundle_digest":{"algorithm":"sha256","value":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"engine":"cedar","engine_version":"4.3.0","policy_id":"repo-write"},"producer":{"name":"example-policy-adapter","version":"0.1.0"},"reason_codes":["BRANCH_PROTECTED"],"resource_type":"git.repository","run_id":"run-governed-sdlc-001","span_id":"00f067aa0ba902b7","spec_version":"0.1.0-alpha.2","time_unix_nano":"1787079600000000000","trace_id":"4bf92f3577b34da6a3ce929d0e0e4736","workflow_id":"workflow-build-feature"} +{"action_type":"repository.write","agent_id":"spiffe://example.test/agent/coder","decision":"deny","enforcement_mode":"enforce","evaluation_duration_ns":182000,"event_id":"018f0f7d-7a13-7cc2-8000-000000000001","event_type":"policy.decision","policy":{"bundle_digest":{"algorithm":"sha256","value":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"engine":"cedar","engine_version":"4.3.0","policy_id":"repo-write"},"producer":{"name":"example-policy-adapter","version":"0.1.0"},"reason_codes":["BRANCH_PROTECTED"],"resource_type":"git.repository","run_id":"run-governed-sdlc-001","span_id":"00f067aa0ba902b7","spec_version":"0.1.0-alpha.3","time_unix_nano":"1787079600000000000","trace_id":"4bf92f3577b34da6a3ce929d0e0e4736","workflow_id":"workflow-build-feature"} diff --git a/conformance/fixtures/valid/usage.json b/conformance/fixtures/valid/usage.json index ec47d5a..833303e 100644 --- a/conformance/fixtures/valid/usage.json +++ b/conformance/fixtures/valid/usage.json @@ -1 +1 @@ -{"agent_id":"spiffe://example.test/agent/coder","cost":{"amount":0.0124,"currency":"USD","pricing_version":"provider-2026-08-01","source":"provider"},"event_id":"018f0f7d-7a13-7cc2-8000-000000000003","event_type":"usage.recorded","input_tokens":4200,"operation":"chat","output_tokens":812,"producer":{"name":"example-usage-adapter","version":"0.1.0"},"provider":"example-ai","request_model":"example-model-2","run_id":"run-governed-sdlc-001","scope":"model_call","spec_version":"0.1.0-alpha.2","time_unix_nano":"1787079590000000000","workflow_id":"workflow-build-feature"} +{"agent_id":"spiffe://example.test/agent/coder","cost":{"amount":0.0124,"currency":"USD","pricing_version":"provider-2026-08-01","source":"provider"},"event_id":"018f0f7d-7a13-7cc2-8000-000000000003","event_type":"usage.recorded","input_tokens":4200,"operation":"chat","output_tokens":812,"producer":{"name":"example-usage-adapter","version":"0.1.0"},"provider":"example-ai","request_model":"example-model-2","run_id":"run-governed-sdlc-001","scope":"model_call","spec_version":"0.1.0-alpha.3","time_unix_nano":"1787079590000000000","workflow_id":"workflow-build-feature"} diff --git a/docs/evidence-chain.md b/docs/evidence-chain.md index 5fb79a8..a265baa 100644 --- a/docs/evidence-chain.md +++ b/docs/evidence-chain.md @@ -1,6 +1,6 @@ # Evidence chain profile -Status: experimental `rfc8785-jcs-v1` for contract `0.1.0-alpha.2`. +Status: experimental `rfc8785-jcs-v1` for contract `0.1.0-alpha.3`. Each accepted event is validated and privacy-checked before entering the chain. Sequence numbers start at zero and represent acceptance order, not event time. diff --git a/docs/otel-genai-compatibility.md b/docs/otel-genai-compatibility.md index 54315b9..4eb0cc4 100644 --- a/docs/otel-genai-compatibility.md +++ b/docs/otel-genai-compatibility.md @@ -1,6 +1,6 @@ # OpenTelemetry GenAI compatibility -Status: pinned compatibility assessment for AgentTrust contract `0.1.0-alpha.2`. +Status: pinned compatibility assessment for AgentTrust contract `0.1.0-alpha.3`. The machine-readable matrix is [`compatibility/otel-genai.json`](../compatibility/otel-genai.json). It is pinned to OpenTelemetry's dedicated GenAI semantic-conventions repository diff --git a/docs/otel-projection.md b/docs/otel-projection.md index 232009d..fa1e839 100644 --- a/docs/otel-projection.md +++ b/docs/otel-projection.md @@ -1,6 +1,6 @@ # OpenTelemetry projection profile -Status: experimental for contract `0.1.0-alpha.2`. +Status: experimental for contract `0.1.0-alpha.3`. The normalized JSON event is the source contract. OpenTelemetry is a projection, not an alternative event model. diff --git a/examples/manual_governance.py b/examples/manual_governance.py index dc5b43f..644a2c3 100644 --- a/examples/manual_governance.py +++ b/examples/manual_governance.py @@ -14,7 +14,7 @@ def emit(self, record): event = { - "spec_version": "0.1.0-alpha.2", + "spec_version": "0.1.0-alpha.3", "event_id": str(uuid.uuid4()), "event_type": "policy.decision", "time_unix_nano": str(time.time_ns()), diff --git a/packages/typescript/README.md b/packages/typescript/README.md index c72d12c..3c21ef4 100644 --- a/packages/typescript/README.md +++ b/packages/typescript/README.md @@ -1,6 +1,6 @@ # `@agentrust-io/telemetry` -TypeScript reference SDK for the AgentTrust Telemetry `0.1.0-alpha.2` contract. +TypeScript reference SDK for the AgentTrust Telemetry `0.1.0-alpha.3` contract. This alpha Node package validates the same closed schemas and metadata-only privacy profile as the Python SDK. It supplies event construction, caller-owned diff --git a/packages/typescript/package-lock.json b/packages/typescript/package-lock.json index 401f09a..c7d1d5a 100644 --- a/packages/typescript/package-lock.json +++ b/packages/typescript/package-lock.json @@ -1,12 +1,12 @@ { "name": "@agentrust-io/telemetry", - "version": "0.1.0-alpha.2", + "version": "0.1.0-alpha.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@agentrust-io/telemetry", - "version": "0.1.0-alpha.2", + "version": "0.1.0-alpha.3", "license": "MIT", "dependencies": { "@opentelemetry/api": "^1.9.0", diff --git a/packages/typescript/package.json b/packages/typescript/package.json index 0d4422d..e9fe3b5 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@agentrust-io/telemetry", - "version": "0.1.0-alpha.2", + "version": "0.1.0-alpha.3", "description": "TypeScript reference SDK for AgentTrust governance telemetry", "keywords": ["ai-agents", "governance", "opentelemetry", "observability", "telemetry"], "type": "module", diff --git a/packages/typescript/schemas/envelope.schema.json b/packages/typescript/schemas/envelope.schema.json index 378067b..719760c 100644 --- a/packages/typescript/schemas/envelope.schema.json +++ b/packages/typescript/schemas/envelope.schema.json @@ -4,7 +4,7 @@ "type": "object", "required": ["spec_version", "event_id", "event_type", "time_unix_nano", "run_id", "producer"], "properties": { - "spec_version": {"const": "0.1.0-alpha.2"}, + "spec_version": {"const": "0.1.0-alpha.3"}, "event_id": {"$ref": "common.schema.json#/$defs/event_id"}, "event_type": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$", "maxLength": 128}, "time_unix_nano": {"$ref": "common.schema.json#/$defs/time_unix_nano"}, diff --git a/packages/typescript/src/factory.ts b/packages/typescript/src/factory.ts index 66fabf2..bec40b8 100644 --- a/packages/typescript/src/factory.ts +++ b/packages/typescript/src/factory.ts @@ -26,7 +26,7 @@ export class EventFactory { if (collisions.length) throw new Error(`payload cannot override envelope fields: ${collisions.join(", ")}`); const normalizedPayload = Object.fromEntries(Object.entries(payload).map(([key, value]) => [key, key.endsWith("_at_unix_nano") ? unixNano(value) : value])); const event = { - spec_version: "0.1.0-alpha.2" as const, + spec_version: "0.1.0-alpha.3" as const, event_id: fields.eventId ?? this.eventIdFactory(), event_type: eventType, time_unix_nano: unixNano(fields.timeUnixNano ?? this.clockNs()), run_id: fields.runId, producer: structuredClone(this.#producer), ...normalizedPayload, diff --git a/packages/typescript/src/types.ts b/packages/typescript/src/types.ts index 2e7b550..c1f989b 100644 --- a/packages/typescript/src/types.ts +++ b/packages/typescript/src/types.ts @@ -1,6 +1,6 @@ export type Scalar = string | number | boolean; export type NormalizedEvent = Record & { - spec_version: "0.1.0-alpha.2"; + spec_version: "0.1.0-alpha.3"; event_id: string; event_type: string; time_unix_nano: string; diff --git a/packages/typescript/test/trace-finalizer.test.ts b/packages/typescript/test/trace-finalizer.test.ts index d39f7e3..d22d507 100644 --- a/packages/typescript/test/trace-finalizer.test.ts +++ b/packages/typescript/test/trace-finalizer.test.ts @@ -21,7 +21,7 @@ test("finalizer derives claims then signs, validates, and self-verifies", () => }); test("tool transcript uses the shared RFC 8785 sequence/event digest", () => { const record = finalizeTrace(snapshot([fixture("action.json")]), config, {signingKey: "private", codec: new RecordingCodec()}); - assert.deepEqual(record.tool_transcript, {hash: "sha256:f3d2eae89a35a5671dd125cf25f300463cfbc31a1411933828eb81b94797e534", call_count: 1}); + assert.deepEqual(record.tool_transcript, {hash: "sha256:6e2753603858fb457881d8fdc91b492ea195fc4754bb8845347c995ed69a6abc", call_count: 1}); const changed = fixture("action.json"); changed.outcome = "error"; changed.error_type = "remote_error"; assert.notEqual((finalizeTrace(snapshot([changed]), config, {signingKey: "private", codec: new RecordingCodec()}).tool_transcript as Record).hash, (record.tool_transcript as Record).hash); }); diff --git a/pyproject.toml b/pyproject.toml index 6d653fc..decd7de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "agentrust-telemetry" -version = "0.1.0a2" +version = "0.1.0a3" description = "Backend-neutral governance telemetry for AI-agent runtimes" readme = "README.md" requires-python = ">=3.10" diff --git a/spec/VERSION b/spec/VERSION index 1f3a604..d594bc9 100644 --- a/spec/VERSION +++ b/spec/VERSION @@ -1 +1 @@ -0.1.0-alpha.2 +0.1.0-alpha.3 diff --git a/spec/schema/envelope.schema.json b/spec/schema/envelope.schema.json index 378067b..719760c 100644 --- a/spec/schema/envelope.schema.json +++ b/spec/schema/envelope.schema.json @@ -4,7 +4,7 @@ "type": "object", "required": ["spec_version", "event_id", "event_type", "time_unix_nano", "run_id", "producer"], "properties": { - "spec_version": {"const": "0.1.0-alpha.2"}, + "spec_version": {"const": "0.1.0-alpha.3"}, "event_id": {"$ref": "common.schema.json#/$defs/event_id"}, "event_type": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$", "maxLength": 128}, "time_unix_nano": {"$ref": "common.schema.json#/$defs/time_unix_nano"}, diff --git a/src/agentrust_telemetry/__init__.py b/src/agentrust_telemetry/__init__.py index 2a494e3..d5ddda0 100644 --- a/src/agentrust_telemetry/__init__.py +++ b/src/agentrust_telemetry/__init__.py @@ -77,4 +77,4 @@ "finalize_trace", ] -__version__ = "0.1.0a2" +__version__ = "0.1.0a3" diff --git a/src/agentrust_telemetry/adapters/base.py b/src/agentrust_telemetry/adapters/base.py index f988fbb..4f572a5 100644 --- a/src/agentrust_telemetry/adapters/base.py +++ b/src/agentrust_telemetry/adapters/base.py @@ -55,7 +55,7 @@ def build( raise ValueError(f"payload cannot override envelope fields: {collision}") timestamp = self._clock_ns() if time_unix_nano is None else time_unix_nano event: dict[str, Any] = { - "spec_version": "0.1.0-alpha.2", + "spec_version": "0.1.0-alpha.3", "event_id": event_id or str(self._event_id_factory()), "event_type": event_type, "time_unix_nano": _unix_nano(timestamp), diff --git a/src/agentrust_telemetry/schemas/envelope.schema.json b/src/agentrust_telemetry/schemas/envelope.schema.json index 378067b..719760c 100644 --- a/src/agentrust_telemetry/schemas/envelope.schema.json +++ b/src/agentrust_telemetry/schemas/envelope.schema.json @@ -4,7 +4,7 @@ "type": "object", "required": ["spec_version", "event_id", "event_type", "time_unix_nano", "run_id", "producer"], "properties": { - "spec_version": {"const": "0.1.0-alpha.2"}, + "spec_version": {"const": "0.1.0-alpha.3"}, "event_id": {"$ref": "common.schema.json#/$defs/event_id"}, "event_type": {"type": "string", "pattern": "^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*)+$", "maxLength": 128}, "time_unix_nano": {"$ref": "common.schema.json#/$defs/time_unix_nano"}, diff --git a/tests/test_repository_gates.py b/tests/test_repository_gates.py index bb56a46..ae9cce7 100644 --- a/tests/test_repository_gates.py +++ b/tests/test_repository_gates.py @@ -63,6 +63,7 @@ def test_contract_versions_map_to_ecosystem_spellings(self): "0.1.0-dev": ("0.1.0.dev0", "0.1.0-dev.0"), "0.1.0-alpha.1": ("0.1.0a1", "0.1.0-alpha.1"), "0.1.0-alpha.2": ("0.1.0a2", "0.1.0-alpha.2"), + "0.1.0-alpha.3": ("0.1.0a3", "0.1.0-alpha.3"), "0.1.0-beta.2": ("0.1.0b2", "0.1.0-beta.2"), "0.1.0-rc.3": ("0.1.0rc3", "0.1.0-rc.3"), "0.1.0": ("0.1.0", "0.1.0"), @@ -76,10 +77,10 @@ def test_contract_version_rejects_unsupported_spellings(self): check_versions.ecosystem_versions("0.1") def test_release_tag_must_match_contract(self): - self.assertEqual(check_release_tag.validate_tag("v0.1.0-alpha.2"), []) + self.assertEqual(check_release_tag.validate_tag("v0.1.0-alpha.3"), []) self.assertEqual( check_release_tag.validate_tag("v0.1.0"), - ["release tag 'v0.1.0' must equal 'v0.1.0-alpha.2'"], + ["release tag 'v0.1.0' must equal 'v0.1.0-alpha.3'"], ) def test_otel_matrix_matches_shipped_projection(self): diff --git a/tests/test_trace_adapter.py b/tests/test_trace_adapter.py index cf012bc..0e8b1fa 100644 --- a/tests/test_trace_adapter.py +++ b/tests/test_trace_adapter.py @@ -74,7 +74,7 @@ def test_action_events_create_truthful_tool_transcript(self): self.assertRegex(record["tool_transcript"]["hash"], r"^sha256:[0-9a-f]{64}$") self.assertEqual( record["tool_transcript"]["hash"], - "sha256:f3d2eae89a35a5671dd125cf25f300463cfbc31a1411933828eb81b94797e534", + "sha256:6e2753603858fb457881d8fdc91b492ea195fc4754bb8845347c995ed69a6abc", ) changed = fixture("action.json")