# Coding-Agent Memory

> Persistent, governed project memory for a coding agent — the decisions, conventions, and gotchas it learns about your codebase, kept across sessions. For developers driving an agent in Claude Desktop, Cursor, or Cline.

## What it is — agent memory that survives the session

A coding agent loses everything at each cold start: the decisions you made together, the conventions it learned to match, the traps it already hit once. The `coding-agent-memory` blueprint gives it a durable place to write those down and read them back — modeled as the facts/entities and episodic flavors of agent memory on Vectros. Each memory is a typed, schema'd record; recall is by meaning (HYBRID search) or by a stable key (exact lookup); and every change keeps a version history, so the agent can see not just what you decided but how the decision evolved.

## What `bootstrap` provisions

Running the blueprint stands up everything below in one shot — no application code.

- **Three schemas**, each HYBRID-indexed (keyword on titles + semantic on the prose body):
  - **`decision`** — a durable architectural/product decision. Fields: `title` (required), `statement` (what was decided), `rationale` (the why — the highest-value, most-recalled field), `status` (`proposed` | `active` | `superseded`), `area`, and `decidedOn` (date). Lookups: non-unique `area` and `status` (equality — "all `active` decisions", "decisions in the `auth` area"), plus a `decidedOn` **range** index ("decisions made this quarter"). Each record also carries a first-class `externalId` — the caller-stable dedup/upsert key and the value other records reference — sent top-level, not a declared field or lookup.
  - **`convention`** — a coding convention the agent reads before it writes code. Fields: `name` (required), `rule` (stated as an imperative), `area`, `status` (`active` | `retired`), `establishedByDecision` (a typed **reference** to the `decision` that established it), and `adoptedOn` (date). Lookups: `area`/`status` and `establishedByDecision` (equality — enumerate "active conventions for `auth`", or "conventions established by decision X"), plus an `adoptedOn` **range** index.
  - **`gotcha`** — a sharp edge: `symptom` (required), `cause`, `fix`, `area`, `status` (`active` | `retired`), and `discoveredOn` (date). Lookups: `area`/`status` (equality) plus a `discoveredOn` **range** index.
- **A least-privilege access profile** — `allowedActions` is exactly `records:r`, `records:c`, `records:u`, `search:r`, `schemas:r`, `inference:r`. The `inference:r` scope powers grounded "why did we decide X?" recall (`rag_ask`) over the captured rationale. Note the **deliberate absence of `records:d`**: every memory type carries a `status`, so a decision is *superseded*, a convention or gotcha *retired* — never deleted, keeping the full audit trail of how the project's thinking changed.
- **A service principal** — `externalId` `coding-agent-memory`, the identity the agent's key acts as.
- **Two seed records** — one `decision` (`seed-use-vectros-for-memory`) explaining why the project uses Vectros as its memory, and one `convention` (`seed-record-the-why`) that **references** that decision — a live typed link the moment the blueprint applies, so the store is never empty and the cross-type relationship is visible from the start.

The whole apply is idempotent: re-running converges on the same state rather than duplicating, because every record is keyed by its `externalId`.

## Before you start

This is an invite-only 0.x preview, so the honest prerequisites: you need an **early-access invite**, and from the dev portal you mint a short-lived **Cognito bridge token** — that human step authenticates the CLI before it can provision anything. You also need **Node** (the CLI and MCP server run via `npx`). That's it; once you have the bridge token in hand, the rest is two commands and a config merge.

## 1. Bootstrap the blueprint

```bash
# install once: npm i -g @vectros-ai/cli  (or use npx @vectros-ai/cli, below)
npx @vectros-ai/cli bootstrap --blueprint coding-agent-memory
```

End to end, this provisions the three schemas, creates the app-context, registers the service principal, gates and creates the least-privilege access profile, mints a narrow scoped key (an `ssk_*`) carrying exactly the six data-plane actions above, and writes the seed records. The minted `ssk_*` is **auto-merged into your Claude Desktop config** so your agent can use it immediately — for Cursor, Cline, or any other MCP client, pass `--print` and paste the printed `mcpServers.vectros` block into that client's MCP config. Because the access profile is gated to data-plane actions only, the key can never touch keys, profiles, app-contexts, users, or billing.

## 2. Give it to your agent (no code)

After bootstrap, your MCP client (Claude Desktop, Cursor, Cline) points at the Vectros MCP server with the new `ssk_*`. The agent now drives the store through the server's data-plane tools — entirely in natural language. A few interactions:

- **"Remember we decided to use cursor-based pagination because offset pagination drifts under concurrent writes."**
  → the agent calls **`record_create`** with `typeName: decision`, a `title`, the `statement`, the `rationale`, `status: active`, and a stable `externalId`.

- **"What did we decide about pagination?"** — in a *fresh* session, with no prior context.
  → the agent calls **`hybrid_search`** to recall by *meaning* across `statement`/`rationale` — optionally narrowing with `filters` on the filterable fields (e.g. `status: active`). It reads back the decision it never would have remembered on its own.

- **"List every active decision"** / **"show me all the gotchas in the `auth` area"** — enumerate a slice, no semantic query.
  → the agent calls **`record_query`** in *lookup* mode on a non-unique lookup field (`field: status, value: active`, or `field: area, value: auth`), or in *list* mode (by `typeName`, no field) to page through every record of a type. This is the direct, deterministic counterpart to `hybrid_search` — **memory needs both**: search to recall by meaning, lookup/list to enumerate a known slice. (And `record_query` by `externalId` fetches one decision exactly.)

- **"That decision changed — we're moving to keyset pagination now."**
  → the agent calls **`record_update`** on the same `externalId`: it can flip the old decision's `status` to `superseded` and record the new one, leaving both in the history.

- **"Record a convention for this, and link it to the decision behind it."**
  → the agent calls **`record_create`** for a `convention` with `establishedByDecision` set to the decision's `externalId`. Because it's a typed **reference**, the platform verifies that decision exists before accepting the write, and you can later enumerate "conventions established by this decision" via the `establishedByDecision` lookup. (Link at runtime, not in the seed — the target is already indexed by then.)

Discovery is free too: the agent can call **`list_schemas`** to learn the `decision` / `convention` / `gotcha` shapes before it writes, so it fills the right fields.

## 3. See it work

The "aha" is cold-context recall. Open a brand-new agent session — no memory of the earlier conversation — and ask *"why are we using cursor-based pagination?"*. The agent runs a `hybrid_search`, finds the `decision` record by meaning, and answers with the original `rationale` it captured weeks ago. Then ask it to show how that decision evolved: the version history surfaces the earlier `active` revision and the later `superseded` one, with the timestamps of each write. The agent didn't re-derive the answer — it *remembered* it, and can show its work.

## How it maps to Vectros

- **Typed, schema'd records** — `decision` / `convention` / `gotcha` are real schemas with typed, validated payloads, not free-text blobs.
- **HYBRID search + grounded `rag_ask`** — every schema is `indexMode: HYBRID`, so recall is keyword on titles *and* semantic on the prose body; with `inference:r` the agent can ask "why did we decide X?" and get a grounded, cited answer over the captured rationale.
- **Lookup *and* search — both access patterns, one schema** — non-unique `area`/`status` lookups let the agent *enumerate* a slice via `record_query`; HYBRID search recalls by meaning (`externalId` has a built-in finder for exact get + idempotent upsert). Memory needs both the "find what I mean" and the "list what I have" paths.
- **Ordered range lookups** — each schema's date field (`decidedOn` / `adoptedOn` / `discoveredOn`) is range-indexed, so the agent can pull "decisions made this quarter" without a search.
- **Typed references between record types** — `convention.establishedByDecision` is a typed link to the `decision` that established it (the platform enforces the target exists at write). Provenance as a first-class edge: "why does this convention exist? → open the decision behind it." Add the reference field as an equality lookup to enumerate "conventions from decision X" (the reverse-direction query isn't exposed here).
- **Version history** — every write keeps an immutable prior revision, so a superseded decision stays visible alongside its successor.
- **Scoped key** — bootstrap mints a narrow `ssk_*` with exactly six data-plane actions; the absence of `records:d` is enforced, not just a convention.
- **MCP, no code** — the agent drives the whole thing through `record_create`, `record_query`, `hybrid_search`, `rag_ask`, `record_update`, and `list_schemas`.

## Notes & limits

- **Synthetic / non-secret data only** for this preview — record decisions and conventions, not secrets or production credentials.
- **The bridge-token step is a real human prerequisite** — you mint a Cognito bridge token from the dev portal before `bootstrap`; it isn't automated away.
- **Data-plane tools only.** The MCP server exposes records/schemas/search/document tools — there is **no web-fetch or web-search tool**, by design. The agent's memory is what you've written to Vectros, nothing it pulls from the open web.
- **No delete.** The blueprint's key carries no `records:d`. Decisions are superseded, never removed — that's the point, and it's also a hard scope limit.
- **Audit is tamper-*evident*, not tamper-proof.** Writes are recorded with a SHA-256 state-continuity chain you can inspect for tampering; continuous automated verification is not yet part of this preview.
