Skip to content

feat(xtest): sync upstream/main (DPoP + PQ/T) and add feature conformance to Pages - #5

Merged
arkavo-com merged 24 commits into
mainfrom
community-xtest-stage2
Jul 19, 2026
Merged

feat(xtest): sync upstream/main (DPoP + PQ/T) and add feature conformance to Pages#5
arkavo-com merged 24 commits into
mainfrom
community-xtest-stage2

Conversation

@arkavo-com

Copy link
Copy Markdown

What

Brings main level with opentdf/tests@main (14 upstream commits) plus the fork's community additions, and wires the newly pulled DPoP and post-quantum KEM suites into the community CI + GitHub Pages report.

Upstream sync (merge of upstream/main)

Community additions on top

  • Pages report (xtest/reporting/generate_site.py): new Feature conformance section — test_dpop.py/test_pqc.py results (classified by junit classname) counted per participating SDK and rendered between the interop and capability matrices; excluded from Base TDF matrix/scorecards; summary.json gains a features array. Dormant lanes show as all-skipped until an SDK claims the feature.
  • community-xtest.yml:
    • Re-pinned start-up-with-containers6dd5f64 and added dpop-challenge-enabled via new workflow_dispatch input dpop-challenge.
    • Ubuntu stage-1 jobs start a km1 key-management KAS (upstream km-check + start-additional-kas recipe) so test_pqc.py fixtures work.
    • Dormant feature lanes: test_dpop.py + test_pqc.py for python/rust (ubuntu), test_dpop.py for swift (macOS — native platform has no km1). Lanes skip until an SDK's cli.sh supports claims the feature, then light up automatically.
    • OTDFCTL_HEADS passed to all pytest steps (head-built otdfctl for admin key ops; PQ/T hybrid-format skew skip for otdfctl ≤ 0.33).
  • docs/community-conformance.md: documents the feature lanes and the new report section.

Merge notes

  • Includes merges of upstream/main and origin/main into this branch, so the PR is cleanly mergeable; merging it brings main to upstream + community additions.
  • xtest/pyproject.toml conflicts resolved to cryptography>=49.0.0 (upstream) keeping defusedxml (fork); uv.lock regenerated.

Validation

  • ruff check + ruff format --check clean; pyright clean on the report generator.
  • Site generator smoke-tested with synthetic junit/supports fixtures (feature rows render, summary.json verified).
  • Workflow YAML parses; step-id/output references verified; no duplicate step ids.

After merge, the Pages site will show DPoP and PQ/T rows once the next Community X-Test run completes on main.

dmihalcik-virtru and others added 21 commits June 23, 2026 09:38
…df#532)

## Problem

[xtest
fails](https://github.com/opentdf/platform/actions/runs/27984367850/job/82822208378)
for `merge_group` events from `opentdf/platform` during go CLI setup:

```
tdfs.py:483: in __init__
    raise FileNotFoundError(f"SDK executable not found at path: {self.path}")
E   FileNotFoundError: SDK executable not found at path:
    sdk/go/dist/refs/heads/gh-readonly-queue/main/pr-3630-8a006469dc6e55455a2ce4715415671d39670ef6/cli.sh
```

The `Prepare go cli` step only built `main`, yet the matrix value was
`go@refs/heads/gh-readonly-queue/...`.

## Root cause

This is a version-resolution bug in `otdf_sdk_mgr/resolve.py`, not a
workflow-config bug.

The platform caller (`opentdf/platform` → `checks.yaml`,
`platform-xtest`) passes the go ref as a commit **SHA** (`otdfctl-ref:
<merge-sha> main`). On a merge-queue run that SHA is pointed at by
exactly **one** ref — the temporary
`refs/heads/gh-readonly-queue/main/pr-<n>-<sha>` branch.

`resolve.py` had all the merge-queue / PR / branch normalization (→
`mq-main-N`, `pull-N`, flattened slashes, `head: true`) **only** in the
`len(matching_tags) > 1` branch. The single-match path stripped just
`refs/tags/`/infix, so it:

1. returned `tag = "refs/heads/gh-readonly-queue/main/pr-…"` — slashes
become the bad nested `dist/refs/heads/…` path the test looked for, and
2. never set `head: true`, so `setup-cli-tool` skipped the source
checkout/build entirely (only `main`, which *is* flagged head, got
built).

## Fix

- Extract `_classify_sha_match()` — normalizes any matched `(sha, ref)`
into a filesystem-safe `tag` (slashes → `--`) and flags PR / merge-queue
/ branch refs as `head`.
- Extract `_ref_specificity()` — when a SHA is pointed at by several
refs, prefer PR > merge-queue > branch/tag.
- Route both single- and multi-match SHA lookups through the helper, so
a merge-queue commit resolves identically regardless of how many refs
point at it. This also drops the previously-dead "unable to
differentiate" error path.

Now the example ref resolves to `tag = mq-main-3630`, `head = true`, `pr
= 3630` — a clean dist dir that gets source-built, with matrix value
`go@mq-main-3630`.

## Testing

- Added `test_single_match_merge_queue` and
`test_single_match_branch_flagged_head` regression tests.
- `uv run pytest` — all 135 pass.
- `uv run ruff check .`, `uv run ruff format .`, `uv run pyright` —
clean.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved commit SHA resolution to reliably identify pull requests,
merge-queue branches, and git branch references with appropriate
prioritization and tag formatting.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem

Follow-up to opentdf#532. xtest still fails during go CLI setup, now on
**push-to-main** events from `opentdf/platform`, as in [this example
failure](https://github.com/opentdf/platform/actions/runs/28032142207/job/82975485936):

```
FileNotFoundError: SDK executable not found at path: sdk/go/dist/HEAD/cli.sh
```

The matrix value was `go@HEAD` and only `main` got built.

## Root cause

The platform caller passes the go ref as the main-tip commit **SHA**
(`otdfctl-ref: <sha> main`). On a push to main, `git ls-remote` lists
that SHA under **two** refs:

```
<sha>	HEAD
<sha>	refs/heads/main
```

`_ref_specificity` scored every non-PR/non-merge-queue ref equally
(`2`), so `min()` kept the **first** entry — the symbolic `HEAD`. That
fell through `_classify_sha_match` to the generic tag path, producing
`tag = "HEAD"` with no `head` flag. So `setup-cli-tool` skipped the
source build (only `main`, separately resolved as a head, was built) and
the test looked for the non-existent `dist/HEAD/cli.sh`.

## Fix

Rank real refs above the bare `HEAD`: **PR > merge-queue > branch > tag
> other**. Now `refs/heads/main` wins over `HEAD`, giving `tag =
"main"`, `head = true` (built from source).

Branch is deliberately ranked **above** tag: the SHA path always
resolves a commit-under-test, and only the branch case sets `head=true`.
So a commit that is simultaneously a branch tip and a release tag (e.g.
right after release-please) still gets a source build rather than
resolving to a tag that wouldn't be built.

## Testing

- Added `test_head_and_branch_prefers_branch` and
`test_branch_preferred_over_tag`.
- `uv run pytest` — 137 pass.
- `uv run ruff check .`, `uv run ruff format .`, `uv run pyright` —
clean.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Tests**
* Added support for testing a new cryptographic mechanism in the test
suite.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: sujankota <sujankota@gmail.com>
…n on branch refs (opentdf#534)

## Problem

PQ/T tests (`test_pqc.py`: X-Wing, secp+ML-KEM hybrids) **silently
skipped on every branch/PR run**, only ever exercised on `main`/nightly.
They skipped with:

```
Algorithm hpqt:xwing not supported by platform
```

even when the platform fully supported it (km1's keyring loads `hpqt:*`,
and the policy-service `key_algorithm_defined` CEL allows the enum
values).

## Root cause

The PQ tests register their keys via the **admin `otdfctl` fixture**
(`conftest.load_otdfctl()`), which picks the CLI in this order:

1. `OTDFCTL_HEADS[0]` → `sdk/go/dist/{tag}/otdfctl.sh` (the head build)
2. `sdk/go/dist/main/otdfctl.sh`
3. fallback → `go run github.com/opentdf/otdfctl@latest`

**`OTDFCTL_HEADS` was never set by the workflow.** For any platform/go
ref that is a branch (not `main`), `dist/main/otdfctl.sh` doesn't exist
either, so the admin CLI fell through to the **released
`otdfctl@latest`** — which predates the `hpqt:*` algorithm mapping. It
rejected `--algorithm=hpqt:xwing` **client-side, before the request
reached the (fully capable) platform**. (Older algorithms like rsa-4096
/ ec-384-521 still passed because `@latest` knows them — which is why
only hpqt skipped.)

## Fix

Set `OTDFCTL_HEADS: ${{ steps.configure-go.outputs.heads }}` on each
pytest step so the admin otdfctl uses the head build
(`sdk/go/dist/{tag}/otdfctl`) that matches what's under test. `heads` is
`[.tag]`, which matches the `dist/{tag}` build-dir naming.

## Supporting changes

- **`fixtures/keys.py`** — include the underlying otdfctl/platform error
in the PQ key-create skip reason. The previous opaque "not supported"
message is what hid this for so long; the enriched message is what
surfaced the `go run …@latest` smoking gun. Worth keeping permanently.
- **`conftest.py`** — `pytest_report_header` echoes the detected
platform version + feature set into the always-visible session header
(feature detection gates skips, and pytest hides captured output for
skipped tests).
- **`tdfs.py`** — lightweight `logger.debug` breadcrumbs on the
PQ-detection failure paths (km1 log missing/unreadable, KAS algorithm
probe failure).

## Validation

Dispatched `xtest.yml` against platform branch
`revert-3625-DSPX-3396-disable-hybrid` (platform + go both): the
`mechanism-xwing` / `mechanism-secpmlkem` tests went from **SKIPPED →
PASSED**.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **Tests**
* Test reports now display detected platform version and feature set in
session headers.
* Enhanced skip messages with detailed feature requirements and error
context.
  * Improved debug logging for test diagnostics and troubleshooting.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…h 4 updates (opentdf#535)

Bumps the github-actions-major group with 4 updates in the / directory:
[actions/setup-python](https://github.com/actions/setup-python),
[actions/github-script](https://github.com/actions/github-script),
[actions/cache](https://github.com/actions/cache) and
[actions/upload-artifact](https://github.com/actions/upload-artifact).

Updates `actions/setup-python` from 5.3.0 to 6.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-python/releases">actions/setup-python's
releases</a>.</em></p>
<blockquote>
<h2>v6.2.0</h2>
<h2>What's Changed</h2>
<h3>Dependency Upgrades</h3>
<ul>
<li>Upgrade dependencies to Node 24 compatible versions by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://github.com/actions/setup-python/pull/1259">actions/setup-python#1259</a></li>
<li>Upgrade urllib3 from 2.5.0 to 2.6.3 in <code>/__tests__/data</code>
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1253">actions/setup-python#1253</a>
and <a
href="https://github.com/actions/setup-python/pull/1264">actions/setup-python#1264</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-python/compare/v6...v6.2.0">https://github.com/actions/setup-python/compare/v6...v6.2.0</a></p>
<h2>v6.1.0</h2>
<h2>What's Changed</h2>
<h3>Enhancements:</h3>
<ul>
<li>Add support for <code>pip-install</code> input by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a> in
<a
href="https://github.com/actions/setup-python/pull/1201">actions/setup-python#1201</a></li>
<li>Add graalpy early-access and windows builds by <a
href="https://github.com/timfel"><code>@​timfel</code></a> in <a
href="https://github.com/actions/setup-python/pull/880">actions/setup-python#880</a></li>
</ul>
<h3>Dependency and Documentation updates:</h3>
<ul>
<li>Enhanced wording and updated example usage for
<code>allow-prereleases</code> by <a
href="https://github.com/yarikoptic"><code>@​yarikoptic</code></a> in <a
href="https://github.com/actions/setup-python/pull/979">actions/setup-python#979</a></li>
<li>Upgrade urllib3 from 1.26.19 to 2.5.0 and document breaking changes
in v6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://github.com/actions/setup-python/pull/1139">actions/setup-python#1139</a></li>
<li>Upgrade typescript from 5.4.2 to 5.9.3 and Documentation update by
<a href="https://github.com/dependabot"><code>@​dependabot</code></a> in
<a
href="https://github.com/actions/setup-python/pull/1094">actions/setup-python#1094</a></li>
<li>Upgrade actions/publish-action from 0.3.0 to 0.4.0 &amp;
Documentation update for pip-install input by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://github.com/actions/setup-python/pull/1199">actions/setup-python#1199</a></li>
<li>Upgrade requests from 2.32.2 to 2.32.4 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://github.com/actions/setup-python/pull/1130">actions/setup-python#1130</a></li>
<li>Upgrade prettier from 3.5.3 to 3.6.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://github.com/actions/setup-python/pull/1234">actions/setup-python#1234</a></li>
<li>Upgrade <code>@​types/node</code> from 24.1.0 to 24.9.1 and update
macos-13 to macos-15-intel by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://github.com/actions/setup-python/pull/1235">actions/setup-python#1235</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/yarikoptic"><code>@​yarikoptic</code></a> made
their first contribution in <a
href="https://github.com/actions/setup-python/pull/979">actions/setup-python#979</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-python/compare/v6...v6.1.0">https://github.com/actions/setup-python/compare/v6...v6.1.0</a></p>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<h3>Breaking Changes</h3>
<ul>
<li>Upgrade to node 24 by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://github.com/actions/setup-python/pull/1164">actions/setup-python#1164</a></li>
</ul>
<p>Make sure your runner is on version v2.327.1 or later to ensure
compatibility with this release. <a
href="https://github.com/actions/runner/releases/tag/v2.327.1">See
Release Notes</a></p>
<h3>Enhancements:</h3>
<ul>
<li>Add support for <code>pip-version</code> by <a
href="https://github.com/priyagupta108"><code>@​priyagupta108</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1129">actions/setup-python#1129</a></li>
<li>Enhance reading from .python-version by <a
href="https://github.com/krystof-k"><code>@​krystof-k</code></a> in <a
href="https://github.com/actions/setup-python/pull/787">actions/setup-python#787</a></li>
<li>Add version parsing from Pipfile by <a
href="https://github.com/aradkdj"><code>@​aradkdj</code></a> in <a
href="https://github.com/actions/setup-python/pull/1067">actions/setup-python#1067</a></li>
</ul>
<h3>Bug fixes:</h3>
<ul>
<li>Clarify pythonLocation behaviour for PyPy and GraalPy in environment
variables by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1183">actions/setup-python#1183</a></li>
<li>Change missing cache directory error to warning by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1182">actions/setup-python#1182</a></li>
<li>Add Architecture-Specific PATH Management for Python with --user
Flag on Windows by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1122">actions/setup-python#1122</a></li>
<li>Include python version in PyPy python-version output by <a
href="https://github.com/cdce8p"><code>@​cdce8p</code></a> in <a
href="https://github.com/actions/setup-python/pull/1110">actions/setup-python#1110</a></li>
<li>Update docs: clarification on pip authentication with setup-python
by <a
href="https://github.com/priya-kinthali"><code>@​priya-kinthali</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1156">actions/setup-python#1156</a></li>
</ul>
<h3>Dependency updates:</h3>
<ul>
<li>Upgrade idna from 2.9 to 3.7 in /<strong>tests</strong>/data by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://github.com/actions/setup-python/pull/843">actions/setup-python#843</a></li>
<li>Upgrade form-data to fix critical vulnerabilities <a
href="https://github.com/actions/setup-python/issues/182">#182</a>
&amp; <a
href="https://github.com/actions/setup-python/issues/183">#183</a>
by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1163">actions/setup-python#1163</a></li>
<li>Upgrade setuptools to 78.1.1 to fix path traversal vulnerability in
PackageIndex.download by <a
href="https://github.com/aparnajyothi-y"><code>@​aparnajyothi-y</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1165">actions/setup-python#1165</a></li>
<li>Upgrade actions/checkout from 4 to 5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://github.com/actions/setup-python/pull/1181">actions/setup-python#1181</a></li>
<li>Upgrade <code>@​actions/tool-cache</code> from 2.0.1 to 2.0.2 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://github.com/actions/setup-python/pull/1095">actions/setup-python#1095</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/setup-python/commit/a309ff8b426b58ec0e2a45f0f869d46889d02405"><code>a309ff8</code></a>
Bump urllib3 from 2.6.0 to 2.6.3 in /<strong>tests</strong>/data (<a
href="https://github.com/actions/setup-python/issues/1264">#1264</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/bfe8cc55a7890e3d6672eda6460ef37bfcc70755"><code>bfe8cc5</code></a>
Upgrade <a href="https://github.com/actions"><code>@​actions</code></a>
dependencies to Node 24 compatible versions (<a
href="https://github.com/actions/setup-python/issues/1259">#1259</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/4f41a90a1f38628c7ccc608d05fbafe701bc20ae"><code>4f41a90</code></a>
Bump urllib3 from 2.5.0 to 2.6.0 in /<strong>tests</strong>/data (<a
href="https://github.com/actions/setup-python/issues/1253">#1253</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/83679a892e2d95755f2dac6acb0bfd1e9ac5d548"><code>83679a8</code></a>
Bump <code>@​types/node</code> from 24.1.0 to 24.9.1 and update macos-13
to macos-15-intel ...</li>
<li><a
href="https://github.com/actions/setup-python/commit/bfc4944b43a5d84377eca3cf6ab5b7992ba61923"><code>bfc4944</code></a>
Bump prettier from 3.5.3 to 3.6.2 (<a
href="https://github.com/actions/setup-python/issues/1234">#1234</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/97aeb3efb8a852c559869050c7fb175b4efcc8cf"><code>97aeb3e</code></a>
Bump requests from 2.32.2 to 2.32.4 in /<strong>tests</strong>/data (<a
href="https://github.com/actions/setup-python/issues/1130">#1130</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/443da59188462e2402e2942686db5aa6723f4bed"><code>443da59</code></a>
Bump actions/publish-action from 0.3.0 to 0.4.0 &amp; Documentation
update for pi...</li>
<li><a
href="https://github.com/actions/setup-python/commit/cfd55ca82492758d853442341ad4d8010466803a"><code>cfd55ca</code></a>
graalpy: add graalpy early-access and windows builds (<a
href="https://github.com/actions/setup-python/issues/880">#880</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/bba65e51ff35d50c6dbaaacd8a4681db13aa7cb4"><code>bba65e5</code></a>
Bump typescript from 5.4.2 to 5.9.3 and update docs/advanced-usage.md
(<a
href="https://github.com/actions/setup-python/issues/1094">#1094</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/18566f86b301499665bd3eb1a2247e0849c64fa5"><code>18566f8</code></a>
Improve wording and &quot;fix example&quot; (remove 3.13) on testing
against pre-releas...</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/setup-python/compare/0b93645e9fea7318ecaed2b359559ac225c90a2b...a309ff8b426b58ec0e2a45f0f869d46889d02405">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/github-script` from 7.0.1 to 9.0.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/github-script/releases">actions/github-script's
releases</a>.</em></p>
<blockquote>
<h2>v9.0.0</h2>
<p><strong>New features:</strong></p>
<ul>
<li><strong><code>getOctokit</code> factory function</strong> —
Available directly in the script context. Create additional
authenticated Octokit clients with different tokens for multi-token
workflows, GitHub App tokens, and cross-org access. See <a
href="https://github.com/actions/github-script#creating-additional-clients-with-getoctokit">Creating
additional clients with <code>getOctokit</code></a> for details and
examples.</li>
<li><strong>Orchestration ID in user-agent</strong> — The
<code>ACTIONS_ORCHESTRATION_ID</code> environment variable is
automatically appended to the user-agent string for request
tracing.</li>
</ul>
<p><strong>Breaking changes:</strong></p>
<ul>
<li><strong><code>require('@actions/github')</code> no longer works in
scripts.</strong> The upgrade to <code>@actions/github</code> v9
(ESM-only) means <code>require('@actions/github')</code> will fail at
runtime. If you previously used patterns like <code>const { getOctokit }
= require('@actions/github')</code> to create secondary clients, use the
new injected <code>getOctokit</code> function instead — it's available
directly in the script context with no imports needed.</li>
<li><code>getOctokit</code> is now an injected function parameter.
Scripts that declare <code>const getOctokit = ...</code> or <code>let
getOctokit = ...</code> will get a <code>SyntaxError</code> because
JavaScript does not allow <code>const</code>/<code>let</code>
redeclaration of function parameters. Use the injected
<code>getOctokit</code> directly, or use <code>var getOctokit =
...</code> if you need to redeclare it.</li>
<li>If your script accesses other <code>@actions/github</code> internals
beyond the standard <code>github</code>/<code>octokit</code> client, you
may need to update those references for v9 compatibility.</li>
</ul>
<h2>What's Changed</h2>
<ul>
<li>Add ACTIONS_ORCHESTRATION_ID to user-agent string by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://github.com/actions/github-script/pull/695">actions/github-script#695</a></li>
<li>ci: use deployment: false for integration test environments by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://github.com/actions/github-script/pull/712">actions/github-script#712</a></li>
<li>feat!: add getOctokit to script context, upgrade
<code>@​actions/github</code> v9, <code>@​octokit/core</code> v7, and
related packages by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://github.com/actions/github-script/pull/700">actions/github-script#700</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Copilot"><code>@​Copilot</code></a> made
their first contribution in <a
href="https://github.com/actions/github-script/pull/695">actions/github-script#695</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v8.0.0...v9.0.0">https://github.com/actions/github-script/compare/v8.0.0...v9.0.0</a></p>
<h2>v8.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update Node.js version support to 24.x by <a
href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a> in <a
href="https://github.com/actions/github-script/pull/637">actions/github-script#637</a></li>
<li>README for updating actions/github-script from v7 to v8 by <a
href="https://github.com/sneha-krip"><code>@​sneha-krip</code></a> in <a
href="https://github.com/actions/github-script/pull/653">actions/github-script#653</a></li>
</ul>
<h2>⚠️ Minimum Compatible Runner Version</h2>
<p><strong>v2.327.1</strong><br />
<a
href="https://github.com/actions/runner/releases/tag/v2.327.1">Release
Notes</a></p>
<p>Make sure your runner is updated to this version or newer to use this
release.</p>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/salmanmkc"><code>@​salmanmkc</code></a>
made their first contribution in <a
href="https://github.com/actions/github-script/pull/637">actions/github-script#637</a></li>
<li><a
href="https://github.com/sneha-krip"><code>@​sneha-krip</code></a> made
their first contribution in <a
href="https://github.com/actions/github-script/pull/653">actions/github-script#653</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/github-script/compare/v7.1.0...v8.0.0">https://github.com/actions/github-script/compare/v7.1.0...v8.0.0</a></p>
<h2>v7.1.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Upgrade husky to v9 by <a
href="https://github.com/benelan"><code>@​benelan</code></a> in <a
href="https://github.com/actions/github-script/pull/482">actions/github-script#482</a></li>
<li>Add workflow file for publishing releases to immutable action
package by <a
href="https://github.com/Jcambass"><code>@​Jcambass</code></a> in <a
href="https://github.com/actions/github-script/pull/485">actions/github-script#485</a></li>
<li>Upgrade IA Publish by <a
href="https://github.com/Jcambass"><code>@​Jcambass</code></a> in <a
href="https://github.com/actions/github-script/pull/486">actions/github-script#486</a></li>
<li>Fix workflow status badges by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://github.com/actions/github-script/pull/497">actions/github-script#497</a></li>
<li>Update usage of <code>actions/upload-artifact</code> by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://github.com/actions/github-script/pull/512">actions/github-script#512</a></li>
<li>Clear up package name confusion by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://github.com/actions/github-script/pull/514">actions/github-script#514</a></li>
<li>Update dependencies with <code>npm audit fix</code> by <a
href="https://github.com/joshmgross"><code>@​joshmgross</code></a> in <a
href="https://github.com/actions/github-script/pull/515">actions/github-script#515</a></li>
<li>Specify that the used script is JavaScript by <a
href="https://github.com/timotk"><code>@​timotk</code></a> in <a
href="https://github.com/actions/github-script/pull/478">actions/github-script#478</a></li>
<li>chore: Add Dependabot for NPM and Actions by <a
href="https://github.com/nschonni"><code>@​nschonni</code></a> in <a
href="https://github.com/actions/github-script/pull/472">actions/github-script#472</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/github-script/commit/3a2844b7e9c422d3c10d287c895573f7108da1b3"><code>3a2844b</code></a>
Merge pull request <a
href="https://github.com/actions/github-script/issues/700">#700</a>
from actions/salmanmkc/expose-getoctokit + prepare re...</li>
<li><a
href="https://github.com/actions/github-script/commit/ca10bbdd1a7739de09e99a200c7a59f5d73a4079"><code>ca10bbd</code></a>
fix: use <code>@​octokit/core/</code>types import for v7
compatibility</li>
<li><a
href="https://github.com/actions/github-script/commit/86e48e20ac85c970ed1f96e718fd068173948b7b"><code>86e48e2</code></a>
merge: incorporate main branch changes</li>
<li><a
href="https://github.com/actions/github-script/commit/c1084728b5b935ec4ddc1e4cee877b01797b3ff9"><code>c108472</code></a>
chore: rebuild dist for v9 upgrade and getOctokit factory</li>
<li><a
href="https://github.com/actions/github-script/commit/afff112e4f8b57c718168af75b89ce00bc8d091d"><code>afff112</code></a>
Merge pull request <a
href="https://github.com/actions/github-script/issues/712">#712</a>
from actions/salmanmkc/deployment-false + fix user-ag...</li>
<li><a
href="https://github.com/actions/github-script/commit/ff8117e5b78c415f814f39ad6998f424fee7b817"><code>ff8117e</code></a>
ci: fix user-agent test to handle orchestration ID</li>
<li><a
href="https://github.com/actions/github-script/commit/81c6b7876079abe10ff715951c9fc7b3e1ab389d"><code>81c6b78</code></a>
ci: use deployment: false to suppress deployment noise from integration
tests</li>
<li><a
href="https://github.com/actions/github-script/commit/3953caf8858d318f37b6cc53a9f5708859b5a7b7"><code>3953caf</code></a>
docs: update README examples from <a
href="https://github.com/v8"><code>@​v8</code></a> to <a
href="https://github.com/v9"><code>@​v9</code></a>, add getOctokit docs
and v9 brea...</li>
<li><a
href="https://github.com/actions/github-script/commit/c17d55b90dcdb3d554d0027a6c180a7adc2daf78"><code>c17d55b</code></a>
ci: add getOctokit integration test job</li>
<li><a
href="https://github.com/actions/github-script/commit/a047196d9a02fe92098771cafbb98c2f1814e408"><code>a047196</code></a>
test: add getOctokit integration tests via callAsyncFunction</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/github-script/compare/60a0d83039c74a4aee543508d2ffcb1c3799cdea...3a2844b7e9c422d3c10d287c895573f7108da1b3">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/cache` from 5.0.5 to 6.0.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/releases">actions/cache's
releases</a>.</em></p>
<blockquote>
<h2>v6.0.0</h2>
<h2>What's Changed</h2>
<ul>
<li>Update packages, migrate to ESM by <a
href="https://github.com/Samirat"><code>@​Samirat</code></a> in <a
href="https://github.com/actions/cache/pull/1760">actions/cache#1760</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/cache/compare/v5...v6.0.0">https://github.com/actions/cache/compare/v5...v6.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/actions/cache/blob/main/RELEASES.md">actions/cache's
changelog</a>.</em></p>
<blockquote>
<h1>Releases</h1>
<h2>How to prepare a release</h2>
<blockquote>
<p>[!NOTE]<br />
Relevant for maintainers with write access only.</p>
</blockquote>
<ol>
<li>Switch to a new branch from <code>main</code>.</li>
<li>Run <code>npm test</code> to ensure all tests are passing.</li>
<li>Update the version in <a
href="https://github.com/actions/cache/blob/main/package.json"><code>https://github.com/actions/cache/blob/main/package.json</code></a>.</li>
<li>Run <code>npm run build</code> to update the compiled files.</li>
<li>Update this <a
href="https://github.com/actions/cache/blob/main/RELEASES.md"><code>https://github.com/actions/cache/blob/main/RELEASES.md</code></a>
with the new version and changes in the <code>## Changelog</code>
section.</li>
<li>Run <code>licensed cache</code> to update the license report.</li>
<li>Run <code>licensed status</code> and resolve any warnings by
updating the <a
href="https://github.com/actions/cache/blob/main/.licensed.yml"><code>https://github.com/actions/cache/blob/main/.licensed.yml</code></a>
file with the exceptions.</li>
<li>Commit your changes and push your branch upstream.</li>
<li>Open a pull request against <code>main</code> and get it reviewed
and merged.</li>
<li>Draft a new release <a
href="https://github.com/actions/cache/releases">https://github.com/actions/cache/releases</a>
use the same version number used in <code>package.json</code>
<ol>
<li>Create a new tag with the version number.</li>
<li>Auto generate release notes and update them to match the changes you
made in <code>RELEASES.md</code>.</li>
<li>Toggle the set as the latest release option.</li>
<li>Publish the release.</li>
</ol>
</li>
<li>Navigate to <a
href="https://github.com/actions/cache/actions/workflows/release-new-action-version.yml">https://github.com/actions/cache/actions/workflows/release-new-action-version.yml</a>
<ol>
<li>There should be a workflow run queued with the same version
number.</li>
<li>Approve the run to publish the new version and update the major tags
for this action.</li>
</ol>
</li>
</ol>
<h2>Changelog</h2>
<h3>6.0.0</h3>
<ul>
<li>Updated <code>@actions/cache</code> to ^6.0.1,
<code>@actions/core</code> to ^3.0.1, <code>@actions/exec</code> to
^3.0.0, <code>@actions/io</code> to ^3.0.2</li>
<li>Migrated to ESM module system</li>
<li>Upgraded Jest to v30 and test infrastructure to be ESM
compatible</li>
</ul>
<h3>5.0.4</h3>
<ul>
<li>Bump <code>minimatch</code> to v3.1.5 (fixes ReDoS via globstar
patterns)</li>
<li>Bump <code>undici</code> to v6.24.1 (WebSocket decompression bomb
protection, header validation fixes)</li>
<li>Bump <code>fast-xml-parser</code> to v5.5.6</li>
</ul>
<h3>5.0.3</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v5.0.5 (Resolves: <a
href="https://github.com/actions/cache/security/dependabot/33">https://github.com/actions/cache/security/dependabot/33</a>)</li>
<li>Bump <code>@actions/core</code> to v2.0.3</li>
</ul>
<h3>5.0.2</h3>
<ul>
<li>Bump <code>@actions/cache</code> to v5.0.3 <a
href="https://github.com/actions/cache/pull/1692">#1692</a></li>
</ul>
<h3>5.0.1</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/cache/commit/2c8a9bd7457de244a408f35966fab2fb45fda9c8"><code>2c8a9bd</code></a>
Merge pull request <a
href="https://github.com/actions/cache/issues/1760">#1760</a>
from actions/samirat/esm_migration_and_package_update</li>
<li><a
href="https://github.com/actions/cache/commit/e9b91fdc3fea7d79165fceb79042ef45c2d51023"><code>e9b91fd</code></a>
Prettier fixes</li>
<li><a
href="https://github.com/actions/cache/commit/e4884b8ff7f92ef6b52c79eda480bbc86e685adb"><code>e4884b8</code></a>
Rebuild dist</li>
<li><a
href="https://github.com/actions/cache/commit/10baf0191a3c426ea0fa4a3253a5c04233b6e18f"><code>10baf01</code></a>
Fixed licenses</li>
<li><a
href="https://github.com/actions/cache/commit/e39b386c9004d72a15d864ade8c0b3a702d47a37"><code>e39b386</code></a>
Fix test mock return order</li>
<li><a
href="https://github.com/actions/cache/commit/b6928203372a8571ff984c0c883ef3a1adfb0c06"><code>b692820</code></a>
PR feedback</li>
<li><a
href="https://github.com/actions/cache/commit/60749128a44d25d3c520a489e576380cf00ff3f1"><code>6074912</code></a>
Rebuild dist bundles as ESM to match type:module</li>
<li><a
href="https://github.com/actions/cache/commit/5a912e8b4af820fa082a0e75cfd2c782f8fbfe0e"><code>5a912e8</code></a>
Fix lint and jest issues</li>
<li><a
href="https://github.com/actions/cache/commit/b9bf592b98b6a5d0cad9929c76247de1cac78abe"><code>b9bf592</code></a>
Update documentation for v6 release</li>
<li><a
href="https://github.com/actions/cache/commit/80f777761d0990932f64ed2740522d7226a49062"><code>80f7777</code></a>
Update packages, migrate to ESM</li>
<li>See full diff in <a
href="https://github.com/actions/cache/compare/27d5ce7f107fe9357f9df03efb73ab90386fccae...2c8a9bd7457de244a408f35966fab2fb45fda9c8">compare
view</a></li>
</ul>
</details>
<br />

Updates `actions/upload-artifact` from 6.0.0 to 7.0.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/upload-artifact/releases">actions/upload-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v7.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>Update the readme with direct upload details by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://github.com/actions/upload-artifact/pull/795">actions/upload-artifact#795</a></li>
<li>Readme: bump all the example versions to v7 by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://github.com/actions/upload-artifact/pull/796">actions/upload-artifact#796</a></li>
<li>Include changes in typespec/ts-http-runtime 0.3.5 by <a
href="https://github.com/yacaovsnc"><code>@​yacaovsnc</code></a> in <a
href="https://github.com/actions/upload-artifact/pull/797">actions/upload-artifact#797</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v7...v7.0.1">https://github.com/actions/upload-artifact/compare/v7...v7.0.1</a></p>
<h2>v7.0.0</h2>
<h2>v7 What's new</h2>
<h3>Direct Uploads</h3>
<p>Adds support for uploading single files directly (unzipped). Callers
can set the new <code>archive</code> parameter to <code>false</code> to
skip zipping the file during upload. Right now, we only support single
files. The action will fail if the glob passed resolves to multiple
files. The <code>name</code> parameter is also ignored with this
setting. Instead, the name of the artifact will be the name of the
uploaded file.</p>
<h3>ESM</h3>
<p>To support new versions of the <code>@actions/*</code> packages,
we've upgraded the package to ESM.</p>
<h2>What's Changed</h2>
<ul>
<li>Add proxy integration test by <a
href="https://github.com/Link"><code>@​Link</code></a>- in <a
href="https://github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
<li>Upgrade the module to ESM and bump dependencies by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://github.com/actions/upload-artifact/pull/762">actions/upload-artifact#762</a></li>
<li>Support direct file uploads by <a
href="https://github.com/danwkennedy"><code>@​danwkennedy</code></a> in
<a
href="https://github.com/actions/upload-artifact/pull/764">actions/upload-artifact#764</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Link"><code>@​Link</code></a>- made
their first contribution in <a
href="https://github.com/actions/upload-artifact/pull/754">actions/upload-artifact#754</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/upload-artifact/compare/v6...v7.0.0">https://github.com/actions/upload-artifact/compare/v6...v7.0.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/upload-artifact/commit/043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"><code>043fb46</code></a>
Merge pull request <a
href="https://github.com/actions/upload-artifact/issues/797">#797</a>
from actions/yacaovsnc/update-dependency</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/634250c1388765ea7ed0f053e636f1f399000b94"><code>634250c</code></a>
Include changes in typespec/ts-http-runtime 0.3.5</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/e454baaac2be505c9450e11b8f3215c6fc023ce8"><code>e454baa</code></a>
Readme: bump all the example versions to v7 (<a
href="https://github.com/actions/upload-artifact/issues/796">#796</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/74fad66b98a6d799dc004d3353ccd0e6f6b2530e"><code>74fad66</code></a>
Update the readme with direct upload details (<a
href="https://github.com/actions/upload-artifact/issues/795">#795</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f"><code>bbbca2d</code></a>
Support direct file uploads (<a
href="https://github.com/actions/upload-artifact/issues/764">#764</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/589182c5a4cec8920b8c1bce3e2fab1c97a02296"><code>589182c</code></a>
Upgrade the module to ESM and bump dependencies (<a
href="https://github.com/actions/upload-artifact/issues/762">#762</a>)</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/47309c993abb98030a35d55ef7ff34b7fa1074b5"><code>47309c9</code></a>
Merge pull request <a
href="https://github.com/actions/upload-artifact/issues/754">#754</a>
from actions/Link-/add-proxy-integration-tests</li>
<li><a
href="https://github.com/actions/upload-artifact/commit/02a8460834e70dab0ce194c64360c59dc1475ef0"><code>02a8460</code></a>
Add proxy integration test</li>
<li>See full diff in <a
href="https://github.com/actions/upload-artifact/compare/v6...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
opentdf#538)

* **New Features**
* Added CLI capability detection for `mechanism-mlkem`, verifying
support via the encryption help output.
* **Tests**
* Improved post-quantum hybrid compatibility handling by adding an
additional conditional skip gate to hybrid KEM roundtrip tests,
preventing runs when version/format skew is detected.
…b-actions-non-major group (opentdf#537)

Bumps the github-actions-non-major group with 1 update:
[actions/setup-python](https://github.com/actions/setup-python).

Updates `actions/setup-python` from 6.2.0 to 6.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/actions/setup-python/releases">actions/setup-python's
releases</a>.</em></p>
<blockquote>
<h2>v6.3.0</h2>
<h2>What's Changed</h2>
<h3>Enhancement</h3>
<ul>
<li>Add RHEL support and include Linux distro in cache keys by <a
href="https://github.com/priyagupta108"><code>@​priyagupta108</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1323">actions/setup-python#1323</a></li>
<li>Fix pip cache error handling on Windows by <a
href="https://github.com/priyagupta108"><code>@​priyagupta108</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1040">actions/setup-python#1040</a></li>
</ul>
<h3>Dependency update</h3>
<ul>
<li>Upgrade minimatch from 3.1.2 to 3.1.5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://github.com/actions/setup-python/pull/1281">actions/setup-python#1281</a></li>
<li>Upgrade actions dependencies by <a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a>
with <a href="https://github.com/Copilot"><code>@​Copilot</code></a> in
<a
href="https://github.com/actions/setup-python/pull/1303">actions/setup-python#1303</a></li>
<li>Upgrade <code>@​actions/cache</code> to 5.1.0, log cache write
denied by <a
href="https://github.com/jasongin"><code>@​jasongin</code></a> in <a
href="https://github.com/actions/setup-python/pull/1324">actions/setup-python#1324</a></li>
<li>Upgrade dependency versions and test workflow configuration by <a
href="https://github.com/HarithaVattikuti"><code>@​HarithaVattikuti</code></a>
in <a
href="https://github.com/actions/setup-python/pull/1322">actions/setup-python#1322</a></li>
</ul>
<h3>Documentation</h3>
<ul>
<li>Update advanced-usage.md by <a
href="https://github.com/Dunky-Z"><code>@​Dunky-Z</code></a> in <a
href="https://github.com/actions/setup-python/pull/811">actions/setup-python#811</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/gowridurgad"><code>@​gowridurgad</code></a>
with <a href="https://github.com/Copilot"><code>@​Copilot</code></a>
made their first contribution in <a
href="https://github.com/actions/setup-python/pull/1303">actions/setup-python#1303</a></li>
<li><a href="https://github.com/jasongin"><code>@​jasongin</code></a>
made their first contribution in <a
href="https://github.com/actions/setup-python/pull/1324">actions/setup-python#1324</a></li>
<li><a href="https://github.com/Dunky-Z"><code>@​Dunky-Z</code></a> made
their first contribution in <a
href="https://github.com/actions/setup-python/pull/811">actions/setup-python#811</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/actions/setup-python/compare/v6...v6.3.0">https://github.com/actions/setup-python/compare/v6...v6.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/actions/setup-python/commit/ece7cb06caefa5fff74198d8649806c4678c61a1"><code>ece7cb0</code></a>
Fix pip cache error handling on Windows. (<a
href="https://github.com/actions/setup-python/issues/1040">#1040</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/1d18d7af5f767c1259ede05a0a5bcc30f3dcf1cf"><code>1d18d7a</code></a>
Update advanced-usage.md (<a
href="https://github.com/actions/setup-python/issues/811">#811</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/d2b357a6a3a3687dd6781a416c0d24fcfd68660e"><code>d2b357a</code></a>
Update dependency versions and test workflow configuration (<a
href="https://github.com/actions/setup-python/issues/1322">#1322</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/8f639b1e75c1048640734b2bb46e22cecf136982"><code>8f639b1</code></a>
Merge pull request <a
href="https://github.com/actions/setup-python/issues/1324">#1324</a>
from jasongin/update-actions-cache-5.1.0</li>
<li><a
href="https://github.com/actions/setup-python/commit/6731c2ba87f530c26324d128c8fdd53499a4d4b0"><code>6731c2b</code></a>
Resolve high-severity audit issues</li>
<li><a
href="https://github.com/actions/setup-python/commit/0cb1a84326b90186fcd211036c65b42819794c87"><code>0cb1a84</code></a>
Add RHEL support and include Linux distro in cache keys (<a
href="https://github.com/actions/setup-python/issues/1323">#1323</a>)</li>
<li><a
href="https://github.com/actions/setup-python/commit/dc6eab6194394e0119523369788b507096f923e2"><code>dc6eab6</code></a>
Update dist</li>
<li><a
href="https://github.com/actions/setup-python/commit/6f4b74bfa2f520a380a620de3615c0dac427f4d3"><code>6f4b74b</code></a>
Strict equality</li>
<li><a
href="https://github.com/actions/setup-python/commit/fa8bde1a9cc6347d06948d66bcd68c598b79eaea"><code>fa8bde1</code></a>
Bump <code>@​actions/cache</code> to 5.1.0, log cache write denied</li>
<li><a
href="https://github.com/actions/setup-python/commit/c8813ba1bc76ebf779b911ad8ffccbf2e449cb48"><code>c8813ba</code></a>
Upgrade <a href="https://github.com/actions"><code>@​actions</code></a>
dependencies and update licenses (<a
href="https://github.com/actions/setup-python/issues/1303">#1303</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...ece7cb06caefa5fff74198d8649806c4678c61a1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-python&package-manager=github_actions&previous-version=6.2.0&new-version=6.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dave Mihalcik <dmihalcik@virtru.com>
…pentdf#540)

While waiting for the catch-22 on the protocol buffer enums

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Updated feature detection in the command-line tool so it no longer
reports support for one specific encryption mechanism check.
* Improved how supported features are evaluated, with related checks now
handled in a cleaner sequence.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
… the uv-major group (opentdf#548)

Bumps the uv-major group in /xtest with 1 update:
[cryptography](https://github.com/pyca/cryptography).

Updates `cryptography` from 48.0.1 to 49.0.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst">cryptography's
changelog</a>.</em></p>
<blockquote>
<p>49.0.0 - 2026-06-12</p>
<pre><code>
* **BACKWARDS INCOMPATIBLE:** Support for ``x86_64`` macOS has been
removed.
  We now only publish ``arm64`` wheels for macOS.
* **BACKWARDS INCOMPATIBLE:** Support for 32-bit Windows has been
removed.
  Users should move to a 64-bit Python installation.
* **BACKWARDS INCOMPATIBLE:** Removed the deprecated
  ``PUBLIC_KEY_TYPES``, ``PRIVATE_KEY_TYPES``,
``CERTIFICATE_PRIVATE_KEY_TYPES``,
``CERTIFICATE_ISSUER_PUBLIC_KEY_TYPES``,
  and ``CERTIFICATE_PUBLIC_KEY_TYPES`` type aliases. Use
``PublicKeyTypes``, ``PrivateKeyTypes``,
``CertificateIssuerPrivateKeyTypes``,
  ``CertificateIssuerPublicKeyTypes``, and ``CertificatePublicKeyTypes``
  instead. These were deprecated in version 40.0.
* **BACKWARDS INCOMPATIBLE:**
:class:`~cryptography.hazmat.primitives.ciphers.algorithms.ChaCha20`
now treats the first 4 bytes of the ``nonce`` as a 32-bit little-endian
block
counter (as defined in :rfc:`7539`) and tracks the number of bytes
processed.
Attempting to encrypt or decrypt more data than the counter allows
before it
would overflow now raises a :class:`ValueError` rather than silently
diverging
from RFC 7539. Setting the counter portion of the ``nonce`` to zero
allows
  encrypting up to 256 GiB with a given nonce.
* **BACKWARDS INCOMPATIBLE:** Loading an X.509 certificate whose ECDSA
or DSA
signature ``AlgorithmIdentifier`` contains encoded NULL parameters now
raises
a :class:`ValueError`. Such certificates are invalid, but older versions
of
  Java emitted them; previously they loaded with a deprecation warning.
* Fixed cross-compilation of the CFFI bindings when
``PYO3_CROSS_LIB_DIR``
  is set. The build now derives the Python include directory from
  ``PYO3_CROSS_LIB_DIR`` instead of querying the host interpreter, which
previously caused the build to fail during cross-compilations for
embedded
  systems, on hosts which have same-version Python development headers
  installed as the target Python.
* Added support for signing and verifying X.509 certificates,
certificate
  signing requests, and certificate revocation lists with
  :doc:`/hazmat/primitives/asymmetric/mldsa` keys, as well as loading
  certificates that contain ML-DSA public keys.
* Added :meth:`~cryptography.hazmat.primitives.hpke.KEM.enc_length` to
:class:`~cryptography.hazmat.primitives.hpke.KEM` so callers can split
the
  encapsulated key from the ciphertext returned by
  :meth:`~cryptography.hazmat.primitives.hpke.Suite.encrypt`.
*
:meth:`~cryptography.x509.verification.ExtensionPolicy.require_present`,
:meth:`~cryptography.x509.verification.ExtensionPolicy.may_be_present`,
and

:meth:`~cryptography.x509.verification.ExtensionPolicy.require_not_present`
now accept any extension type. Previously only a fixed set of extension
  types was supported, which made it impossible to account for otherwise
  unrecognized critical extensions during path validation.
* Added support for using :class:`~cryptography.x509.Certificate`,
  :class:`~cryptography.x509.CertificateSigningRequest`, and
:class:`~cryptography.x509.CertificateRevocationList` as field types in
  :doc:`/hazmat/asn1/index` structures.
* Added :func:`~cryptography.hazmat.asn1.value_set`, a class decorator
that
&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pyca/cryptography/commit/e300bbe2f1bec75e5ee7e0ab7b196958831b3db6"><code>e300bbe</code></a>
bump version and changelog for 49.0.0 (<a
href="https://github.com/pyca/cryptography/issues/15030">#15030</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/fa74cd8031b263edb50307f6d5a9a70df9f0a541"><code>fa74cd8</code></a>
Add external mu (message representative) support for ML-DSA (<a
href="https://github.com/pyca/cryptography/issues/14979">#14979</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/f594db3f315e621473c58721961f502ba2a286ec"><code>f594db3</code></a>
chore(deps): bump openssl from 0.10.80 to 0.10.81 (<a
href="https://github.com/pyca/cryptography/issues/15029">#15029</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/608e0119532153336310e51747724c6b9d107df7"><code>608e011</code></a>
chore(deps): bump openssl-sys from 0.9.116 to 0.9.117 (<a
href="https://github.com/pyca/cryptography/issues/15028">#15028</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/a322bc4fb2bd2fd6f345fdb155cac226b1770dad"><code>a322bc4</code></a>
chore(deps): bump cc from 1.2.63 to 1.2.64 (<a
href="https://github.com/pyca/cryptography/issues/15027">#15027</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/33181a74d41aa859b05f3720700a31c8e5b9e54c"><code>33181a7</code></a>
Reject critical nameConstraints extensions containing directoryName
constrain...</li>
<li><a
href="https://github.com/pyca/cryptography/commit/6080dc7f08e7473544b07df95833ff2ee843266e"><code>6080dc7</code></a>
Bump dependencies that dependabot isn't (<a
href="https://github.com/pyca/cryptography/issues/15026">#15026</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/121faa33a717559a8b0f0180b2d4e7785234af79"><code>121faa3</code></a>
chore(deps): bump virtualenv from 21.4.2 to 21.4.3 (<a
href="https://github.com/pyca/cryptography/issues/15023">#15023</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/829520baa909eff95d64e5ebd165544d6fd60172"><code>829520b</code></a>
Add more robust processing for DH parameters. (<a
href="https://github.com/pyca/cryptography/issues/15016">#15016</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/0f0500141cec535846f36c4c68d02b03126386b5"><code>0f05001</code></a>
Bump downstream dependencies in CI (<a
href="https://github.com/pyca/cryptography/issues/15025">#15025</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pyca/cryptography/compare/48.0.1...49.0.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cryptography&package-manager=uv&previous-version=48.0.1&new-version=49.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added support for a new capability check for ML-KEM encryption
support.
* The CLI can now detect whether the required encryption feature is
available before reporting support.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The Pages site previously consumed only the python artifact and rendered a
bare two-table page. Rebuild it as a proper conformance homepage:

- generate_site.py: aggregate every community artifact into per-SDK
  scorecards, an encrypt×decrypt interop matrix parsed from junit test ids,
  and a capability matrix listing all SDKs (python/rust/swift/go), with
  provenance (source run, platform ref, go peer) and an enriched
  summary.json. Self-contained HTML, light/dark, defusedxml for parsing.
- export_supports.py: capability snapshot extracted from the YAML heredoc
  and parameterized; now exported for python, rust, swift, and the go
  reference peer so every column has data.
- community-pages.yml: download all community-*stage* artifacts from the
  source run, pass run provenance, pin Pages actions by SHA, add timeouts.
- community-xtest.yml: set -o pipefail on the three piped pytest steps —
  `pytest | tee` was swallowing failures (latest run reported green with
  3 failing python tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dvm7uKaNssz7ztu3nAmf7u
…SyntaxError

otdf-python-v0.9.1 dual-wraps KAS and breaks OIDC realm discovery, failing
community python cells. Checkout 825b041 (b-long#167) until a
post-0.9.1 release. Also parenthesize multi-exception except in generate_site.
Parenthesized except (A, B) is reformatted to A, B under target-version
py314, which is valid in 3.14. Match ruff format so CI --check passes.
Picks up rust→python Stage-2 fix (omit payload.tdf_spec_version).
…opentdf#529)

## What

Wires up end-to-end DPoP (Demonstrating Proof-of-Possession) coverage in
the
cross-client test suite, including the `dpop_nonce_challenge`
capability, and
hardens the surrounding CLI shims and CI diagnostics.

## Why

DPoP-bound clients were not actually exercised end-to-end: the shims
read
`CLIENTID` but never enabled DPoP proof generation, so the tests passed
without verifying the bound flow. This branch makes the DPoP client
provision
and emit proofs, validates the nonce-challenge path, and fixes the
platform
action pins that carry the DPoP `htu`/`htm` validation fixes.

## Changes

**Tests**
- `test_dpop.py`: the autouse `_dpop_client_env` fixture now also sets
  `XT_WITH_DPOP=ES256`, so the DPoP-bound `opentdf-dpop` client actually
  generates proofs during encrypt/decrypt.

**SDK CLI shims**
- `sdk/js/cli.sh`: wire `CLIENTID`, `CLIENTSECRET`, and DPoP into the
shim.
- `sdk/java/cli.sh`: delegate `dpop_nonce_challenge` detection to the
binary;
enable `--verbose` when available (checked on the root help, where it is
`ScopeType.INHERIT`); cache the `help` capability probes by jar mtime to
cut
  per-operation JVM startup overhead and keep JVM warnings out of logs.
- `tdfs.py`: surface the `dpop_nonce_challenge` capability and log
subprocess
  stdout/stderr on encrypt/decrypt failure for xdist visibility.

**CI**
- `xtest.yml`: bump platform action SHA pins to pick up the DPoP
`htu`/`htm`
strict-validation fixes; add `dpop-challenge` boolean input (default
`false`)
to `workflow_dispatch` and `workflow_call` so callers opt in to the
nonce
challenge rather than having it hardcoded; pass `OTDFCTL_HEADS` to all
pytest
  steps; upload platform and KAS server logs as artifacts on failure.

## Test plan

- Locally: `uv run pytest test_dpop.py --sdks "go java js" -v` against a
platform built
  from the pinned action SHA (DPoP enabled).
- CI: 
  - ```sh
     gh workflow run xtest.yml \
      --repo opentdf/tests \
      --ref fix-dpop-nonce-challenge \
      -f dpop-challenge=true \
      -f platform-ref=DSPX-3397-platform-go-sdk \
      -f otdfctl-ref=DSPX-3397-platform-go-sdk \
      -f java-ref=DSPX-3397-java-sdk \
      -f js-ref=DSPX-3397-web-sdk
    ```   
- 🟢
https://github.com/opentdf/tests/actions/runs/28523446372/job/84558571384


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Added an optional DPoP nonce-challenge toggle to the test workflow.
* Enhanced CLI tooling to enable DPoP and override auth credentials,
including redacted command output.
  * Improved SDK wrapper behavior to pass DPoP settings when enabled.
* **Bug Fixes**
* Made nonce-challenge handling more consistent by automatically
retrying with the required nonce.
  * Improved feature detection for DPoP capabilities across SDK tooling.
* **Chores**
* Refreshed pinned CI test actions and updated fixtures to include the
DPoP-bound client.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: dmihalcik <dmihalcik@users.noreply.github.com>
…#558)

## Problem

The java-sdk removed the user-facing `--dpop` / `--dpop-key` CLI flags
in opentdf/java-sdk#374. DPoP is now always-on by default, and
capability is exposed through the `supports` subcommand instead.

The Java wrapper's `supports dpop` case still detects DPoP by grepping
`help encrypt` for the `--dpop` flag:

```bash
dpop)
  set -o pipefail
  java -jar "$SCRIPT_DIR"/cmdline.jar help encrypt | grep -iE -- '--dpop'
  exit $?
  ;;
```

With the flags gone this grep finds nothing, exits 1, and xtest skips
java DPoP tests:

```
SKIPPED [2] tdfs.py:619: java@... sdk doesn't yet support [dpop]
```

The sibling `dpop_nonce_challenge` case already delegates to the
`supports` subcommand and is unaffected.

## Fix

Detect `dpop` the same way `dpop_nonce_challenge` already does — via the
`supports` subcommand, whose exit code is the capability contract (0 =
supported, 1 = not):

```bash
dpop)
  java -jar "$SCRIPT_DIR"/cmdline.jar supports dpop
  exit $?
  ;;
```

`set -o pipefail` is dropped since there's no longer a pipe.

## Verification

With a current java `cmdline.jar` installed: `./cli.sh supports dpop;
echo $?` prints `0`, and `dpop_nonce_challenge` still returns `0`. Only
`xtest/sdk/java/cli.sh` changes; other SDK wrappers are untouched.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
  * Improved detection of DPoP support in the Java CLI feature probe.
* Prevents incorrect results caused by relying on help output and flag
matching.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Dave Mihalcik <dmihalcik@virtru.com>
…entdf#559)

Ppins the `start-up-with-containers` action to the fix branch for
testing.

## Why

opentdf/platform#3594 introduced a regression: a misplaced `exit 0` in
the `Map the config to the keys` step of
`test/start-up-with-containers/action.yaml` skips creation of
`opentdf.yaml` whenever the platform under test lacks PQC keys (e.g.
released tags like v0.9.0 that predate `service/cmd/keygen`). Every
later step then fails with `stat opentdf.yaml: no such file or
directory`.

Fix: opentdf/platform#3750 (branch `fix/ci-startup-yaml-pqc-guard`,
`c4038bdd72b8777654aa36266ad721710d220f4d`).

## Change

- `.github/workflows/xtest.yml`: pin `start-up-with-containers` from
`0612ea89 # main` → `c4038bd` (the fix branch) so CI exercises the fix.
- `.github/workflows/vulnerability.yml` is intentionally **left** at
`11af44a5 # pqc-enabled` — it's on a different lineage and isn't
affected by this bug.

## Follow-up

- Merge opentdf/platform#3750, then re-pin this back to the resulting
`main` SHA.
- A more principled replacement for the version/file heuristics
(capability probe via keygen) is planned separately.
Follow-up to opentdf#559. Now that
[opentdf/platform#3750](opentdf/platform#3750)
has merged, re-pin the `opentdf/platform` test actions from the
temporary fix branch / stale main SHA to a **stable, named snapshot** of
current platform main.

To avoid the pins reading as "floating `main`", the target SHA is tagged
in opentdf/platform as **`ci-startup-yaml-fix`** (annotated tag →
`6dd5f649347fb2314c6090ea6d090a5c673d58a6`). Pins stay SHA-locked
(supply-chain best practice); the tag is the human-readable comment.

## Changes (`.github/workflows/xtest.yml`)

| Action | Before | After (SHA `6dd5f649`, tag `ci-startup-yaml-fix`) |
|---|---|---|
| `start-up-with-containers` (L309) | `c4038bd` (fix branch) | ✅ |
| `start-additional-kas` ×6 (L604–670) | `0612ea89` (stale main) | ✅ |

## Notes

- `6dd5f649` is the squash-merge of #3750 ("always generate
opentdf.yaml") and was current platform `main` HEAD; the
`ci-startup-yaml-fix` tag makes it a durable pointer.
- `start-additional-kas/action.yaml` is **unchanged** between `0612ea89`
and `6dd5f649` (verified via `compare`) — a SHA-only sync.
- `vulnerability.yml` intentionally left on its `# pqc-enabled` pin
(separate lineage).
# Conflicts:
#	xtest/pyproject.toml
#	xtest/uv.lock
# Conflicts:
#	xtest/pyproject.toml
#	xtest/uv.lock
Pull the upstream DPoP (opentdf#529, opentdf#558) and ML-KEM/PQ-T (opentdf#531, opentdf#534, opentdf#538,
opentdf#540, opentdf#551) suites into the community conformance surface:

- generate_site.py: new Feature conformance section — testcases from
  test_dpop.py / test_pqc.py (by junit classname) are counted per
  participating SDK and rendered between the interop and capability
  matrices; excluded from the Base TDF matrix and scorecards;
  summary.json gains a features array.
- community-xtest.yml:
  - re-pin start-up-with-containers to 6dd5f64 (opentdf/platform#3750
    yaml fix), matching upstream, and pass dpop-challenge-enabled from
    a new workflow_dispatch input.
  - start a km1 key-management KAS in the ubuntu stage-1 jobs (km-check
    + start-additional-kas, upstream recipe) so test_pqc.py can run.
  - run dormant feature lanes: test_dpop.py + test_pqc.py (python, rust
    on ubuntu), test_dpop.py (swift on macOS — native platform has no
    km1). Lanes skip until an SDK's cli.sh claims the feature.
  - pass OTDFCTL_HEADS to all pytest steps (head-built otdfctl for
    admin key ops on branch refs; PQ/T hybrid-format skew skip).
- docs/community-conformance.md: document the dormant feature lanes.
Comment on lines +56 to +70
def _ref_specificity(ref: str) -> int:
"""Sort key for refs that share a SHA, lowest wins.

PR head, then merge-queue, then a branch, then a tag, then anything else
(e.g. the symbolic ``HEAD`` that ``ls-remote`` lists alongside the branch
it points at — never a useful dist tag on its own). A branch is preferred
over a tag because the SHA path resolves a commit-under-test: the branch
case flags it as a ``head`` so it is built from source, whereas a tag that
happens to point at the same commit would not be.
"""
if ref.startswith("refs/pull/"):
return 0
if re.match(MERGE_QUEUE_REGEX, ref):
return 1
if ref.startswith("refs/heads/"):

@gitar-bot gitar-bot Bot Jul 19, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Bug: resolve.py silently collapses ambiguous multi-tag SHA matches

The old _resolve_against code raised a ResolveError ("SHA points to multiple tags, unable to differentiate") when a SHA matched several refs and none fell into a preferred bucket (e.g. two release tags on the same commit, no branch). The new min(matching_tags, key=_ref_specificity) (resolve.py:261) always returns a winner — _ref_specificity maps unmatched refs to 4, so ties are broken silently by ls-remote output order instead of surfacing an error. This is fine for the common branch/PR/merge-queue cases the new tests cover, but a genuinely ambiguous case (e.g. two tags with no head ref) now resolves to an essentially arbitrary tag instead of failing loudly, and no test exercises that path anymore.

Keep the deterministic tie-break for the common cases, but still flag true ambiguity (multiple refs with the same, lowest, tag-or-lower specificity) as an error.:

sha, ref = min(matching_tags, key=lambda st: _ref_specificity(st[1]))
best = _ref_specificity(ref)
if best >= 3 and sum(1 for _, r in matching_tags if _ref_specificity(r) == best) > 1:
    return {
        "sdk": sdk,
        "alias": version,
        "err": (
            f"SHA {version} points to multiple tags, unable to differentiate: "
            f"{', '.join(r for _, r in matching_tags)}"
        ),
    }
return _classify_sha_match(sdk, version, sha, ref, infix)

Was this helpful? React with 👍 / 👎

Comment thread xtest/sdk/go/cli.sh
Comment on lines 118 to 123
dpop | dpop_nonce_challenge)
# DPoP support is signalled by the --dpop / --dpop-key flag on encrypt.
# The same probe covers nonce-challenge support: when nonce mode is
# required by the server, the SDK's existing 401-retry uses the same
# plumbing as the base DPoP path.
set -o pipefail
"${cmd[@]}" help encrypt | grep -iE -- '--dpop'
"${cmd[@]}" --version --json | jq -e --arg f "$2" '.supported_features |
index($f)'
exit $?
;;

@gitar-bot gitar-bot Bot Jul 19, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Edge Case: go cli.sh dpop/dpop_nonce_challenge probe relies on an unverified otdfctl JSON field

xtest/sdk/go/cli.sh:118-123 detects DPoP/nonce-challenge support via otdfctl --version --json | jq -e '.supported_features | index($f)', replacing the previous help encrypt | grep --dpop probe. Unlike the java CLI change in the same PR, which delegates to an actual supports subcommand baked into the jar, this assumes the go otdfctl --version --json output has gained a supported_features array — if that field doesn't exist on some otdfctl versions in rotation (e.g. older releases resolved via OTDFCTL_HEADS pinning elsewhere in this PR), jq -e on a missing key returns null/exit 1, so the probe just reports "unsupported" rather than erroring, but this could silently mask real support or misreport across otdfctl version skew without a fallback to the old help-text grep.

Fall back to help-text detection if supported_features is absent, so version skew doesn't just report 'unsupported' with no diagnostic.:

dpop | dpop_nonce_challenge)
  set -o pipefail
  if "${cmd[@]}" --version --json 2>/dev/null | jq -e --arg f "$2" '.supported_features // [] | index($f)' >/dev/null 2>&1; then
    exit 0
  fi
  "${cmd[@]}" help encrypt | grep -iE -- '--dpop'
  exit $?
  ;;

Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

Note

Automatic reviews are paused because of a high rate of recent commits on your team. You can still comment "Gitar review" to run one anytime, and automatic reviews resume on their own by August 1.
Learn more

Code Review 👍 Approved with suggestions 0 resolved / 2 findings

Integrates upstream DPoP and PQ/T feature suites into the community CI and Pages report. Note that SHA resolution for ambiguous tags is currently silent and the Go CLI DPoP probe relies on an unverified JSON field.

💡 Bug: resolve.py silently collapses ambiguous multi-tag SHA matches

📄 otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py:56-70 📄 otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py:257-262

The old _resolve_against code raised a ResolveError ("SHA points to multiple tags, unable to differentiate") when a SHA matched several refs and none fell into a preferred bucket (e.g. two release tags on the same commit, no branch). The new min(matching_tags, key=_ref_specificity) (resolve.py:261) always returns a winner — _ref_specificity maps unmatched refs to 4, so ties are broken silently by ls-remote output order instead of surfacing an error. This is fine for the common branch/PR/merge-queue cases the new tests cover, but a genuinely ambiguous case (e.g. two tags with no head ref) now resolves to an essentially arbitrary tag instead of failing loudly, and no test exercises that path anymore.

Keep the deterministic tie-break for the common cases, but still flag true ambiguity (multiple refs with the same, lowest, tag-or-lower specificity) as an error.
sha, ref = min(matching_tags, key=lambda st: _ref_specificity(st[1]))
best = _ref_specificity(ref)
if best >= 3 and sum(1 for _, r in matching_tags if _ref_specificity(r) == best) > 1:
    return {
        "sdk": sdk,
        "alias": version,
        "err": (
            f"SHA {version} points to multiple tags, unable to differentiate: "
            f"{', '.join(r for _, r in matching_tags)}"
        ),
    }
return _classify_sha_match(sdk, version, sha, ref, infix)
💡 Edge Case: go cli.sh dpop/dpop_nonce_challenge probe relies on an unverified otdfctl JSON field

📄 xtest/sdk/go/cli.sh:118-123

xtest/sdk/go/cli.sh:118-123 detects DPoP/nonce-challenge support via otdfctl --version --json | jq -e '.supported_features | index($f)', replacing the previous help encrypt | grep --dpop probe. Unlike the java CLI change in the same PR, which delegates to an actual supports subcommand baked into the jar, this assumes the go otdfctl --version --json output has gained a supported_features array — if that field doesn't exist on some otdfctl versions in rotation (e.g. older releases resolved via OTDFCTL_HEADS pinning elsewhere in this PR), jq -e on a missing key returns null/exit 1, so the probe just reports "unsupported" rather than erroring, but this could silently mask real support or misreport across otdfctl version skew without a fallback to the old help-text grep.

Fall back to help-text detection if supported_features is absent, so version skew doesn't just report 'unsupported' with no diagnostic.
dpop | dpop_nonce_challenge)
  set -o pipefail
  if "${cmd[@]}" --version --json 2>/dev/null | jq -e --arg f "$2" '.supported_features // [] | index($f)' >/dev/null 2>&1; then
    exit 0
  fi
  "${cmd[@]}" help encrypt | grep -iE -- '--dpop'
  exit $?
  ;;
🤖 Prompt for agents
Code Review: Integrates upstream DPoP and PQ/T feature suites into the community CI and Pages report. Note that SHA resolution for ambiguous tags is currently silent and the Go CLI DPoP probe relies on an unverified JSON field.

1. 💡 Bug: resolve.py silently collapses ambiguous multi-tag SHA matches
   Files: otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py:56-70, otdf-sdk-mgr/src/otdf_sdk_mgr/resolve.py:257-262

   The old `_resolve_against` code raised a `ResolveError` ("SHA points to multiple tags, unable to differentiate") when a SHA matched several refs and none fell into a preferred bucket (e.g. two release tags on the same commit, no branch). The new `min(matching_tags, key=_ref_specificity)` (resolve.py:261) always returns a winner — `_ref_specificity` maps unmatched refs to 4, so ties are broken silently by `ls-remote` output order instead of surfacing an error. This is fine for the common branch/PR/merge-queue cases the new tests cover, but a genuinely ambiguous case (e.g. two tags with no head ref) now resolves to an essentially arbitrary tag instead of failing loudly, and no test exercises that path anymore.

   Fix (Keep the deterministic tie-break for the common cases, but still flag true ambiguity (multiple refs with the same, lowest, tag-or-lower specificity) as an error.):
   sha, ref = min(matching_tags, key=lambda st: _ref_specificity(st[1]))
   best = _ref_specificity(ref)
   if best >= 3 and sum(1 for _, r in matching_tags if _ref_specificity(r) == best) > 1:
       return {
           "sdk": sdk,
           "alias": version,
           "err": (
               f"SHA {version} points to multiple tags, unable to differentiate: "
               f"{', '.join(r for _, r in matching_tags)}"
           ),
       }
   return _classify_sha_match(sdk, version, sha, ref, infix)

2. 💡 Edge Case: go cli.sh dpop/dpop_nonce_challenge probe relies on an unverified otdfctl JSON field
   Files: xtest/sdk/go/cli.sh:118-123

   `xtest/sdk/go/cli.sh:118-123` detects DPoP/nonce-challenge support via `otdfctl --version --json | jq -e '.supported_features | index($f)'`, replacing the previous `help encrypt | grep --dpop` probe. Unlike the java CLI change in the same PR, which delegates to an actual `supports` subcommand baked into the jar, this assumes the go `otdfctl --version --json` output has gained a `supported_features` array — if that field doesn't exist on some otdfctl versions in rotation (e.g. older releases resolved via OTDFCTL_HEADS pinning elsewhere in this PR), `jq -e` on a missing key returns `null`/exit 1, so the probe just reports "unsupported" rather than erroring, but this could silently mask real support or misreport across otdfctl version skew without a fallback to the old help-text grep.

   Fix (Fall back to help-text detection if supported_features is absent, so version skew doesn't just report 'unsupported' with no diagnostic.):
   dpop | dpop_nonce_challenge)
     set -o pipefail
     if "${cmd[@]}" --version --json 2>/dev/null | jq -e --arg f "$2" '.supported_features // [] | index($f)' >/dev/null 2>&1; then
       exit 0
     fi
     "${cmd[@]}" help encrypt | grep -iE -- '--dpop'
     exit $?
     ;;

Was this helpful? React with 👍 / 👎 | Gitar

…w guard

Review finding on PR #5: is_released() accepts an 'sdk/' version prefix
((?:sdk/)?v?...) but _parse_semver only stripped a leading 'v', so a go
SDK versioned sdk/v0.33.0 parsed to None and skip_pqc_hybrid_format_skew
silently no-oped — the opaque hybrid-KEM crypto failure it pre-empts
would surface as a raw test failure instead of a clean skip. Normalize
with re.sub(r"^(?:sdk/)?v?", "", version); also fixes lstrip('v')
stripping more than the single prefix.
… probe fallback

resolve.py: the _classify_sha_match refactor dropped the old hard error
for genuinely ambiguous SHA matches; min() silently picked ls-remote
order when several tag-level refs shared a commit. Restore the loud
failure when the winning specificity is tag-or-worse with no unique
winner, keeping the deterministic PR/queue/branch precedence. Two new
tests cover the ambiguous-tags error and the single-tag + HEAD case.

sdk/go/cli.sh: the dpop/dpop_nonce_challenge probe read
.supported_features from otdfctl --version --json, a field current
otdfctl builds do not emit, so go DPoP support never detected and the
lanes stayed permanently dormant. Keep the JSON probe for builds that
have it, fall back to the previous 'help encrypt | grep -- --dpop'
probe otherwise.
@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@arkavo-com arkavo-com changed the title Sync upstream/main (DPoP + PQ/T fixes) and surface feature conformance on Pages feat(xtest): sync upstream/main (DPoP + PQ/T) and add feature conformance to Pages Jul 19, 2026
…emantics

- start-additional-kas requires kas-port (8585 for km1); omission failed
  the step before KAS start.
- km-check: field DECLARED (true or false) means the platform build
  understands the key_management preview flag → supported=true. My
  condensed version echoed the field value, which is false by default
  in opentdf-dev.yaml, so km1 started without key management.
- ruff format resolve.py (scriptcheck gate).
@github-actions

Copy link
Copy Markdown

X-Test Failure Report

@arkavo-com
arkavo-com merged commit 5d2bd80 into main Jul 19, 2026
25 of 32 checks passed
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