v0.5.1 — polish: 4 bugs fixed, async-server parity, 3-platform CI verified
Summary
Post-v0.5.0 audit pass. Four real bugs fixed, async-server brought up to v0.5 parity, docs caught up to current behavior, test vectors expanded, CI matrix verifies all three platforms on every push. No new protocol features. No breaking changes.
Bugs fixed
Streaming detection too permissive
`agent.py` was detecting streaming via `hasattr(result, 'iter') and not isinstance(result, dict)`. That matches lists, tuples, strings, dataclasses, etc. A handler returning `['a','b']` was silently streamed. Narrowed to `inspect.isgenerator()`. Regression test added.
`async_server.py` significantly behind sync
The async path lacked all v0.2-v0.5 hardening: no size cap, no read timeout, no streaming RES_CHUNK support — would crash if any generator-returning dispatch hit it. Brought to parity. Same constructor args, same behavior, ASGI flavor.
`lak_channel.py` wiring bug
Bridge set `self._pact._server_dispatch = bridged_dispatch` but `PACTAgent.serve()` reads `self._dispatch`. The bridge was never actually wired. Fixed. Module docstring updated with known limitations.
Dead `_request_auto_grant` stub
Always returned `None`. Was the only consumer of `self.auto_grant`. Removed. Constructor parameter kept for back-compat (now silent no-op).
Public API expanded
`init.py` now exports the full surface (19 symbols) including `PACTMessage`, `build_req`, `build_res_chunk`, `send_message_streaming`, `verify_capability`. Pre-v0.5.1, streaming users had to reach into submodules.
Documentation caught up
| Doc | Update |
|---|---|
| README | Status v0.2.0 → v0.5.x. Two types → three. Test count → 141. Phase table → release table. Platform support table refreshed. |
| `spec/PACT_v1.md` | New §12 addendum covering all v0.2-v0.5 additions (RES_CHUNK, identity_doc, cap_envelope, stream, new fault codes, fail-closed verification, rotation continuity, cap envelope inline rules, durable state). Original §1-§11 untouched. |
| `docs/PACT_Specification.md` | "Two types" → "three types". v0.5 update note. |
| `pyproject.toml` | Development Status: 3-Alpha → 4-Beta. Python 3.11/3.12/3.13 classifiers. Crypto + Networking topic classifiers. |
Test vectors expanded
`tests/vectors/pact_v1_vectors.json`: 214 lines → 619 lines. Six new vector categories with deterministic bytes:
- Rotation event (sequence=1, signed by pre-rotated key)
- Attenuated capability (delegation chain length 1)
- REQ with `identity_doc` (TOFU handshake)
- REQ with `cap_envelope` (cross-machine A→B→C delegation)
- RES_CHUNK stream (3 chunks, last marked final)
- Error RES with v0.2+ standard fault code
Anyone implementing PACT in another language now has reproducible bytes for every wire-format addition. All 24 existing vector tests still pass.
CI matrix actually verifies platform claim
`.github/workflows/test.yml`: `ubuntu-latest` only → `ubuntu + macos + windows`. 9 jobs total (3 OS × 3 Python). `fail-fast: false` so per-platform regressions are visible.
This v0.5.1 PR was the first time CI ran on macOS or Windows. All 9 jobs passed on the first try:
| 3.11 | 3.12 | 3.13 | |
|---|---|---|---|
| Linux | ✅ 39s | ✅ 40s | ✅ 40s |
| Windows | ✅ 1m4s | ✅ 1m45s | ✅ 1m4s |
| macOS | ✅ 8m14s | ✅ 8m15s | ✅ 8m19s |
The README's three-platform claim is no longer asserted — it's verified on every push.
Test results
| v0.5.0 | v0.5.1 | |
|---|---|---|
| Tests passing | 140 | 141 |
| Documented xfails | 0 | 0 |
| CI platforms | Linux | Linux + macOS + Windows |
| Public exports | 6 | 19 |
| Test vector categories | 6 | 12 |
| Spec coverage | v0.1 | v0.1 + v0.2-v0.5 §12 addendum |
Install
```bash
pip install --upgrade pact-passport
```
Stats arc — full session, v0.1.3 → v0.5.1
| v0.1.3 (case study era) | v0.5.1 | |
|---|---|---|
| Tests | 118 + 1 xfail | 141 |
| Critical auth bypasses | 3 | 0 |
| Durability gaps | 1 | 0 |
| Wire-level delegation | broken | works |
| Streaming | not supported | supported |
| Open issues | 7 | 0 |
| Spec coverage | v0.1 only | v0.1 + addendum |
| Test vectors | 6 categories | 12 categories |
| CI platforms | 1 | 3 |
| Public exports | 6 | 19 |
| Releases | 1 | 8 (v0.1.3, v0.1.4, v0.2.0, v0.2.1, v0.3.0, v0.3.1, v0.4.0, v0.5.0, v0.5.1) |