### 5.2 Protocol layer — `delegus-base-v1` (OPEN)

Reproducible by anyone given: Grant, Proof, Action, RP DID, a clock, the issuer's DID document snapshot, and the status-list credential snapshot. Each check yields `true | false | "skipped"`.

| # | Check | DENY reason |
|---|---|---|
| P1 | Grant parses and conforms to §3 (incl. `parentGrant` absent) | `GRANT_MALFORMED` / `UNSUPPORTED_FEATURE` |
| P2 | `kid` names a verification method present in the DID document snapshot | `ISSUER_KEY_NOT_FOUND` |
| P3 | Grant signature verifies | `GRANT_SIGNATURE_INVALID` |
| P4 | `now ≥ validFrom` | `GRANT_NOT_YET_VALID` |
| P5 | `now < validUntil` | `GRANT_EXPIRED` |
| P6 | Status credential signed by Delegus; bit at `statusListIndex` is 0 | `AUTHORITY_REVOKED` |
| P7 | `audience`, if present, contains RP | `AUDIENCE_MISMATCH` |
| P8 | Proof parses and conforms to §4 (incl. `jti` format) | `PROOF_MALFORMED` |
| P9 | Proof signature verifies against Agent key | `PROOF_SIGNATURE_INVALID` |
| P10 | Proof `iss` == Grant `sub` | `PROOF_AGENT_MISMATCH` |
| P11 | Proof `grant` == Grant `id` | `PROOF_GRANT_MISMATCH` |
| P12 | Proof `aud` == RP DID | `PROOF_AUDIENCE_MISMATCH` |
| P13 | `iat` within window | `PROOF_EXPIRED` |
| P14 | `action_hash` == hash of submitted Action | `PROOF_ACTION_MISMATCH` |
| P15 | Action valid for its `type` | `ACTION_MALFORMED` |
| P16 | Some Capability matches `action.type` | `ACTION_NOT_AUTHORIZED` |
| P17 | All constraint keys known | `UNKNOWN_CONSTRAINT` |
| P18 | Currency authorized | `CURRENCY_NOT_AUTHORIZED` |
| P19 | `amount ≤ maxAmount` | `AMOUNT_EXCEEDS_AUTHORITY` |
| P20 | `resource` matches a pattern | `RESOURCE_NOT_AUTHORIZED` |

The normative text of this table, published at a stable URL, is the **profile document**; its SHA-256 is `protocol.profile_hash` in every receipt.

