Update `AiAgentChangesLogs.md` in project root directory on each completion. Include timestamp, project state, my prompt and your changes. Be simple when you are simply fixing a small bug. Be concise and conclusive when you are updating large portion of the codebase. Sample format: 
```markdown
## 2026-01-01 14:00
State: <the state of the project linked to this section>

<My github username>: <a summary of my prompt, shorten it if too long>
<!-- you may want to use git to check my git username, since there are multiple people working in the same branch -->

Ai: <a summary on what have you changed? Especially the mechanism, dependencies, schemas, etc...>
```

## 2026-06-26 (Qdrant version-gate skip) — branch fix/qdrant-check-compatibility — 1.6.4 -> 1.6.5
State: part of the keble.backend discovery report-hang fix (memory-step calls had no timeout).

zma: discovery run wedged ~1h on a report's memory step; full fix includes the Qdrant 1.16-vs-1.18 mismatch.

Ai: pass `check_compatibility=False` to all four Qdrant client constructions in
`keble_db/session.py` (sync + async, new-instance + cached). A client(1.16)/server(1.18)
minor drift previously logged a warning AND ran a construction-time version probe on every
client build — avoidable risk. The mismatch is benign for our ops; backend additionally
wraps every Qdrant call in `asyncio.wait_for`, so a sick server fails fast regardless. No
API/schema change. Rebuilt wheel bundled into `keble.backend/dependencies/`.

## 2026-06-25 (Decimal -> Decimal128 at the Mongo CRUD seam) — branch fix/mongo-decimal128-encoding — 1.6.3 -> 1.6.4
State: hotfix; positioning UNEXPECTED_PROCESSING_ERROR was a `bson.InvalidDocument: cannot encode Decimal`.

zma: positioning study failed with UNEXPECTED_PROCESSING_ERROR; investigate + find the systematic issue
(lack of tests / side-effect comments). Root cause: keble-segmenting `OptionNumericRange.lower/upper` are
`Decimal`, and pymongo cannot BSON-encode a raw Python Decimal — so every PRICING dimension with a
numeric_range crashed at the Mongo write. Fix at the keble-db chokepoint (owner choice).

Ai: made `Decimal` a first-class Mongo-safe type at the single seam every doc flows through.
- New `encode_decimal128`/`decode_decimal128` recursive walkers in `keble_db/crud/mongo_util.py`
  (Decimal<->bson.Decimal128; dict/list/tuple; idempotent; leaves ObjectId/datetime/str/None untouched).
- Wired into `MongoCRUDBase` (`crud/mongo.py`): encode on EVERY write
  (create/acreate/create_multi/acreate_multi/update/aupdate/update_multi/aupdate_multi), decode on every
  model-returning read via a new `_to_model` (first/afirst/get_multi/aget_multi). Raw `*_doc` readers
  unchanged. Side-effect comments added on all seams.
- Tests (`tests/test_crud/test_mongo_decimal128.py`): walker unit tests + REAL-Mongo round-trip (Decimal
  scalar + nested list of Decimal bounds incl. open-ended None) for acreate/aupdate/afirst — the
  persistence coverage that the mock-only P3 tests lacked. Existing Mongo CRUD tests still green (the 3
  red `test_qdrant_*` are pre-existing Qdrant infra, unrelated).
- No data migration: pre-fix numeric_range writes all crashed, so no legacy raw-Decimal docs exist.

## 2026-05-07 16:34 CST
State: branch `fix/sql-pool-limits`; `keble-db 1.6.3` bounds SQLAlchemy connection pools.

zma:
- Investigate production FastAPI login failures with PostgreSQL
  `FATAL: sorry, too many clients already`.
- Fix and merge to main after the production line is available.

Ai:
- Replaced hardcoded SQLAlchemy pool sizes (`1000` sync, `100` async) with
  bounded defaults (`3` pool + `2` overflow per engine/process).
- Added `DbSettingsABC` pool override properties plus startup validation for
  pool size, overflow, recycle, and timeout values.
- Added focused tests proving sync and async SQL engines follow configured pool
  limits before any database connection is opened.

## 2026-04-23 13:59 CST
State: branch `refactor/milestone-rebaseline-docs`; `keble-db` improve docs now keep `AgentDbDeps` DB/progress-only.

zma:
- Implement the milestone rebaseline plan.
- Clarify queue publication should not be added to shared DB deps.

Ai:
- prepended `improve.README.md` with the current DB deps source of truth
- documented `AgentDbDeps` as DB handles plus optional shared progress only
- clarified no Celery, broker client, or enqueue callable belongs in `keble-db`
- left code unchanged

## 2026-04-23 11:44 CST
State: branch `refactor/agent-deps-build-progress`; `keble-db 1.6.2` owns the outer agent progress task field.

zma:
- Move unified `progress_task` to the outer agent deps scope.
- Avoid nested package-specific progress task fields such as `deps.segmenting.progress_task`.

Ai:
- added optional `AgentDbDeps.progress_task`
- documented that package deps should inherit `AgentDbDeps` and keep package state under typed namespaces only
- added `tests/test_agent_deps.py` coverage
- bumped manifests to `1.6.2`
- verification:
  - `uv run pytest tests/test_agent_deps.py tests/test_api_deps.py -q` -> `5 passed`
  - `uv build --wheel` -> `dist/keble_db-1.6.2-py3-none-any.whl`

## 2026-02-12 22:27
State: Added stronger generic typing to Redis async cache helper; Redis-related tests pass.

zhenhao-ma: Check uncommitted changes and optimize `acache_or_get` typing so `args` and `kwargs` follow `getter_func`.

Ai: Updated `ExtendedAsyncRedis.acache_or_get` with `ParamSpec` + `TypeVar` (`Callable[P, Awaitable[T]]`, `*args: P.args`, `**kwargs: P.kwargs`) so call-site arguments are type-checked against `getter_func`. Added typed `serializer_func`, explicit return type, safe cast on cache hit, and simplified expiry selection to typed key access. Ran `pytest -q tests/test_redis_fix.py tests/test_redis_decode.py tests/test_redis_decode_issue.py` (13 passed).

## 2026-02-13 10:18
State: Added comprehensive Redis cache helper and encoder test coverage; targeted Redis/encoder suites are green.

zhenhao-ma: Redo after merge and create full test suite for `acache_or_get` and `jsonable_encoder`.

Ai: Added `tests/test_wrapper/test_redis_acache_or_get.py` with end-to-end coverage of cache-miss/hit behavior, serializer path, `None` non-caching behavior, custom TTL handling, and `jsonable_encoder` serialization roundtrip with typed model reconstruction. Added `tests/test_jsonable_encoder.py` covering pydantic alias/exclude behavior, dataclass+datetime/UUID/path encoding, custom encoders, SQLAlchemy-safe key filtering, include/exclude filtering, and iterable normalization. Validation: `pytest -q tests/test_wrapper/test_redis_acache_or_get.py tests/test_jsonable_encoder.py` (11 passed), plus broader related run `pytest -q tests/test_wrapper/test_redis.py tests/test_redis_decode.py tests/test_redis_decode_issue.py tests/test_redis_fix.py tests/test_encoder.py tests/test_wrapper/test_redis_acache_or_get.py tests/test_jsonable_encoder.py` (29 passed).

## 2026-02-21 11:33
State: FastAPI Neo4j dependencies now provide transaction-scoped objects; related dependency tests and Neo4j CRUD tests are green.

zhenhao-ma: Fix Neo4j dependency shape in this library.
- Keep current API names for Neo4j deps.
- Return Neo4j transactions instead of Neo4j sessions.
- Update return typing accordingly to address async shared-session concurrency issues.

Ai: Refactored `ApiDbDeps.get_neo4j_session`, `get_aneo4j`, and `get_async_neo4j_session` to open session context internally and yield `Transaction` / `AsyncTransaction` instead of `Session` / `AsyncSession`. Updated `AgentDbDeps.aneo4j` type to `AsyncTransaction`. Added unit tests in `tests/test_api_deps.py` to validate sync/async Neo4j dependencies yield transaction objects and preserve alias behavior. Updated `README.md` to document Neo4j dependency behavior change. Validation: `pytest -q tests/test_api_deps.py` (4 passed), `pytest -q tests/test_crud/test_neo4j.py` (12 passed).

## 2026-02-21 11:41
State: Neo4j async dependency/session contract split is now explicit: session-named APIs return sessions, while `get_aneo4j` defaults to transaction.

zhenhao-ma: Adjust Neo4j contract after previous change.
- Keep session-style APIs (e.g. `get_async_neo4j_session`) returning sessions.
- Update `session.py` and fully scan library so `get_aneo4j` defaults to returning a transaction.

Ai: Updated `Db.get_aneo4j` in `keble_db/session.py` to be async and default to `AsyncTransaction` (`as_transaction=True`), while allowing explicit session return with `as_transaction=False`. Kept `Db.get_async_neo4j_session` as session-returning and made `ApiDbDeps.get_neo4j_session` / `ApiDbDeps.get_async_neo4j_session` yield sessions again; `ApiDbDeps.get_aneo4j` continues yielding transactions. Updated async Neo4j CRUD fixture to use `db.get_async_neo4j_session` for session-based CRUD calls, added dedicated tests for `Db.get_aneo4j` default/override behavior (`tests/test_session_neo4j_async.py`), refreshed API dep tests, and updated README behavior notes. Validation: `pytest -q tests/test_api_deps.py tests/test_crud/test_neo4j.py tests/test_session_neo4j_async.py` (18 passed), `pytest -q` (175 passed).

## 2026-02-21 21:45
State: Neo4j async dependency contract now exports `AsyncDriver` instead of async transaction; full suite remains green.

zhenhao-ma: Correct previous Neo4j direction based on latest commit context.
- `get_aneo4j` should export `AsyncDriver` (not transaction).
- Re-apply across library based on previous conversation and current branch state.

Ai: Reworked Neo4j async contract to driver-first. `Db.get_aneo4j` in `keble_db/session.py` now returns `AsyncDriver` directly (sync method, default `new_instance=False`), and transaction overload logic was removed. `ApiDbDeps.get_aneo4j` now yields an `AsyncDriver` from `Db.get_aneo4j(new_instance=False)`, while session-named APIs continue to yield sessions. Updated `AgentDbDeps.aneo4j` typing to `AsyncDriver`, refreshed README Neo4j dependency notes, and updated tests (`tests/test_api_deps.py`, `tests/test_session_neo4j_async.py`) to validate driver export behavior. Validation: `pytest -q tests/test_api_deps.py tests/test_session_neo4j_async.py tests/test_crud/test_neo4j.py` (18 passed), `pytest -q` (175 passed).

## 2026-02-23 01:01
State: Fixed async Neo4j DI lifecycle for request isolation.

zhenhao-ma: patch core issue behind commerce IRL failures.

Ai: Updated async Neo4j dependency management in `keble_db`.
- `keble_db/deps/api.py`
  - `ApiDbDeps.get_aneo4j` now uses `self.__db.get_aneo4j(new_instance=True)` and closes driver via `await self.__db.try_close_async(driver)` after yield.
  - This avoids sharing one AsyncDriver across different event loops in test/server contexts.
- `tests/test_api_deps.py`
  - expanded async driver stub with `close()` tracking.
  - updated `test_api_deps_async_neo4j_driver` expectation (`new_instance=True`) and close assertion.
  - added `DummyApiDb.try_close_async` stub behavior.
- Validation:
  - `python -m pytest -q tests/test_api_deps.py::test_api_deps_async_neo4j_driver` passed.

## 2026-03-26 11:14
State: Added the reusable Mongo multi-update primitive needed by the DB-first cleanup pass in `keble-segmenting`.

zma:
- execute the `improve.README.md` cleanup plan from `keble-segmenting`
- add the shared bulk update primitive before local client work

Ai:
- Added `MongoCRUDBase.update_multi(...)` and `MongoCRUDBase.aupdate_multi(...)` in `keble_db/crud/mongo.py`.
- The new APIs reuse `cleanse_query_for_list(...)`, accept `QueryBase.ids` plus extra filters, and return the native Mongo `UpdateResult`.
- Extended `tests/test_crud/test_mongo.py` with sync/async coverage for:
  - update by ids
  - update by filters
  - update by ids + filters
  - zero-match updates
  - `modified_count`
- Validation:
  - `uv run pytest tests/test_crud/test_mongo.py -k 'update_multi or aupdate_multi'`
