# Changelog

All notable changes to Keyfob are documented here. The format is based on
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.1.1

Patch — the built-in ETS store keeps its own contract when it isn't running.

### Fixed

- **Reading from `Keyfob.Store.ETS` raised instead of answering `:error`.**
  The behaviour declares `get(key()) :: {:ok, value()} | :error`, but the
  implementation called `:ets.lookup/2` straight out, which raises on a table
  that does not exist — so the contract broke whenever the store was not
  running: during startup before the child begins, between a crash and the
  supervisor's restart, or in a host that never added it to a supervision
  tree. A caller cannot reasonably be asked to rescue a documented lookup.

- **`take/1`, `update/2` and `delete/1` exited instead of reporting.** They
  call a named GenServer, and a call to a process that is not alive exits. For
  operations that already have a failure value in the behaviour, that exit is
  strictly worse than the failure they declare: `take/1` backs `consume/2`, so
  an unreachable store crashed the caller rather than simply not signing
  anybody in — a 500 on a web login where "this link is invalid or has
  expired" was both the honest answer and the same outcome.

  They now return `:error` (`:ok` for `delete/1`, where an entry in a store
  that is gone is gone, and which runs as cleanup after a successful `take/1`
  where exiting would fail a flow that had already succeeded).

  `put/3` is deliberately unchanged and still fails loudly. It has no failure
  value in the behaviour, and inventing `:ok` for a write that did not happen
  would hand back a token nothing has stored — a request that cannot be
  approved, failing later and further from the cause.

## 0.1.0

Initial release.

### Added

- QR device-handoff login rendezvous: `create_request/1`, `peek/2`,
  `approve/3`, `deny/2`, `consume/2`, and the `topic`/`subscribe`
  helpers.
- Secret split — the QR-borne request token can never log anyone in; a
  separate one-time login token is minted at approval and delivered only
  to the waiting LiveView over PubSub.
- `Keyfob.Store` behaviour with a built-in single-node `Keyfob.Store.ETS`
  (serialized `update/2` + `take/1` for lost-update and single-use
  safety, background expiry sweep).
- `Keyfob.QR` inline-SVG renderer (via `eqrcode`) and headless
  `Keyfob.Components.panel/1` + `confirm_screen/1`.
- `Keyfob.Live` glue for the desktop panel.
- Telemetry for every transition.
