# MandateRegistryV3 integration notes

V3 has not been deployed. The mandate registry was therefore hardened in place rather than preserving unsafe behavior.

## Required integration changes

- Before a module can call `consume`, the registry owner must call
  `setModuleAuthorization(module, true)`. `consume` rejects all other callers with
  `UnauthorizedModule`.
- A consuming module must authenticate the actor that initiated its action and pass that
  address in the final `operator` argument to `consume`. The registry compares it to the
  operator snapshotted at registration. A module must not accept an arbitrary operator
  address from an untrusted request.
- `registerMandate` now requires a local, deployed `IERC8004IdentityRegistry` at
  `identityRegistry`, the current `identityRegistryChainId`, active principal and operator
  agents, matching principal/operator/beneficiary fields, and operator authorization for
  the principal agent.
- A nonce is now a registration nonce: it is reserved by `(principal, nonce)` after a
  successful registration and cannot register a different mandate. It is not consumed on
  every permitted action, because one mandate can authorize multiple actions until expiry
  or cap exhaustion.
- The four scope arrays are each limited to 32 items:
  `allowedActions`, `prohibitedActions`, `allowedContracts`, and `allowedSelectors`.

## API and behavior changes

- `MandateState` now returns identity, principal, operator, beneficiary, time, nonce,
  chain, and protocol-version metadata in addition to mutable use state. Consumers that
  destructure the returned struct must update their ABI bindings.
- `isActive` now also enforces the registered `notBefore`/`notAfter` window.
- `registerMandate` accepts only `protocolVersion == "3.0.0"`, an unexpired, ordered time
  window, and identity-bound metadata.
- `revokeMandate(bytes32)` is the preferred revocation function. The former
  `revokeMandate(bytes32,address)` overload remains only for source compatibility; its
  address must equal the immutable registered principal and is never used for authorization.
- The `consume` ABI keeps the same argument types. Its final argument is named `operator`
  (formerly `caller`) and is checked against immutable registered state; access is now also
  module-allowlisted.

Owner allowlist updates emit `ModuleAuthorizationUpdatedV3`.

## Validation

- `forge fmt --check`
- `forge build`
- `forge lint contracts/mandate/MandateRegistryV3.sol test/mandate/MandateRegistryV3.t.sol`
- `forge test --force --match-contract MandateRegistryV3Test -vv` (16 passing)
- `forge test -vv` (58 passing)
