CHANGELOG.md

# Changelog

## 0.7.1

### Changed

- Bumped `foil` dependency from `0.1.3` to `0.1.4` (CI/infrastructure
  refresh; `error/0` type tightened; macro-based DRY refactor with
  no perf change).
- Bumped `metal` dependency from `0.1.1` to `0.1.2` (CI/infrastructure
  refresh; one `system_continue/3` spec fix from `ok` to
  `no_return()`).

No source changes in shackle itself. Behaviour, API, and benchmarks
are identical to 0.7.0.

## 0.7.0

### Breaking

- Minimum supported Erlang/OTP version is now **25**. OTP 21–24 are no longer tested and the compatibility code paths for those releases have been removed.

### Changed

- Replaced the `granderl` dependency with **`knot`** (in-house C NIF
  using wyrand). `shackle_utils:random/1` now calls `knot:uniform/1`
  — same signature, same range guarantees, no behavioural difference
  at call sites. `granderl 0.1.5` on hex.pm fails to build on OTP 27+
  (its `preamble.sh` invokes `erl -noshell -s init stop -eval ...`
  with options in an order that causes the node to terminate before
  `-eval` runs, leaving `ERTS_INCLUDE_DIR` empty); the fix exists in
  granderl's master but its hex package is not under our ownership,
  so we couldn't release a fix. `knot` is a tiny C NIF (~80 LOC)
  that builds correctly on every supported OTP and matches
  hand-written C dispatch overhead. Benchmarks (Apple Silicon, OTP
  29, 10M iterations of `uniform(254)`, median of 5 runs):

  | conc | rand:uniform/1 | granderl:uniform/1 | knot:uniform/1 |
  |---|---|---|---|
  | 1   | 34 ns | 13 ns  | **12 ns**  |
  | 8   | 9 ns  | 7 ns   | **3.3 ns** |
  | 32  | 6 ns  | 8 ns   | **3.2 ns** |
  | 128 | 6 ns  | 8.5 ns | **3.1 ns** |

- CI matrix now covers OTP 25, 26, 27, and 28; `actions/checkout` upgraded to v5.
- `telemetry` dependency bumped from 1.2.1 to 1.4.2.
- README documents the full set of telemetry events shackle emits and their measurement shapes.

### Removed

- `ATOMICS`, `DECENTRALIZED_COUNTERS`, `ETS_TAKE`, and `SSL_HANDSHAKE` platform_define macros.
- `OTP_RELEASE` ifdef block in `shackle_internal.hrl` and the associated pre-OTP-21 logger / stacktrace fallbacks.
- `shackle_utils:info_msg/3` and `shackle_utils:warning_msg/3`.
- ETS-based fallback path in `shackle_status` (the persistent_term + counters path is now unconditional).

## 0.6.20

See git history for details.