# Stateful recurrence

Represent convolution and recurrent state in a hybrid decoder plan.

[View canonical HTML](https://pllm.run/sdk/build/operators/stateful-recurrence/)

Document ID: `pllm.docs.operators.stateful-recurrence`  
Release: `0.1.0`

Hybrid decoders declare convolution and recurrent state separately from key/value cache state. `causal_convolution` consumes prior convolution state while `convolution_state_update` produces the next bounded state. `gated_delta_rule` consumes normalized Q/K, value, decay, beta, and prior recurrent state; `gated_delta_state_update` records the corresponding state transition.

Separate result and state-transition operations avoid implicit multi-output graph edges. Their shared inputs and attributes bind both records to one semantic update. `rms_norm_gated`, `gated_delta_decay`, and `sigmoid` retain the surrounding gating equations.

Presence in a validated plan is not implementation coverage. Current compiler profiles fail closed on these operators.

## Python SDK example

```python
from pathlib import Path

from pllm import lower_model

fixture = Path("crates/pllm-models/tests/fixtures/Qwen3.5-4B-851bf6e-config.json")
plan = lower_model(fixture.read_bytes(), batch=1, max_input_tokens=16, max_new_tokens=4)
operators = {operation["operator"] for operation in plan.prefill["operations"]}
missing = [row["operator"] for row in plan.coverage().operators if row["level"] == "missing"]
assert {"causal_convolution", "gated_delta_rule", "gated_delta_state_update"} <= operators
assert "gated_delta_rule" in missing
```

API: [Python SDK objects and signatures](/sdk/reference/python/pllm/#objects-and-signatures)

Run this example from a PLLM source checkout; package installations do not include
the pinned Qwen3.5 fixture. This reports unsupported operators without executing them.
