# `Relyra.Metadata.Cadence`
[🔗](https://github.com/szTheory/relyra/blob/v1.1.0/lib/relyra/metadata/cadence.ex#L1)

Pure cadence resolver for Phase 21 scheduled metadata refresh.

The 1-hour hard floor is BAKED IN here per D-14 (InCommon Federation
Metadata Registration Practice Statement: ≤1 refresh per relying party
per hour). A future enum revision that adds a more aggressive preset
cannot bypass the floor.

Pure: no I/O, no Ecto, no telemetry. Deterministic-with-jitter
(`Enum.random/1` is the only nondeterminism source).

# `cadence_seconds`

```elixir
@spec cadence_seconds(atom()) :: non_neg_integer()
```

# `cadence_values`

```elixir
@spec cadence_values() :: [atom()]
```

# `next_refresh_at`

```elixir
@spec next_refresh_at(atom(), DateTime.t()) :: DateTime.t()
```

Computes the next refresh time given a cadence preset and a base time.

- Applies ±15% jitter ONCE per scheduling decision (D-12: persisted, not
  recomputed on tick — callers MUST persist the returned timestamp on
  `MetadataSource.next_refresh_at` rather than recomputing each tick).
- Enforces the 1-hour InCommon hard floor (D-14).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
