VPP / VPSF / ZKPay ; Architectural Articulation¶
Internal document. Load-bearing reference for design reviews, ADR cascades, and onboarding. Canonical as of 2026-05-21. Update when any of the three layers changes scope.
1. The three layers in one paragraph¶
VPSF (Vauban Proof Stack Framework / Vauban Claim Algebra) is a chain-agnostic grammar: a
sextuplet type (Subject, Predicate, Evidence, TemporalFrame, RevelationMask, Anchor) plus five
composition operators (∧ → ⊕ ▷ ¬). It produces and verifies abstract Claims; it knows nothing
about payment, privacy, or any specific chain. VPP (Vauban Privacy Protocol) is a privacy
primitive layer built on top of VPSF: it wraps Claims in shielded envelopes, manages stealth
addresses, nullifiers, and viewing keys, and provides the ShieldedClaim type. ZKPay
(Vauban Pay, repo vauban-zkpay) is a payment product: it instantiates VPSF Claims as
PaymentIntent, SettlementReceipt, RefundClaim, and DelegationGrant, wires them to x402 V2
HTTP headers, and settles on Starknet L2 (first reference implementation; chain-agnostic by
invariant per ADR-ECO-031).
2. Layer roles¶
2.1 VPSF ; grammar invariant¶
Sources : vauban-claim-rs crate (crates/claim/src/lib.rs), IETF
draft-vauban-claim-algebra-00, ADR-ECO-004, ADR-ECO-031.
Role : define the irreducible data type and its algebra. Nothing else.
Scope : encoding (canonical CBOR, RFC 8949 §4.2.1), structural invariants, the five composition operators with validity rules, 71 conformance test vectors (target ≥85).
What it produces : a Claim value (opaque sextuplet) ; a CompositionRecord when an
operator is applied ; ValidationReport from the structural validator.
What it does NOT do :
- Cryptographic verification of Evidence payloads (STARK, BBS+, SD-JWT-VC). Deferred to
downstream crates (zkpay-verifier, VPP adapter). Stated explicitly in lib.rs:28-29.
- On-chain Anchor resolution. Deferred to adapter sub-crates.
- Payment, settlement, privacy shielding, or stealth addressing. Not its domain.
- Any Starknet, EVM, Solana, or Bitcoin type in the core crate. Zero chain deps in
crates/claim/Cargo.toml (verified: serde, ciborium, sha2, thiserror only).
Chain-agnostic discipline (ADR-ECO-031 §2.1, enforcement-grade) : no chain-specific type
ever enters vauban-claim core. Per-chain adapters (vauban-claim-starknet, future
vauban-claim-evm) consume the core via trait objects ; the core does not import them.
2.2 VPP ; privacy primitive layer¶
Sources : vauban-privacy-protocol/, VPP architecture docs
docs/architecture/01-privacy-primitives.md and docs/architecture/06-claim-algebra-integration.md,
VPP CLAUDE.md.
Role : wrap any Claim in a privacy-preserving envelope. Provide the cross-product building blocks for receiver anonymity, selective disclosure, and audit-on-demand.
Scope :
- ShieldedClaim struct ; wraps a Claim sextuplet, adds stealth_address, warrant_tokens,
encrypted_viewing_key.
- Stealth addressing ; Phase 1 STARK-curve ECDH (not PQ), Phase 2 ML-KEM-768 + Poseidon2
(NIST FIPS 203, post-quantum).
- shield() / unshield() operations.
- Nullifier discipline for ShieldedClaim revocation ; dual-track (holder + issuer SMT).
- Viewing keys ; encrypted on-chain, selective disclosure to auditors/regulators.
- Composition privacy rules ; how each VPSF operator preserves or constrains disclosure
under shielding (conjunction narrows to intersection of disclosed sets, etc.).
- STARK-based range proofs, set membership proofs, predicate-based anonymous credentials.
What it produces : ShieldedClaim, WarrantToken, StealthAddress, privacy-augmented
composition records.
What it does NOT do :
- Define payment semantics (PaymentIntent, amount fields, x402 wire format). Payment is
ZKPay's domain.
- Replace VPSF. VPP sits above VPSF and leaves the sextuplet grammar unchanged.
ShieldedClaim.inner is a plain Claim.
- Settle on-chain or batch-aggregate payment transactions.
- Define the x402 HTTP wire format.
Current phase : Phase 1 (Cairo + SDK implementation, sprint-576). Pre-mainnet gates: Stage 1 + Stage 2 cryptographic audits per ADR-ECO-015 (Critical = 0 required each stage).
ZKPay integration point : the ShieldingBackend trait in ZKPay. Default backend is
TransparentBackend (MVP, Phase 0). Phase 2a switches to Strk20Backend (STRK20 protocol-native
privacy). Phase 2b switches to VppBackend (ML-KEM-768 full post-quantum shielding, gated on
VPP audit Stage 1 completion (a Phase 2b gate).
VPP scope remains broad (ADR-ECO-031 §1.2 D2 correction) : VPP is a chain-agnostic privacy companion. STRK20 is one per-chain primitive that VPP may consume as a backend. VPP scope was not narrowed by STRK20 launch. STRK20 covers token-level privacy on Starknet; VPP covers claim-level privacy (stealth addressing, warrant tokens, ML-KEM-768 envelope) on any chain where VPSF claims are anchored.
2.3 ZKPay ; payment product¶
Sources : vauban-zkpay/ repo, spec v0.3 (docs/specs/vauban-zk-payment-spec-v0.3.md),
ADR-ECO-022 v2, ADR-ECO-021 v2.
Role : instantiate VPSF Claims as payment objects, connect them to the x402 V2 HTTP payment protocol, and settle them on Starknet L2 (current reference implementation).
Scope :
- Four PaymentClaim types, each a concrete instance of the VPSF sextuplet:
PaymentIntent, SettlementReceipt, RefundClaim, DelegationGrant.
- x402 V2 wire format ; PAYMENT-REQUIRED, PAYMENT-SIGNATURE, PAYMENT-RESPONSE HTTP headers,
canonical CBOR body.
- zkpay-verifier : STARK proof verification (Stwo Circle STARK M31, =2.2.0), nullifier
check (Valkey), CEI flow.
- zkpay-prover-stwo : prover crate, feature-gated cairo_air::verify_cairo adapter.
- Starknet adapter : VaubanSettlement.cairo extension (not a parallel CreditRegistry),
ProofChainAnchor.cairo on L3 Madara.
- Four integration trait ports: Claim (HARD, vauban-claim v0.1.0), ShieldingBackend
(INTERFACE), HumanityGate (INTERFACE), PaymentSigner (INTERFACE). Plus ClaimExporter
(ROADMAP, Phase 2b).
- Batch aggregation via ⊕ operator (K payment intents, single Stwo aggregate proof).
- Same-subject HARD INVARIANT (MVP) : composition.rs:301-303 returns SubjectMismatch
unconditionally when subjects differ. Cross-subject composition requires VCA v0.2 linkage
proof validation (not yet implemented).
What it produces : verified payment receipts (SettlementReceipt Claims), batch settlement
transactions on Starknet, audit-ready CBOR-encoded Claim bundles.
What it does NOT do :
- Define the VPSF grammar or algebra. ZKPay consumes vauban-claim as a hard dependency; it
cannot modify the grammar.
- Implement privacy primitives (stealth addressing, warrant tokens, ML-KEM-768 envelopes). These
come from VPP via the ShieldingBackend trait.
- Replace Stwo or STRK20. ZKPay consumes them as chain-level primitives via adapter sub-crates.
Positioning (ADR-ECO-022 v2, ADR-ECO-031) : ZKPay is the Starknet-first reference
implementation of VPSF for the HTTP payment vertical. It is NOT the invariant. Future adapters
(vauban-zkpay-evm, Q3 2027 testnet target; -solana, -bitcoin conditional Phase 4+) consume
the same VPSF core and the same payment vertical without touching it.
3. Dependency graph (chain-agnostic discipline)¶
The arrows below mean "depends on / consumes". The direction is strictly downward in the grammar layer (ZKPay and VPP both depend on VPSF; VPSF depends on neither).
┌─────────────────────────────────────────────────────────────────┐
│ ZKPay (vauban-zkpay) — payment product │
│ PaymentIntent / SettlementReceipt / RefundClaim / DelegationGrant│
│ x402 V2 wire · Stwo prover · VaubanSettlement.cairo │
│ │
│ Consumes VPP via ShieldingBackend trait (Phase 2b VppBackend) │
└──────────────────────┬──────────────────────┬───────────────────┘
│ │ (Phase 2b only)
HARD dep │ │ INTERFACE dep
(vauban-claim crate)│ │ (ShieldingBackend)
│ ┌────────────┴──────────────────┐
│ │ VPP (vauban-privacy-protocol) │
│ │ ShieldedClaim · StealthAddress│
│ │ ViewingKey · WarrantToken │
│ │ ML-KEM-768 + Poseidon2 │
│ │ │
│ │ Consumes VPSF Claim sextuplet │
│ │ as ShieldedClaim.inner │
│ └────────────┬──────────────────┘
│ │ HARD dep
│ (vauban-claim crate)
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ VPSF (vauban-claim crate, chain-agnostic by invariant) │
│ Claim sextuplet · 5 operators (∧→⊕▷¬) · validator │
│ Canonical CBOR · 71 conformance test vectors │
│ │
│ No Starknet · No EVM · No Solana · No payment semantics │
│ No proof verification · No on-chain resolution │
└─────────────────────────────────────────────────────────────────┘
│
adapter pattern (ADR-ECO-031 §2.2)
┌────────────┴───────────────────────────────┐
│ │
vauban-claim-starknet vauban-claim-evm (Phase 4+)
(StarknetAnchor, (EvmAnchorTrait)
Stwo Evidence adapter)
Chain-agnostic invariant enforced by :
- rules/architecture/vpsf-chain-agnostic.md (intent-only enforcement, Phase 0)
- CI lint target vpsf-chain-agnostic-lint.yml (Phase MVP Sprint 1, blocks chain-specific
deps in vauban-claim core Cargo.toml)
- scripts/check-chain-agnostic.sh (custom lint, run at every commit)
- Verified empirically : crates/claim/Cargo.toml lists zero Starknet/EVM/Solana/Bitcoin deps.
4. Anti-conflations (frequently asked)¶
Q1 : "ZKPay = VPSF on Starknet" ; WRONG.
ZKPay is one product that consumes VPSF. VPSF is the grammar; ZKPay adds payment semantics
(PaymentIntent predicate body, amount_max, currency, nullifier), x402 V2 wire format, an Stwo
prover pipeline, and a Starknet settlement adapter. Glacis, Rempart, Brain, Citadel, Forge also
consume VPSF; they are not ZKPay. "VPSF on Starknet" conflates grammar with product and grammar
with chain. The correct framing (ADR-ECO-031 §2) : ZKPay is the Starknet-first reference
implementation of VPSF for the HTTP payment vertical.
Q2 : "VPP is just an old name for VPSF" ; WRONG.
VPSF is the grammar layer (sextuplet + algebra, vauban-claim-rs). VPP is a distinct product
(vauban-privacy-protocol) that builds on top of VPSF to add privacy primitives: ShieldedClaim
envelope, stealth addressing, viewing keys, warrant tokens, ML-KEM-768 PQ key encapsulation. VPP
has its own CLAUDE.md, its own charter, its own sprints, and its own pre-mainnet audit gates.
The confusion originates from "ZK" appearing in both names; the domains are orthogonal.
VPP docs/architecture/06-claim-algebra-integration.md §1 states explicitly: "The Privacy
Protocol does NOT replace the Claim Algebra. It wraps Claims in shielded envelopes."
Q3 : "VPSF lives inside ZKPay" ; WRONG.
VPSF is an upstream crate (vauban-claim-rs) that ZKPay declares as a hard dependency. The
dependency arrow points from ZKPay toward VPSF, not the reverse. VPSF has no knowledge of
PaymentIntent or x402. Updating ZKPay does not change VPSF. Updating VPSF (new operator,
revised CDDL) requires a downstream migration in ZKPay and VPP, not the other way around.
Architecturally : VPSF is the keystone (ADR-ECO-021 v2, Pillar #4); ZKPay is a load-bearing
consumer, not the housing.
Q4 : "VPP covers payments" ; PARTIALLY, with precise boundary.
VPP does NOT define payment semantics. It has no PaymentIntent type, no x402 integration, no
settlement contract. VPP contributes to payments via one integration point: the ShieldingBackend
trait in ZKPay. MVP uses TransparentBackend (no shielding); Phase 2b swaps to VppBackend
which wraps a PaymentIntent inside a ShieldedClaim, adding stealth address, ML-KEM-768
envelope, and warrant tokens. The payment predicate remains a ZKPay concern; the privacy
envelope is a VPP concern. The boundary is the ShieldingBackend trait.
Q5 : "Why does ZKPay need VPSF if it has its own STARK proofs ?" ; answered.
Stwo (the prover) verifies the cryptographic validity of a witness. VPSF validates the
structure and algebra of a Claim: field presence, composition rules, temporal frame
intersection, subject matching. These are orthogonal. A STARK proof can be cryptographically
valid while the surrounding Claim sextuplet is structurally malformed (missing TemporalFrame,
invalid RevelationMask, operator confusion). The vauban_claim::validator::validate call in
the CEI verification flow (zkpay-verifier §4.9 step 2) is a structural gate that runs before
the STARK proof check. Additionally, VPSF provides the composability model: the same Claim
type that wraps a PaymentIntent can be ∧-composed with a HumanityClaim from Glacis. Without
VPSF as shared grammar, this cross-domain composition has no canonical type, no operator, and no
single-proof verification path.
Q6 : "Why does ZKPay use vauban-claim if VPP also provides primitives ?" ; answered.
vauban-claim (VPSF) is the structural grammar. VPP provides the privacy envelope. They solve
different problems. ZKPay needs VPSF to express PaymentIntent as a well-typed, composable Claim.
ZKPay needs VPP (Phase 2b) to wrap that Claim in a shielded envelope with stealth addressing. In
MVP (Phase 0), ZKPay uses VPSF directly and does not use VPP at all (ShieldingBackend =
TransparentBackend). VPP is not a prerequisite for ZKPay MVP; it is an optional enhancement gated
on VPP audit completion (a Phase 2b gate).
Q7 : "STRK20 replaces VPP for ZKPay" ; WRONG.
STRK20 provides token-level privacy on Starknet (sender, receiver, amount, type hidden at the
Starknet protocol layer, via ShieldedClaim note model, single shared Privacy Pool). VPP provides
claim-level privacy (ML-KEM-768 stealth addressing, warrant tokens, ShieldedClaim with viewing
keys, VPSF-level composition privacy rules). These are two distinct layers in the three-layer
privacy stack (spec v0.3 §2.4) : token-level (STRK20) + payment-level (ZKPay RevelationMask)
+ claim-algebra-level (VPSF ∧→⊕▷¬). VPP maps to the ZKPay payment-level + claim-algebra-level
envelope. STRK20 is one backend that ZKPay can consume via Strk20Backend (Phase 2a), not a
replacement for VPP's claim-level shielding (Phase 2b). ADR-ECO-031 §1.2 D2 explicitly records
the correction: "VPP narrow repositioning post-STRK20 was directionnellement faux."
Q8 : "VPP is specific to Starknet" ; WRONG.
VPP's scope is chain-agnostic by design (aligned with VPSF chain-agnostic invariant per
ADR-ECO-031). ML-KEM-768 and Poseidon2 run on any platform. ShieldedClaim wraps a VPSF
Claim sextuplet, which is chain-agnostic. VPP's current reference implementation targets
Starknet (NullifierRegistry on Starknet, StealthRegistry on Starknet), but this is a first
implementation, not an invariant ; the same pattern applies to the ShieldedClaim
for an EVM or Solana VPSF adapter Phase 4+.
Q9 : "ZKPay can operate without VPSF if the STARK proof is valid" ; WRONG.
The Claim trait is a HARD dependency in ZKPay (not swappable per §1.3 of spec v0.3 and
CLAUDE.md architecture summary). Every payment artifact in ZKPay is a Claim instance; removing
VPSF would require rewriting all four payment types, the composition pipeline, the CBOR encoding,
and the cross-product composability demonstrated in production (Glacis ∧ Rempart, commit
10c2d317). The statement "aucune alternative" in the trait table (spec §1.3) is deliberate.
5. Naming + branding discipline¶
Per ADR-ECO-012 (brand hierarchy) and ADR-ECO-021 v2 (VPSF Pillar #4).
| Name | Context | Form |
|---|---|---|
| VPSF | Technical, governance, ADRs, code comments | All-caps, no expansion needed after first use per doc |
| Vauban Claim Algebra | Preferred in IETF drafts and external technical communications | Title-case |
vauban-claim |
Rust crate name, Cargo.toml, code imports |
lowercase-hyphen |
| VPP | Technical, governance, ADRs | All-caps |
| Vauban Privacy Protocol | First use in external or governance doc | Title-case |
vauban-privacy-protocol |
Repo name, path references | lowercase-hyphen |
| Vauban Pay | User-facing brand, marketing, landing pages, investor pitch | Title-case ; "Vauban" + "Pay" ; never "zkpay" to end-users |
vauban-zkpay |
Repo name, Citadel project slug, internal references | lowercase-hyphen |
| ZKPay | Acceptable shorthand in technical internal docs only | No user-facing use |
Brand hierarchy position (ADR-ECO-012) : - VPSF is Pillar #4 in the Quadri-Synergy architecture (ADR-ECO-021 v2) ; not a sub-brand, a structural invariant. It has no user-facing marketing name. - Vauban Pay is a sub-brand under the Vauban umbrella (ADR-ECO-012 Niveau 2 or Niveau 3 pending council ratification). It does not appear in ADR-ECO-012 v1 (published 2026-04-26, before ZKPay was formalized) ; that is an open gap to resolve at next charter sync. - VPP is an infrastructure component ; no standalone sub-brand tagline at Phase 0.
External communications discipline (ADR-ECO-031, rules/governance/multi-chain-ambition-discipline.md) :
pre-Phase 4 (before first non-Starknet adapter testnet), use the framing:
"Starknet-first reference implementation of the chain-agnostic Vauban Claim Algebra (VPSF)".
Do not write "Vauban Pay is multi-chain" or "VPSF supports EVM/Solana today".
6. Cross-references¶
| Subject | Canonical document |
|---|---|
| VPSF grammar (sextuplet, 5 operators) | vauban-claim-rs/crates/claim/src/lib.rs ; IETF draft-vauban-claim-algebra-00 |
| VPSF chain-agnostic invariant | ADR-ECO-031 (governance/decisions/ADR-ECO-031-vpsf-chain-agnostic-invariant-starknet-first-reference.md) ; rules/architecture/vpsf-chain-agnostic.md |
| VPSF as Pillar #4 | ADR-ECO-021 v2 (governance/decisions/ADR-ECO-021-vpsf-tri-synergy-pillar.md) |
| VPP architecture | vauban-privacy-protocol/docs/architecture/ (7 docs) ; VPP CLAUDE.md |
| VPP claim-algebra integration | vauban-privacy-protocol/docs/architecture/06-claim-algebra-integration.md |
| ZKPay canonical spec (v0.3) | vauban-zkpay/docs/specs/vauban-zk-payment-spec-v0.3.md |
| ZKPay transition plan | ADR-ECO-022 v2 |
| ZKPay architecture index | vauban-zkpay/docs/architecture/index.md |
| ZKPay same-subject HARD INVARIANT | Spec v0.3 §3.3.5 ; vauban-claim-rs/crates/claim/src/composition.rs:301-303 |
| Brand hierarchy | ADR-ECO-012 (governance/decisions/ADR-ECO-012-brand-hierarchy-umbrella-and-subbrands.md) |
| ShieldingBackend trait (ZKPay ↔ VPP interface) | Spec v0.3 §1.3 ; vauban-zkpay/docs/architecture/ports.md |
| Pre-mainnet audit gates (VPP) | ADR-ECO-015 |
| Multi-chain external comms discipline | rules/governance/multi-chain-ambition-discipline.md |
Open contradictions¶
One genuine tension, not papered over.
VPP Phase 1 stealth addressing is NOT post-quantum (STARK-curve ECDH, discrete log). ZKPay spec v0.3 §2.6 cites ML-KEM-768 as "planned Phase 2" and footnotes the VPP ORQ-1 resolution. However, the spec also lists "Post-quantum natif" as invariant #1 in §1.
The tension: ZKPay's Phase 0 MVP is post-quantum at the STARK proof level (Circle STARK M31) but
not at the shielding level (Phase 2b VppBackend is not implemented ; Phase 1 Strk20Backend
stealth uses STARK-curve ECDH which is not PQ). The "Post-quantum natif" claim in §1 accurately
describes the proving system (Stwo); it does not yet apply to the full payment envelope when
shielding is active.
Impact : no immediate design change required (MVP ShieldingBackend = Transparent, shielding
off by default). Requires an errata note in spec v0.3 §1 qualifying "Post-quantum natif" as
applying to the STARK proof component, with Phase 2b VppBackend (ML-KEM-768) as the gate for
full-envelope PQ. The VPP audit Stage 1 gate tracks this.
Status : flagged ; not blocking MVP; requires spec §1 errata before institutional pitch that cites full PQ as a live guarantee.