Arising from int-0002 — Zero-ceremony operation — one binary, no server, no daemon
A storage interface (local FS | GitHub API) is committed to before the first surface ships
One abstraction, decided now because everything downstream assumes it: all reads and writes go through a storage interface with two implementations.
- **local** — the filesystem, for the CLI, the hooks, and `dira ui`. - **github** — the GitHub Contents API over OAuth, for the phone and any surface that has no checkout.
Every mutation is expressed as **an entry-file change** (which dec-0002 made a single-file operation). So a write is `PUT one file` on the github backend and `write one file` on local — the same operation shape, and therefore the same code above the interface.
The consequence is that GitHub *is* dira's sync server, and it was already paid for: auth, offline caching, conflict handling, audit history, and access control are all problems GitHub solved. A tap on the phone becomes a commit; the laptop's next `dira reindex` picks it up; the next session's brief contains it. No dira server exists anywhere in this picture — which is what makes the "never required" half of cst-0004 structurally true rather than a promise.
Alternatives on record — 3
✗Build the CLI against the filesystem directly, add an abstraction when mobile arrivesrefused The query and mutation paths would grow filesystem assumptions everywhere — path walking, glob, atomic rename, file locks — and retrofitting an interface through them later is the kind of refactor that gets deferred forever.
The interface is nearly free on day one and expensive on day four hundred.
revisit ifmobile is abandoned entirely as a surface
✗Run a dira sync server so all clients talk to one APIrefused It violates int-0002 and it re-creates the ops burden, on-call, and security surface that a solo maintainer cannot carry alongside kazi.
It also destroys the strongest thing dira can say to a developer audience: your data never touches our servers.
✗Use a third-party sync SDK (CloudKit, Firebase, Turso)refused Adds a dependency and an account for a problem the user's existing git remote already solves, and splits the record across two systems of truth.
Adds a dependency and an account for a problem the user's existing git remote already solves, and splits the record across two systems of truth.