Jake Savin

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


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.

More soon…



Leave a Reply

Discover more from Jake Savin

Subscribe now to keep reading and get access to the full archive.

Continue reading