Skip to content

Align with TEA spec 1.0.0, keep 0.4.0 server compatibility - #34

Open
aurangzaib048 wants to merge 30 commits into
sbomify:masterfrom
aurangzaib048:feat/tea-1.0.0-alignment
Open

aurangzaib048 wants to merge 30 commits into
sbomify:masterfrom
aurangzaib048:feat/tea-1.0.0-alignment

Conversation

@aurangzaib048

@aurangzaib048 aurangzaib048 commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Aligns libtea with TEA spec 1.0.0 (upstream CycloneDX/transparency-exchange-api at 41e8586) while keeping 0.4.0 servers working. sbomify's own TEA servers (sbomify/sbomify, pypi-tea) still serve 0.4.0, so the client supports both instead of dropping 0.4.0.

  • Spec-version aware client: TeaClient.spec_version / is_legacy, taken from spec_version=, the /v<semver> base-URL suffix, or the 1.0.0 default. from_well_known() negotiates 1.0.0 first, then 0.4.0, fails over across both, and keeps the advertised spelling (/v1.0.0+build.5).
  • Required fields enforced: fields required by both versions are non-Optional; 1.0.0-only fields are checked on 1.x responses through one _v1_problems hook and relaxed for 0.4.0 servers via the {"tea_legacy": True} validation context.
  • MD5 rejected from 1.x servers (still accepted from 0.4.0 servers and in the CLI --checksum).
  • Token pagination: page_offset → page_token, has_next / next_page_token, a new PaginatedCollectionResponse, and newly paginated release/collection lists. On 0.4.0 servers the token is the offset. Iterators guard against repeated tokens and stop after 10,000 pages.
  • 1.0.0 response shapes: the flattened release-with-collection objects (ProductReleaseWithCollection is new), tei:// TEIs alongside urn:tei:, the 1.0.0 error types (unknown values tolerated, TeaRequestError.error_type).
  • New 1.0.0 features: discovery by PURL (discover(purl=...), tea-cli discover --purl) and server-hosted artifact downloads (download_artifact_content). The token goes only to the API base, never on a redirect, and HTTPS→HTTP redirects are refused.
  • Conformance: 28 checks (new pagination_token); discovery checks use tei:// and require a TEA error body on 1.0.0. The search checks follow page tokens past empty 1.x pages.
  • 0.4.0 artifact path fixed: on 0.4.0 servers get_artifact now calls /artifact/{uuid}, the only artifact endpoint 0.4.0 defines. libtea 0.5.1 called /artifact/{uuid}/latest, which 0.4.0 servers (including trust.sbomify.com) answer with 404. get_artifact_version raises TeaValidationError on 0.4.0 servers, since 0.4.0 has no versioned artifact endpoint.

Breaking Python API changes are listed in the README's new Upgrading section. Deferred 1.0.0 items (/token, ETag/304, signature downloads, sort parameters, servers[] routing, a CLI --spec-version option) are in docs/FUTURE.md.

Changes by layer

Layer Changes
Models _v1_problems hook + legacy context, non-Optional both-version fields, Collection.created_date, generic paginated base + PaginatedCollectionResponse, ProductReleaseWithCollection, 1.0.0 ErrorType, removed pre-0.4.0 shims (distribution_type(s), mimeType)
Client version resolution and negotiation, page_token pagination, discover(purl=), download_artifact_content, empty-discovery check on 1.x, version-specific artifact path
HTTP error type parsed from a bounded 4 KiB body read, authenticated first hop with unauthenticated redirects, HTTPS→HTTP redirect refusal, RecursionError mapped to TeaError
Discovery tei:// parsing, exact-version preference before compatible downgrade
CLI --page-token, discover --purl, tei:// download/inspect, server-hosted downloads, inspect fixes for 1.0.0 data
Conformance pagination_token check, 1.0.0-aware discovery checks (28 total)
Docs README (spec versions, Upgrading), cli.md, conformance.md, FUTURE.md, CLAUDE.md

Test plan

  • 1035 tests passing (877 before), 95% branch coverage
  • The previous suite is pinned to /v0.4.0 base URLs and still passes, as a 0.4.0 regression suite
  • ruff check . clean
  • ruff format --check . clean
  • mypy clean
  • Pre-commit hooks pass
  • Verify against a live TEA 0.4.0 server (trust.sbomify.com/tea/v0.4.0): tea-cli conformance gives 17 pass, 11 skip (features that server doesn't offer, such as CLE and versioned collections), 0 fail. This run found the artifact-path bug above, which was fixed in 0eff4bc. from_well_known("trust.sbomify.com") negotiates 0.4.0, and offset page tokens page through all 11 product releases.
  • Verify against a live TEA 1.0.0 server when one is available

…t release

Artifact rows tolerate a missing name, type, mediaType or url (TEA 1.0.0
server-hosted formats carry no url). Unpinned components resolve the release
with the latest createdDate, since 1.0.0 lists releases oldest first.
…ngrade

With version=None, from_well_known now builds its attempts from exact matches
across every supported version (keeping cross-version failover) and only
falls back to a compatible downgrade when none is advertised as-is. A server
offering 0.4.0 and 1.0.0-rc.1 now negotiates 0.4.0 without a warning.
- Deeply nested JSON on 2xx API and .well-known responses raises
  TeaValidationError / TeaDiscoveryError instead of RecursionError.
- Iterators follow nextPageToken past an empty page that still has hasNext;
  the seen-token set and page cap keep the loop bounded.
- A non-string page_token raises TeaValidationError before any request.
- TEA 1.0.0 pages must carry results.
- Conformance discovery_404 on 1.0.0 requires a TEA error body.
Artifact downloads now refuse a redirect from an https hop to http, as
discovery already does. Regression guards: basic auth is sent on the first
hop and dropped on the redirect hop, and the same-host redirect test checks
the first hop carried the bearer token.
…deferred items

README Upgrading: Python-built models follow the 1.0.0 rules (use the legacy
context for 0.4.0-shaped data), unsupported /v<semver> majors raise
ValueError, dict keyword construction of ComponentReleaseWithCollection
fails, and negotiation downgrades only without an exact match.
FUTURE.md: a --spec-version override for the CLI and conformance tools, and
bounding 3xx bodies that requests reads during downloads.
Copilot AI balanced review requested due to automatic review settings October 21, 2026 16:40

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The cross-version migration and authenticated download changes warrant human review, with unresolved conformance failures and live-server validation pending.

2 open issues
What changed in this PR

Updates libtea for TEA 1.0.0 while preserving 0.4.0 server compatibility.

Changes:

  • Adds version-aware validation, discovery, and token pagination.
  • Supports server-hosted artifact downloads with credential-safe redirects.
  • Expands regression tests, conformance checks, and migration documentation.
File Description
tests/​unit/​test_validation.py Tests validation context and legacy tokens.
tests/​unit/​test_protocols.py Pins protocol tests to 0.4.0.
tests/​unit/​test_models.py Covers version-aware models and pagination.
tests/​unit/​test_conformance_runner.py Uses the legacy endpoint.
tests/​unit/​test_conformance_plugin.py Updates legacy client expectations.
tests/​unit/​test_conformance_checks.py Tests version-aware conformance checks.
tests/​spec_data.py Adds shared versioned fixtures.
tests/​integration/​test_integration.py Updates distribution-field expectations.
tests/​conftest.py Adds separate version fixtures.
tests/​client/​test_iterators.py Tests legacy offset continuation.
tests/​client/​test_http.py Tests error parsing and nested JSON.
tests/​client/​test_download.py Tests authenticated URL restrictions.
tests/​client/​test_discovery.py Covers TEI parsing and negotiation.
tests/​client/​test_client.py Updates legacy client regression tests.
tests/​client/​test_client_v1.py Adds 1.0.0 client coverage.
tests/​client/​test_cache.py Pins cache tests to 0.4.0.
tests/​cli/​test_cli_fmt.py Tests updated model formatting.
src/​libtea/​protocols.py Updates the client interface.
src/​libtea/​models.py Adds version-aware schemas and pagination.
src/​libtea/​exceptions.py Exposes request error types.
src/​libtea/​discovery.py Supports TEI URIs and advertised versions.
src/​libtea/​conformance/​plugin.py Updates usage examples.
src/​libtea/​conformance/​_checks.py Adapts checks and adds token validation.
src/​libtea/​conformance/​__init__.py Updates conformance examples.
src/​libtea/​cli.py Adds new discovery and download workflows.
src/​libtea/​_validation.py Passes legacy context into validation.
src/​libtea/​_http.py Adds authenticated downloads and bounded error parsing.
src/​libtea/​_cli_fmt.py Updates pagination and field rendering.
src/​libtea/​__init__.py Exports new models.
README.md Documents compatibility and migration.
docs/​FUTURE.md Records deferred features and limitations.
docs/​conformance.md Documents version-aware checks.
docs/​cli.md Updates commands and examples.
CLAUDE.md Updates architecture and development guidance.

Review effort: Balanced

Comment thread src/libtea/conformance/_checks.py Outdated
Comment thread src/libtea/conformance/_checks.py Outdated
Copilot AI balanced review requested due to automatic review settings October 22, 2026 11:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

TEA 0.4.0 serves artifact metadata at /artifact/{uuid}; /artifact/{uuid}/latest
and /artifact/{uuid}/{version} exist only in 1.x. A live conformance run against
trust.sbomify.com (0.4.0) failed get_artifact with 404. get_artifact now picks the
path from the negotiated version, and get_artifact_version raises
TeaValidationError on 0.4.0 servers before any request.
Copilot AI balanced review requested due to automatic review settings October 25, 2026 12:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants