Keeping these notes short-ish, because it wasn't much of a goal-achieving week, and I'm having difficulty remembering where the time went...

Letta Code

Letta released a research preview of their Letta Code utility. Letta is a platform and tool for building AI agents that can create and edit their own persistent memories, and Letta Code is a CLI for using one of those agents as a replacement for Claude Code.

This is exciting for me, because I use Claude Code fairly often, and I see Letta as a potential tool for taming my scattershot attention. The allure of an agent who retains memories about a project I'm working on sounds much better than having to wade through old conversations to find an issue I mentioned off-hand, or something Claude mentioned earlier that I might want to address now.

I gave Letta Code a shot with paperbnd.koplugin, where I had it implement the ability to move books from the "To Read" list to your "Currently Reading" list. I typed in 3 prompts, and the total API calls cost me $2. It would have only been 2 prompts, but the second one mysteriously errored out halfway through.

The results? Pretty good. The code was concise and solid, so no complaints from me. I need to make the decision of whether or not the value of the agent memory and output offset the literal cost. I'm not sure I'm fully convinced yet, but I'm continuing to poke around with it.

Cistern, AKA Fissure AKA Brainstalk

Several years ago, I read a couple chapters of Getting Things Done by David Allen, and I really liked the basic system he presented: when you have a thought, write it down and store it in a place you trust where you can revisit it at a regular, scheduled time.

My trusted knowledge management tool at that point was Logseq--which has the problem of being local-first software. What was the best way to capture a thought on the go, and then have it end up in my Logseq graph?

Thus, I built what I called Brainstalk, named after the Risk of Rain 2 item. It had simple GET/POST/DELETE endpoints for storing and retrieving text snippets, called items. I built out a Logseq plugin, which used a WebSocket connection to sync items in real time to the editor as they were POSTed--courtesy of Deno Deploy's BroadcastChannel implementation.

I'll never forget my first demo to a friend, who thought it was so cool that I could type something into a Siri Shortcut and have it appear on my desktop monitor instantly.

I shelved the project for awhile, as work picked up and I didn't have time. When I came back to it, I had shifted PKM apps several times--I used Reflect, Capacities, and then I was using Obsidian--so I narrowed the scope to just Obsidian and renamed the project Fissure. Nothing else changed, besides the Obsidian plugin and a reworked UI.

Again, work happened. It's not like my need for a quick-capture app went away, so when I left that position, I revisited Fissure. It's not a great project name, so we rebranded again to Cistern, gave it a new coat of paint, and even implemented an MCP server, so you can process items with the help of your favorite LLM.

Where am I going with this?

Well, this week, I got an email from Stytch, the OAuth provider I had settled on, telling me that they had been acquired by Twilio. This bummed me out, but it got me thinking again about the decisions I made building Cistern which I didn't really like:

  • I'm using a managed OAuth service. It's a great way to allow passkey and magic link auth for my service, but it's another cost and security vulnerability. And they can always get acquired by a company I don't like.

  • I'm hosting a database. It's a security vulnerability, you have to trust that I'm not going to look at your notes, and it costs me money.

  • I've implemented my own realtime WebSocket endpoint. I haven't found a satisfying way to standardize and communicate the standard structure of messages to other developers.

If only I had a way to solve those problems, I thought--then I was struck by a realization: What if Cistern was an Atproto app?

Consider:

  • I can use the user's existing BlueSky or other Atproto account, and therefore I don't need to track users myself.

  • I can store records in the user's PDS, so they don't need to trust me with them. There's not much need for an AppView-level cache, either, since Cistern items are only meant to be consumed by their creator.

  • Instead of building my own realtime infrastructure, I can use the Jetstream, and the Lexicon spec makes it easy to communicate message structure to folks who want to work with Cistern items themselves.

The glaringly obvious problem, of course, is that all Atproto data (at this time) is public. My understanding is that this is a problem that can be solved by encrypting the contents of an item before storing the record--so, I have some homework to do as to what methods I should use. This is what I've been occupied with for the last 4 days or so.

Anyways, I've yapped on for long enough; this didn't really end up being that short after all. If you've read this far, I really appreciate you. Have a great week!