diff --git a/README.md b/README.md index 2d4dd32..2cdb5ce 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ docs/ platform-spec-alignment-review.md contracts/ membership-platform-interfaces.md + conformance/ + membership-gating-vectors.md schemas/ offer.v1.schema.json entitlement.v1.schema.json diff --git a/docs/conformance/membership-gating-vectors.md b/docs/conformance/membership-gating-vectors.md new file mode 100644 index 0000000..22ed6b5 --- /dev/null +++ b/docs/conformance/membership-gating-vectors.md @@ -0,0 +1,129 @@ +# EDUT Membership and Entitlement Gating Conformance Vectors (v1) + +This document defines deterministic pass/fail vectors for membership-gated commerce. + +## Vector Group A: Wallet Intent and Signature + +1. A1 `intent_success` +- Given valid wallet address, origin, and chain +- When `POST /secret/wallet/intent` is called +- Then status is `pending_signature` and nonce+deadline are returned + +2. A2 `intent_replay_blocked` +- Given an already consumed `intent_id` +- When verify is called again +- Then request is rejected and state does not regress + +3. A3 `signature_address_mismatch` +- Given signature recovered to wallet X and request address wallet Y +- When verify executes +- Then state becomes `rejected` and no membership quote is issued + +4. A4 `intent_expired` +- Given intent past deadline +- When verify executes +- Then result is `intent_expired` + +## Vector Group B: Membership Mint Activation + +1. B1 `quote_requires_verified_signature` +- Given designation not in `signature_verified` +- When quote is requested +- Then quote is denied + +2. B2 `quote_expired` +- Given quote past deadline +- When confirm is called +- Then membership remains inactive + +3. B3 `confirm_tx_success` +- Given valid tx hash with expected currency/amount/recipient +- When confirm executes +- Then state transitions to `membership_active` + +4. B4 `confirm_tx_wrong_amount` +- Given tx amount does not match quote +- When confirm executes +- Then state remains `pending_membership_mint` + +5. B5 `confirm_tx_wrong_recipient` +- Given tx recipient is not membership contract +- When confirm executes +- Then state remains `pending_membership_mint` + +6. B6 `confirm_wrong_chain` +- Given tx on disallowed chain +- When confirm executes +- Then request fails closed + +## Vector Group C: Checkout Membership Gate + +1. C1 `checkout_block_no_membership` +- Given wallet with no active membership +- When checkout quote is requested +- Then checkout is denied + +2. C2 `checkout_allow_active_membership` +- Given wallet with active membership +- When checkout quote is requested +- Then quote is returned + +3. C3 `checkout_block_suspended_membership` +- Given suspended membership +- When checkout is requested +- Then checkout is denied + +4. C4 `checkout_block_revoked_membership` +- Given revoked membership +- When checkout is requested +- Then checkout is denied + +## Vector Group D: Entitlement Activation Gate + +1. D1 `activation_allow_active_entitlement` +- Given entitlement state `ACTIVE` +- When runtime activation is requested +- Then activation succeeds + +2. D2 `activation_block_suspended` +- Given entitlement state `SUSPENDED` +- When runtime activation is requested +- Then activation fails closed + +3. D3 `activation_block_revoked` +- Given entitlement state `REVOKED` +- When runtime activation is requested +- Then activation fails closed + +4. D4 `activation_block_expired` +- Given entitlement state `EXPIRED` +- When runtime activation is requested +- Then activation fails closed + +## Vector Group E: Evidence Integrity + +1. E1 `receipt_fields_complete` +- Every successful membership and purchase receipt contains: + - wallet + - membership status snapshot + - offer_id + - policy_hash + - quote_id + - tx_hash + - chain_id + - entitlement_id (for purchase) + +2. E2 `receipt_hash_stable` +- Given identical input payload +- Receipt hash must be identical across replays + +3. E3 `audit_non_regression` +- Once state reaches `membership_active`, audit log cannot be removed or mutated without append-only evidence entry + +## Pass Criteria + +A build is conformant only when all vectors pass. + +## Fail-Closed Rule + +Any uncertainty in chain confirmation, quote validity, policy hash, or state sync must block activation/purchase by default.