Skip to content

Commit 0abb3ec

Browse files
committed
CI: run Python SDK suites, mypy, and the cross-impl determinism judge
ci.yml's pnpm -r test never reaches python/ (not a workspace member), so byte-identity was only enforced locally. New path-scoped workflow builds @atrib/sdk (filtered install), installs the atrib distribution editable, and runs pytest + mypy strict on Python 3.10 and 3.12. A final step re-runs python/tests/cross_impl with -rs and fails loudly if the judge would silently skip (its graceful node/dist-missing skip must never mask a disabled harness in CI). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011ZsFiTVkgLp3BoBXQiJ3ba
1 parent 322b6c2 commit 0abb3ec

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

.github/workflows/python-sdk.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Python SDK conformance and cross-impl determinism
2+
3+
# The `atrib` Python distribution (python/) is not a pnpm workspace member,
4+
# so ci.yml's `pnpm -r test` never reaches it. This workflow runs the
5+
# Python conformance suites, mypy strict, and the cross-implementation
6+
# determinism judge (python/tests/cross_impl/), which drives the built
7+
# @atrib/sdk through packages/sdk/scripts/cross-impl-vectors.mjs and
8+
# byte-compares records/hashes/tokens across the two implementations
9+
# (D136). Path-scoped to the byte-identity surface.
10+
11+
on:
12+
push:
13+
paths:
14+
- 'python/**'
15+
- 'packages/sdk/**'
16+
- 'packages/mcp/**'
17+
- 'services/atrib-emit/**'
18+
- 'spec/conformance/**'
19+
- '.github/workflows/python-sdk.yml'
20+
pull_request:
21+
paths:
22+
- 'python/**'
23+
- 'packages/sdk/**'
24+
- 'packages/mcp/**'
25+
- 'services/atrib-emit/**'
26+
- 'spec/conformance/**'
27+
- '.github/workflows/python-sdk.yml'
28+
29+
# Default to read-only GITHUB_TOKEN; jobs that need more (release.yml does)
30+
# specify their own permissions block.
31+
permissions:
32+
contents: read
33+
34+
# Opt into Node.js 24 for transitive JS actions (see ci.yml for rationale).
35+
env:
36+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
37+
38+
jobs:
39+
test:
40+
runs-on: ubuntu-latest
41+
strategy:
42+
fail-fast: false
43+
matrix:
44+
# Floor from python/pyproject.toml requires-python plus a current
45+
# release; byte-identity must hold on both.
46+
python-version: ['3.10', '3.12']
47+
steps:
48+
- uses: actions/checkout@v6
49+
with:
50+
token: ${{ github.token }}
51+
52+
- uses: pnpm/action-setup@v6
53+
54+
- uses: actions/setup-node@v6
55+
with:
56+
node-version: '24'
57+
cache: 'pnpm'
58+
59+
- uses: actions/setup-python@v6
60+
with:
61+
python-version: ${{ matrix.python-version }}
62+
cache: 'pip'
63+
64+
# The cross-impl judge needs the TS SDK built; a filtered install
65+
# keeps this workflow from paying for the whole workspace.
66+
- run: pnpm install --frozen-lockfile --filter @atrib/sdk...
67+
68+
- run: pnpm --filter @atrib/sdk... build
69+
70+
- run: python -m pip install -e "python/[dev]"
71+
72+
- name: Python suites (conformance, behavior, parity, cross-impl)
73+
run: python -m pytest python/tests -q
74+
75+
- name: mypy strict
76+
run: python -m mypy
77+
working-directory: python
78+
79+
- name: Cross-impl determinism judge must actually run (not skip)
80+
# The judge skips gracefully when node or packages/sdk/dist is
81+
# missing; in CI both exist, so any skip means the harness is
82+
# silently disabled — fail loudly instead.
83+
run: |
84+
python -m pytest python/tests/cross_impl -q -rs 2>&1 | tee /tmp/cross-impl.out
85+
if grep -qiE '\bskipped\b' /tmp/cross-impl.out; then
86+
echo '::error::cross-impl determinism tests were skipped in CI'
87+
exit 1
88+
fi

python/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,11 @@ pytest python/tests
100100
mypy # configured in pyproject.toml
101101
```
102102

103+
CI runs the same suites plus the cross-implementation determinism judge on
104+
Python 3.10 and 3.12 via `.github/workflows/python-sdk.yml`, path-scoped to
105+
the byte-identity surface (`python/`, `packages/sdk/`, `packages/mcp/`,
106+
`services/atrib-emit/`, `spec/conformance/`). The judge step fails loudly
107+
if it would silently skip.
108+
103109
The conformance corpora are consumed unmodified from `spec/conformance/`;
104110
a port failure is a spec-bug discovery, not something to route around.

0 commit comments

Comments
 (0)