# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.3.1] - 2026-07-08

<!-- generated by git-cliff -->

## [0.3.0] - Unreleased

### Breaking changes

- Config schema `config_version` is `2.0.0`. The dynamic plugin DTO uses camelCase top-level fields: `baseUrl`, `timeoutMs`, `outputTemplates`, `batchEndpoint`, `adaptive`, and `token`.
- Adaptive mode requires both an `adaptive` block and `batchEndpoint`. Batched delivery always emits the canonical Pattern C `BatchEnvelope` to that endpoint.

### Features

- Adaptive mode opts in via the `adaptive` config block (`adaptiveMinBatchSize`, `adaptiveMaxBatchSize`, `adaptiveWindowSize`, `adaptiveBatchTimeoutMs`) and coalesces items into `BatchEnvelope` payloads. Each batch item is a rendered per-query body template, or the default `DefaultChangeNotification` envelope when no body template applies; `outputTemplates` may be combined with adaptive batch mode (only the body template applies to batched items, since a batch is a single POST).
- Configuration is validated at construction: `HttpReactionBuilder::build()` validates base URL, timeout, adaptive ranges, batch endpoint path, HTTP methods, headers, templates, and route keys.
- Per-query routes resolve by full query id, then by the **last dotted segment** of the query id (`routes.my_query` matches a wire id of `source.my_query`), then by the shared default template.
- Template render context includes `query_id`, `query_name`, `timestamp`, `metadata`, `operation`, and the applicable `before`, `after`, and `data` values.
- New `from_query` builder alias for `with_query`.
- Render-error fallback is per template kind: URL failures use `/changes/{queryId}`, body failures use the default envelope on the configured route, and invalid header values drop only that header.
- HTTP delivery retries transient failures up to three attempts and logs permanent HTTP failures before continuing.
- New `HttpReactionBuilder` helpers: `with_default_template`, `with_query_template`, `with_output_templates`, `with_adaptive`, `with_batch_endpoint`, and `with_recovery_policy`.
- Descriptor exposes named OpenAPI sub-schemas and `SchemaUiAnnotator` groupings for the config.
- Output wire format published as a standalone JSON Schema at `schema/output.schema.json`, generated from the Rust types in `src/output.rs` and kept in sync by `make schema` (verify) / `make update-schema` (regenerate).
- **Resumable delivery (at-least-once).** The reaction now advances a per-query checkpoint driven by successful (acked) delivery: in standard mode after each result is delivered, and in adaptive mode after each coalesced batch POST succeeds. On restart the host `ReactionManager` forwarder skips results at or below the persisted checkpoint, so the reaction only persists checkpoints and relies on the framework for dedup.
- **Recovery policy** is configurable per instance via `HttpReactionBuilder::with_recovery_policy` or the descriptor `recoveryPolicy` field (`strict` | `auto_skip_gap`). Under `strict` (default) a sustained delivery failure fail-stops the reaction (`Error`) so the un-acked work replays from the query outbox on restart; under `auto_skip_gap` the failed batch is skipped and the reaction keeps running. Auth/permission rejections (401/403/407) are treated as sustained failures (subject to the recovery policy), **not** dropped — so an expired or rotated credential cannot silently lose events. Only genuinely permanent failures (other 4xx such as 400/404/405/422, SSRF-blocked/unresolvable URLs, invalid method/auth-token config) are dropped and never fail-stop.

<!-- generated by git-cliff -->

## [0.2.5] - 2026-06-16

### Miscellaneous Tasks

- Updated the following local packages: drasi-core, drasi-lib, drasi-plugin-sdk

<!-- generated by git-cliff -->

## [0.2.4] - 2026-06-11

### Miscellaneous Tasks

- Updated the following local packages: drasi-core, drasi-lib

<!-- generated by git-cliff -->

## [0.2.3] - 2026-06-03

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib, drasi-plugin-sdk

<!-- generated by git-cliff -->

## [0.2.2] - 2026-05-21

### Features

- Secret store plugin system with file, keyring, and Azure Key Vault providers ([#460](https://github.com/drasi-project/drasi-core/issues/460))

### Miscellaneous Tasks

- Normalize Apache-2.0 license headers across all .rs files ([#462](https://github.com/drasi-project/drasi-core/issues/462))

<!-- generated by git-cliff -->

## [0.2.1] - 2026-05-20

### Features

- **plugin-sdk:** Add SchemaUiAnnotator and x-ui annotations for plugin UI forms ([#421](https://github.com/drasi-project/drasi-core/issues/421))

<!-- generated by git-cliff -->

## [0.2.0] - 2026-05-12

### Bug Fixes

- Lossless config persistence — preserve ConfigValue envelopes, camelCase keys, and passwords ([#422](https://github.com/drasi-project/drasi-core/issues/422))

### Miscellaneous Tasks

- Release ([#446](https://github.com/drasi-project/drasi-core/issues/446))

<!-- generated by git-cliff -->

## [0.1.17] - 2026-05-11

### Bug Fixes

- Lossless config persistence — preserve ConfigValue envelopes, camelCase keys, and passwords ([#422](https://github.com/drasi-project/drasi-core/issues/422))

<!-- generated by git-cliff -->

## [0.1.16] - 2026-04-28

### Miscellaneous Tasks

- Updated the following local packages: drasi-plugin-sdk

<!-- generated by git-cliff -->

## [0.1.15] - 2026-04-27

### Miscellaneous Tasks

- Updated the following local packages: drasi-core, drasi-plugin-sdk, drasi-lib

<!-- generated by git-cliff -->

## [0.1.13] - 2026-04-23

### BUG

- Aggregating results missing in reactions ([#322](https://github.com/drasi-project/drasi-core/issues/322))

<!-- generated by git-cliff -->

## [0.1.11] - 2026-03-16

### Miscellaneous Tasks

- Updated the following local packages: drasi-core, drasi-lib, drasi-plugin-sdk

<!-- generated by git-cliff -->
## [0.1.10] - 2026-03-09

### Miscellaneous Tasks

- Updated the following local packages: drasi-plugin-sdk

<!-- generated by git-cliff -->
## [0.1.9] - 2026-02-26

### Miscellaneous Tasks

- Updated the following local packages: drasi-core, drasi-lib

<!-- generated by git-cliff -->
## [0.1.8] - 2026-02-13

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
## [0.1.7] - 2026-02-11

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
## [0.1.6] - 2026-02-10

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
## [0.1.5] - 2026-02-07

### Miscellaneous Tasks

- Updated the following local packages: drasi-core

<!-- generated by git-cliff -->
## [0.1.4] - 2026-02-05

### Miscellaneous Tasks

- Updated the following local packages: drasi-lib

<!-- generated by git-cliff -->
<!-- generated by git-cliff -->
