Overview
I want to split Seraph from Ordinal, and make it its own module.
Right now the revision system is smeared across revisions.py, commit_flow.py, and a handful of places in the renderer and context builder. Multiple parts of the system know a little bit about how revisions work, and they all make assumptions about each other. Revision data gets created in one place, interpreted in another, and finished somewhere else.
The database path is derived from content_dir and hardcoded to content/.revisions/revisions.db. That puts build state inside the content tree and makes it look like authored material.
The sqlite connection uses row_factory = sqlite3.Row, and those rows get passed straight out of the revisions code. Callers then poke at them using string keys like row["worked_hours"], row["meta_json"], and row["timestamp"]. At that point the schema is no longer private. Every caller has to know column names, which fields can be missing, and how nulls behave. That knowledge is duplicated all over the codebase.
What I actually want is very simple. The revision system produces two kinds of data: commit records and article cache records. Each of those needs a defined structure. The same fields should exist every time, with the same names and the same kinds of values. Type coercion, defaults, and parsing should happen exactly once when the data is loaded. If the representation is dicts, the keys need to be consistent. If it's dataclasses, they still need a clean way to turn into dicts for templates and JSON output.
Anything that depends on commit history, previous values, or stored metadata belongs in the revisions code. commit_flow should not be inspecting raw rows to figure out previous totals. The renderer should not be parsing meta_json or knowing how revision fields are stored. Nothing downstream should be deriving values from raw storage fields. They should just receive data that is ready to use.
More to come...