Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs/adr/0001-ports-and-adapters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 0001. Hexagonal architecture with ports and adapters

- Status: Proposed
- Date: 2026-10-16

## Context

The Academy RAG code has no interfaces. Embeddings, vector search, the LLM, parent storage and lexical search are all hard-wired:

- to the QVAC HTTP API;
- to SQLAlchemy models;
- to files under `QVAC_INGEST_DIR`.

Configuration is read at import time. Models and clients are module-level singletons.

The engine has to serve two consumers with different backends:

- Academy, which uses QVAC;
- the Code-RAG research track, which needs GPU-local models and code embeddings.

## Decision

The engine is organised as ports and adapters.

- `agentic_rag.ports` defines `typing.Protocol` interfaces:
- `Embedder`, `VectorStore`, `LexicalIndex`, `ParentStore`
- `Reranker`, `LLM`, `Cache`, `TokenCounter`
- Core packages (`types`, `ingest`, `retrieval`, `evidence`, `generation`, `agent`, `eval`) depend only on ports.
- Every adapter lives under `agentic_rag.adapters` and sits behind an optional extra.
- Dependencies are injected through constructors.
- Configuration is a single `EngineConfig` object built with pydantic-settings.
- Every port has an in-memory fake in `adapters/memory`.
- import-linter enforces the dependency rules in CI.

## Consequences

- Backends can be swapped without touching pipeline code.
- Unit tests and the eval smoke test run without models or network access.
- More upfront design. Port changes need an ADR, which slows changes to the interfaces.
- Academy code has to be refactored while it is being ported. Lifting it as-is is not possible.
36 changes: 36 additions & 0 deletions docs/adr/0002-uv-workspace-monorepo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# 0002. uv workspace monorepo for engine, code-rag and research

- Status: Proposed
- Date: 2026-10-16

## Context

The repository hosts three things that evolve together:

- a reusable library;
- an AST-aware extension of that library, which brings heavy dependencies (tree-sitter grammars, GPU stacks);
- research code (benchmark, datasets, experiments).

We want a single CI and a single lockfile. Code-RAG dependencies must not leak into the engine install.

## Decision

The repository is a uv workspace, using Python 3.11.

| Package | Distribution | Import name |
|---|---|---|
| `packages/engine` | `agentic-rag` | `agentic_rag` |
| `packages/code-rag` | `agentic-rag-code` | `agentic_rag_code` |

- `agentic-rag-code` depends on `agentic-rag`.
- `research/` holds runners and experiment configs that depend on both packages. It is not a published package.
- `services/qvac-worker` is a Node 22 project with its own `package.json`.
- Tooling: ruff (lint and format), mypy `--strict` on `packages/`, pytest, and import-linter.

## Consequences

- Atomic changes can span the engine and code-rag.
- There is one lockfile, so environments are reproducible.
- Each package keeps its own dependency set and extras.
- CI has to run per-package jobs and a Node job.
- Releasing the engine needs package-scoped tags, for example `engine-v0.1.0`.
28 changes: 28 additions & 0 deletions docs/adr/0003-qvac-as-optional-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 0003. QVAC as an optional adapter, not the engine runtime

- Status: Proposed
- Date: 2026-10-16

## Context

In Academy, the QVAC SDK (Node 22, llama.cpp, HyperDB) provides embeddings (GTE-Large), dense indexing and LLM inference (Qwen3-4B) behind an HTTP service. Its limits for this project:

- Embedding models cannot be chosen from Python.
- The service does not use the GPU.
- It lacks index deletion.
- It has had runtime stability issues: native runtime crashes, and long model downloads in CI.

The AST research needs code-specific embeddings and GPU-local models on an RTX 5080. Academy has to keep working on QVAC.

## Decision

- QVAC is one adapter set, `agentic_rag.adapters.qvac` behind the `[qvac]` extra. It implements `Embedder`, `VectorStore` and `LLM` over the documented HTTP contract.
- The Node worker is ported to `services/qvac-worker`. It gets a `DELETE` route and a versioned contract under `services/qvac-worker/contract/`.
- A `local` adapter set is the default for research: sentence-transformers embeddings, a llama.cpp LLM on the GPU, and a vector store chosen by ADR in milestone E3.
- CI does not depend on QVAC. Tests use in-memory fakes, plus a separate worker test job.

## Consequences

- Academy can adopt the engine with no behaviour change, through the QVAC adapter.
- Research is not limited by what the QVAC SDK supports.
- Two backend stacks have to be kept at parity. The eval suite has to pass on both (exit criterion of E3).
23 changes: 23 additions & 0 deletions docs/adr/0004-copy-then-migrate-from-academy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# 0004. Copy from Academy now, migrate Academy later

- Status: Proposed
- Date: 2026-10-16

## Context

The engine's API will change a lot while it is being extracted. Making Academy depend on it from day one would require coordinated pull requests in two repositories for every interface change.

## Decision

- Generic code and its tests are copied from `BitPolito/bitcoin-academy` into this repository and refactored here.
- Every porting pull request records the Academy commit it was copied from, in the form `Source: bitcoin-academy@<sha> <path>`.
- Academy is not modified until the engine reaches a tagged release (milestone E5).
- Milestone E6 then migrates Academy to `agentic_rag[qvac]` and removes the duplicated code.
- Fixes made in Academy in the meantime are ported deliberately. A `source/academy-sync` issue tracks them.

## Consequences

- The engine can iterate freely without breaking Academy.
- There are temporarily two copies of the RAG code.
- Drift has to be tracked until E6.
- E6 has to re-baseline Academy's evaluation to prove parity.
14 changes: 14 additions & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Architecture Decision Records

Each ADR records one significant decision: its context, the decision itself, and the consequences.

- **File name:** `NNNN-kebab-title.md`.
- **Status:** one of Proposed, Accepted, Superseded by NNNN, or Deprecated.
- **When an ADR is required:** any change to a port, a public contract (for example `EvidencePack` or the QVAC HTTP contract), the repository layout, or the core tooling.

| ADR | Title | Status |
|---|---|---|
| [0001](0001-ports-and-adapters.md) | Hexagonal architecture with ports and adapters | Proposed |
| [0002](0002-uv-workspace-monorepo.md) | uv workspace monorepo for engine, code-rag and research | Proposed |
| [0003](0003-qvac-as-optional-adapter.md) | QVAC as an optional adapter, not the engine runtime | Proposed |
| [0004](0004-copy-then-migrate-from-academy.md) | Copy from Academy now, migrate Academy later | Proposed |
Loading