Files
anonymizer/CHANGELOG.md
Mobiletic 81b6b03239 feat: harden generic preset, add LLM retry, and finish tooling/docs
- PatternDef.validate + Luhn-gated credit-card detection; de-overlap the
  generic phone/date/IP patterns; presets.swiss unchanged (production behavior)
- strip g/y flags from nameHint so .test() is stateless (latent footgun)
- openAICompatibleProvider: bounded retry on transient failures (network /
  timeout / 429 / 5xx), configurable via retries + retryDelayMs
- eslint + prettier + vitest coverage (97%); CI runs lint/format/coverage
- docs: README badges + new-option docs, SECURITY.md, issue/PR templates

26 tests passing; build emits ESM+CJS+types.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:03:20 +01:00

1.4 KiB

Changelog

All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.1.0] - Unreleased

Added

  • Initial public release, extracted from Mobiletic's production Swiss-nLPD chatbot.
  • 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.