Field notes from a single weekend
The three open-source AI commits that shipped on April 25-26, 2026 and made my Mac agent better at seeing itself
The big roundup pages for that weekend list model weights and arXiv papers. They are not wrong, but they are aimed at one floor of the building. On the floor below, where a desktop AI app actually meets your machine, the work that landed in those 48 hours was three commits in a public repo. None of them shipped a new model. All of them changed what the agent on your Mac could honestly do once a model answered. This is a chronological recount of those three commits, the files they touched, and what each one made possible the Monday after.
“133 of 138 Feedback Submitted events in the last 30 days had length 0.”
Commit 2fbc891c, body, m13v/fazm, 2026-04-25
The three commits, in order
- Sat 20:26 PT
2fbc891cDistinguish silent from modal feedback in analytics. - Sun 14:12 PT
bdf57afdRelease 2.4.2 (CHANGELOG.json bump, four user-visible fixes). - Sun 16:02 PT
be29a3c7Update SQL tool description with observer_activity schema notes.
Reproduce locally with git log --since=2026-04-25 --until=2026-04-27 --pretty=format:"%h %ad %s" --date=short in a clone of github.com/m13v/fazm.
Saturday, April 25
The analytics patch that exposed 96.4% of self-reported user feedback as silent log uploads
The fastest way to ruin a feedback funnel is to fire the same PostHog event for two genuinely different things. Fazm has a floating action bar with an exclamationmark.triangle button labelled Report an issue. The intent is one-click log upload, no form. The implementation, until April 25, called FeedbackWindow.sendSilently(), which fired Feedback Opened and Feedback Submitted (length 0) in the same tick. From the funnel's point of view a silent log upload looked indistinguishable from a real form-based complaint.
What the commit body actually says, verbatim: 133 of 138 Feedback Submitted events in the last 30 days had length 0. Almost the entire stream of inbound feedback was the floating-bar button, not the modal. Anyone reading the dashboard before April 25 would have concluded that users were submitting empty complaints, when in fact users were uploading logs through a completely separate code path.
The fix is two characters of intent and a property bag. The Swift call sites for the floating bar pass source: "silent"; the modal-form code path passes source: "modal" (the default). Now the funnel can be filtered to real form-based feedback and the dashboard stops lying.
commit 2fbc891c, Desktop/Sources/PostHogManager.swift
// Desktop/Sources/PostHogManager.swift, before commit 2fbc891c
func feedbackOpened() {
track("Feedback Opened")
}
func feedbackSubmitted(feedbackLength: Int) {
track("Feedback Submitted", properties: [
"feedback_length": feedbackLength
])
}This is the boring kind of open-source AI work that no roundup ever covers and that every product eventually has to do. Telemetry hygiene is half the surface area of any agent that shipped a year ago. Most of the user-feedback decisions a consumer AI app makes downstream of release week are made on dashboards. If the dashboard is wrong, the decisions are wrong.
Sunday, April 26 at 14:12 PT
v2.4.2 went out, mostly papering over the seams of a busy week
The release itself is a CHANGELOG.json bump (commit bdf57afd) and a Codemagic build trigger. What it carried into users' hands is small but intentional. Read these the way you would read a diff in a long-running open-source repo: each line is the shape of a complaint someone filed.
v2.4.2, 2026-04-26, four user-visible fixes
- Smart (Opus) model preference no longer disappears after an app update. Stored opus now maps to the renamed ACP model ID instead of falling back to Sonnet.
- Workspace directory picker primary button reads Select instead of Open, because Open was confusing in a dialog that does not open the folder, only assigns it.
- Custom API Endpoint help text now names local LLM bridges as a first-class example, not just corporate proxies and GitHub Copilot gateways.
- Stripe checkout cancellation redirect no longer dumps users on a generic error page when they back out of a subscription flow.
The third bullet is the one that connects to the wider news cycle for that weekend. The Custom API Endpoint accepts any Anthropic-compatible base URL. Until v2.4.2 the help text implied that meant a corporate gateway or a GitHub Copilot proxy. Naming local LLM bridges turns the field into the official integration point for whatever Hugging Face checkpoint you happen to be running on your own hardware. Point ANTHROPIC_BASE_URL at a local serving layer, restart the app, and the same accessibility-tree tool surface rides along behind whichever model you point at it.
The Smart/Opus mapping fix is a smaller story but a familiar one. When a backend renames a model ID, every client that stored the old key has to translate at read time or the preference goes stale. The fix is a one-line lookup that rewrites the persisted opus key to the new ACP ID before comparing against the live available-model list. Boring plumbing, the kind that exists in every cross-version client that wants to survive its own backend.
Sunday, April 26 at 16:02 PT
The six-line schema doc that taught the agent how to read its own observer_activity log
Two hours after the release went out, commit be29a3c7 landed. The diff is six lines of natural language inside a tool description string in acp-bridge/src/fazm-tools-stdio.ts. No new code paths. No new endpoints. Just words.
The SQL tool runs against the local fazm.db SQLite database. One of its tables is observer_activity, which logs every Card-style nudge the observer surfaced (a meeting reminder, a task suggestion, a stale-tab notice). The table's columns are id, type, content, status, userResponse, createdAt, actedAt. The catch: the human-meaningful fields (the card's title, body, the option labels the user could click) live JSON-encoded inside content, not as siblings. Before April 26, when a user asked what did I dismiss yesterday, the agent would write SELECT body FROM observer_activity WHERE ... and bounce off a column-not-found error. After April 26 the tool description tells the model the truth.
commit be29a3c7, acp-bridge/src/fazm-tools-stdio.ts, line 282
// acp-bridge/src/fazm-tools-stdio.ts, before commit be29a3c7
description: `Run SQL on the local fazm.db database.
Supports: SELECT, INSERT, UPDATE, DELETE.
SELECT auto-limits to 200 rows. UPDATE/DELETE require WHERE.
DROP/ALTER/CREATE blocked.
Use for: app usage stats, time queries, task management,
aggregations, anything structured.`,What does this look like at runtime, end to end? When the user asks what reminders fired this morning, the bridge sends the updated tool description with the SQL request. The model writes a SELECT json_extract(content, '$.title') query. The bridge runs it against fazm.db, gets back rows, and pipes them back through the tool result. The model now has the real card titles, not opaque JSON blobs.
end to end, after April 26
This is the smallest possible kind of code change with the largest possible kind of effect on agent behaviour. It is the difference between a model that bluffs through a schema and a model that reads the schema and quotes it back. None of this looks like AI work in the way the news cycle defines AI work. All of it is what the news cycle's output runs on, once it reaches a real machine.
Why the boring layer matters more than the headline layer
Every weekend in late April 2026 produced a wave of new checkpoints, new fine-tunes, new arXiv preprints. None of them showed up on a Mac without a client that knew how to talk to them. The client work is rarely flashy. It is help text on a settings field, a property name on an analytics event, a schema-notes paragraph in a tool description. It is the work that decides whether the model on the other end of your local API endpoint can actually answer the question you asked.
The pattern across these three commits is the same: be honest about what your software actually sees. The PostHog patch stopped the dashboard from claiming users had submitted 138 empty complaints when they had really uploaded 133 logs. The v2.4.2 help text stopped pretending the Custom API Endpoint was only for corporate proxies. The schema-notes paragraph stopped letting the agent guess at table layouts. None of those is a model release. All of them are open-source AI updates in the only sense that matters once the model has finished downloading.
The repo is at github.com/m13v/fazm. The four files referenced in this piece are Desktop/Sources/PostHogManager.swift, Desktop/Sources/FeedbackView.swift, acp-bridge/src/fazm-tools-stdio.ts, and the top of CHANGELOG.json. Every claim in this article points at one of them.
Want a Mac agent that reads its own database honestly?
If you spend your week on small-business desktop work and want to see what local accessibility-API control looks like end to end, book 20 minutes.
Frequently asked questions
What actually shipped in fazm on April 25-26, 2026?
Three things, all in the public m13v/fazm repo. April 25 at 20:26 PT, commit 2fbc891c added a source property (silent vs modal) to the Feedback Opened and Feedback Submitted PostHog events in Desktop/Sources/PostHogManager.swift. April 26 at 14:12 PT, the v2.4.2 release went out (CHANGELOG.json, version 2.4.2, date 2026-04-26). April 26 at 16:02 PT, commit be29a3c7 appended a six-line schema-notes block to the SQL tool description in acp-bridge/src/fazm-tools-stdio.ts so the agent could query its own observer_activity log without flailing on column lookups.
What is the 96.4% number from?
Verbatim from the body of commit 2fbc891c: 133 of 138 Feedback Submitted events in the last 30 days had length 0. That is 96.4 percent. The cause was the exclamationmark.triangle Report an issue button on the floating bar, which calls FeedbackWindow.sendSilently() and used to fire Feedback Opened plus Feedback Submitted (length 0) instantly, indistinguishable in the funnel from a real form-based complaint. The fix added a source property so silent log uploads can be filtered out of the funnel.
Why does a six-line SQL tool description matter for an open-source AI project?
Because the SQL tool is how the local agent inspects its own activity. Fazm stores Card-style observer prompts inside the observer_activity table at /Users/<you>/Library/Application Support/Fazm/fazm.db, but the actual title, body, and option text live JSON-encoded inside the content column, not as siblings. Before April 26 the agent would write SELECT body FROM observer_activity WHERE id = ? and get column-not-found. After commit be29a3c7 the SQL tool's description tells the model: card fields like title and body live INSIDE content (JSON blob), not as columns, use json_extract(content, '$.body') to read them. Six lines, but the agent stopped guessing.
What did v2.4.2 fix?
Four small things, all on April 26, 2026. The Smart (Opus) model preference no longer evaporates after an app update, because the persisted opus key now maps correctly to the renamed ACP model ID. The workspace directory picker labels its primary button Select instead of Open. The Custom API Endpoint help text mentions local LLM bridges as a first-class example, not just corporate proxies and GitHub Copilot gateways. The Stripe checkout cancellation redirect no longer dumps users on an error page when they back out of a subscription flow.
Where do I verify this myself?
git clone https://github.com/m13v/fazm, then cd fazm and run git log --since=2026-04-25 --until=2026-04-27 --pretty=format:%h %ad %s --date=short. You should see commits 2fbc891c, bdf57afd, and be29a3c7. Open CHANGELOG.json and the entry { version: 2.4.2, date: 2026-04-26 } sits near the top of the releases array. The exact diff for the SQL tool description is in acp-bridge/src/fazm-tools-stdio.ts around line 282. The PostHog source property change is in Desktop/Sources/PostHogManager.swift around line 520.
How does this compare to what other open-source agent projects pushed that weekend?
Different layer of the stack. The headline open-source AI items everyone covers for late April 2026 are model weights (Llama 4 Maverick refreshes, Codestral 2 under Apache 2.0, Hugging Face fine-tune drops) and protocol releases. Fazm lives one floor down, where the model meets the user's actual machine. The April 25-26 commits are not about new weights, they are about whether a desktop agent can talk to its own database honestly, whether telemetry reflects real user intent, and whether your saved model choice survives a routine release. Boring on paper, load-bearing in practice.
Why ship a telemetry patch as an open-source commit instead of a backend feature flag?
Because the funnel pollution was on the client. The exclamationmark.triangle button calls feedbackOpened then feedbackSubmitted with length 0 in a single tick from FeedbackView.sendSilently() in Desktop/Sources/FeedbackView.swift. No backend flag could undo events the client had already sent. The only honest fix is to label the events at the source. Once the Swift call sites pass source: silent, every consumer downstream (PostHog dashboards, the Project Funnel Stats job, the support workflow that triages real complaints) can filter on it.
What is observer_activity and why does the agent want to read it?
It is the local SQLite table that records every card the observer surfaced to the user (a meeting reminder, a task suggestion, a stale-tab nudge), what the user did with it, and when. Columns are id, type, content, status, userResponse, createdAt, actedAt. The agent reads it when you ask things like what did I dismiss yesterday, what reminders fired this morning, or how often have I clicked through on the Calendar follow-up suggestion. Without the schema notes shipped on April 26, the agent would treat content as a string and miss the structured fields. With them, it reaches the JSON inside.
Is the SQL tool dangerous?
It is scoped on purpose. The tool description (acp-bridge/src/fazm-tools-stdio.ts, lines 280-300) declares: SELECT auto-limits to 200 rows, UPDATE/DELETE require WHERE, DROP/ALTER/CREATE blocked. So the agent can read its own log freely, can mark a card as actedAt-not-null after you tell it to, but cannot truncate the table or drop the database. The April 26 commit only added documentation, not new permissions.
How does the Custom API Endpoint change in v2.4.2 connect to the open-source AI release cycle?
Help text. Before v2.4.2 the field hinted at corporate proxies and Anthropic-compatible gateways. After v2.4.2 it names local LLM bridges explicitly, which is the integration most relevant to anyone running Codestral 2, Llama 4, or any Hugging Face checkpoint behind a local serving layer. You point ANTHROPIC_BASE_URL at http://localhost:<port>/v1 and the same MCP catalog and accessibility-tree control surface ride along. The product side of fazm is now openly inviting that workflow as a primary use case, not a hack.
Adjacent reading
AI news in the last 24 hours, April 2026: model releases, new papers, open-source projects
The wider context for what landed during late April 2026, traced back to the source files that absorbed it.
AI news April 16-17, 2026: model releases, papers, open source, and the one JSON file
The MCP-server registry that turned every Claude Code tool into a native Mac control surface, in one config file.
Claude Cowork and why desktop agents need accessibility APIs not screenshots
Why the layer below the model matters more than the model. AX trees vs. pixel pipelines on retina, dark mode, and a UI tweak.
Comments (••)
Leave a comment to see what others are saying.Public and anonymous. No signup.