# Changelog All notable changes to this project are documented here. The format is based on [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). ## [0.2.0] - Unreleased ### Added - **`legend`** on every result — abbreviation → French meaning (`PER`→`Personne`, `M`→`Masculin`), safe to forward to a downstream LLM so it understands the placeholder tokens. Backed by a built-in `DEFAULT_LEGEND` so coverage is guaranteed even if the model omits entries. - The default prompt now lets the model **coin new uppercase abbreviations** for entities/attributes/ context it discovers and return their meanings in `legende`. - `PatternDef.meaning` — optional human label for a tag, surfaced in the `legend`. `presets.swiss`/ `presets.generic` ship French meanings. - `AnonymizationError` (exported) — thrown when anonymization can't complete and no fallback exists; carries the originating error in `.cause`. ### Changed (breaking) - **Regex fallback is now opt-in.** `patterns` no longer defaults to `presets.swiss`. With no fallback, an LLM failure throws `AnonymizationError` (fail-closed) and the pre-filter is bypassed. At least one of `llm` or `patterns` is required, or the constructor throws. - `AnonymizationResult` gained a required `legend` field; `LlmProvider.anonymizeBatch` returns `legend`. - `anonymizeChunks(chunks, seed)` — `seed` is now `{ mapping, legend? }` (was the bare mapping) and the return includes `legend`. ## [0.1.0] - Unreleased ### Added - Initial public release. - `Anonymizer` — pre-filter → LLM → regex fallback, bidirectional validation, deterministic coreference, and de-collision across question and retrieved chunks (`anonymize`, `anonymizeChunks`, `deanonymize`). - `makeStreamDeanonymizer` — streaming-safe de-anonymization that never leaks a split placeholder. - `openAICompatibleProvider` — pluggable LLM detection over any OpenAI-compatible Chat Completions API. - `presets.swiss` and `presets.generic` regex pattern sets; fully configurable custom patterns. - Regex-only mode (no LLM provider required). - `PatternDef.validate` — optional second-stage predicate to cut false positives; `presets.generic` uses it for a Luhn check on credit-card candidates, and de-overlaps its phone/date/IP patterns. - `openAICompatibleProvider` retries transient failures (network/timeout/429/5xx) via `retries` and `retryDelayMs` options; non-transient 4xx and malformed responses are not retried. - Hardened the `nameHint` heuristic: `g`/`y` flags are stripped internally so `.test()` is stateless.