Why:
- Plan 001 Phase 4 needs batched, concurrency-bounded embedding wired into
the inline upload path, with process-wide capacity/timeout/chunk-limit
guards (ADR-0017).
- The BM25 analyzer and dense-model config are ported from the `emet`
evaluation lab, which benchmarked them against the real Farsi corpus
(bm25-fa-norm-stop; nomic-embed-text-v2-moe at 768-dim; text-embedding-3-large
at native 3072-dim), closing open items in ADR-0001/ADR-0005.
Changes:
- New: embedding ports, orchestration (embed_chunks), request-bounds
helpers, and dense/sparse adapters (analyzers.py, bm25.py,
openai_compatible.py).
- upload.py now parses/chunks/embeds inline behind INGESTION_MAX_CONCURRENCY
(503), INGESTION_TIMEOUT_SECONDS (504), and the chunk-count ceiling (413);
every failure path still writes a terminal job row.
- Lifespan builds and warms both dense embedders at startup (fail-soft) and
creates the sparse embedder and concurrency semaphore.
- httpx moves from dev to main dependencies (adapters use it directly).
Impact:
- Qdrant point upserts are still Phase 5 -- chunks_indexed stays 0.
- New EMBEDDING_* env vars documented in .env.example; safe defaults.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds src/application/ingestion/ -- Persian normalization, DOCX body
walk with structural data/layout table classification, CSV/XLSX row
rendering, and fixed-size token chunking (cl100k_base, 400/60/512) --
as pure functions per ADR-0015, tested against real production
documents (asia_data_sample, kept out of the repo). ADR-0018 records
where this diverges from ADR-0004 (fixed-size default, no invented
headings/tree, structural table classification, header-provable
labeling only). Plan 001's scope line is corrected from CSV-only to
DOCX/XLSX/CSV, and CLAUDE.md's stale project-status paragraph is
updated to match current implementation state.
Why:
- ingestion is inline in the request instead of dispatched through RabbitMQ/outbox/worker; ADR-0014 is superseded (not deleted) and named as the design to adopt once ingestion needs to move off the request path.
Changes:
- new ADR-0017 plus amendments to every ADR/plan that referenced the job-shaped/broker contract, so none silently contradict it.
Impact:
- no broker, outbox, or worker code; rabbitmq test marker removed.
Add the initial src/ package (empty FastAPI entrypoint, Settings stub),
an .env.example placeholder, and expand .gitignore for test/coverage
artifacts, environment files, and local Claude Code overrides. Also
documents the Alembic async bootstrap command in ADR-0009.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Switch the durable ingestion/maintenance job-dispatch broker decision from
NATS JetStream to RabbitMQ (aio-pika), rewriting ADR-0014 and propagating
the terminology change through ADR-0015, ADR-0016, and the ingestion
vertical-slice plan. Adds aio-pika as a runtime dependency.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Why:
- Establish explicit ownership and lifetime rules for application, request/job, and operation-scoped resources.
Changes:
- Define FastAPI lifespan ownership for engines, clients, graphs, and pools.
- Define dependency-managed sessions and request context.
- Require explicit transaction boundaries and dependency passing.
- Prohibit shared global SQLAlchemy sessions and import-time network clients.
Impact:
- Application resources are created and closed by their process owner.
- Request and job resources must not be shared across concurrent units of work.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why:
- Establish the versioned FastAPI boundary for authentication, tenant isolation, chat runs, file ingestion, point management, and health checks.
Changes:
- Define /v1 routers, bearer-token authentication, scopes, response envelopes, error conventions, and job-shaped ingestion responses.
- Rename the older indicative /chunks routes to /points while preserving the existing Qdrant payload and CRUD semantics.
- Define tenant injection and concurrency requirements at the HTTP boundary.
Impact:
- The REST API is owned by ADR-0008 when older endpoint examples differ.
- Clients should use /v1/points and /v1/threads resource paths.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why:
- Establish the application-owned relational source of truth for tenants, authentication, ingestion, audit, graph runs, LLM usage, and feedback.
Changes:
- Define SQLAlchemy 2.x and Alembic conventions.
- Specify tenant, API-key, ingestion, audit, graph-run, pricing, usage, and feedback tables.
- Document indexing, retention, privacy, and multitenancy rules.
Impact:
- Postgres schema changes must be implemented through Alembic migrations.
- FastAPI must not run DDL during startup.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why:
- Design the LangGraph-based insurance chatbot: retrieval-grounded
answering, grounded clarification, and handoff to a human assistant
owned by the existing main backend.
Changes:
- ADR-0006: graph nodes/edges, escalation triggers, and the
backend-owned handoff signal contract.
- ADR-0007: Postgres checkpointer, thread model (thread_id as the
shared identifier), history trimming strategy, and cross-thread
user memory via the Store.
Impact:
- Design-only; no code changes yet.