# Command policy `src/adapter/outbound/cache-redis/src/main/resources/redis-sdk/redis-command-policy.yml` is the single source of truth for what this SDK is willing to do with each Redis command. Official server metadata decides what a command *is*; this file decides what we allow. A command that is not classified there is refused. Adding a command therefore means editing that file, not writing code — and the edit is where the risk decision is made and reviewed. ## Fields | Field | Default | Meaning | | --- | --- | --- | | `risk` | required | `R1` routine, `R2` needs an explicit permit, `R3` administrative, `R4` never allowed | | `support` | required | `TYPED`, `ADVANCED_TYPED`, `RAW_ONLY`, `ADMIN_ONLY`, `VERSION_GATED`, `BLOCKED` | | `minimum-version` | `7.2` | lowest server version that carries the command | | `access` | derived from `support` | which ACL account may issue it | | `blocking` | `false` | occupies its connection until the server replies | | `optional-block` | `false` | the command also has a non-blocking form; only `XREAD` and `XREADGROUP` carry it | | `read-only` | `false` | never mutates the dataset | | `retry-safe` | `read-only` | may be retried after a failure that could have reached the server | | `may-be-ambiguous` | `!read-only` | a failure may leave the outcome unknown | | `timeout-profile` | derived | `FAST`, `COLLECTION`, `ADMIN`, `BLOCKING` | | `key-spec` | `1 1 1` | where the keys are, or `none`, or `movable` | | `required-policy` | – | the permit policy an R2 command demands | ## Rules the catalog enforces - An R2 `ADVANCED_TYPED` command must name the permit policy it requires. There is no R2 command that anyone may issue without an issued permit. - An R4 command must be `BLOCKED`, and an R3 command must be `ADMIN_ONLY`. The type system refuses the other combinations at load time. - A `BLOCKED` command carries no ACL account, so no path in the SDK can reach it. - A blocking command must use the `BLOCKING` timeout profile, and its request must declare a bounded server block — unless it also declares `optional-block`, which only the two stream reads do. - Deprecated command names stay `BLOCKED` even when the SDK offers their behaviour. The typed sorted-set ranges issue `ZRANGE ... BYSCORE|BYLEX|REV`, not `ZRANGEBYSCORE`, so what the guard was told and what reaches the wire are the same command. ## Where each support level is reachable from | Support | Reachable from | | --- | --- | | `TYPED` | the typed operations, no permit | | `ADVANCED_TYPED` | the typed operations, with the named permit | | `VERSION_GATED` | a capability bean that exists only when the probe found the feature | | `RAW_ONLY` | `sdk.raw`, and only with a deployment-registered approval | | `ADMIN_ONLY` | `sdk.admin`, read-only diagnostics only | | `BLOCKED` | nowhere |