Roadmap

This is a list of things that do not work yet, not a list of things coming soon. Everything on it is either a defect we found in our own store or a measurement we cannot take with the code as it stands. There are no dates, because we have missed enough of them elsewhere to know what they are worth.

The ordering is by what unblocks the most, and the first three items are all the same shape: the store knows things it cannot tell anyone.

Shipped since this site went up

Three things have moved. Two are code and one is a measurement; none of the three is the whole item it belongs to, and the parts still open are named below each.

Two honest bounds on that. It is implemented in the client layer — our own fleet's tool surface — over generic engine tags, and it is not in the packaged MCP server yet (item 3 below). And it is not retroactive: as of 26 August 2026, 243 of 8,810 facts in our store carry an author, because everything written before 24 August was written by code that had no way to say.

1. An export that contains your memory

Status: open. First item, and has been since we started publishing.

The engine's export and import endpoints move a bank template — configuration, mental models, directives. Not one fact. The listing API that does return facts hands back 11 of the 26 stored columns, and three of the fifteen it drops are room, hall and layer — plus all 201,154 links.

So memory does not round-trip, and it does not round-trip RCLL to RCLL, which is the part that makes it a defect rather than a missing integration. A command named export that returns a valid file which is not your memory is worse than no command at all: it is a backup you find out about on the day you restore it.

What lands: a full dump — every column, every link, provenance intact — targeting the published portable agent-memory interchange specification rather than a format of our own. The direction we intend to demonstrate first is the one that costs us something: getting memory out of RCLL.

2. Import, so the dump is a round trip

Status: open. Half of it exists.

The export side has been written and run against our own store: 217,580 rows, rooms, halls, layers and all links included. The other direction does not exist, and until it does the dump is an archive rather than a migration.

This is also what makes the MEMORY_MODE switch honest. The installer offers none, embedded and standalone, and they share one tree, one image and one migration line specifically so that a dump from one loads into another. Today changing the answer leaves what you already stored where it was. That is a documented limitation on the front page and it should not stay one.

3. Attribution in the packaged server

Status: shipped in our fleet, not in the artifact.

The author tag, the mine filter and the author echoed on every result are live in the tool layer our own agents call. The npm package fleet-memory-mcp in the public repository does not carry them yet — it exposes the engine's generic tags argument and nothing on top of it.

We are saying that plainly rather than letting the front page imply otherwise, because the gap is exactly the kind that gets discovered by someone who cloned the repository on the strength of a sentence on a website. It lands with the first release.

4. Reads, recorded

Status: open. This is the one that blocks the measurement the product rests on.

After two months and a fleet's worth of work, our store cannot say which fact has ever been useful. access_count is 0 on all 8,810 rows — the column exists and is never incremented — and the audit table has 0 rows. Upstream removes that column in 0.9.x, which is a defensible cleanup of a field nobody wrote, and it does mean read telemetry has to be built rather than switched on.

A counter is the wrong shape anyway. The question is not how many times but returned to whom, which needs an append-only row per read, not an integer per fact. Paired with item 5 it makes the handoff dataset accumulate by itself.

5. The recall payload, logged

Status: open.

Query, rooms asked for, ids returned. This one is retroactive in effect — turn it on and the dataset builds itself from ordinary use, with no backfill and no separate collection step.

Today the only cross-agent signal we have comes from the client's log, which records the tool name per call and nothing about what came back: 939 writes and 195 reads across 72 conversations. We can reconstruct who wrote what by joining those rows against the orchestrator's own tables. That is archaeology, not instrumentation.

6. The cross-agent suite

Status: one of the four measures is done — the silo ablation, run 26 August on a public dataset. The other three are still blocked on 4 and 5.

MeasureWhat it answersMetric
Handoff rateWhat share of recalls return at least one fact written by a different agent%, per agent and per room
IsolationWhether a scoped read can return a fact it should not see leak rate, target 0
Handoff retrieval qualityOn queries whose evidence was written by another agent, how good is retrievalnDCG@10, recall@20
Silo ablationThe same query set against per-agent silos versus one fleet storedelta on the above — run, on a public dataset

Same metrics as our retrieval numbers, so the results land in the same units. The silo ablation is the control every shared-memory pitch implies and none of them runs; ours is now run, on LoCoMo rather than on our own store, and it came out partly against us — sharing a store costs ranking quality, and scoping buys back about half of it. The numbers are here. The other three measures in this table still need items 4 and 5, because they ask about our fleet's reads and a public dataset has none.

7. Backfill the authorship we already lost

Status: open, and partly unrecoverable.

8,567 facts were written before attribution existed. The author is not in the store and cannot be derived from it. It is recoverable for a subset by joining the client's log rows against the orchestrator's tables — offline, approximate, and worth doing once rather than pretending the corpus is uniform.

8. A room registry, and a janitor on the write path

Status: decided 26 August 2026. Steps 2 and 4 below shipped the same day, in our client layer. Steps 1 and 3 are open, and the order below is not the order we shipped in.

A fact's room is assigned once, at write time, and nothing ever changes it. We looked for a reassignment path in the engine and there is none — no endpoint, no background job, no query that updates the column. The classifier runs exactly once, inside the retain pass.

Creating a room, though, was never the problem. The column is plain text with no constraint, and the classifier only fires when the caller left it empty — so passing a new string has always created a room. Five of our rooms exist that way and match no pattern in the engine. What a fleet cannot do is see which rooms exist, tell a live room from a typo, or bring two spellings of one subject back together. That is what gets built, in this order:

  1. Rooms for the half of the store that has none. 4,077 facts — every raw L2 observation — carry no room, because consolidation writes them and never assigns one, and a room filter matches none of them. This is a defect, not a feature, and it ships first: a janitor trained on the fleet's vocabulary while 46% of that vocabulary is missing would learn the wrong vocabulary.
  2. A listing call. Names, counts, wildcards — the tags endpoint already does exactly this for the more incidental field, so this is one query against a different column, not new machinery. Shipped 26 August, client-side — not as a new engine endpoint but as a census of the room: tags the janitor writes, merged with the known-room list so it is not empty before the backfill runs. The engine still has no /rooms, and the packaged MCP server still ships the hard-coded list, which has already gone stale.
  3. The registry. One row per room: canonical name, aliases, count, status (live, provisional, merged), and whether a human or the system created it. An observed index, not a constraint — room stays free text and an unknown string still writes. The registry records; it does not veto.
  4. The janitor, at write time rather than nightly. A caller who writes deploy lands in deployment, and the string they typed is kept on the fact as a tag. Nothing about the original call is lost, and since tags are already listable and filterable, every rewrite is auditable and reversible with what exists today — no audit table, no migration.

The evidence this is worth doing is in our own store: 595 facts mention a deploy and sit in ten different rooms, 260 of them in no room at all. And the classifier cannot put anything in deployment\bdeploy lives inside the pipeline pattern, which is tested first and wins, so every fact in deployment got there by hand. The automatic and manual paths disagree by construction.

Three things it deliberately does not do. Only spelling merges automatically — case, separators, plurals, exact prefixes; agent and orchestrator are not two spellings of one word, and anything semantic becomes a proposal held as provisional until a person agrees. A merge never removes the old spelling from the read path, because a prompt written last month must not start returning silence when the store tidies up underneath it. And the registry does not become a permission system — it says what exists, not who may read it. The full shape is here.

What shipped, and the reordering. The janitor (4) and the listing call (2) were built and merged on 26 August; the registry (3) and the backfill (1) were not. So we shipped in the order 4, 2 — having argued above for 1 first. The reason is that the janitor stops drift being created while the backfill only removes drift already there, and the janitor turned out to be the cheaper of the two by a wide margin. The argument for doing 1 first still stands and 1 is still first in line; what changed is that we did not wait for it. Without the registry there is no provisional status, so nothing semantic is merged at all — only spelling.

Why it stopped being a tidiness item. The scoping ablation we ran the same week measured what a mis-routed room costs: a recall filtered to a room that does not hold the answer scores exactly zero, in every configuration and every question type. Two spellings of one subject are therefore not an aesthetic problem — they are a query that silently returns nothing. The numbers →

Counts read on 26 August 2026 from our own store, which is live and moves by the hour. What it blocks: nothing else on this list, but it is the difference between a fleet whose rooms mean something in month three and one whose rooms are 40 near-duplicates nobody dares merge.

9. Fusion weights that match the measurement

Status: measured, not shipped.

Our default weights reciprocal-rank fusion equally across channels. On multi-hop questions — the shape "agent A found it, agent B needs it" — that is measurably the wrong default: dense retrieval alone delivers evidence into the rerank window for 48.8% of those questions and equal-weight fusion for 43.2%. Halving the lexical channel's weight beats the current default in every category at once.

It is not shipped because it was measured on a two-channel substrate and the engine fuses four. A weight that is right for two is not automatically right for four, and shipping it on that evidence would be exactly the move we criticise other people for. The tables and the mechanism →

10. The reranker is 85% of a recall

Status: known, quantified, not fixed.

3.016 s p50 total, of which the cross-encoder is 2.570 s on CPU. Everything else — four retrievals, fusion, the token cut — is 0.289 s. The fix is a GPU or a smaller reranker, not an index rewrite, which is why we publish the split rather than the total.

11. Two inherited defects on the write path

Status: diagnosed, ours now.

12. A first release

Status: npm done; image and registry entry still open.

The source is public and MIT, and so is the package: fleet-memory-mcp 0.1.0 is on npm, built and signed by CI with provenance. The deprecated 0.0.0 under it went up for one reason — npm will not attach a trusted publisher to a package name that does not exist yet, so the first version could not itself be the CI-signed one. What is still not done: no container image is pushed, and we have not submitted to the MCP registry. The order was forced rather than chosen — the registry verifies the package name against the published manifest, so npm had to come first — and every one of these steps freezes a name permanently.

The loose end from before the rename is closed: the older package under the previous name now carries a deprecation notice pointing at this one, including the environment variable you need to keep reading the bank you already have. It was deprecated, not deleted — deleting it would break the installs it still serves.

13. Catch up with upstream

Status: unblocked, not done.

Our fork's true branch point is now recorded and shares a merge base with upstream's current release, so the upgrade is an ordinary rebase rather than archaeology. It has not been run. Until it is, we are four releases behind the engine we are built on, and any comparison anyone draws between the two should be read with that in mind.

14. An accuracy number, eventually

Status: deliberately absent.

We publish retrieval quality — did the right evidence come back, and how high. We do not publish accuracy, and will not until the harness runs on your machine with the reader, judge, seed and dataset version printed next to the figure. Changing the reader-and-judge pair moves that score more than changing the memory store does, which is what makes an unqualified "77% on LoCoMo" unusable — including if it were ours.

Not on the roadmap, on purpose