Your coding agent can read git log. It can't read the four things you tried that didn't work. A developer has built NexusMem, a local-first memory engine for AI coding agents that indexes git history, shell commands, project docs, and assistant transcripts into a SQLite database, serving ranked context over MCP or CLI. The tool uses BM25 and vector search fused with Reciprocal Rank Fusion, and the developer found that shared priors were needed to avoid ranking errors, cutting API token spend by about 40% in practice. The project is open source on GitHub. I've been building NexusMem https://github.com/yaminbakoh4-dot/NexusMem mostly alone, in long stretches, for a few weeks. It's a local-first memory engine for AI coding agents: it indexes your git history, shell commands with exit codes , project docs, and optionally your assistant transcripts into a SQLite database on disk, then serves back a ranked, token-budgeted slice of it over MCP or a CLI. No account, no cloud, no telemetry. The pitch, in one line: your agent can already read git log . It cannot read the four things you tried last Tuesday that didn't work — and that's the part actually worth remembering. This week two strangers showed up and started fixing things I didn't ask them to fix. That felt like a good excuse to write about what it does and why. Coding agents get context from two places: what you paste in, and what they can grep. Neither one remembers process . Git tells an agent what shipped. It has nothing to say about the three approaches you tried before the one that worked, or which shell commands exited non-zero while you were debugging it. That information exists for maybe a day, in your terminal scrollback, and then it's gone. NexusMem's answer is boring on purpose: read what already exists on disk git log, shell history, markdown docs , normalize it into one node shape, index it, and rank it well enough that a query returns the right five things instead of the right fifty. The retrieval side is BM25 over SQLite FTS5, plus a vector pass over sqlite-vec if an embedding model is reachable, fused with Reciprocal Rank Fusion. RRF fuses on rank position only, never raw scores — that's the whole point of using it, since a BM25 cost and a vector distance live on unrelated scales and position is the only thing they agree on. On top of the fused rank, two priors adjust the score: signal a fix: commit outranks a chore: ; a shell command that exited non-zero outranks one that succeeded and recency . Both are real signal. Both also almost broke the whole thing. Dogfooding the tool on its own repo, a query about a PowerShell hook returned two unrelated same-day fix: commits at ranks 3 and 4, while the commit that actually answered the query sat at rank 6. The priors were capped individually — each could overturn at most a 2× relevance gap — but the score multiplies them together, so a fresh, high-signal commit which describes most of an active working day could overturn 4×. The fix wasn't a bigger cap, it was a shared one: priors now split one budget across both of them, derived so each is worth exactly √2 , not asserted by feel. I only found this because I kept running real queries against the tool's own commit history and reading the output critically instead of trusting the ranking math on paper. That's most of what building this has actually been: dogfood, find the case where it's confidently wrong, write a test that fails before the fix and passes after. The README has a "Where it breaks" section and I've tried to keep it truthful rather than reassuring. A few examples: sync from.There's also a number I was tempted to lead with and didn't: the original target was cutting API token spend by more than 70% versus sending full context. Measured end-to-end on this repo, it's closer to 40%. The 70% figure describes what the packing math shows against its own candidate set, which is a real number but a different, rosier question than "how much less did the agent actually read." The README says this outright instead of quietly reporting the friendlier number. I built this solo, iterating in long sessions, for weeks. This week, for the first time, someone I don't know opened an issue asking to add end-to-end stdio transport coverage for the MCP server — the existing tests only exercised an in-memory transport, which can't prove protocol framing survives a real process boundary. They described their approach in a comment first, then shipped a PR https://github.com/yaminbakoh4-dot/NexusMem/pull/9 that spawns the actual built CLI as a child process and asserts every line written to stdout parses as JSON-RPC. CI caught a real Windows-only bug in their first pass a .cmd shim needs shell: true to spawn on Windows — they fixed it within the hour and it merged clean. A second person forked the repo the same day and, without opening an issue first, found something I hadn't: the PowerShell hook always inserted its block with \n line endings, but a profile written by a Windows editor is CRLF by convention, so installing the hook silently turned a CRLF file into a mixed-ending one — and removing it later left a stray bare newline behind. That's a subtle enough bug that finding it means actually reading the code, not skimming it. Neither of those things needed me. That's the part worth sitting with — the project became legible enough, on its own, for someone else to extend it correctly on the first try. npx nexusmem init npx nexusmem sync nexusmem query "windows spawn failure" Requirements are just Node 22+ and git. Ollama is optional and only affects semantic search — BM25 works fully without it. Repo's here https://github.com/yaminbakoh4-dot/NexusMem if you want to poke at it, and there's now a CONTRIBUTING.md https://github.com/yaminbakoh4-dot/NexusMem/blob/master/CONTRIBUTING.md if you find something worth fixing.