{"id":6563,"date":"2026-07-05T08:31:03","date_gmt":"2026-07-05T01:31:03","guid":{"rendered":"https:\/\/daiilynews.cu.ma\/?p=6563"},"modified":"2026-07-05T08:31:03","modified_gmt":"2026-07-05T01:31:03","slug":"tadelstein9-two-tier-memory-a-queryable-long-term-memory-for-ai-coding-agents-the-two-tier-fix-for-the-context-window-wall-%c2%b7-github","status":"publish","type":"post","link":"https:\/\/daiilynews.cu.ma\/?p=6563","title":{"rendered":"tadelstein9\/two-tier-memory: A queryable long-term memory for AI coding agents \u2014 the two-tier fix for the context-window wall \u00b7 GitHub"},"content":{"rendered":"<p> <br \/>\n<br \/>\nA queryable long-term memory for AI coding agents \u2014 the two-tier fix for the context-window wall.<\/p>\n<p>Companion essay: &#8220;Your AI&#8217;s Memory Breaks on Real Work. The Fix Is Fifty Years Old.&#8221;<\/p>\n<p>An AI coding agent&#8217;s default long-term memory is a stack of markdown files it loads into context at the start of every session. That works at ten files. It fails at a hundred and forty: everything competes for one finite context window, and past the edge the memory silently truncates \u2014 the agent quietly forgets, re-solves solved problems, contradicts last week&#8217;s decisions. You blame the model. The filing system is the problem.<br \/>\nIt&#8217;s an old problem. Loading a whole file and scanning it is the pre-relational habit that databases were invented, in 1970, to kill: store it structured, index it, fetch only the row you need.<\/p>\n<p>Tier 1 \u2014 an index, always loaded. One line per solved problem: a title and a pointer. Cheap to carry every session. It tells the agent what exists, never the detail. (INDEX.md, generated from tier 2 so it never drifts.)<br \/>\nTier 2 \u2014 a database, queried on demand. Every hard problem becomes a row in a plain SQLite file \u2014 problem, root cause, what worked, the gotcha, the artifacts. A thousand rows cost the agent nothing until it runs a query. When something smells familiar, it asks the table instead of rummaging through prose.<br \/>\nStop loading the library. Keep an index you can hold, and a database you can question.<\/p>\n<p>python3 memory.py init<\/p>\n<p>python3 memory.py add \\<br \/>\n  &#8211;area db &#8211;title &#8220;SQLite can&#8217;t persist a view over an ATTACH-ed database&#8221; \\<br \/>\n  &#8211;problem &#8220;CREATE VIEW over an attached db vanished on the next connection&#8221; \\<br \/>\n  &#8211;root-cause &#8220;the view binds to the attach alias, not the file&#8221; \\<br \/>\n  &#8211;solution &#8220;materialize into the main db, or re-ATTACH and re-create the view on open&#8221; \\<br \/>\n  &#8211;gotcha &#8220;no error is raised \u2014 the view simply isn&#8217;t there next session&#8221; \\<br \/>\n  &#8211;tags &#8220;sqlite,attach,view&#8221;<\/p>\n<p>python3 memory.py query &#8220;attach view disappears&#8221;<br \/>\npython3 memory.py get 1<br \/>\npython3 memory.py index      # regenerate INDEX.md from the database<br \/>\nThe part that isn&#8217;t the database<br \/>\nThe tool alone is a trap. It earns its keep only with a habit and a little hygiene:<\/p>\n<p>Query before you rebuild. An agent&#8217;s reflex is to solve, not to look up. Make &#8220;search the memory first&#8221; a standing rule, or the database becomes dead weight.<br \/>\nKeep rows honest. Write them the day you solve the thing; delete them the day they turn out wrong. A stale row misleads worse than an empty table.<br \/>\nRetrieval has a ceiling. Full-text search (built in here, via FTS5) finds the words you match, not the row you meant. When you outgrow it, bolt semantic search \/ embeddings onto this same relational base \u2014 don&#8217;t start there.<\/p>\n<p>Point your agent&#8217;s project instructions at two rules:<\/p>\n<p>On a new hard problem, query first; act on a hit.<br \/>\nOn solving something novel, add a row, then index.<\/p>\n<p>The always-loaded INDEX.md primes the agent on what it already knows; the database holds the rest, for free.<\/p>\n<p>File<br \/>\nRole<\/p>\n<p>schema.sql<br \/>\nthe solutions table + an FTS5 full-text index kept in sync by triggers<\/p>\n<p>memory.py<br \/>\nstdlib-only CLI: init \/ add \/ query \/ get \/ list \/ index<\/p>\n<p>INDEX.md<br \/>\ntier-1 index, generated from the database (git-ignored)<\/p>\n<p>memory.db<br \/>\ntier-2 store \u2014 your data (git-ignored)<\/p>\n<p>No dependencies. Python 3 and its bundled sqlite3.<\/p>\n<p>Built in the open by Tom Adelstein. The pattern came out of a working session with Claude Code, Anthropic&#8217;s coding agent: I pitched the relational approach; the agent built, tested, and hardened this implementation. The human\u2013AI collaboration is the point \u2014 and, fittingly, the subject of the companion essay.<\/p>\n<p>MIT \u00a9 2026 Tom Adelstein<br \/>\n<br \/><br \/>\n<br \/><a href=\"https:\/\/github.com\/tadelstein9\/two-tier-memory\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A queryable long-term memory for AI coding agents \u2014 the two-tier fix for the context-window wall. Companion essay: &#8220;Your AI&#8217;s Memory Breaks on Real Work. The Fix Is Fifty Years Old.&#8221; An AI coding agent&#8217;s default long-term memory is a stack of markdown files it loads into context at the start of every session. That [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":6564,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[676],"tags":[],"class_list":["post-6563","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech-ai"],"_links":{"self":[{"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/posts\/6563","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6563"}],"version-history":[{"count":0,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/posts\/6563\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=\/wp\/v2\/media\/6564"}],"wp:attachment":[{"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daiilynews.cu.ma\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}