@@ -7,6 +7,94 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
88## [ Unreleased]
99
10+ ### Internal 0.5.11 milestone (not published, 2026-08-07)
11+
12+ The FathomDB 0.8 milestone: the engine migration and its legacy-file guard,
13+ provenance-keyed storage with engine-owned projections, bounded readers,
14+ engine-served log search (#11 ), per-client erasure, and TUI ballast
15+ (#24 , #27 , #28 ). Everything below ships publicly with the next published
16+ release; the breaking FathomDB change applies only to ` db ` -extra users.
17+
18+ ### Added
19+
20+ - ** TUI: failover audit trail (#24 ).** The model detail pane shows the recent
21+ failovers involving that model (timestamp, original → target, reason) from
22+ an incremental JSONL tail, and the Overview status line counts failovers in
23+ the last 5 minutes — what * actually happened* , alongside the configured
24+ chain the models table already shows.
25+ - ** TUI: provider-wide rate-limit escalation (#27 ).** ` impacted_clients ` (a
26+ live-only value the separate-process TUI cannot compute from its replica)
27+ is now part of the admin provider snapshot; the providers table badges the
28+ Impacted cell with ` ⚠ESC ` at the escalation threshold, the provider detail
29+ pane names the impacted clients and whether escalation is ongoing, and a
30+ ` provider_escalation ` alert rule fires on the event itself.
31+ - ** TUI: Gemini response-mode distribution (#28 ).** Provider and client detail
32+ panes show mode percentages instead of raw counts, with a skew flag when a
33+ single mode exceeds 80% of a meaningful sample (≥10 recent responses).
34+
35+ - ** Per-client erasure (CLI + admin API).** `airlock admin erase-client
36+ <client-id > --confirm <client-id >` and ` POST
37+ /airlock/admin/clients/{client_id}/erase` remove every FathomDB row whose
38+ provenance is that authenticated client id. Loopback-only (like
39+ ` force_quarantine ` ), audited with the full ` EraseReport ` in the
40+ ` admin_action ` record, idempotent, and honest about failure: a partial
41+ erasure answers HTTP 409 with the obligation outstanding and is never
42+ reported as done. ** Scope:** this erases the search/analysis store only —
43+ JSONL logs are untouched and governed separately by ` AIRLOCK_MAX_LOG_DAYS ` ;
44+ a user-facing deletion obligation requires both.
45+ - ** Log search served by the engine (#11 ).** ` search_request_logs ` exposes
46+ FathomDB's search over the FTS projections (error text, messages, response
47+ text), and the advisor gains a ` search_logs ` tool on the same seam. The
48+ result labels itself honestly: ` hybrid ` only when dense retrieval could
49+ actually contribute; ` lexical_only ` with the reason otherwise (the normal
50+ path here — no embedder is configured); the advisor's JSONL fallback is
51+ labelled ` substring ` . A degraded result is never presented as hybrid, and a
52+ hybrid result carries ` soft_fallback ` when a branch could not contribute.
53+
54+ ### ⚠️ Breaking
55+
56+ - ** FathomDB migrated to 0.8.x (` fathomdb>=0.8.21,<0.9 ` ).** The 0.3.x store is
57+ abandoned with no migration path: Airlock now refuses to open a 0.3.x database
58+ file (naming the file and the reason) rather than letting 0.8.x silently adopt
59+ it, and the default database filename moved from ` airlock.db ` to
60+ ` airlock-fathom.db ` so an existing state directory can never be adopted by
61+ accident. Old files are left in place; their records remain in the JSONL logs.
62+
63+ ### Changed
64+
65+ - The opt-in remote analyzer executor defaults to ` claude-sonnet-5 `
66+ (was ` claude-sonnet-4-5 ` ); ` AIRLOCK_ANALYZER_REMOTE_MODEL ` still overrides.
67+ Owner decision — this is a paid path.
68+ - The Fathom request logger writes 0.8.x dict batches with a mandatory
69+ ` source_id ` on every row: the ** authenticated client ID** (` key:<last8> ` ),
70+ stamped by the guardian at pre-call from the validated bearer key and always
71+ overwriting any client-supplied value — never the forgeable
72+ ` X-Airlock-Client ` header. Unauthenticated traffic collapses to the
73+ ` no_client ` sentinel, so no write path can produce an unerasable row.
74+ ` source_id ` is the axis per-client erasure will target.
75+ - RequestLog projections (filterable/rankable fields, FTS over error text,
76+ messages, and response text) are declared to the engine via
77+ ` configure_projections ` ; Airlock no longer maintains any derived index.
78+ No vector projection is declared — no embedder is configured, by design.
79+ - ` api/queries.py ` reads through ` fathomdb.read ` with an explicit ` ReadView `
80+ (active rows only) and the typed ` fathomdb.errors ` hierarchy — the
81+ ` AttributeError ` -based capability sniffing and silent empty-list fallbacks
82+ are gone.
83+ - ** No datastore read is unbounded anymore.** ` get_request_logs ` /
84+ ` get_billing_metrics ` default to the shared 50k ` DATASTORE_QUERY_LIMIT `
85+ (the old default was ` limit=1000000 ` — a limit in name only) and report
86+ truncation instead of dropping it: billing metrics carry
87+ ` truncated ` /` limit_hit ` , the TUI Overview marks a partial cost sum with
88+ ` (partial) ` , and the advisor's ` get_recent_errors ` reports the datastore
89+ window the same way it reports the JSONL one.
90+
91+ ### Removed
92+
93+ - ` _ensure_vector_stub_table ` (a 0.3.1 write-path workaround; 0.8.x owns its
94+ indexes).
95+ - ` search_logs ` and its Python-side substring fallback, superseded by the
96+ engine's hybrid search (#11 ).
97+
1098## [ 0.5.10] — 2026-08-05
1199
12100The first published release since 0.5.8. It carries ** two milestones** : the
0 commit comments