~/writing · post
i gave my ai co-writer amnesia for a year. then i built it a memory.
the confession
I write a My Hero Academia fanfic. There, I said it.
It started the way these things always start. You watch a show, you love it, and somewhere in the back of your head a question sets up camp and refuses to leave: what if. What if there were one more student in Class 1-A? What if she wasn’t what she seemed? Mine is a girl named Mira who looks like a quiet kid with a weird mass-density quirk and is actually something a lot stranger and a lot more dangerous, hiding it behind twelve crystalline rings she forged out of her own blood.
I never planned on writing eighty thousand words. I’m a software engineer, not a novelist. I was going to sit down with Claude and write one scene, just to see her on a page.
Then another.
Somewhere around scene twenty I realized I had accidentally started writing a novel. Somewhere around scene fifty-five I realized I had a different problem entirely.
the goldfish across the desk
Here is what nobody tells you about writing long-form fiction with an AI. The model is brilliant for exactly one scene. Then you open a fresh session and it has the memory of a goldfish.
“Write a scene where Bakugo confronts Mira.”
Sure. And the AI cheerfully writes Bakugo acting like they’re old friends — they aren’t; trust sits at about a 3 out of 10, and the whole point of their dynamic is that he’s furious she keeps eclipsing him. Or it has him casually reference Mira’s true nature, a secret that doesn’t get revealed until scene 43. Or it heals an injury that was supposed to still be hurting.
Every session, the canon evaporated, and I was the one holding the bucket.
This is the hackathon’s whole premise, actually. “Your AI woke up in Vegas with no memory of last night.” I had been living that movie for a year. My co-writer woke up with amnesia every single morning.
the bureaucracy
So I compensated, the way you compensate for a colleague with no memory: write everything down and shove it under their nose before every conversation.
It grew into a small bureaucracy of markdown. Folders for the story bible. Sheets for each character’s current state, for the relationships between them, for the timeline. And three prompts I ran by hand: a Story Briefing that assembled “here’s where everyone is right now” before each scene, a Character Updater that walked the cast afterward and revised what changed, a Continuity Auditor that checked a draft against everything established.
Copy the files in, run the prompt, copy the output back out, edit the sheets myself. It worked. It was also enormously tedious, and it failed silently: miss one update, and three scenes later the AI is confidently building on a fact that’s no longer true.
Funny thing about memory. Humans don’t notice it until it’s gone. Apparently we don’t notice building it, either.
the realization
It took me embarrassingly long to see what I had actually made.
Every writing session started the same way. Read everything. Write. Update everything. Check everything.
I kept calling them prompts. They weren’t prompts. The briefing was a read. The updater was a write. The auditor was a query against established facts. They were database operations pretending to be markdown. I had reinvented a database, badly, out of files and willpower.
And then a hackathon landed in my week, sponsored by Cognee — an open-source memory engine that does exactly this, automatically. The feeling was somewhere between vindication and being gently mocked by the universe.
kioku
Kioku (記憶, Japanese for memory) is what I built that week. The pitch is one line:
Give your story a memory.
Point it at your scenes, your character sheets, your world bible. It reads everything into a memory that persists. Before you write, it briefs you — and the AI — on the true current state. After you write, it checks the draft against canon and tells you what you broke. When you accept the scene, it updates itself and gets a little smarter about your world. The amnesiac becomes someone who has read your entire story and remembers all of it.
The fanfic is just my demo corpus. The thing itself is for anyone who writes long — novelists, fanfic writers, the person running a five-year D&D campaign. Everyone who ever thought what if and then drowned in their own continuity.
why a search box wasn’t enough
A flat vector search can answer “what happened with Bakugo?” It can’t answer the questions that actually keep fiction coherent, because those are questions about structure and time. Who trusts whom, by how much, since when. Who knows the secret as of scene 30 — and who is still in the dark. What this character’s body looked like at this exact point in the timeline.
Those are graph questions. Cognee keeps a vector index and a knowledge graph, and it builds the graph for you by reading the text: characters become nodes, relationships become edges with properties. Its lifecycle mapped onto my hand-rolled bureaucracy almost one to one — remember() is my Character Updater, recall() is my Story Briefing, improve() re-enriches the graph after each addition (the thing I never managed by hand), and forget() removes a scene cleanly before a rewrite.
Four functions. Each one a job I used to do manually, at 2am, with a spreadsheet’s worth of markdown open.
the build
No build goes smoothly, and the honest version of this story is the useful one.
Python had other plans. The machine was running Python 3.14, fresh off the presses, and Cognee leans on compiled dependencies that hadn’t caught up yet. Half an hour of dependency archaeology later, I reached for uv, pinned a saner Python, and got a clean install. Lesson re-learned: the bleeding edge cuts.
No keys, no servers, no budget. No OpenAI key, no Ollama, no GPU. It sounds like a wall; it turned out to be the strongest version of the open-source story. Embeddings went to Fastembed, which runs locally for free; the language model went to Gemini’s free tier. The whole stack ran on a laptop for nothing.
The free tier has teeth. The good Gemini Flash models cap at twenty requests a day for free, and Cognee makes hundreds of calls to ingest a corpus. The fix was the one model with real headroom (Flash Lite, 500/day), embeddings off the quota entirely, and — most importantly — incremental ingestion. A content hash per file means an unchanged scene costs exactly zero calls. You pay the big ingest once.
The hard problems weren’t plumbing. They were fiction. Mira is also “Hoshino Mira,” also her hero name, also “she” — naive extraction shatters one person into four nodes, so identity gets resolved through an alias map before it touches the graph. A fact in a story isn’t simply true — it’s true and known by some characters and not others, and that changes over time: Bakugo can’t act in scene 30 on a secret he learns in scene 43, and Mira’s public cover story is a deliberate lie the checker must not flag. And a briefing for scene 30 must never leak a fact established in scene 40, so every state carries a validity window and recall respects it.
A flat search engine can’t touch any of that. A graph with a clock can. That’s the whole reason the project exists.
the trap
You don’t really trust a memory until you’ve tried to trick it.
Halfway through the week I wrote a trap for my own product: a scene that reads perfectly — competent prose, right voices — with five continuity violations planted in it. The kind a fresh, memoryless LLM actually commits. Bakugo states Mira’s deepest secret thirteen scenes early. He apologizes to her, warmly. A teacher’s power works on her when canon says it can’t. A weeks-long injury heals overnight. And she casually does, in public, a thing she has hidden from everyone for fifteen years.
Then I planted a sixth thing that is not a violation — her behaving more warmly than her old character sheet says, because she genuinely grew in recent scenes — to see if the guard would false-positive on character development.
First run: three of five caught, and the control correctly left alone. The catch that mattered most — the leaked secret — came back with counter-evidence quoted from Bakugo’s own internal monologue three scenes earlier. A vector search could never have flagged it, because the leaked fact is true and sits right there in the corpus, semantically similar to everything around it. The graph knows the one thing similarity can’t: that the fact is true and Bakugo isn’t supposed to have it yet.
The two misses taught me more than the hits. Both were failures of my prompt’s imagination, not the memory’s: the auditor was checking claims, not conduct — public hovering asserts nothing false; the act itself is the violation — and my own leniency rule had excused any injury that heals instead of doing the math on how fast. Two prompt surgeries later, the guard checks behavior against secrecy and arithmetic against recovery time. Continuity, it turns out, is mostly a discipline of asking rude questions precisely.
the ai that briefs itself
The feature I actually built all of this for is not the web app. It’s a Model Context Protocol server — five tools that hand the story’s memory to the AI itself.
The first time I typed “write the next scene” into Claude Code and watched it call the briefing tool on its own, draft against the returned state, run the continuity check on its own draft, catch its own mistake, and revise — that was the moment the whole year clicked shut. The ritual I performed every writing session executed itself in about a minute, and none of it depended on my ability to remember what to paste.
Not a dashboard for your story. An amnesia cure the amnesiac administers to themselves.
what shipped
By the end of the week: the memory desk, an interactive graph of every soul the memory knows — 567 nodes, 2,669 typed relationships like discovered_secret and is_best_friend_of — a milestone timeline, the MCP server, incremental ingestion, all of it running for exactly zero dollars. The repo also ships a tiny original story — The Salt Ledger, four scenes about a lighthouse keeper who archives the memories the sea returns (I am aware of what I did there) — so a stranger with docker compose up gets the full system, live, on a story they’ve never read. The character sheets I spent a year maintaining by hand? For a new writer, the memory generates them from the prose.
The graph view paid for itself in an unexpected way: it made the memory’s flaws visible. My protagonist appears as three separate nodes — “Mira,” “Hoshino Mira,” “Mira Hoshino” — because entity extraction doesn’t know they’re one person yet. I could hide that. Instead it’s the first item on the roadmap, on screen, in the demo. A memory honest about what it misremembers is worth more than one that performs perfection.
the name for the thing
The cliché is that LLMs need memory. True, and too vague to be useful. What this week actually taught me is more specific: memory isn’t storage. Dumping every scene into a vector database is storage, and it doesn’t help, because the questions that make a story coherent — who, when, who-knew, what-changed — live in the relationships between facts and in their position in time. Memory is structure. A graph and a clock.
I started this project because I was tired of reminding my co-writer who everyone was. I ended it realizing I’d been building a memory system for a year before I ever heard the term. Sometimes the best part of a project isn’t solving the problem. It’s discovering that the thing you’ve been building all along had a name.
The fanfic, for the record, is going somewhere dark and good. Mira is about to stop sitting on the sidelines. And for the first time in a year, my co-writer remembers why that matters.
Kioku is open source — the code, the sample story, and the roadmap are on GitHub. Built with Cognee, and with Claude as a coding assistant — which is only fair, given the subject.