openspec/work/simplify-context-and-workspace-model/slices/store-lifecycle-proof/spec.md
A registered standalone OpenSpec repo provably supports the same basic lifecycle as an OpenSpec root inside a project repo, including the sharing path that is the reason standalone repos exist: a teammate or second machine can clone the repo, register it, and continue the work.
To make that proof honest, this slice closes the gaps the lifecycle trips over today: setup that leaves a commitless Git repo buried in app data, register errors that loop into each other, and command guidance that drops the selected store mid-flow.
The proof itself is one chained journey test that drives the built CLI through both checkouts and asserts that the end state is nothing but normal OpenSpec files.
--init-git becomes the default, setup commits
exactly the files it created, and setup never silently chooses the XDG
data directory: non-interactive runs require --path, and interactive
runs prompt for a location even when an id is supplied. A store is a
repo the user places, not app data. Because Git cannot track empty
directories, setup adds tracked placeholder files to otherwise-empty
store directories so a fresh clone reproduces the healthy root shape.
Setup verifies a usable Git commit identity before creating anything
and fails with the exact fix when it is missing, rather than inventing
an OpenSpec-local identity.--store <id>, the root banner
also prints on failures once resolution succeeded, and new change
names the next command. status stops printing workspace-era
"Planning home" language.context-store unregister as the escape hatch. The unhealthy-root
refusal says what is missing, including the empty-clone case.view (Phase 4), agent guidance and help-surface
discoverability (slice 1.4), context-store terminology renaming (L7),
archive browsability via list/show (L11), doctor repairs, and
multi-checkout support for one store id on one machine.A human says where their planning repo should live, and one command makes it a real repo:
openspec context-store setup team-context --path ~/src/team-context
The folder is a Git repository with an initial commit containing the store shape. The next-steps output teaches the two things the user needs: how to put work in the store, and the one thing OpenSpec will not do for them:
Next: run normal OpenSpec commands against this store, for example:
openspec new change <change-id> --store team-context
To share this store, commit and push it like any Git repo.
A teammate clones the repo and registers it:
git clone [email protected]:acme/team-context.git
openspec context-store register team-context
Because setup committed the store shape, the clone is immediately a healthy
OpenSpec root and register succeeds without ceremony. From then on, both
machines run the same normal commands with --store team-context, and every
hint those commands print keeps the store in the loop, so following the
output never strands the user in the wrong root.
context-store doctor tells the Git truth without touching anything:
whether the repo has commits yet, whether there are uncommitted changes, and
whether a remote is configured. It reports; the user (or their agent)
decides what to do.
In scope:
context-store setup Git defaults: initialize Git by default
(--no-init-git remains the opt-out) and create an initial commit
containing exactly the files setup created..gitkeep) in store directories
that would otherwise be empty, so the committed shape survives cloning.context-store setup requires an explicit location in non-interactive or
JSON mode; interactive mode prompts for one, suggesting a user-visible
path rather than the managed XDG data directory.context-store doctor human and JSON output:
commits present, uncommitted changes, remote configured, with warnings
for the commitless-repo clone trap and for store directories that exist
but contain no tracked files.new change,
status, instructions, list, show, validate, archive): hints
carry --store <id> when a store is selected, the root banner also
prints on post-resolution failures, and new change names the next
command.Planning home line from status output.Out of scope:
view anywhere in this slice; opening the right files together is
Phase 4.context-store terminology renaming (L7).list/show (L11).--fix behavior.git init plus one initial commit are
the entire Git write surface of this slice, and doctor's Git reporting
is read-only.context-store setup without Git flagsopenspec/specs/ and openspec/changes/archive/) contain a tracked
placeholder file, because Git cannot track empty directoriescreated_files and the initial
commitopenspec/specs/ or openspec/changes/archive/ directories
are emptycreated_files and in setup's commit
when Git is in play--no-init-git--path--path usage--path, even when the store id is supplied~/openspec/<id>), not the managed XDG data directorycontext-store setupgit config
commands that fix itgit commit would
accept it--no-init-git does not require a Git identity--store <id> usagegit section reports whether commits exist,
whether uncommitted changes exist, and whether a remote is configuredopenspec/specs/ or openspec/changes/archive/ exists but
contains no tracked filesteam-context is registered at one pathcontext-store unregister as the way to switch checkouts.openspec-store/store.yaml id differs from the
requested --id.openspec-store/store.yaml after confirmed
conversion of a healthy root--store team-contextopenspec command--store team-contextinstructions apply with no
active changes)Using OpenSpec root bannernew change succeedsstatus reports on a changePlanning home line or other
workspace-planning vocabularyThe journey runs in the existing CLI e2e harness against the built binary, with isolated global state per simulated machine.
context-store list, doctor, then
new change, status, instructions, artifact writes, validate,
list, show, and archive with --store from the project repoopenspec/changes/archive/ with
the store's openspec/specs/ updatedlist --specs and show for a spec promoted by machine A's
archived changenew change, status, instructions, artifact
writes, validate, and archive with --store for a second changeopenspec/
rootopenspec/ artifacts, the
thin .openspec-store/store.yaml identity file, and Git state