Problem
A workspace store is one kind for its whole life (0.13.0): git-backed, or server-backed. self init --cloud refuses a directory that already holds a store, and no verb moves the records of a git-backed store onto a workspace server.
So a machine that has kept its records in a git-backed store since before 0.13.0 — every project, every log — cannot attach that history to a workspace. Its only path to a server-backed store is self init --cloud in an empty directory, which starts from nothing and repoints the machine away from the history it has.
The gap is being worked around outside the CLI: a browser page that reads log.jsonl from disk and pushes it in batches. That is a snapshot, not a sync, and it lives in the wrong place — the CLI already owns the queue, the push, the author stamp and the refusal table.
What exists already
- Both kinds of store keep the same file per project:
projects/<slug>/log.jsonl.
- The push contract dedupes by
event_id and answers a duplicate batch with nothing applied; a changed body under a known id is a 409, one append at a time.
- The pusher (P1–P10) already handles every response a workspace can give, including the 404 that creates a project the server has never seen.
Nothing on the server side needs to change.
Proposal
One CLI verb that turns a git-backed store's logs into a server-backed store's queue, and then lets the existing sync layer carry them. Sketch:
self init --cloud --from <path-to-git-store>
or a standalone verb (self store migrate), whichever the case table prefers.
What it does, in order:
- sign in and choose the workspace, exactly as
--cloud does today
- for every registered project in the source store, register it in the workspace (or adopt the one already there by slug)
- append the source log's events to the new store's queue, in log order, as unsent
- hand off to the pusher; the machine pointer moves only after the queue is written
What it does not do:
- rewrite the source store: it stays a git-backed store, untouched, so the move can be abandoned by pointing the machine back at it
- fold anything: the fold is the same package on both sides
- convert in place: the one-kind-for-life rule stays; this makes a NEW server-backed store from a git-backed one
Cases the table should settle
- a project the workspace already holds under the same slug, with a log that shares a prefix with the source (adopt, push the tail; duplicates absorbed)
- a project the workspace holds whose log disagrees under a known id (409 — blocked append, the rest go; the report names it)
- an author stamp: source events carry the machine's origin; the pushed copy names the account that migrated them, and the fold must read the same state either way
- partial failure before the pointer moves (the new directory is removed, as
--cloud does today)
- a source store with projects not linked on this machine (registered on the server anyway? or skipped and listed?)
- size: a source log over the batch limit goes in as many appends as the pusher already cuts
Why now
Every store created before 0.13.0 is git-backed. Without this, the server-backed kind is only for new workspaces, and the people with the most history are the ones who cannot bring it.
Problem
A workspace store is one kind for its whole life (0.13.0): git-backed, or server-backed.
self init --cloudrefuses a directory that already holds a store, and no verb moves the records of a git-backed store onto a workspace server.So a machine that has kept its records in a git-backed store since before 0.13.0 — every project, every log — cannot attach that history to a workspace. Its only path to a server-backed store is
self init --cloudin an empty directory, which starts from nothing and repoints the machine away from the history it has.The gap is being worked around outside the CLI: a browser page that reads
log.jsonlfrom disk and pushes it in batches. That is a snapshot, not a sync, and it lives in the wrong place — the CLI already owns the queue, the push, the author stamp and the refusal table.What exists already
projects/<slug>/log.jsonl.event_idand answers a duplicate batch with nothing applied; a changed body under a known id is a 409, one append at a time.Nothing on the server side needs to change.
Proposal
One CLI verb that turns a git-backed store's logs into a server-backed store's queue, and then lets the existing sync layer carry them. Sketch:
or a standalone verb (
self store migrate), whichever the case table prefers.What it does, in order:
--clouddoes todayWhat it does not do:
Cases the table should settle
--clouddoes today)Why now
Every store created before 0.13.0 is git-backed. Without this, the server-backed kind is only for new workspaces, and the people with the most history are the ones who cannot bring it.