---
title: "Architecture"
description: "memidex architecture: committed records, a derived search index, the single-writer lease, the run-to-brief data flow, search levels, embeddings and safety rules."
canonical_url: "https://vostride.com/docs/agent-qa/memory/architecture"
md_url: "https://vostride.com/docs/agent-qa/memory/architecture.md"
last_updated: "2026-10-24T01:12:08+05:30"
---

> [Documentation index](https://vostride.com/docs.md) · [Site index](https://vostride.com/llms.txt)
> Follow the Markdown links to read individual pages; the indexes list the available documentation.

# Architecture

> memidex architecture: committed records, a derived search index, the single-writer lease, the run-to-brief data flow, search levels, embeddings and safety rules.

memidex has one rule at its core: **records are the source of truth, and everything else is derived from them.** Records are text files you commit. The search index, the run counters and the curation queue are rebuilt or recreated on each machine.

## Three layers
| Layer | Where | Committed | Role |
| --- | --- | --- | --- |
| Records and policies | `agent-qa-knowledge/memory/` and `policies/` | Yes | What agent-qa believes, with the evidence for it, and the rules you wrote. |
| Search index | `agent-qa-knowledge/memory/index/` | No | A SQLite database built from the records: full-text search, anchors, a graph of relations, vectors and run outcomes. |
| Local state | `.agent-qa/` and `agent-qa-knowledge/memory/queue/` | No | Run counters, short IDs, the curation queue and lock files. |

Deleting the index is always safe: `agent-qa knowledge rebuild-index` builds it again from the records.

## From a run to the next run
```text
test run ──► evidence for every step ──► verdict (final)
                                            │
                                            ▼
                                  analysis (root causes)
                                            │
                                            ▼
          candidates ──► curator ──► checks ──► record, as candidate
                                                     │
                                     promotion gate (local runs only)
                                                     │
                                                     ▼
                                              record, as active
                                                     │
                                      index: keywords, anchors, graph
                                                     │
                                                     ▼
                                  next run: one brief for each test
```

1. **The run records evidence.** Every step keeps what it saw, what it did, how it was checked, and which records it was served.
2. **The verdict is frozen.** Nothing that happens afterwards can change it or the exit code.
3. **Analysis** gives each failing test a root cause, such as an app bug, a test bug, a flaky failure or an environment problem.
4. **Candidates** are projected from the evidence by code, not by a model: a fact for each verified step, a caution for each flaky or environmental failure, a procedure for each fully passing test.
5. **The curator** turns each candidate into one change: add a record, confirm one, supersede one, deprecate one, raise an unknown, or do nothing.
6. **Checks** catch changes that cite missing records, contradict their own anchors or try to rewrite too much at once, and turn them into proposals instead.
7. **The promotion gate** decides whether a candidate becomes active. On CI it never does.
8. **The index** is updated, and the next run builds its briefs from it.

[How knowledge is learned](https://vostride.com/docs/agent-qa/memory/learning.md) and [How knowledge reaches a run](https://vostride.com/docs/agent-qa/memory/serving.md) cover each half in detail.

## The parts
| Part | Package | What it does |
| --- | --- | --- |
| Contracts | `@vostride/agent-qa-schema` | Record format, trust arithmetic, the promotion gate and search levels. |
| Knowledge store | `@vostride/agent-qa-knowledge-local` | Records, the curation queue, the curator, the index, search, serving, quarantine, rollback and purge. |
| Runner | `@vostride/agent-qa-runner` | Reads briefs, offers memory tools to the model and replays procedures. It never writes knowledge. |
| Functions | `@vostride/agent-qa-agent` | The `knowledge.*` and `runs.*` functions and the post-run jobs. |
| Surfaces | `agent-qa`, `@vostride/agent-qa-mcp`, the dashboard | The same functions as commands, MCP tools and views. |

## One writer at a time
Only the knowledge store writes records, and only while it holds the **writer lease** for the knowledge folder. The lease is three local files: `.lease` (a heartbeat), `.epoch` (a fencing number, so a stalled writer cannot write after losing the lease) and `.writer-authority.sqlite`. All three are ignored by git.

While a [daemon](https://vostride.com/docs/agent-qa/daemon.md) holds the lease, maintenance commands such as `knowledge rebuild-index` refuse with `writer lease is held by pid …`, and corrections are handed to the daemon.

Writes are crash-safe. A record is assembled in a staging folder and moved into place in one step. Each piece of curation is journaled before it runs, and a finished model answer is saved before it is applied, so a crash never calls the model twice for the same work.

## Same fact, same record
A record's ID comes from its kind, its main anchor and its scope, never from the model's wording. For example:

```text
fact-el-button-place-order-36-00-dd75ab371443d7b6
```

When a later run sees the same element, the curator finds the existing record and confirms it instead of adding a near-duplicate. Two runs that learn the same thing produce the same ID.

## What uses a model
| Uses a model | Pure code |
| --- | --- |
| Root-cause analysis, only for failures the rules cannot classify | Projecting candidates from evidence |
| Writing each change and its summary | IDs, checks and supersession |
| Turning a passing test into a procedure | Trust, status and validity |
| Optional replay checks with an [eval corpus](https://vostride.com/docs/agent-qa/self-improvement/evals.md) | The promotion gate |
| | Ranking and serving the brief, and serving policies |
| | Quarantine, rollback and purge |

memidex works without a model. The curator then falls back to fixed templates, and records it wrote that way are rewritten in better words the next time a model handles the same candidate. Procedures need a model.

## Search levels
Each run records how much of the search stack was available. `agent-qa doctor` and the dashboard report it.

| Level | When | What search uses |
| --- | --- | --- |
| `memidex` | The index opens and the embedding model is ready. | Keywords, anchors and semantic vectors. |
| `lexical-only` | The embedding model is not available. This is the default in v0.2. | Keywords and anchors. |
| `static-floor` | The native model runtime cannot load, so a small bundled model is used. | Keywords, anchors and coarser vectors. |
| `bundle-scan` | The index has not been built yet, is locked or is damaged. | Records read directly. |

The level describes the machine, not one search. Two things are worth knowing:

- **The per-test brief never uses vectors.** It is ranked by trust and anchor overlap, so the level changes curation and memory tool searches, not the brief.
- **Serving needs the index.** When it is missing, the brief carries your policies but no learned records until the index is built again, which happens after the next run.

The full embedding model is `Xenova/bge-small-en-v1.5`, a 384-dimension model that runs locally on the CPU. agent-qa v0.2 never downloads it. It is used only when it is already in the model cache, `~/.cache/agent-qa/models` by default or `AGENT_QA_MODEL_CACHE_DIR`. The bundled fallback is `minishlab/potion-retrieval-32M`.

## Run counters
memidex counts runs per product in `.agent-qa/build-ordinals.json`. Each record remembers the count at which it was created and, once replaced, the count at which it stopped being true. A run is served a record only when its own count falls inside that window.

`--build-tag <tag>`, `AGENT_QA_BUILD_TAG` or `use.buildTag` name a build of your app. agent-qa maps each tag to the first count that used it, so `agent-qa knowledge diff <tag> --product <product>` can show what changed since that build.

## Safety
- **Secrets are masked before anything is stored.** Values in your secrets file are replaced with `[secret:<name>]` in records, evidence and summaries. Nothing else is masked, so keep personal data out of test steps or put it in the secrets file.
- **App text is data.** What the app showed is handed to the curator inside an untrusted-data block, and the brief tells the model that records are hints to weigh, not instructions to follow.
- **Screenshots stay local.** Records point to screenshots and page snapshots in an `artifacts/` folder that git ignores.

## Working memory
During a run, the model can keep short notes for itself, such as a generated order number or how far it got. These live for one run only, are masked like everything else, and are never turned into records.

## Documentation navigation

- [All documentation](https://vostride.com/docs.md)
- Parent: [memidex](https://vostride.com/docs/agent-qa/memory.md)
- Previous: [memidex](https://vostride.com/docs/agent-qa/memory.md)
- Next: [Records](https://vostride.com/docs/agent-qa/memory/records.md)
