# Changelog
The format follows [Keep a Changelog](https://keepachangelog.com/) and the
project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased]
### Added
- Initial extraction as a standalone library.
- DAG builder with cycle detection (`Baton`, `Baton.DAG`).
- Node-backed state store (`workflow_nodes`) — no `oban_jobs.meta` mutation.
- Worker macros: `Baton.Worker`, `Baton.LLMWorker`.
- Dependency gating, completion-triggered rescheduling, retry idempotency.
- Multi-model fan-out + synthesis (`Baton.MultiModel`).
- `Baton.Plugin` (Oban plugin) for orphan rescue and failure telemetry.
- `Baton.Pricing` behaviour + reference implementation.
- Per-step stats and context-window capture (optional features).
- Versioned schema via `Baton.Migration`.
- Terminal `{:workflow_finished, _}` PubSub event (and
`[:baton, :workflow, :finished]` telemetry) when a workflow's last step
settles, with `:completed`/`:failed` outcome and the failed step names
(`Baton.Completion`).
- `Baton.Plugin` backstops that notification for workflows that settle
without a clean worker return (hard crash / Oban kill).
- Schema **v2**: `workflow_completions` table — an atomic claim guaranteeing the
finished notification fires exactly once across the worker and plugin paths.
- Configurable LLM client for `Baton.Debug.call_llm/3`
(`config :baton, llm_client: ...`).
- Opt-in data retention: `Baton.Plugin` can prune Baton's own tables
(`workflow_nodes`, `workflow_step_stats`, `workflow_debug_logs`,
`workflow_completions`) once their Oban job is pruned, with an optional shorter
age cap for `workflow_debug_logs` (`prune: true`, `debug_log_max_age:`).
See `Baton.Retention`.
### Changed
- `Baton.Migration.up/down` now default to the latest schema version when
`:version` is omitted.
- `Baton.MultiModel.configure/2` model injection now happens inside
`Baton.add/4`, so the documented `configure |> Baton.add` usage works.
`Baton.MultiModel.add/4` is deprecated (now a passthrough).
### Removed
- `Baton.Stats.record_cache_hit` (dead code — was never called).
### Fixed
- `Baton.LLMWorker` no longer injects the Oban Pro-only `:kill_timeout`
option, which made `use Baton.LLMWorker` fail to compile under Oban OSS.
Replaced with a configurable `timeout/1` callback (`:timeout` option, default
`:infinity`).
- PubSub broadcast failures no longer crash workers — broadcasting is now
best-effort over telemetry (`Baton.Events`).
- `Baton.LLMWorker` stores the step result before recording stats and no
longer raises on an unexpected `llm_usage` key, preventing a wasted/repeated
LLM call on retry.