Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 47 additions & 6 deletions .github/workflows/contract-boundary.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,66 @@
name: contract-boundary
name: full-suite

on:
pull_request:
push:
branches: [ main ]

permissions:
contents: read

jobs:
boundary:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.11", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install package with dev dependencies
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Run contract boundary tests
- name: Run full repository test suite
run: PYTHONPATH=. python -m pytest -q
Comment thread
erinepshovel-code marked this conversation as resolved.

release-artifact:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.11"
- name: Build wheel from declared package metadata
shell: bash
run: |
set -euo pipefail
python -m pip install --upgrade pip
python -m pip wheel . --no-deps --wheel-dir dist
- name: Install wheel outside source tree and smoke-test public package
shell: bash
run: |
PYTHONPATH=. python -m pytest -q tests/test_contract_spec.py
set -euo pipefail
expected=$(python - <<'PY'
import tomllib
with open("pyproject.toml", "rb") as handle:
print(tomllib.load(handle)["project"]["version"])
PY
)
wheel=$(printf '%s\n' dist/pcea-*.whl)
test -f "$wheel"
python -m venv /tmp/pcea-release-smoke
/tmp/pcea-release-smoke/bin/python -m pip install --no-deps "$wheel"
cd /tmp
EXPECTED_VERSION="$expected" /tmp/pcea-release-smoke/bin/python - <<'PY'
import os
from importlib.metadata import version
import pcea

assert version("pcea") == os.environ["EXPECTED_VERSION"]
assert callable(pcea.encrypt_state)
assert callable(pcea.decrypt_state)
assert pcea.PCEAInstance is not None
PY
4 changes: 2 additions & 2 deletions .github/workflows/manifest-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ jobs:
manifest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.11'
- name: Vendored generate.py matches skill-lib (no local fork)
Expand Down
33 changes: 20 additions & 13 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ benchmarks/
bench.py Throughput/latency benchmark across codec → kdf → element → seed → state → instance

.github/workflows/
contract-boundary.yml CI gate running tests/test_contract_spec.py on PRs + pushes to main
contract-boundary.yml Full pytest matrix + built-wheel release-artifact smoke gate on PRs + pushes to main

.agents/skills/ meta-module-build / msdmd / test-build agent skill docs

Expand All @@ -132,12 +132,15 @@ pip install -e ".[dev]"
# Runtime install only (no test deps)
pip install .

# Run the full test suite (pyproject sets testpaths = ["tests"])
pytest
# Run the same repository test surface exercised by the CI matrix
PYTHONPATH=. python -m pytest -q

# Run only the CI contract-boundary gate (mirrors the workflow)
# Run only the narrower PCEA↔UCNS contract test when debugging that boundary
PYTHONPATH=. python -m pytest -q tests/test_contract_spec.py

# Build the release wheel locally; CI additionally installs it outside the source tree
python -m pip wheel . --no-deps --wheel-dir dist

# Run the performance benchmark
python benchmarks/bench.py
```
Expand Down Expand Up @@ -201,26 +204,30 @@ assert dec.decrypt(e1) == [seed(99)]
line 1, header on line 2).
- **PCEA↔UCNS contract (Option A)** — PCEA decrypts/inverts via keys, never via
UCNS inverse/catalogue APIs. `contract.py` holds the canonical constants and the
list of `FORBIDDEN_UCNS_SYMBOLS`. `tests/test_contract_spec.py` is the release gate.
list of `FORBIDDEN_UCNS_SYMBOLS`. `tests/test_contract_spec.py` is the focused
executable witness for that boundary; release readiness is the full CI suite plus
the built-wheel artifact smoke check.
- `cipher.py`, `codec.py`, and `kdf.py` are security-critical — treat changes with
extra scrutiny. Do not ship machine-generated crypto without independent review.

---

## Gotchas

- **`tests/test_contract_spec.py` is the release gate.** It (and the whole
suite) is green today — a plain `pytest -q` passes (91 passed, 21 skipped at
time of writing; re-derive the exact count rather than trusting it here). An
earlier revision of this file carried an unresolved merge conflict
(`RUNTIME_FILES` vs `RUNTIME_MODULES`) that broke collection; that is resolved.
The intended logic lives in `pcea/contract.py` (`RUNTIME_MODULES`,
`FORBIDDEN_UCNS_SYMBOLS`).
- **`tests/test_contract_spec.py` is one release-critical contract witness, not the
whole CI release gate.** The active `contract-boundary.yml` workflow runs the full
pytest suite on Python 3.9, 3.11, and 3.13 and separately builds a wheel, installs
it into a clean environment outside the source tree, verifies package metadata,
and smoke-tests the public API. An earlier revision of `test_contract_spec.py`
carried an unresolved merge conflict (`RUNTIME_FILES` vs `RUNTIME_MODULES`) that
broke collection; that is resolved. The intended boundary logic lives in
`pcea/contract.py` (`RUNTIME_MODULES`, `FORBIDDEN_UCNS_SYMBOLS`).
- **`tests/test_metadata_headers.py` globs `pcea/*.py` and `tests/*.py`** and
enforces the `# ratios:` seal on line 1 and the provenance header on line 2 of
every runtime/test module — so any new file under `pcea/` or `tests/` must
carry both, or that test fails.
- CI (`contract-boundary.yml`) runs `test_contract_spec.py` as the release gate.
- CI (`contract-boundary.yml`) is authoritative for repository release readiness:
full pytest matrix plus the built-wheel release-artifact smoke check.

---

Expand Down