# Changelog

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

Watch names are the event ids consumers route on, and the event payload is
versioned by its `"schema"` field. A change to either is a breaking change and
will be called out here.

## [Unreleased]

## [0.1.0]

Initial release. Ships signal tiers 0 through 2; tracing is deliberately out of
scope.

### Added

- `use Kepler` and the `watch` DSL: `source`, `measure`, `filter`, `enrich`,
  `recent`, `severity`, `sink`, `meta`, and `fire`.
- **Crash attribution.** `source crash_report: :any` and
  `source supervisor_report: :child_terminated` deliver OTP crash and
  supervisor reports, with `enrich` pulling the dying process's state, last
  message, stacktrace, and `Logger` metadata into the event. One crash produces
  one event despite OTP emitting three reports for it.
- A two-part event contract: a small, fully-required core (`id`, `node`,
  `watch`, `timestamp`, `severity`, `state`) plus a best-effort `context` map
  whose inapplicable keys are absent rather than null.
- Named sinks with per-watch routing (`sink :siem`), and a `guarantee:` key
  declaring `:best_effort` or `:at_least_once`. Only `:best_effort` is
  implemented; asking for `:at_least_once` warns at boot and delivers
  best-effort.
- An optional `c:Kepler.Sink.format/1` callback, so a sink's wire format is
  replaceable without reimplementing its transport.
- Compile-time checking of every declaration — unknown measurements, unknown
  identifiers in conditions, duplicate watch names, and cycles between
  conditions are build failures.
- Tier 0 sources: `system_monitor:`, with graceful yielding when another
  process already holds the node's single system monitor.
- Tier 1 sources: `telemetry:`, with `:count`, `:rate`, `:sum`, `:average`, and
  `percentile:` aggregates backed by lock-free counters and a log-linear
  histogram.
- Tier 2 sources: `process:` and `vm:`, sampled from a declared watchlist on
  the tick.
- Composite conditions across watches, evaluated in dependency order.
- `sustained:` and `cooldown:` debouncing as part of the declaration, plus
  optional `resolve: true` notices.
- Ring buffer capture (`recent`), so an event carries the observations around it.
- `Kepler.Sink.Webhook` with HMAC-SHA256 signing and TLS verification, and
  `Kepler.Sink.Callback` — two implementations rather than three, so the
  behaviour is shaped by real use rather than guessed at in three directions.
- `Kepler.Transport` for plugging in an HTTP client you already run.
- Bounded, non-blocking emission with a configurable drop policy. An event
  routed to several sinks is delivered to all of them concurrently and in
  isolation: a sink that raises, exits, or wedges is recorded as that sink's
  failure and cannot stop its siblings. A sink that stops responding is killed
  after `:delivery_timeout`.
- `Kepler.Budget`: self-measured overhead and automatic shedding.
- `Kepler.status/0`, `Kepler.watches/0`, `Kepler.recent/1`, `Kepler.tick/0`,
  and `Kepler.drain/1` for introspection and testing.

[Unreleased]: https://github.com/houllette/kepler/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/houllette/kepler/releases/tag/v0.1.0
