PAP is published at draft stage specifically to invite feedback, objections, and alternative proposals.
- Protocol-level feedback: Does the trust model hold? Are there attack vectors we've missed? Can the capture test be tightened?
- Competing implementations: Python (PyO3) and TypeScript (
@pap/core) implementations exist alongside the Rust reference. More languages welcome — if the spec is only readable in one language, the spec is incomplete. - Integration patterns: How to add PAP compliance to an existing LangChain agent, CrewAI workflow, or MCP tool provider.
- Formal specification review: The protocol currently lives in code. An RFC-style document needs adversarial review.
- Real-world testing: Run the examples against actual services. Where does the protocol break? What's missing?
- Rust stable toolchain — install via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- cargo — included with rustup
The Tauri-based desktop app and several crates require native libraries:
sudo apt-get update && sudo apt-get install -y \
libgtk-3-dev \
libwebkit2gtk-4.1-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libssl-devThe registry SSR tests additionally need:
sudo apt-get install -y pkg-config libpq-devInstall Xcode Command Line Tools:
xcode-select --install| Tool | Version | Needed for |
|---|---|---|
| Node.js + npm | 20+ | Browser extension, E2E tests |
| Python | 3.8+ | pap-python bindings |
| maturin | 1.5+ | Building Python bindings |
| Java (JDK) | 17+ | Java bindings |
| Gradle | 8+ | Java binding tests |
| wasm-pack | latest | WASM builds |
| trunk | latest | Leptos frontend builds |
| Playwright | 1.50+ | E2E smoke tests |
| just | latest | Development command runner (just setup, just dev) |
git clone https://github.com/Baur-Software/pap.git
cd pap
cargo build --workspace
cargo test --workspaceTo run a protocol example:
cargo run -p pap-search-examplepap/
├── crates/ # Protocol library crates
│ ├── pap-core/ # Mandate, scope, session, receipt, extensions
│ ├── pap-did/ # DID generation, session keypairs (did:key, Ed25519)
│ ├── pap-credential/ # W3C VC envelope, SD-JWT selective disclosure
│ ├── pap-credential-store/ # Encrypted vault for seeds, VCs, continuity tokens
│ ├── pap-proto/ # Protocol message types and envelope
│ ├── pap-transport/ # HTTP client/server for 6-phase handshake
│ ├── pap-federation/ # Cross-registry sync, announce, peer exchange
│ ├── pap-marketplace/ # Agent advertisement, registry, discovery
│ ├── pap-agents/ # Shared agent implementations (AgentExecutor trait)
│ ├── pap-webauthn/ # WebAuthn signer abstraction + software fallback
│ ├── pap-tee/ # Trusted execution environment support
│ ├── pap-c/ # C FFI bindings (cdylib + staticlib)
│ ├── pap-wasm/ # WebAssembly bindings (@pap/sdk npm package)
│ ├── pap-python/ # PyO3 bindings for Python
│ └── papillon-shared/ # Shared models between Papillon frontend/backend
├── apps/
│ ├── papillon/ # Tauri desktop reference implementation
│ ├── papillon-extension/ # Chrome MV3 browser extension
│ └── registry/ # Chrysalis federated registry (Axum + Leptos SSR)
├── bindings/
│ ├── cpp/ # C++ RAII header-only wrapper
│ ├── csharp/ # .NET 8 P/Invoke bindings
│ └── java/ # JNA-based Java bindings
├── examples/ # 10 self-contained protocol examples
├── benches/ # Criterion.rs benchmarks + regression gate
├── docs/ # Specification and protocol documentation
├── e2e/ # Playwright E2E tests
└── ci/ # CI helper scripts
File an issue for:
- Protocol design questions or concerns
- Implementation bugs
- Missing test coverage
- Documentation gaps
- Feature requests (evaluated against the capture test)
- Fork the repo
- Create a feature branch from
main - Write tests for new functionality
- Ensure
cargo test --workspacepasses (Rust) - Ensure
cargo clippy --workspacehas no warnings (Rust) - Ensure
cargo fmt --allis clean (Rust) - For TypeScript changes:
cd packages/pap-ts && npm test && npm run typecheck - Open a PR with a clear description of what changed and why
Use conventional prefixes:
feat/short-description— new featuresfix/short-description— bug fixeschore/short-description— maintenance, deps, CIdocs/short-description— documentation changes
We use Conventional Commits. Format:
<type>(<optional scope>): <description>
Types: feat, fix, chore, style, docs, refactor, test, perf
Examples from recent history:
feat: Chrysalis federation integration
fix: resolve all pre-existing WASM Clippy warnings surfaced by cache bust
style: apply rustfmt to pap_uri module
chore: bump version to 0.6.0, update CHANGELOG for pap:// URI scheme
feat(generic): render PapLink as confirmation-gated intent button
Every contribution is evaluated against a single question: does this reduce or expand the attack surface for incumbent platform capture?
Proposals that introduce new trusted third parties, centralize discovery, soften disclosure enforcement, or create compatibility with metering models should be evaluated as potential capture vectors first and protocol improvements second.
This is not a purity test. It is a design constraint. The protocol's value is that it structurally prevents the patterns that captured every previous generation of open standards.
# All tests
cargo test --workspace
# Single crate
cargo test -p pap-core
# Registry with SSR features
cargo test -p pap-registry --features ssr# Run benchmarks
cargo bench -p pap-bench
# Check for regressions (>20% p50 threshold)
bash benches/check_regression.shPerformance targets (p50):
- Ed25519 keypair: < 1 ms
- DID derivation: < 0.5 ms
- Mandate sign: < 2 ms
- Chain verify (depth 3): < 5 ms
- SD-JWT issue: < 3 ms
- Session open: < 20 ms
cd crates/pap-python
maturin develop
pytestBuild the C FFI library first, then run Gradle tests:
cargo build -p pap-c --release
cd bindings/java
./gradlew testcd e2e
npm install
npx playwright install chromium --with-deps
cd ../apps/papillon/frontend && trunk build --release && cd ../../../e2e
npx playwright test tests/smoke.spec.ts --workers=1Tier 2 functional tests require a running Chrysalis registry container:
# Build and start the registry
docker build -t chrysalis-registry -f e2e/Dockerfile.ci-chrysalis .
docker run -d -p 8080:8080 --name chrysalis-test chrysalis-registry
# Wait for the registry to be healthy
npx wait-on http://localhost:8080/federation/identity --timeout 60000
# Run the tier-2 tests
cd e2e && npx playwright test tests/tier2-functional.spec.ts
# Clean up
docker stop chrysalis-test && docker rm chrysalis-testEach example demonstrates a specific protocol feature. All 11 examples are self-contained and runnable with cargo run -p <name>:
# 6-phase handshake & local execution
cargo run -p pap-search-example # 6-phase handshake, loopback
cargo run -p pap-travel-booking-example # SD-JWT selective disclosure
cargo run -p pap-delegation-chain-example # Multi-hop mandate delegation
cargo run -p pap-credential-lifecycle-example # VC issuance and decay
cargo run -p pap-protocol-envelope-example # JWS signing and verification
cargo run -p pap-selective-disclosure-decay-example # Mandate decay state machine
cargo run -p pap-payment-example # Ecash payment attachment
cargo run -p pap-webauthn-ceremony-example # WebAuthn signer
# Requires `just registry-local` (Chrysalis registry):
cargo run -p pap-networked-search-example # Networked agent discovery and execution
cargo run -p pap-federated-discovery-example # Cross-registry federation sync
# TEE simulation:
cargo run -p tee-attestation # Trusted execution environment attestation
# Or using just:
just run-example pap-search-exampleThe Papillon browser extension requires WASM bindings from pap-wasm:
cd apps/papillon-extension
npm install
npm run build:wasm # builds pap-wasm → wasm/ directory
npm run build # TypeScript check + Vite build → dist/
# For development (watch mode):
npm run devFor Firefox, generate the Firefox-compatible manifest:
npm run firefox:manifestAll checks run on every push to main and on pull requests. Your PR must pass all of them.
| Job | What it does | Reproduce locally |
|---|---|---|
| Check | cargo check --workspace --all-targets |
Same command |
| Test | cargo test --workspace |
Same command |
| Test (registry SSR) | cargo test -p pap-registry --features ssr |
Same command |
| Clippy | cargo clippy --workspace --all-targets -- -D warnings |
Same command |
| Format | cargo fmt --all -- --check |
cargo fmt --all to fix |
| Docker workspace | Validates Dockerfile workspace consistency | bash ci/check-docker-workspace.sh |
| Benchmark | Runs benchmarks + regression gate (>20% p50) | cargo bench -p pap-bench && bash benches/check_regression.sh |
| Smoke test | Playwright E2E tests for Papillon desktop | See E2E Smoke Tests |
| Chrysalis E2E | Integration tests for Chrysalis registry (Docker) | See E2E Smoke Tests |
Before opening a PR, run at minimum:
cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspaceIf you modified anything under apps/papillon/frontend/ or any crate it depends on
(crates/papillon-shared, crates/pap-did, crates/pap-proto, crates/pap-core), also run:
just check-wasmThe frontend lives in its own Cargo workspace and is excluded from --workspace flags, so
cargo check/test --workspace silently skips it. just check-wasm runs
cargo check --target wasm32-unknown-unknown against the frontend manifest directly, catching
js-sys/web-sys API errors and missing struct fields in seconds rather than waiting for
trunk build --release to fail in CI.
- Rust stable toolchain
cargo fmtfor formatting (config:rustfmt.tomlwithedition = "2021")cargo clippywith-D warnings— all warnings are treated as errors in CI- Tests co-located with implementation (in
mod testsblocks) - All public types documented with
///doc comments - Examples should be self-contained and demonstrate a specific protocol feature
Major architectural changes should be discussed in an issue before implementation. This includes:
- New crates
- Changes to the mandate/session/receipt types
- New protocol phases or extensions
- Transport layer changes
- Federation protocol changes
By contributing, you agree that your contributions will be licensed under the project's MIT OR Apache-2.0 dual license.