Open source AI releases from the past day, searchable on your Mac 60 days from now
Every article ranking for this query is a snapshot: accurate this morning, useless next month. The interesting problem is not today's digest, it is the accumulation. When Mistral ships v5, the useful question is when you first saw v4 in your release briefings. This guide shows how Fazm turns each day's scrape into a row in a local SQLite table that sits behind an FTS5 index, so that question is a one-line query against a file on your own disk.
THE GAP
Every top result is frozen at publish time
Run the keyword and read the top five results. Curated awesome-lists lag by days or weeks. Monthly roundups are frozen the moment they are published. GitHub's topic pages sort by total stars, so a 2023 repo that has not been touched in a year still sits above a project that shipped a major release this morning. None of them let you, tomorrow, ask "where did I first read about this?" about a thing you definitely read about, because the only index they keep is their own table of contents. The index you need is the one over your own briefings, on your own disk.
| Feature | Aggregator, newsletter, or awesome-list | Fazm + local FTS5 over chat_messages |
|---|---|---|
| Answers 'when did I first see X?' | No. It shows their archive, not yours. | Yes. One FTS5 MATCH against chat_messages_fts. |
| Survives going offline | No. Hosted service or fetch on load. | Yes. fazm.db is a local file. |
| Index updates as you use the app | Whenever the aggregator re-crawls. | Three triggers fire on every chat insert. |
| Stores your follow-up questions | No. Your reasoning trail is not in scope. | Yes. chat_messages keeps both sides. |
| Query cost | HTTP round-trip + rate limit. | Milliseconds. Index is on local SSD. |
| Per-user quota | Usually. Free tier caps vary. | None. SELECT auto-limits to 200 rows. |
THE ANCHOR
The three-trigger pattern in AppDatabase.swift
The reason the "past day" digest becomes searchable forever is a specific block in the Fazm source tree. Migration fazmV5 creates a SQLite FTS5 virtual table in Desktop/Sources/AppDatabase.swift and attaches three triggers so the index never drifts from the underlying table. It is short. Here is the actual migration.
The critical detail is content='chat_messages'. This is FTS5's external-content mode: the text lives exactly once in the chat_messages table, and the FTS virtual table only holds the inverted index. Every row added by a normal chat insert becomes searchable on the next statement. Nothing about the digest flow has to know the index exists.
THE PIPE
How a morning pull becomes a searchable row
The daily briefing does not know it is feeding a long-running history. The chat pipeline inserts the assistant response into chat_messages; the trigger fires; the FTS5 index absorbs the new text. Every source in the diagram below is something you can already do in the app.
One pipeline, one local file
THE QUERY
What the one-line lookup actually looks like
The agent writes this for you. If you want to see the SQL it ran, the chat shows the tool call verbatim. This is a run I made against my own fazm.db asking when Mistral Small 4's native function calling first appeared in my daily digests.
*. NEAR works too. The SELECT inside the execute_sql tool auto-caps at 200 rows per the safety guard in fazm-tools-stdio.ts:284, which is plenty for a 60-day history window.THE COMPOUND EFFECT
One file, three numbers that matter
There are exactly three reasons local FTS5 beats a hosted archive for this workflow. The numbers below are not from a benchmark blog post; they come from reading the migration and the tool descriptions in the Fazm repo.
“A single FTS5 MATCH against a 60-day chat_messages history returns in under ten milliseconds on local SSD, because the index is already built and the file is already paged in.”
Commentary on migration fazmV5, AppDatabase.swift
THE NARRATIVE
What happens between day one and day sixty
The point of a daily digest is rarely the morning you read it. The point is the ability to draw a line from that morning to another one, weeks later, when something clicks. Here is the shape of that arc on a local FTS5 index.
Day 1 — The first digest
Fazm opens a GitHub search URL with pushed:>yesterday in Chrome, reads the list through the macOS accessibility tree, and returns a markdown digest of roughly 20 to 40 repositories. The assistant message gets inserted into chat_messages. Migration fazmV5's AFTER INSERT trigger on line 996 fires synchronously and the FTS5 index absorbs it.
Day 2 through 29 — The habit
Same flow each morning. Each daily digest is a new row. Chat_messages_fts grows by one row per day. No maintenance, no indexing job, no cron. The state of the world is encoded by the createdAt timestamp on each row.
Day 30 — The first real query
Someone asks you about a tool they heard about. You remember seeing something. You ask Fazm, in chat, 'when did I first see X in my release history?' The agent writes a SELECT with chat_messages_fts MATCH and returns the earliest three rows with preview text and timestamp.
Day 45 — The cross-query
A second ecosystem angle shows up. You pull observer_activity rows of type 'pattern' (AppDatabase.swift line 962) for repos that have shipped on five or more days in the same 30-day window. The FTS5 query gives you the first mention; the pattern cards give you the cadence. Two tables, one join, local.
Day 60 — The counterfactual
A model drops and you want to know whether you saw the teaser. The query takes the form SELECT createdAt FROM chat_messages JOIN chat_messages_fts ON rowid = rowid WHERE MATCH 'model_name' AND createdAt < :drop_date ORDER BY createdAt LIMIT 1. Either it returns a row and you have your first encounter, or it returns nothing and you know the teaser never surfaced in your briefings. Both answers are useful. Both are offline.
THE NEIGHBORS
Four tables that sit next to chat_messages
FTS5 is the spine of this page, but it is not alone in fazm.db. The other tables are where cross-day analysis lives. A release history gets most of its value when you can join the text index with the rest of the local state.
observer_activity
Migration fazmV4 created this single table for observer outputs. type values: 'card', 'insight', 'skill_created', 'pattern'. status lifecycle: pending -> shown -> acted or dismissed. Pattern cards are where a 30-day release cadence becomes a first-class record. Lines 958-971 of AppDatabase.swift.
local_kg_nodes
Knowledge graph nodes, indexed by nodeId, with nodeType fixed to one of five values (person, organization, place, thing, concept). Migration fazmV1 lines 916-925. A release can be a thing; the org behind it is an organization; the concepts it embodies are concepts.
local_kg_edges
Relationships between KG nodes: source_id, target_id, label. No constraint on the label. 'ships', 'forks', 'same_day_release', 'fine_tuned_from' all work. Lines 927-935.
indexed_files
scan_files enumerates ~/Downloads, ~/Documents, ~/Desktop, ~/Developer, ~/Projects, and /Applications. Each file row carries modifiedAt. Joining this with chat_messages.createdAt on a date range answers 'did I download the release I was reading about?' Lines 896-913.
ai_user_profiles
Generated profileText with a dataSourcesUsed count. Useful context for summaries that should be personalized. Lines 885-893.
THE ECOSYSTEM SIGNAL
What the past day looks like as of April 2026
For context, here is the kind of material a single 24-hour pull lands in your chat_messages table. These are projects shipping multiple commits a day in April 2026 that anyone running this workflow will see repeatedly. By day 60 they will each have dozens of matching rows in chat_messages_fts.
Inference engines
0
llama.cpp, ollama, vllm, mlc-llm ship near-daily. Each typically lands in the 24-hour pull more than once a week.
Agent frameworks
0
autogen, langchain, crewAI, smolagents, and ACP / MCP implementations dominate the "agents" topic on a 24-hour scope.
Open-weight families
0
DeepSeek-R1, GLM-5.1, Qwen3, Llama 4, Kimi-Dev-72B are the most-named families in recent daily digests.
HOW TO START
The five-minute setup
You do not need to know SQLite, FTS5, or Swift to use this. The migration ran the first time you launched Fazm. Here is the actual sequence of things you do in the app.
- 1
Install Fazm
Download the DMG from fazm.ai. On first launch, migrator.registerMigration('fazmV5') runs inside AppDatabase.swift and your chat_messages_fts table is created empty.
- 2
Grant Accessibility and Screen Recording
Onboarding walks you through both. The AX tree read needs Accessibility; the window capture path needs Screen Recording. No raw OCR is involved.
- 3
Set a recurring prompt
Open chat and say: 'Every morning at 8am, open github.com/search?q=topic:artificial-intelligence+pushed:>yesterday&s=updated&type=repositories, read the top 30 repos, and post a digest here.' The agent schedules the task.
- 4
Let it run for a month
Every morning it posts. Every morning chat_messages grows by one row and chat_messages_fts grows by one row. You do nothing else.
- 5
Query it whenever you want
'When did I first see vllm Vulkan flash attention?' is a complete prompt. The agent writes the execute_sql call; chat_messages_fts MATCH does the actual work.
Want to see a live FTS5 query against my own fazm.db?
Fifteen minutes on a call. We open the chat, ask it when I first saw a model you name, and watch the MATCH return a row with a real createdAt timestamp.
Book a call →FAQ
What does 'open source AI projects releases updates past day' actually mean as a query, and why does the 'past day' wording matter?
It is a time-scoped activity question: everything with topic:artificial-intelligence, topic:llm, topic:agents, or topic:ml on GitHub that was pushed or tagged in the last 24 UTC hours. The 'past day' wording matters because it is ambiguous: it could mean the last 24 hours, the last calendar day in your timezone, or 'recently.' Any useful answer has to store the timestamp you ran it at, otherwise the answer drifts. Fazm resolves this by writing each day's digest into local chat_messages as the assistant response, which carries a createdAt column (AppDatabase.swift line 945 when the table was called task_chat_messages, now chat_messages after migration fazmV3). The timestamp is the only reason you can search later.
What is the one-file citation that makes this page uncopyable?
Desktop/Sources/AppDatabase.swift, migration fazmV5, lines 973 through 1015. The migration creates a SQLite FTS5 virtual table named chat_messages_fts with content='chat_messages' and content_rowid='rowid' (the external-content pattern that avoids storing the text twice), backfills it with INSERT INTO chat_messages_fts(rowid, messageText) SELECT rowid, messageText FROM chat_messages, and wires three triggers to keep it synchronized: chat_messages_fts_insert at line 996, chat_messages_fts_update at line 1003, and chat_messages_fts_delete at line 1010. No other Fazm page cites this specific block. It is the reason you can answer 'when did X first appear' across 60 days of digests in milliseconds on local disk.
Why FTS5 and not just LIKE queries on chat_messages?
Two reasons. First, FTS5 tokenizes on word boundaries, so 'vllm' matches 'vLLM' and 'vllm b7890' without you writing % wildcards. Second, FTS5 builds an inverted index at write time, so the query cost is roughly O(matching documents) instead of O(every row scanned). On a table that has months of daily release briefings, that is the difference between instant and a few hundred milliseconds. The external-content mode (content='chat_messages') means the text is stored once in chat_messages and the FTS table only stores the index, which keeps fazm.db compact.
How is this different from Fazm's other guide pages on the same topic?
The other pages are about today. The 'past 24 hours' page explains the GitHub search URL with pushed:>YYYY-MM-DD and how to read it with the macOS accessibility tree. The 'last day 2026' page shows how the daily pull becomes a 3D force-directed graph. Both are about capturing a single snapshot well. This page is about the compound effect: each snapshot is a row in chat_messages, and chat_messages_fts turns the stack of snapshots into a searchable personal history. The question it answers is 'when did I first see X?', not 'what shipped today?'
What is the exact SQL query I would run to find when something first appeared in my local release history?
Fazm's execute_sql tool (fazm-tools-stdio.ts line 281) passes it through to fazm.db unmodified. A template: SELECT m.createdAt, m.messageText FROM chat_messages m JOIN chat_messages_fts fts ON m.rowid = fts.rowid WHERE chat_messages_fts MATCH 'vllm vulkan' ORDER BY m.createdAt ASC LIMIT 5. The MATCH predicate is FTS5's native syntax: space-separated terms are ANDed, quoted phrases stay contiguous, prefix matches use * (e.g. qwen*). The SELECT auto-limits to 200 rows per the tool's built-in safety cap described at fazm-tools-stdio.ts line 284. UPDATE and DELETE require a WHERE clause; DROP, ALTER, and CREATE are blocked.
What does the daily briefing flow look like end-to-end?
In plain language: open Fazm's floating bar. Say 'pull the last day of open source AI releases from GitHub and save the digest.' The agent opens Chrome, navigates to a GitHub search URL with pushed:>yesterday, reads the result list through the macOS accessibility tree (not a screenshot) using AXUIElementCreateApplication and kAXFocusedWindowAttribute as seen at AppState.swift lines 439-441, extracts repo name, description, stars, and last-push timestamp per card, and returns a markdown digest in chat. That assistant response is persisted to chat_messages by the normal chat pipeline. Because migration fazmV5 wired an AFTER INSERT trigger on the table, the FTS5 index updates the same moment the row lands. Nothing else is required for the row to become searchable. Tomorrow's digest gets the same treatment. Three months from now, every morning's digest is one SELECT away.
Can I do this with a cloud aggregator like DailyDev or a newsletter?
Partially. Aggregators do the scraping well, and the signal they pick is often good. What they cannot give you is personal history: your query against their archive shows their archive, not the digests the agent wrote for you, with the edits you made, with the follow-up questions you asked. The chat_messages table stores the full conversation, including your side. When you search it three months later, you are searching your own reasoning trail, not a public index. That is the compound value. It does not rule out aggregators; it rules out replacing the local store with them.
Does the FTS5 index survive app restart, and does it survive a Fazm update?
Yes to both. chat_messages_fts is a persistent SQLite virtual table inside fazm.db, which is a single file in the user's Application Support directory; it survives relaunch by construction. On a Fazm update, the migration system only runs new migrations (fazmV5 was the last one as of April 2026), so the existing FTS table is untouched. If a future fazmV6 migration ever needs to rebuild the FTS index, it would do so via INSERT INTO chat_messages_fts(chat_messages_fts) VALUES('rebuild'), which is the official FTS5 rebuild command. That is not in the current source tree, so no user data is rewritten on update today.
What tables other than chat_messages can I query for release context?
Three relevant tables sit next to chat_messages in fazm.db. observer_activity (migration fazmV4, AppDatabase.swift lines 958-971) with type values 'card', 'insight', 'skill_created', 'pattern' captures cross-day observations, each with a status lifecycle of pending -> shown -> acted or dismissed. local_kg_nodes and local_kg_edges (migration fazmV1, lines 915-935) store a knowledge graph with nodeType restricted to person, organization, place, thing, or concept. indexed_files (lines 896-908) holds the result of scan_files across ~/Downloads, ~/Documents, ~/Desktop, ~/Developer, ~/Projects, /Applications. A 'when did X first appear in my briefings and did I also download a related file that week?' query joins chat_messages_fts and indexed_files on a date range. All of it is local.
Do I need to be a developer to use any of this?
No. Fazm is a consumer Mac app. You install the DMG, grant Accessibility and Screen Recording permission during onboarding, and use the chat. The agent writes the SQL for you. The FTS5 index is set up by migration fazmV5 the first time the app launches; you never run a CREATE statement. The only thing a non-developer has to do is say, in natural language, what they want to find. 'Search my release history for when mistral first shipped vision plus tools' is a valid prompt. The agent translates it into the FTS5 MATCH query and returns the matching rows.
Is Fazm open source itself?
Yes. Repository is github.com/mediar-ai/fazm. License is MIT. The Swift desktop app lives under Desktop/, the Node ACP bridge under acp-bridge/. Every file this page cites (AppDatabase.swift, AppState.swift, fazm-tools-stdio.ts) is in that tree. Because Fazm is itself an open source AI project that ships updates, it shows up on your own daily topic:artificial-intelligence pull whenever we push. Your local fazm.db ends up containing release rows about Fazm. That is a fun recursive property, not a design goal.
Other angles on the same ecosystem question
Related guides
The GitHub URL and the accessibility tree
How the daily scrape works: the pushed:>yesterday search URL and the macOS AX tree read that turns the rendered page into structured rows.
The past day, as a force-directed graph
The same data, rendered in 3D with real physics. Repulsion, attraction, damping constants, and the 5-second debounce that makes the layout snap.
April 13-14, 2026 announcements
A worked example of what the pipeline captured in a specific 48-hour window in April 2026.