feat(python): gtm phase 2 pyo3 bindings for awp-core - #10
Conversation
Adds a tiny stdin-driven verifier binary (`awp-verify`) and a pinned deterministic test vector so cross-language attestation signing (Rust ↔ Python) can be self-tested byte-for-byte. The vector covers canonical-encoding, signature, output_hash, and signing_payload — any drift in either language fails both test suites in the same CI run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wraps awp-core's signing path in a PyO3 abi3-py39 extension so Python callers (LangGraph SDK, awp-cloud client, design partners) can produce attestations whose signatures verify byte-identically in Rust. Surface (per planning/gtm-phase-2-plan.md → Step 1): - AgentIdentity.generate / load_or_create / from_secret_bytes - sign_attestation(dict, identity) — dict canonicalised inside Rust - verify_attestation(attestation, pubkey) - Attestation field accessors (id, agent_id, agent_pubkey, output, ...) The cross-language self-test under tests/cross_language.py pins byte-for-byte equality against the Rust vector in crates/awp-core/tests/cross_language_vector.rs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`make check` now builds the awp-verify binary, builds the awp-python wheel with maturin develop, and runs pytest against crates/awp-python/tests. awp-python is excluded from cargo test because its cdylib triggers a libpython link error outside maturin's build environment — the Python test suite covers that crate's surface end to end. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GitHub Actions workflow builds awp-core-py wheels for macOS (x86_64, arm64), Linux (x86_64, aarch64 manylinux 2_28), and Windows (x86_64) on every PR and tag push. Cross-language pytest runs on each platform against Python 3.9 and 3.12 to confirm abi3 coverage. Publish to TestPyPI is gated behind manual workflow_dispatch with a publish_testpypi boolean per the GTM Phase 2 plan — the real-PyPI promotion is a separate decision tied to the design-partner close. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Agent Run ReportImplementation Commits
Review ReportRequirements Checked
Gaps FoundNone. Fixes MadeNone. Quality Gate
Reviewer noteThe spec phrasing "Module name: |
Resolves conflicts in `.gitignore` and `Makefile` against Step 1 (`gtm-phase-2/pyo3-bindings`, merged as PR #10): - `.gitignore`: union of both branches' additions. Step 2 keeps the cloud's local-dev blob path; Step 1 keeps the Python tooling ignores (venv, pycache, maturin dist, in-place PyO3 extension artefacts). - `Makefile`: combined `.PHONY` list; `check` now depends on `lint test check-python cloud-check` so the top-level gate covers both the Python wheel + pytest path from Step 1 and the `services/awp-cloud/` sub-workspace from Step 2. Verified post-merge: - `make lint test cloud-check`: PASS (Rust workspaces clean, 33 awp-cloud tests green). - `make check-python`: PASS (19 awp-python tests green).
Summary
Implements Step 1 of GTM Phase 2 (
planning/gtm-phase-2-agent-prompts.md→ "Step 1 — GTM Phase 2: PyO3 Bindings"): a Python extension that wrapsawp-core's signing path so attestations produced from Python verify byte-identically in Rust.crates/awp-python/— PyO3 abi3-py39 bindings, distribution nameawp-core-py, Python import nameawp.AgentIdentity.generate / load_or_create / from_secret_bytes,sign_attestation(dict, identity),verify_attestation(att, pubkey), and fullAttestationfield accessors.crates/awp-core/tests/cross_language_vector.rsandcrates/awp-python/tests/cross_language.py. Drift on either side fires both test suites.awp-verifybinary (crates/awp-core/src/bin/awp_verify.rs). Python pipes a signed attestation through it for Rust-side verification; the reverse direction asserts byte equality ofsigning_payload.make checkextended to build the wheel viamaturin developand run pytest (19 tests pass)..github/workflows/python-wheels.yml): builds wheels for macOS (arm64 + x86_64), Linux (x86_64 + aarch64 manylinux 2_28), and Windows (x86_64); runs pytest on Python 3.9 + 3.12 per platform; TestPyPI publish gated by manualworkflow_dispatchper the GTM plan.Test plan
make checkpasses (cargo fmt clean, clippy-D warningsclean,cargo test --workspace --exclude awp-pythongreen, maturin develop + pytest 19/19 green).cargo run --example kyc_receipts,cargo run --example dispatcher_flow).python -c "import awp; ident = awp.AgentIdentity.generate('agent-test'); att = awp.sign_attestation({'task': 'hello'}, ident); assert awp.verify_attestation(att, ident.public_key); print('ok')"→ok.python -m pytest crates/awp-python/tests/cross_language.py -v→ 7 passed (sign_python_verify_rust, sign_rust_verify_python, canonical_bytes_match, plus 4 more).Non-goals (deferred)
awp-cloudintegration — handled by parallel Steps 2-3 in the same phase.Implements Step 1 — PyO3 Bindings.
🤖 Generated with Claude Code