From 1f7156b7cbbee446350485929c84d3884ec27f7a Mon Sep 17 00:00:00 2001 From: Imran Siddique Date: Mon, 27 Jul 2026 20:53:56 -0700 Subject: [PATCH] feat: conform to TRACE v0.2 profile URI TR-ENV now requires tag:agentrust-io.com,2026:trace-v0.2 and fails a record carrying the v0.1 identifier. The v0.1 URI named agentrust.io, a domain this project never controlled, which RFC 4151 does not permit for a tag URI. Cutover rather than dual acceptance, deliberately: a conformance suite that passed both identifiers would certify records minted under a domain we do not own, which is the thing being corrected. v0.1 records are checked with the 0.3.x releases, which stay published. Nothing else about the record format changed. Also adds .venv/ to .gitignore. The repo ignored __pycache__ and dist but not virtualenvs, so a local .venv was staged by a `git add -A` in this branch's first attempt. Co-Authored-By: Claude Opus 5 (1M context) --- .gitignore | 4 ++++ CHANGELOG.md | 8 ++++++++ docs/error-codes.md | 4 ++-- docs/levels.md | 14 +++++++------- docs/modules/tr-env.md | 2 +- docs/quickstart.md | 4 ++-- docs/tutorials/writing-conformance-tests.md | 4 ++-- pyproject.toml | 2 +- schemas/trace-claim.json | 6 +++--- src/trace_tests/modules/tr_env.py | 2 +- tests/conftest.py | 4 ++-- tests/test_level0.py | 2 +- tests/test_level1.py | 6 +++--- tests/unit/test_loader.py | 4 ++-- tests/unit/test_tr_env.py | 2 +- tests/unit/test_tr_sig.py | 6 +++--- tests/vectors/invalid_missing_runtime.json | 2 +- tests/vectors/valid_cmcp_runtime.json | 2 +- tests/vectors/valid_level0.json | 2 +- tests/vectors/valid_level0_with_transcript.json | 2 +- 20 files changed, 47 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 380a428..a5ef85c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ __pycache__/ dist/ *.egg-info/ .coverage + +# Local virtual environments +.venv/ +venv/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 119dda9..5e3e3b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +### Changed + +- **BREAKING: the suite now conforms to TRACE v0.2.** `TR-ENV` requires the profile `tag:agentrust-io.com,2026:trace-v0.2` and fails a record carrying the v0.1 identifier. The v0.1 URI named `agentrust.io`, a domain this project never controlled, which RFC 4151 does not permit for a tag URI; see agentrust-io/trace-spec#107. Nothing else about the record format changed, so a producer migrates by updating the profile string and bumping `agentrust-trace` to 0.5.0. + + This is a deliberate cutover rather than dual acceptance: a conformance suite that passed both identifiers would certify records minted under a domain we do not own. A v0.1 record is checked with the 0.3.x releases of this suite, which stay published. + +- Registry, verifier, and documentation hosts moved from `agentrust.io` to `agentrust-io.com`. + ## v0.3.0 — 2026-07-21 - `azure-cvm-sev-snp` platform accepted (`runtime.platform`): Azure confidential VMs run SEV-SNP behind a Hyper-V paravisor (vTPM-rooted). Added to the bundled schema enum and the TR-RTE valid-platform set so Azure TRACE records pass conformance. Matches `agentrust-trace>=0.4`. diff --git a/docs/error-codes.md b/docs/error-codes.md index bd3289d..8e30abb 100644 --- a/docs/error-codes.md +++ b/docs/error-codes.md @@ -6,7 +6,7 @@ All TRACE test failures emit a structured error code of the form `TR--/` or a `did:` URI | | TR-ENV-004 | One or more required fields are absent | Add the missing field(s); check the [Schema Reference](https://trace.agentrust-io.com/schema) for the full required set | @@ -47,7 +47,7 @@ All TRACE test failures emit a structured error code of the form `TR-- dict: record = { "cmcp_version": "1.0", "trace": { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": int(time.time()) - 30, "subject": "spiffe://cmcp.gateway/session/my-test", "runtime": { @@ -228,7 +228,7 @@ Common codes you will encounter: | Code | Field | Fix | |------|-------|-----| -| TR-ENV-001 | `eat_profile` | Must be `tag:agentrust.io,2026:trace-v0.1` | +| TR-ENV-001 | `eat_profile` | Must be `tag:agentrust-io.com,2026:trace-v0.2` | | TR-ENV-002 | `iat` | Must be a Unix timestamp in the last 24 hours | | TR-SIG-001 | `signature` | Signature missing or does not verify | | TR-SIG-002 | `cnf.jwk` | Key must be OKP/Ed25519 | diff --git a/pyproject.toml b/pyproject.toml index 8bbc795..6fe8009 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ description = "TRACE conformance test suite" readme = "README.md" license = { text = "Apache-2.0" } authors = [ - { name = "agentrust.io" }, + { name = "agentrust-io.com" }, ] keywords = ["trace", "conformance", "attestation", "ai-agents", "provenance"] classifiers = [ diff --git a/schemas/trace-claim.json b/schemas/trace-claim.json index 61259e6..5f69e69 100644 --- a/schemas/trace-claim.json +++ b/schemas/trace-claim.json @@ -1,15 +1,15 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://agentrust.io/schema/trace-v0.1.json", + "$id": "https://agentrust-io.com/schema/trace-v0.1.json", "title": "TRACE Trust Record", - "description": "A TRACE v0.1 Trust Record — hardware-attested governance evidence for an AI agent execution.", + "description": "A TRACE v0.2 Trust Record — hardware-attested governance evidence for an AI agent execution.", "type": "object", "required": [ "eat_profile", "iat", "subject", "model", "runtime", "policy", "data_class", "build_provenance", "appraisal", "transparency", "cnf" ], "properties": { - "eat_profile": {"type": "string", "const": "tag:agentrust.io,2026:trace-v0.1"}, + "eat_profile": {"type": "string", "const": "tag:agentrust-io.com,2026:trace-v0.2"}, "iat": {"type": "integer", "minimum": 1700000000}, "subject": {"type": "string", "pattern": "^(spiffe://|did:)"}, "model": { diff --git a/src/trace_tests/modules/tr_env.py b/src/trace_tests/modules/tr_env.py index 0fc72f2..4e1e405 100644 --- a/src/trace_tests/modules/tr_env.py +++ b/src/trace_tests/modules/tr_env.py @@ -8,7 +8,7 @@ from trace_tests.result import Finding, Status -_PROFILE = "tag:agentrust.io,2026:trace-v0.1" +_PROFILE = "tag:agentrust-io.com,2026:trace-v0.2" _SUBJECT_RE = re.compile(r'^(spiffe://[^/]+/.+|did:[a-z0-9]+:.+)$') _IAT_MIN = 1_700_000_000 diff --git a/tests/conftest.py b/tests/conftest.py index f3f900b..83c1bc5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -41,7 +41,7 @@ def _build_signed_cmcp_record(*, platform: str = "tpm2", nonce: str | None = Non iat = int(time.time()) - 30 # fresh but not future-dated trace: dict = { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": iat, "subject": "spiffe://cmcp.gateway/session/conformance-test", "runtime": { @@ -135,7 +135,7 @@ def _build_software_only_record() -> dict: record: dict = { "cmcp_version": "1.0", "trace": { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": iat, "subject": "spiffe://cmcp.gateway/session/level2-test", "runtime": { diff --git a/tests/test_level0.py b/tests/test_level0.py index f3c3def..148c4b7 100644 --- a/tests/test_level0.py +++ b/tests/test_level0.py @@ -18,7 +18,7 @@ def test_schema_valid(self, schema, valid_level0): jsonschema.validate(valid_level0, schema) def test_eat_profile_sentinel(self, valid_level0): - assert valid_level0["eat_profile"] == "tag:agentrust.io,2026:trace-v0.1" + assert valid_level0["eat_profile"] == "tag:agentrust-io.com,2026:trace-v0.2" def test_iat_is_positive_integer(self, valid_level0): assert isinstance(valid_level0["iat"], int) diff --git a/tests/test_level1.py b/tests/test_level1.py index c05f474..e036663 100644 --- a/tests/test_level1.py +++ b/tests/test_level1.py @@ -48,11 +48,11 @@ def test_eat_protected_header_content_type(self, signed_eat_fixture): In the cMCP profile the eat_profile field inside trace serves the role of the COSE protected header content-type: it binds the record to the - TRACE v0.1 specification and prevents cross-profile replay. + TRACE v0.2 specification and prevents cross-profile replay. """ trace = signed_eat_fixture["trace"] - assert trace.get("eat_profile") == "tag:agentrust.io,2026:trace-v0.1", ( - "trace.eat_profile must be 'tag:agentrust.io,2026:trace-v0.1'" + assert trace.get("eat_profile") == "tag:agentrust-io.com,2026:trace-v0.2", ( + "trace.eat_profile must be 'tag:agentrust-io.com,2026:trace-v0.2'" ) def test_signature_verifies_against_cnf_key(self, signed_eat_fixture): diff --git a/tests/unit/test_loader.py b/tests/unit/test_loader.py index 0c21657..1ba3f94 100644 --- a/tests/unit/test_loader.py +++ b/tests/unit/test_loader.py @@ -13,13 +13,13 @@ VALID_CMCP = { "cmcp_version": "1.0", - "trace": {"eat_profile": "tag:agentrust.io,2026:trace-v0.1"}, + "trace": {"eat_profile": "tag:agentrust-io.com,2026:trace-v0.2"}, "gateway": {"session_id": "s1"}, "signature": "sig", } VALID_TRACE = { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": 1748000000, "subject": "spiffe://example.org/agent/test", } diff --git a/tests/unit/test_tr_env.py b/tests/unit/test_tr_env.py index 80eee58..65a1484 100644 --- a/tests/unit/test_tr_env.py +++ b/tests/unit/test_tr_env.py @@ -6,7 +6,7 @@ from trace_tests.result import Status _VALID = { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": int(time.time()) - 600, # fresh: 10 minutes old "subject": "spiffe://example.org/agent/test", "cnf": {"jwk": {"kty": "OKP", "crv": "Ed25519", "x": "dGVzdA"}}, diff --git a/tests/unit/test_tr_sig.py b/tests/unit/test_tr_sig.py index 7a7ad91..30917f4 100644 --- a/tests/unit/test_tr_sig.py +++ b/tests/unit/test_tr_sig.py @@ -28,7 +28,7 @@ def _make_signed_record() -> dict: record = { "cmcp_version": "1.0", "trace": { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": 1748000000, "subject": "spiffe://cmcp.gateway/session/unit-test", "runtime": { @@ -111,7 +111,7 @@ def test_plain_trace_embedded_ed25519_signature_passes(): x = _b64url(pub.public_bytes_raw()) trace: dict = { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": 1748000000, "subject": "did:mesh:spiffe://example.org/agent/test", "runtime": {"platform": "software-only", "measurement": "sha256:" + "a" * 64}, @@ -135,7 +135,7 @@ def test_plain_trace_tampered_embedded_signature_fails(): x = _b64url(pub.public_bytes_raw()) trace: dict = { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": 1748000000, "subject": "did:mesh:spiffe://example.org/agent/test", "runtime": {"platform": "software-only", "measurement": "sha256:" + "a" * 64}, diff --git a/tests/vectors/invalid_missing_runtime.json b/tests/vectors/invalid_missing_runtime.json index b31dc25..62d0d9c 100644 --- a/tests/vectors/invalid_missing_runtime.json +++ b/tests/vectors/invalid_missing_runtime.json @@ -1,5 +1,5 @@ { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": 1748000000, "subject": "spiffe://example.org/agent/test/001", "model": {"provider": "anthropic", "model_id": "claude-sonnet-4-5"}, diff --git a/tests/vectors/valid_cmcp_runtime.json b/tests/vectors/valid_cmcp_runtime.json index 17702b8..16b8d11 100644 --- a/tests/vectors/valid_cmcp_runtime.json +++ b/tests/vectors/valid_cmcp_runtime.json @@ -1,7 +1,7 @@ { "cmcp_version": "1.0", "trace": { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": 1748000000, "subject": "spiffe://cmcp.gateway/session/test-session-001", "runtime": { diff --git a/tests/vectors/valid_level0.json b/tests/vectors/valid_level0.json index 064f761..8403581 100644 --- a/tests/vectors/valid_level0.json +++ b/tests/vectors/valid_level0.json @@ -1,5 +1,5 @@ { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": 1748000000, "subject": "spiffe://example.org/agent/credit-risk/01926b4c-1234-7abc-9def-000000000001", "model": { diff --git a/tests/vectors/valid_level0_with_transcript.json b/tests/vectors/valid_level0_with_transcript.json index c58440c..37c1b2d 100644 --- a/tests/vectors/valid_level0_with_transcript.json +++ b/tests/vectors/valid_level0_with_transcript.json @@ -1,5 +1,5 @@ { - "eat_profile": "tag:agentrust.io,2026:trace-v0.1", + "eat_profile": "tag:agentrust-io.com,2026:trace-v0.2", "iat": 1748000001, "subject": "spiffe://example.org/agent/payments/01926b4c-1234-7abc-9def-000000000002", "model": {