Jake Savin

“Have no fear of perfection: you'll never reach it.” – Salvador Dalí


  • A new Frontier: Frontier in the Terminal With a REPL

    Previously: Old databases are new again

    Why implement a REPL? And what the heck is a REPL anyway? Why should I care?

    As some remember, classic Frontier had the QuickScript Window: Type some UserTalk, click Run, get the result in a little output area. It was useful, and we used it. A lot!

    While working on the new headless version, I found myself wanting that quick loop instead of a series of stateless one-off terminal commands that fired up the runtime and returned a result in Terminal.app. It should be something closer to a browser JavaScript console: interactive, inspectable, aware of context, and fast enough to support real exploration. More importantly Frontier is a stateful environment. I needed the runtime to come up and stay up while I was working with it. That was part of the original DNA and I didn’t have it. (And I didn’t want to wait for a GUI to exist to get it.)

    So I built a REPL.

    What’s a REPL and why build one?

    REPL, if the acronym isn’t familiar, is an old idea: read, eval, print, loop. Terminals are REPLs. The Apple ][ prompt is a REPL. DOS and PowerShell are REPLs. SQL shells are REPLs, and even Swift has one. In some ways AI coding agent harnesses and AI chat interfaces are REPLs too.

    This turned out to be more than a convenience. Implementing a REPL for Frontier was the moment I stopped thinking only about porting the system forward and maintaining backward-compatibility, and started thinking deeply about what would make it useful in the modern era beyond (eventually) having a GUI that could connect to a remote headless instance.

    Before this, interaction was awkward: I could run Frontier in the terminal as a one-shot process. I could pass it a UserTalk expression or verb call and get a result. I could move legacy .root files over from Windows and migrate them to the new 64-bit format. I could interact with the object database indirectly through file-based mechanics. But none of that was really interactive – instead it was iterative, painful, slow, and error-prone.

    This was a real problem when I was doing database migration stabilization. I needed to inspect tables and objects, verify that migrated data was sane, and do it fast enough to have a flow. I already had hundreds of unit tests and was building a suite of integration tests to validate UserTalk functionality, but automated tests only get you so far. They tell you something failed, but they don’t give you a leg to stand on while you figure out what the hell went wrong when something breaks.

    What did I actually build?

    The first version of was basically QuickScript in the terminal with scrollback. That was very useful but didn’t bring me much joy if I’m being honest here. First I wanted more interactivity, so next I added a /list dot.path.to.table command to show the contents of a table, and then a /jump dot.path.to.table command to move to a different table (roughly analogous to Frontier’s original Jump/Cmd-J command), with the current table’s dot-path shown in the REPL prompt. That mattered more than I expected: When the prompt shows where you are, it stops feeling like a generic shell and starts feeling like Frontier, albeit just a little bit.

    That immediately changed the way I worked on and tested the headless app. I could inspect objects directly. I could do string (path.to.object) and see the full contents of a script or text object instead of squeezing output through a tiny one-line field like we did in days of yore. I could run verbs, see which ones failed, get a line number, and then go inspect an exported script as text on disk to get an idea of what had gone wrong. (I’d already exported all the script code in Frontier.root to text files.) Even now I’m working today on tightening that loop by adding surrounding-line context directly in the REPL so you can see the context of an error, not just the error message and line number.

    How AI-assisted coding plays in

    The basic REPL “bring-up” was actually pretty easy to do with Claude Code. I explained what I wanted and the first rev was done in 30 minutes or so. The harder parts came later…

    Context tracking for implementing the /jump command was a relatively small lift. Log spew was a bigger issue: The REPL is only useful if you can read it without a bunch of noise, and there was way too much noise. Cleaning that up actually became a broader logging upgrade effort spanning a few days: I built a logging framework with real stdout/stderr discipline, documented how it worked, and added agent policies so they wouldn’t casually pollute the interactive surface going forward. After that came persistent REPL-local variables, essentially a REPL runtime stack that survives across commands. That was a little tricky, but I benefited from knowing the UserTalk runtime and object database really well and was able to do it quickly once I understood how it should work.

    The hardest part, and still unfinished, is dynamic menus…

    Frontier always had (at least while I worked with it) a menu bar that would dynamically change depending on what you were doing: Which object am I editing? What type is it? What tools do I have installed? Is the webserver running? What custom commands does this user have?…

    I don’t want headless Frontier to lose that part of its original character. So I started building a text-based menu system that relies on Frontier’s native menubarType and dynamic menu system, which is mostly implemented in UserTalk code triggered from kernel-level callbacks. It’s invoked with the ‘/’ key the way VisiCalc did it (prior art is super-important!): The slash key brings up a horizontal textual menu and arrow keys or letter keys navigate/activate items and sub-menus. (I wrote about VisiCalc’s menus being carried into Excel in 2013: The Longest-lived Shortcut Key In Personal Computing)

    The Role of AI

    AI helped a lot here, with the biggest lifts being code archaeology, test scaffolding, refactoring and removing dead code, and raw leverage. At that stage my workflow was still pretty interactive and serial: one job at a time, lots of back-and-forth, occasional mistakes and back-pedaling. Most of all, learning what works and what doesn’t.

    The way I work with these things is way more structured now: Typically I do short planning sessions (not always in plan mode), keep a well-maintained backlog, extensive docs and policies, and hooks that prevent breakage, and lots of custom skills at both a global- and project-level that encapsulate how I like to work, and how my way of working works best with AI agents.

    The shift in thinking has enabled larger mostly autonomous workflows with the AI notifying me when it needs help or gets stuck. And I’m still tuning the process continuously. The tools don’t arrive pre-shaped to your standards. You have to shape them or you’ll find yourself frustrated with inconsistent results and a spaghetti-mess of code that you can’t easily reason with, much less fix. (20 years as a TPM is showing its colors here!)

    The part that matters most: The real story here isn’t “AI helped write some code.” It’s all about codifying workflows, and for me this ended up translating to:

    1. Plan first at a high level, review, and iterate on the plan
    2. Make an execution plan if complexity warrants it
    3. Create a worktree and branch to isolate parallel work and protect the main branch
    4. Write tests first (test-driven development / TDD)
    5. Implement and iterate until tests pass
    6. Run the full suite to catch side-effects and regressions
    7. Push a PR as a checkpoint on an atomic work unit
    8. Run a review loop, fix all of the serious issues, and track the rest
    9. Merge and clean up the worktree
    10. Sync the main branch locally and do a human smoke test

    That’s the system that lets me move quickly without turning the codebase into mush. And now I have skills that implement each step, and skills that wrap them into logically related loops, and even more skills that wrap the whole thing in autonomous chains that only interrupt me when the agent needs help, keep running notes as they go in a place I can see them, and enable me to work many times faster than I was when I was implementing the REPL.

    This was an early major milestone for me with agentic coding. Not because it was a huge amount of code, and not because it did something I couldn’t have done myself. But because it changed the frame for me about what was possible with these tools, and what a headless Frontier could become.

    Up to that point I was mostly asking: Can I get Frontier to compile, run, and survive on modern systems with real backward compatibility? An important question to be sure. But once the REPL existed, a bigger question appeared: How do I make command-line Frontier genuinely useful on its own in a modern context?

    And once I started asking that, the next question showed up immediately: What role could Frontier play in the agentic world we’re entering now, and how do the ideas from the prior Frontier era apply in this world?

    That led to other things later, like a protocol layer that would be useful both for future UI work and for AI agents to interact with Frontier directly. But that’s another post. 😉

    This was the moment the project stopped feeling like a port and started feeling like it could grow up to be a truly modern tool.

    More soon…

    Ps. If you work with Claude Code or Codex and need help let me know. I want to figure out how to make this way of working easier for others, but please also be mindful about the fact that I only have so much time in a day and Frontier is not my only high-bandwidth project.

  • A new Frontier: Old databases are new again

    Once I got Frontier building and runing headless (the bootstrap), the next question was: Can this thing survive contact with its own past? This was going to be essential because Frontier doesn’t do very much without at least Frontier.root (the system database) and applications like mainResponder.root, manila.root, and all of their friends and siblings.

    This is where the work stopped being about compilation and started being about trusting the data. A modern Frontier that can’t safely read, migrate, and save old roots isn’t really Frontier.

    A lot of this work turned out to be about the database format itself. Early important decisions included making a new, modern v7 storage format, ensuring it remains cross-platform by deciding on endianness (big-endian), 64-bit format throughout, date/time management that won’t fall over in 2034, addressing via on-disk offsets (again 64-bit), conversion in memory, and exporting old databases to the new format. The file format had to be clean, explicitly shaped and not quietly tied to whatever CPU happens to be running the code. The goals are portability and longetivity, and that kind of thing isn’t trivial and can’t be hand-waved away.

    The approach was to exhaustively document every bit of the legacy format, and use that to inform a set of architectural decisions and documentation that Claude Code could follow and implement in phases. All of it would be test-driven-development (TDD) in order to minimize the likelihood of unnoticed regressions as the work progressed. I worked systematically through every supported object type: scalars first (strings, numbers, decimals, etc), and then externals (outlines, scripts, rich-text objects, binaries, etc).

    This was the long, grinding sequence of work that was needed to get everything to convert correctly to the new format. The migration path had to preserve meaning across a whole zoo of object types, with nested references, old packing assumptions, and database context bugs that only showed up once I started working to convert Frontier.root end-to-end.

    It was a long chain of fixes and refactorings: decode legacy headers properly, route external handles to the destination database instead of the source, force external tables into memory at the right time, separate legacy read behavior from modern write behavior, widen addresses and timestamps safely, make sure guest databases and cross-database references weren’t quietly using the wrong context, and keep testing the whole thing until the migrated roots would actually reopen and behave post-migration.

    One of the hardest pieces was rich text (WPText format). Frontier’s old word-processing format depended on a third-party library called Paige, which is a long-obsolete text engine. I got lucky here: the Paige library had been released as open source by a company that had acquired it because it was critical to their business. That meant I could reverse-engineer the old data-storage format instead of guessing at it or blindly throwing out the formatting information. I ended up building a portable extractor that reads the legacy Paige blobs without using the Paige code at all. It reconstructs the useful formatting information, and converts the content to RTF for modern storage. That was actually a huge turning point that proved again to me that this could actually work.

    I want to be clear: Getting the database working and migrated to a format that would survive in the long-term was not one heroic patch. (By the way, don’t do that!) It was a long archaeological dig, with lots of small corrections that only made sense once the previous work was already in place.

    People sometimes imagine the hard part is “getting the old code to compile.” Sometimes that isn’t even close. Sometimes the hard part is teaching an old system how to tell the truth in the current era while not losing its memory in the process.

    Next: Frontier in the Terminal With a REPL

  • A new Frontier: Bootstrapping

    Previous: A new Frontier: The Real Start

    The early phase isn’t dramatic, but it’s important.

    Before Frontier could become useful again, it had to be buildable on modern operating systems, readable, writable, browsable… survivable. This is where the rubber hit the road.

    One could easily imagine that the hard part about a project like this is preserving the existing code, but the hard part is actually preserving the meaning of the existing code after the world it was written for has mostly disappeared. (And being willing to delete things!)

    When I started in October, the work wasn’t about adding features. It was about setting up the minimum conditions required to worked honestly in this code bringing in the context of modern software development and operating systems: 64-bit, ARM and Intel support, POSIX compliance, ANSI C, modern file handling, dependency minimization, and a database path that didn’t immediately collapse into a pile of mush the second it touched current hardware.

    The core idea was to make it very portable (Linux, MacOS, Windows), very opinionated about sticking to standards (ANSI-C, POSIX, minimal and encapsulated OS-specific API dependencies), and to strip away all of the cruft from the 1990’s and early 2000’s that had been holding Frontier back and making it difficult to reason about. That also meant it needed to start as a headless app, with a CLI interface, and later a REPL. That was the only way to viably push into the modern era.

    Some of the early work was obvious: clearing out dead build scaffolding, old project files, old toolchain baggage, and old assumptions that had survived long past their expiration date. Necessary, but not fun and not particularly interesting.

    Then it got real: A headless Frontier that can’t load Frontier.root isn’t a viable platform since so much of what Frontier is, is implemented in UserTalk in Frontier.root. I quickly turned to a series of pushes on this front: serializer round-trips, byte order normalization, legacy header decoding, migration behavior, root hydration, migrating rich-text to RTF instead of 3rd-party legacy formats, and all the stuff that would have made most people run fast in the other direction. If I didn’t have AI assistance this stage of the work would have been at least grueling, and for me personally probably impossible to do successfully.

    This is also where it stopped being theoretical for me. Once I was in the database path, understanding how the ODB actually worked, and learning where the problems and assumptions were, we went from “let’s see if it compiles” to “Can this code survive in the present tense?”

    A lot of the early wins were small, concrete, and frankly boring: Decode old database headers correctly, convert legacy Pascal-format table payloads to modern ones, stop clobbering the original root files during migrations, add DB scanners so I can see what’s actually there, and build a file access layer that didn’t depend on MacOS or Windows assumptions.

    It turned out that this wasn’t side work before the “real” project. This was the project: The overarching goal was to ensure that Frontier’s old databases could be read, migrated, written back out, and trusted on modern systems. That would open it up and make it possible to work with Frontier again as a real runtime in a terminal context: REPL, debugger, scripting improvements, AI-assisted workflows…

    Leveraging Claude Code I created a substrate for all the future work: Canonical modern database, headless runtime that works with legacy system data and code, planning docs and instrumentation to keep me and the AI honest, and enough structure and “memory” that I didn’t have to reinvent the wheel every time I wanted to work on the next piece.

    It’s not glamorous but this time spent early on was essential for enabling the subsequent AI-assisted work. The critical pieces were first making sure the code could compile and run well enough to shift into a stepwise process for moving things forward against a documented plan. In parallel I developed methodologies for documenting work and next steps: test-driven-development (TDD), architectural docs and decision logs, capturing and codifying important prior art, and a set of Claude Code skills and agents with specific expertise that would accelerate the work and reduce mistakes.

    More soon…

  • A new Frontier: The Real Start

    Previous: Reviving UserLand Frontier (and friends)

    When I started working on modernizing Frontier last October, the obvious story would have been “old codebase gets ported to modern hardware.” That’s not wrong per se, but it’s not what actually happened.

    I had already had multiple conversations with ChatGPT in early/mid-2025 about how a this project might look. They were useful… but not actionable. It was still too daunting to seriously consider attempting. (“Oh hey: Let’s climb Mt. Everest. Wait, it’s how high?!? And you’re not a mountain climber? And you don’t like the cold? And you need oxygen tanks?!? Whoops!”)

    I started hearing more and more about Cursor, so I decided to try it. It’s free to download: What could possibly go wrong? I had some chats with Cursor (not even sure which model), and did some high-level planning and exploration. This yielded real fruit in terms of understanding what was there and what a modernization project might look like and getting some initial documentation in place, but when I tried to start actually implementing the kinds of changes that were needed Cursor fell over and made a mess. Pause.

    So very early on, it was clear that this wasn’t going to be a simple project. Frontier came from a world where a lot of assumptions were implicit and the world has since moved on: 32-bit data structures (including even 16-bit integer and 8-bit ASCII assumptions), legacy MacOS runtime behavior, cooperative multi-tasking with time-slicing, UI code intertwined with runtime code, and a bunch of state that could just sort of “be there” in that world because there was always one user, one machine, one app, one moment in time. That world has been gone for a while.

    A short time later when OpenAI launched Codex, I decided to try Codex CLI. That’s when the real work started, and the rest of October was dominated by Codex-driven work: Initial 32-bit → 64-bit migrations, database updates, and the like. The 32-bit → 64-bit move was the biggest early one, forced by Apple’s ending support for 32-bit. And also Rosetta went away, so that meant networking was going to need a rewrite. Lots of stuff.

    The first phase of the project wasn’t about features at all. It was about establishing the groundwork for a new system that could coexist with modern tools, on modern operating systems, with a contemporary architecture, and cross-platform compatibility. With stdio support. With real multi-tennancy and protected user spaces. The long-lived dream of a Linux version of Frontier was still far away, but with this tooling was now in sight albeit still distant. We had even attempted a Linux port in 2005/2006 and failed. It was just too big of a job for UserLand given the resources available at the time.

    Linux support would mean we had to have 64-bit, ARM support (in today’s world), headless execution, a modernized object database with a migration path and access controls, removing lots of legacy Apple dependencies. So early on in this project I decided we needed to move to standard ANSI C for cross-platform support, and POSIX compliance (same reason). And then I started sketching a rough plan for how to do all this work – initially planning using Codex.

    Around this time (November or December, 2025) all of my nerd friends, and indeed the whole nerd internet, started raving about Claude Code. I installed it. I watched a bunch of videos. I looked at how people were using it. The trigger for me to switch was stumbling across this video on YouTube. Tâches, a non-coder, had created a whole software business from nothing using Claude Code, including a set of agentic tools he called Get Shit Done (GSD), which he shared as open source for anyone to use. That’s what drove me to switch to Claude Code, and I’ve been there ever since.

    Around the same time, I had realized that moving this project forward absolutely required writing things down as I went: plans, notes, phase docs, architectural guardrails, status reports, handoff docs for moving between sessions, and on and on and on… And not just for my edification, but because the AI agents (first Codex, now Claude Code) would absolutely depend on this documentation and breadcrumb trail. Agents only remember what’s in the current session (for now), and whenever I started a new session, poof – it was all gone! This code base is far too large to pull it all in at the start of a session. Frontier is not a toy. 😉

    The earliest work was more archaeology than anything else. You don’t just kick the tires on a codebase like this and start shipping updates. Well, you can, but then you get what you deserve. So the first step was to get the AI to read the code systematically, understand what components existed and how they worked, and document everything. That’s what the preliminary phase of this project was about: Just. Understand. The. Scope. Of. The. Problem.

    Looking back at my October pull requests, a lot of the larger project is already visible there in embryo. Not the details, obviously. But the overarching shape of it. The need for portability. The need to make old databases survivable. The need to separate “it runs on my machine” from “this is now a system we can reason about.” The need to turn hidden assumptions into explicit structure.

    That’s the part that I think people tend to miss about large-scale projects. The hard part usually isn’t getting it to compile or figuring out what features are supposed to be there. The hard part is finding all the invisible details, and the bargains that were made with the environment it came from.

    And Frontier had a lot of those.

    So if I had to point to the real beginning of this project, it wasn’t some flashy milestone later on. It was the moment the work stopped being “let’s revive this old thing” and became “okay, we’re going to systematically rebuild its operating assumptions.”

    That’s a different project.

    And, as it turns out, it was the real one.

    Next: A new Frontier: Bootstrapping

  • Reviving UserLand Frontier (and friends)

    I’m starting a set of posts about how I’m using AI to help bring UserLand Frontier back to life.

    I found Frontier in 1995 when I was living in Amsterdam (another story), and was trying to figure out how to automate dialing into my ISP at night while I was asleep and phone charges were cheap. I wanted to sync my email at night so that I could stay in touch with my people in the US with as little cost as possible.

    I bought an inexpensive Mac Performa 360(?) at a local swap-meet, and quickly discovered, quite by accident, that I could get onto the internet over dial-up, and that there were web servers and web sites and it was all very new and strange and cool. The tools were arcane and hard to figure out, but they worked. The very early web was a mix of nerd, newsey, techie, and social place. I’m definitely a nerd, but I also care about humans in general, and that was the spirit of the space that Dave had been trying to build: Humans matter and the ways they communicate matter. Opinions matter, and the networks of opinionmakers matters. Product ideas matter and we should value experimentation with a foundation of standards – Fundamentally, Individuals matter and we should all have our own voices and platforms. That stood out to me. It resonated with my own values, and I jumpted onboard.

    When it comes to UserLand, I’d already been using and programming in Frontier for about five years before finally joining the company as a developer in 2000. I had already used Frontier to build test automation tools and build tools at Sonic Solutions, (pre-Jenkins-era infrastructure). I’d used it for side projects like the CMS for my first website at jspace.org — an “online journal” (before the terms Weblog and Blog existed) — which was built on UserLand’s website framework. And I was using it as a web-dev at Macworld in 1999 where I contributed to their web publishing workflows and search engine.

    In 2000 I joined UserLand as a developer with Dave Winer as CEO, Brent Simmons and Andre Radke as developers. Frontier was the runtime that enabled Manila and Radio UserLand, both of which were important in the early blogging era. Radio was also one of the first end-to-end podcast-enabled products, back when podcasting wasn’t even a category yet. I ended up as the lead developer and release engineer behind Radio’s launch after the initial prototyping that Dave and Andre did. A bit later on I contributed bits in Manila and Radio UserLand related to the Creative Commons work that grew out of the Berkman Center at Harvard, where Dave was a Fellow at the time.

    I’ve wanted to modernize Frontier for at least ten years. I had a long-tail of things I’d wanted to do inside UserLand before leaving for Microsoft, and since the Frontier kernel was open source it was always possible — at least in theory. But I never had the right combination of available time and C-coding chops, and I lacked familiarity with the deeper parts of the C-based Frontier/UserTalk runtime for it to be a realistic thing to attempt. Brent tried a few approaches and eventually gave up, which says something about the size of the job. (A half-million lines of legacy C code would scare any normal person who valued their personal life, emotional stability, and sanity.)

    The Frontier kernel was started as 16-bit Mac application that ran on legacy Mac OS I think around System 5 or System 6. It was eventually migrated to be 32-bit native and depended on the original Mac Toolbox and later the Carbon API, and basically legacy everything. Today the only build of Frontier that still runs is the Windows version which was released in 1997. When I started this, it couldn’t even be compiled and packaged for macOS because the runtime core wasn’t 64-bit native. It included a rich text editor that was licensed at the C-library level and which was no longer maintained. It had a script compiler based on YACC. It had a database format that relied on 32-bit architectures… and on and on and on…

    An intractible problem for a single developer who wanted desperately to pull this open source project into the modern era, but has a family and a full-time job. And then… AI coding tools arrived.

    I first started discussing what this project might look like with ChatGPT around two years ago. We made a project plan. We figured out where the hard parts🐉 might be. We had a high-level project overview, but no ability to write the code yet outside of copy-paste, and no way to review the existing code en masse. (I was still considering starting the project myself anyway.)

    Then Cursor appeared. Now there was an IDE with AI built-in. So I went to Cursor and fed it my ChatGPT-originated plans and asked it to inspect the existing code and create a more detailed plan. That got me to the next stage: A high-level multi-phase technical plan with more details and some idea about what order the work needed to be done in based on priority and dependency.

    Then Codex arrived, and I was able to use it to do a lot of the 32-bit to 64-bit conversion (required to build for macOS these days) mostly autonomously, although it did have to have a number of revisits.

    And then everyone I know who is using AI for coding was starting to talk about about Claude Code and how amazing it was… I resisted at first. Codex was doing amazing things for me, but it was also tripping up on a lot of stuff and I was starting to get frustrated and a little disillusioned, so I decided to try Claude Code CLI, and boom!💥 It blew up for me. I felt like I had a pair-programming partner with deep skills, broad technical knowledge, and the ability to implement whatever I envisioned as quickly as I could come up with ideas for what was needed next. I was leveraging my 20 years of technical program and project management in ways I would never have envisioned. (And which were never reinforced as valuable in my decades of work in the software enterprise world – again another story.)

    I started creating agents first, and then skills, and then meta-skills and meta-meta-skills — all to help me work faster with fewer mistakes. I wired up workflows within workflows within workflows. Now a few months later, I’ve got a robust tool-chain with quality gates that makes this work happen mostly reliably and with very high quality, where I’m serving the role of strategist and architect, and my AI agents are my team, or sometimes multiple teams. I’ve even taught them how to read, write, test, and debug UserTalk scripts, something their training data would have only barely touched on, if even at all. I enhanced the Frontier runtime itself to make script editing and UserTalk debugging available to my agents.

    The foundation has shifted. It’s thing now, that one motivated person with the right technical background and a clear vision can actually push forward on immense projects as long as they’re not stymied by legacy corporate processes. Not because the work is easy: It isn’t. But the leverage is different.

    Frontier’s modernization might be one of the largest open source C-language projects in the world that’s 100% managed with AI by a single person. Research I did in April suggests this is the case, but that won’t be true forever since these models and agentic harnesses are advancing very fast, and I’m sure there will be more similarly large and complex one-person efforts soon if not already.

    There’s a personal dimension too: In 2006, when I stopped being a full-time developer and moved into program and project management work, I shifted from technical delivery, to managing the work of the people who deliver technical things. Now I’m coding full time again — on Frontier and on ThreadFlow (a startup I’m building with a small group that includes an old Apple ][ hacking buddy from seventh grade who I’ve known for almost 40 years). And it feels great! Not only because I’m mostly my own boss again, but also because I’m working on passion projects: Building great products, with love, that people will enjoy using, and that provide real value in their lives. ♥️

    Frontier for the modern world: Modern GUI, multi-user/multi-tennant system, security by design, and the ability to run all the old apps (maybe modernized versions of them) again — that’s the vision. And I also hope to help revive the pivotal community around Frontier that was inspirational to me, and an idealistic driver of the pre-enshitification vision of what the web could still become.

    Next: The New Frontier: The Real Start

  • RIP Pickles

    Today we said goodbye to Pickles the Wonder Pug, aka Black Lightning. He gave our family nine years of unconditional love, snugs, snorts, and romps—guarding our safety, and protecting us from garbage collectors, mailmen, airplanes, and helicopters. He passed peacefully with his whole family around him.

    Rest in peace, Pick-pick. ❤️❤️❤️

  • I’ve Migrated to WordPress.com

    I’ve been meaning to do this forever, and now the deed is done. I’ve been self-hosting my blog in one way or another, across many platforms and machines since 1997(!), and though I still run my own services for some stuff, keeping my WordPress site healthy, updated, and secure is work I can’t justify doing myself any more.

    So today I used Claude Cowork to help me migrate to WordPress.com hosting. The whole process took about 30 minutes from downloading my content, to creating a new site and signing up for the Personal tier. This will give me plenty of space and the site is now way faster than it used to be. More importantly, I no longer have to worry about maintaining that part of my own IT infrastructure, backups, security, and all the other fun stuff that comes with self-hosting. 🎉

    Over the years I’ve gradually moved more and more of the things I think are important (i.e. I’d be really bummed if I lost them) to providers that can do it better than I can, keeping in mind that I only want to put my data in places where I can migrate it back out if I ever need or want to do that. WordPress has a long history of alignment with the data portability ethos, and I’m happy that my site is now here.

    Onward!

  • Gabe’s Interview With Me On The Music Industry

    My son Gabe interviewed me today about my take on how music has changed over the years with changes in the music industry, changes in music production and technology, and why the music he and I both love so much from the ’70’s and ’80’s is different than so much of the music of today.

    Gabe: Can you tell me the story about Frank Zappa getting out of his record contract again?

    Jake: Yeah, sure. Frank Zappa was signed to Warner Brothers records and he didn’t like the way that they managed his band, and he had a 10 record contract. He had done eight records with them already and he wanted to get out of his contract, but the only way to do it would be to finish all 10 records, so what he did when he got the budget for the 9th album album was go into the studio and use that money to record two whole albums worth of stuff. Then he handed them over and he’s like “here you go, I’m done” First they tried to say that they weren’t up to the quality standard, so they could keep him on the label, right, because they didn’t want him to go somewhere else and make money for someone else. Then he’s like “no they’re totally up to the quality of all of the records that I’ve delivered to you, I’m out of my contract,” and Warner Brothers sued him. He went to court and he and his lawyers won the case and he got out of the record contract, but what this did was cause the industry to change the way their standard contracts are working. So now if you’re a new band and you sign a contract with Warner Brothers or anybody else, they have a minimum amount of time in between each album that you deliver to them.

    Gabe: And what is that time?

    Jake: It depends on the contract – it’s usually a year.

    Gabe: Okay. How do you think commercialization has affected how music is perceived?

    Jake: What do you mean by perceived, like perceived by listeners?

    Gabe: Like from a random person viewing a song. If they don’t know anything about how that was commercialized how do you think commercialization has affected how we perceive music?

    Jake: Well I think the record industry has always really… the way that they sell their products is by selling a kind of mythology around it, right? They sell this story, and for someone like a teenager who’s a big fan of some musician or artist or whatever, they often have this fantasy that they want to be that person. So what the record industry has done is they take advantage of that desire, and they sell this sort of myth like “oh yeah, you can be a singer-songwriter and you’re playing your guitar and singing your songs that you wrote in a coffee shop somewhere, and one day a record executive will walk in and hear you, and they’ll sign you to a big contract and make you a whole lot of money, and you’ll be rich and famous and your life will be awesome.” I experienced this when my band was trying to get a record deal. They would make all kinds of crazy promises and put all kinds of famous, well known people in front of you to try and sell that myth to you, right? I remember one time we were working with a guy who was a mid-level music producer and he happened to know this man who was the A&R person who had signed The Who, and they set up a meeting, and took us to a really nice restaurant in his really expensive Mercedes. They bought us really expensive food, and he told all these stories like, “Oh yeah, when I was signing The Who, they all wanted movie theaters in their houses, and they all wanted Rolls Royces, and they wanted all new instruments,” and all this stuff, and he was trying to imply that we can have that too. Of course he was in no position at that point in time– this was decades later– he was in no position to make any promises like that, but by telling us the story it made us feel pressured to sign a deal with them, which we ended up no doing because we didn’t trust him. We used the excuse that not everyone in the band was there, so we basically spun it like, “Now we can’t speak for the rest of the band we have to bring it to them but we’ll sign your letter of intent.” And then we turned them down for that reason. But we were worried because we didn’t really have any money, and if he had taken us to court or something, you know if we had signed something with them and then backed out of it, it might have been a big problem for us. But that’s what the record industry has done forever – they sell this, I call it the “Rock and Roll Myth”, but they do the same thing to the AR people – like the people who work for the record companies whose job it is to go out and find new music – they sell them the same myth, right? They’ve got this, you know, 20 year old kid just out of college or whatever, and they tell him to come to work for Warner Brothers or come work for Sony or come work for Universal Music Group and you can find the next to Beyoncé, or you can be that person who finds the next big hit, so they sell them the same thing! Then when those people come in and pitch this band they want to want to sign with their record label, they’re telling you a story that they actually believe themselves, right? So what that creates is then all of these artists are just clamoring to go sign these deals, but the deals are usually terrible. They hardly make any money from the records, and the royalties for online streaming are really small. These days it’s different now, because all the distribution is all online but the business is the same. Most artists make most of their money from concerts, but it also could be from merchandising like selling T-shirts, or selling posters or bumper stickers and things like that. But a lot of artists these days make a lot of money by doing sponsorship deals, so they’ll have their personality on their Instagram – you know they’re an influencer – and they’re they’re using some product, so it’s really a kind of advertising, right? It’s not really about the music anymore and they’re selling a story about that person’s life. So the record companies have decided is that there’s a lot more money in it for them, and it’s a lot cheaper for them to just churn out hits from the hit machine, out one hit after another, and they sound like everything else because they just write the same kind of thing over and over again – they’ve got writers you know and musicians that they hire and pay them hourly or they pay them a salary – and they just churn out this generic music. They don’t even usually take the time anymore to do what they used to call “development deals”, where they’ll give somebody some money so that they can quit their day job and have enough time to actually write, and get really good at their art. They don’t really do that anymore either.

    Gabe: So what do you think we can do to improve the music standards today?

    Jake: Well I think the industry is so different now. There’s a lot less money in it because they’re not selling CDs. I think it’s it’s easy to forget that when CDs first came out everybody had vinyl records and cassette tapes, and the CDs sounded so much better that everyone wanted the digital recordings, and so people bought their whole collections that they already had on on vinyl – they bought those same things over again on CD. But instead of costing $8, CDs would cost like $15 or $18 and they made a huge amount of money from that in a short period of time. And now nobody buys music anymore. It’s all online streaming, so there’s no way to get someone to pay $20 to get the same album that they already had.

    Gabe: Lots of people get it for free…

    Jake: Yeah or they pay a monthly fee to a streaming service like Apple Music or Spotify or whatever, so the economics are really different. The record companies make money in other ways now. I’m sure in the Super Bowl halftime show everything that they were wearing in that show is something that, you know, some manufacturer of that product, including all the shoes, the roller skates, all that stuff they – are paying the record companies to put their stuff in front of people. It’s a really good thing is that music production is so much cheaper to do now, and you can record a whole album on your laptop and the quality is just as good. You need a couple of really good microphones maybe, a few hundred dollars a piece, and maybe a couple of instruments and then everything else is in software.

    Gabe: But don’t you think that can affect the quality? Like how much time you put into a song or an album can affect the quality?

    Jake: Yes, absolutely. What’s different now is that because the recording equipment, like the ability to record an album, is so much less expensive that people don’t have to have a record label to do a record – you can do it yourself. And if you look at Billie Eilish, she and her brother recorded that first album in their bedroom, and they spent years getting it right. They had as much time as they wanted to spend on it because they didn’t have to answer to anyone else. They didn’t have to turn in an album on time and they weren’t limited by how much studio time they could afford to pay for, so they could do it all themselves and they could spend as many hours on it as they wanted to. And I think that’s why that first album was so good and why so many people really liked it. The disadvantage though is that you have to learn how to do it, and most people don’t understand the recording process well enough to do a good job. Another problem is that a lot of people are thinking that they’re are a lot better at music than they actually are – but the people who are good at music can now make it themselves. The problem is: How do you get people to learn that you exist? That’s what the record labels are for in historically, right? And there are ways to do it now. You can become an influencer yourself, you can play lots of shows out in your hometown. But it’s a lot of work, and it’s the same kind of work that’s it’s no different than when I was trying to do it back in the ’90’s. You just have to put in a lot of work, and play lots of shows for people, and promote yourself. 

    Gabe: What was the greatest era of music to you, because a lot of people say that the 70s was the best era, but what was your favorite and why?

    Jake: It’s a tough question for me to answer because I like so many different kinds of music, and there’s some music that’s coming out now that’s really fantastic. There’s even some mainstream music that’s coming out now that I especially like. Some of the new jazz is really cool. Beyoncé just did a country song which actually is not terrible, although I could do without the music video. But I think if I had to pick like a decade that had the largest amount of my favorite music it’s probably the ’70’s or more specifically around 1975 to 1983.

    Gabe: So compared to now what do you think the difference of quality comes from in that period from the ’70’s into the early ’80’s?

    Jake: Almost nobody had synthesizers then, and if they did they had actually to play them themselves. They didn’t have computer sequencers. There were some drum machines but they weren’t very good and they were not used very much especially in rock music. Part of the sound of a rock band is the drum set so people actually had to learn to play drums, and if you’re recording in the studio and you don’t have digital editing then you have to actually be good at playing – you can’t just be kind of okay. Nowadays because everybody can edit every note to the exact position they want, and if there’s a pitch that’s wrong they can correct it, and there are all these tools that make it easy to not have to actually learn your craft as a musician or a singer – that wasn’t the case in the ’70s. Like you had to actually know what the hell you were doing.

    Gabe: Do you think the shift in people not using actual instruments is a good thing or a bad thing and why?

    Jake: I think that the tools that are available today are so amazing and varied and fantastic, and there are some musicians that are using them in very creative ways. Some of the bands that a lot of people know about do this kind of stuff, which sort of crosses over between Rock and computer-based music and digital sounds, and I think there are a huge number of creative opportunities that are available. But I think that because of the way the industry works everybody is just churning out things so fast that they don’t take the time to actually apply that creativity, so I think it’s a great thing if you want to make something really new, but it’s very hard to stay focused long enough to do a good job.

    Gabe: How do you feel about new pop and the modern era of rap and pop in general?

    Jake: I mean I never really been a huge pop music fan except when I was, you know, in my preteens, just because the industry’s always been that way. Look at music from the ’50’s: A lot of those songs sound a lot the same. There were few musicians that contributed to some of that music that were really fantastic and amazing and have had a huge influence over many many years like Carol Kaye who was a really famous bass player from that era. But generally speaking I’ve never ever really liked pop music that much. Rap music – I liked some of the gangster rap that came out in the ’90’s. I like the Beastie Boys – some of their stuff not all of it – but I don’t like the so-called “new rap”. I think to me it sounds lazy from a musical standpoint, and honestly some of it is just offensive. And the music is not interesting at all. The backing tracks would be like three bass notes and a couple of kick drum hits and like maybe a synth pad, and stuff like that, and there’s just nothing there. So I honestly I don’t understand the appeal.

    Gabe: It feels empty?

    Jake: It feels very empty, yeah. It’s doesn’t have a dynamic shape, it doesn’t tell a story, and it’s just flat. I think this is one of the reasons why country music is starting to get more and more popular. I was just looking at a survey at work about this. I think it’s because country songs have had a very long tradition of telling stories, and people, humans, are really wired to hear a good story – which by the way is why it was so easy for the record labels to sell The Rock and Roll Myth – because you want to be in the story. You want the story to be about you, right?

    Gabe: Why do you think music in general is important? What do you think is music’s overall impact on society?

    Jake: That’s a great question. When I had switched my major from psychology to music when I was in college, my girlfriend at the time was kind of questioning me like, “What are you going to do with that? How are you going to do good in the world?” And I was not very articulate about it, but I tried to make a case for how music connects people together, and how it helps them to learn about their own emotions by hearing someone else talk about how they’re feeling and what their experiencing just like literature does. But I also think that music… there’s something about the way that humans work, you know, even very ancient cultures had music and drumming and dance. So some of it also is about preserving traditions and transmitting culture to new generations. I also think that it’s there’s a sort of tangible, physical experience and emotion that you get when you hear a really amazing song or really amazing piece of music. It can really be emotionally moving, and I think that that just shows how strongly connected people are to that mode of expression. Asking why music is important is a little bit like asking why talking or writing are important. It’s all about expression and communication and connection.

  • Thanksgiving 2020

    It goes without saying, but I’ll say it anyway: Much of 2020 has been an abysmal dumpster-fire of a year.

    Between election insanity, ongoing political divisiveness and disfunction, systemic racism, economic inequality, the still-raging pandemic and the vast number of individual tragedies that have been caused by it, and the ever-looming disaster of climate change, uncertainty and fears about our future are seemingly everywhere.

    In spite of all this — or perhaps because of it — I wanted to list some of the things I am thankful for.

    Thankful for Family

    I’m thankful for my wonderful, smart, loving wife Cindy, and our amazing and funny born-leader of a son Gabe. The two of them bring me so much joy. I never imagined I would love two people as much as I do, and with each passing year that love has only grown. 🤗

    Everyone in my family is healthy. Cindy and Gabe are both doing well. Remote schooling is going fine even though Gabe the extrovert misses in-person classes. Our black pug, Pickles, is awesome and helps keep us sane. We live in the beautiful city of Seattle, and we love our neighborhood. We’re warm and dry and safe.

    My extended family are also healthy, with work, roofs over our heads, happy kids, and plenty to eat. We’re all in the Pacific Northwest now, and have even managed to see each other a little bit – very carefully – during the pandemic. Cindy’s family are back east, and like mine, they’re also all healthy and generally happy.

    I am thankful that we’re all hanging in there through this incredibly challenging time, and have been relatively unaffected by the pandemic and the horrible political climate we’ve all been living in. Love to all of you!

    I Have a Job I Love

    In April, I was let go from Rover.com where I’d been working for just over a year, due to the impacts of COVID-19. I immediately made it my full-time job to find work, knowing that many people would be doing the same and there would be a lot of competition. I was amazed at how the tech community very quickly built networks and resources for everyone who now found themselves in the same position as myself. Especially here in Seattle, we really rallied, both for the people we knew personally, and for those we didn’t.

    For me, the search ended after about six weeks when I landed a full-time position with Amazon Music, via a referral from Phil Kimmey who was my manager at Rover, through his cousin who worked at Amazon Music.

    Starting a new job 100% remotely hasn’t been without its challenges, but I am loving it so far. And I am incredibly thankful not just for the work itself, but also that I’m again working in a space that overlaps my two passions – technology and music.

    America Came Through for Biden

    I won’t go into any details. There’s quite enough of that to go around elsewhere on the Internet.

    I am extremely thankful that America came through for Biden and therefore for itself. There are still many huge problems to solve, and now that the election is finally behind us and the transition has started, we again have hope that we can make progress on solutions.

    Happy Thanksgiving everyone, and here’s an early toast to 2021! 🍾

    P.S.: I almost forgot! We now have multiple vaccines that appear to be highly effective, along with evidence that the immunity they imbue will be long-lasting. Now that America has come through for itself with the election, there’s a very good chance that many or most of us could receive one of these in 2021. And once we’re past the crisis-point in this epidemic, we will be able to take on the other huge issues that face our nation and the world.

  • What Happened at Tonight’s Debate?

    What Trump thinks happened in tonight’s debate against Joe Biden:

    What actually happened: