fix(schema): move schema $id off a domain we do not own - #42
Merged
Conversation
All eight schemas, in all three copies, identified themselves under https://agentrust.io. That domain is not ours. It serves a 114 byte parked lander, `window.location.href="/lander"`, and it answers HTTP 200 for every path, so a resolver fetching a schema $id gets HTML and a success code rather than a 404 it could act on. The real site is agentrust-io.com, on GitHub Pages. This is the same class of defect trace-spec corrected in its v0.1 to v0.2 cutover, where a v0.1 identifier would have let a record minted under a domain we do not own keep passing as conformant. Changes the $id host in spec/schema, src/agentrust_telemetry/schemas and packages/typescript/schemas, plus the id template in validation.ts. Relative $refs are untouched and still resolve, because the host swap keeps the base hierarchical. Neither SDK dereferences $id. Both load schemas locally and register them by $id, so nothing depends on the URL being fetchable and this needs no hosting change to be correct. Serving the eight files at that path is worth doing and is not a prerequisite. Considered and rejected: tag:agentrust-io.com,2026:telemetry/... to match trace-spec's EAT profile URI. Python needs every cross-schema $ref rewritten absolute for that to resolve at all, and Ajv cannot resolve tag: URIs even when they are absolute, so it would break the TypeScript SDK. trace-spec uses a tag URI as a claim value, not as a JSON Schema $id with refs hanging off it. Gates: check_versions, check_schemas, check_typescript_schemas, check_otel_compatibility, 13/13 conformance fixtures, 108 Python tests, 41 TypeScript tests, governed_workflow. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xyu1wLe68MPCKaqUXeEpXn
Merged
imran-siddique
added a commit
that referenced
this pull request
Sep 2, 2026
Release preparation for `0.1.0-alpha.2`, following step 1 and 2 of `RELEASING.md`. ## What is in this release All three already merged to `main`: | PR | | |---|---| | #41 | wire `spec_version` now matches `spec/VERSION` | | #42 | schema `$id` moved off `agentrust.io`, a domain we do not own | | #43 | npm dist-tag derived from `spec/VERSION` | ## Why a new version instead of releasing v0.1.0-alpha.1 npm already holds `0.1.0-alpha.1` from the bootstrap publish that `RELEASING.md` explicitly sanctions: > If npm does not expose publisher settings until the first version exists, bootstrap only that first package ownership using npm's interactive 2FA flow `release.yml` publishes both registries from one release event, and `release-assets` has `needs: [publish-pypi, publish-npm]`. Cutting `v0.1.0-alpha.1` would publish PyPI, fail `publish-npm` on the duplicate version, and skip attestation entirely. A fresh version lets one build feed both registries with provenance intact, which is what the pipeline exists to do. PyPI has never been published, so `0.1.0-alpha.2` will be its first version. ## On the moved digests `spec/VERSION` is the contract version and the source both package versions derive from, so bumping it changes the wire `spec_version`, which sits inside the RFC 8785 bytes that get hashed. Both goldens were regenerated from the code rather than hand-edited, and Python and TypeScript independently agree on the new tool-transcript hash. ## A dead test case, found while bumping `tests/test_repository_gates.py` had `"0.1.0-alpha.1"` as a dict key **twice**: ```python "0.1.0-alpha.1": ("0.1.0.dev0", "0.1.0-alpha.1.0"), "0.1.0-alpha.1": ("0.1.0a1", "0.1.0-alpha.1"), ``` Python keeps the last, so the first entry was silently discarded and the `dev` phase has never been tested. Its npm spelling was wrong as well: `0.1.0-alpha.1.0` is not something `ecosystem_versions` can produce for any input. Restored as a real `0.1.0-dev` case, with both alpha spellings now asserted. ## Verification | Gate | Result | |---|---| | `check_versions` | `contract=0.1.0-alpha.2 python=0.1.0a2 npm=0.1.0-alpha.2` | | `check_release_tag v0.1.0-alpha.2` | pass | | `npm_dist_tag` | `alpha` | | `check_schemas` / `check_typescript_schemas` / `check_otel_compatibility` | pass | | Conformance fixtures | 13/13 | | Python tests | 111 pass | | TypeScript tests | 41 pass | ## After this merges 1. Configure the npm trusted publisher for `@agentrust-io/telemetry`, now possible because the package exists. 2. Create the GitHub release tagged `v0.1.0-alpha.2` targeting `main`. 3. Approve the `pypi` and `npm` deployment jobs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Xyu1wLe68MPCKaqUXeEpXn Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
All eight schemas, in all three copies, identify themselves under
https://agentrust.io:That domain is not ours. It serves 114 bytes:
A parked-domain lander. It also answers HTTP 200 for every path, so anything resolving a schema
$idgets HTML with a success code rather than a 404 it could act on. Our real site isagentrust-io.com, served from GitHub Pages.Before this PR,
agentrust-io.comappeared in zero files in the repository.This is the same class of defect trace-spec corrected in its v0.1 to v0.2 cutover, where the concern was letting "a record minted under a domain we do not own continue to pass as conformant."
The change
The
$idhost inspec/schema/,src/agentrust_telemetry/schemas/andpackages/typescript/schemas/, plus the id template invalidation.ts. One line per file, 25 files.Relative
$refs are untouched and still resolve, because swapping the host keeps the base hierarchical.Why this needs no hosting change to be correct
Neither SDK dereferences
$id. Both read the schemas from local files and register them in their validator by$id, so nothing depends on the URL being fetchable. Serving the eight files at that path is worth doing and is not a prerequisite for this to be right. Even unserved, an identifier on a domain we control is strictly better than one on a parked domain that returns 200 and HTML.Considered and rejected: a tag URI
tag:agentrust-io.com,2026:telemetry/...would have matched the identifier style trace-spec v0.2 uses. It does not work here, tested both ways:referencing): relative$refs cannot resolve against a non-hierarchicaltag:base. Making all cross-schema refs absolute does fix it, and passes 6/6 valid and 7/7 invalid fixtures.tag:URIs at all, even fully absolute ones.can't resolve reference tag:agentrust-io.com,2026:telemetry/v0.1/schema/common.schema.json#/$defs/event_idSo a tag URI would break the TypeScript SDK. trace-spec uses one as a claim value (
eat_profile), not as a JSON Schema$idwith refs hanging off it, which is why the parallel does not carry.Verification
check_versions/check_schemas/check_typescript_schemas/check_otel_compatibilityexamples/governed_workflow.pyagentrust.ioBranched from
main, so it is independent of #41 and the two can land in either order.🤖 Generated with Claude Code
https://claude.ai/code/session_01Xyu1wLe68MPCKaqUXeEpXn