sorrel/docs/cli

The sorrel CLI

A persistent, single-user local VCS over the real engine. Every command reads and writes content-addressed objects under .sorrel/; state survives process restarts; everything supports --json for tools and agents.

The core loop

$ sorrel init                      # .sorrel/: object store + manifest + HEAD
$ echo "hello" > a.txt
$ sorrel status                    # dirty: added a.txt (real diff vs HEAD)
$ sorrel change create -m "add a"  # snapshot, diff, Change object, advance HEAD
$ echo "world" >> a.txt
$ sorrel diff                      # line-level unified hunks vs HEAD
$ sorrel change create -m "edit a"
$ sorrel log                       # snapshot DAG walk with change ids,
                                   # authors, and messages

status and change create use the engine's stat cache, so unchanged files are never re-hashed. log resolves each snapshot to the Change that produced it through a small index in .sorrel/changes.index.

Lanes: parallel work without branch noise

$ sorrel lane create --name agent/feature
$ sorrel lane list                 # every lane, its head, the active one marked
$ sorrel lane switch <lane-id>     # restores that lane's tree (refuses if dirty)

Each lane has its own head under .sorrel/heads/. Two lanes advance independently — exactly what parallel agents need to work without stepping on each other.

Merge: fast-forward or real three-way

$ sorrel merge <lane-id>
# fast-forward when the active lane has not diverged
# otherwise: engine three-way merge (merge base + line merge)

# on conflicts:
#   - conflicted files get <<<<<<< ours / ======= / >>>>>>> theirs markers
#   - .sorrel/MERGE_STATE records the stored MergeResult object
#   - HEAD does not move
$ sorrel merge --abort             # restore the pre-merge tree

Clean merges write a merged snapshot with both parents and record a merge Change. Conflicted merges leave inspectable state: marker-annotated files in the tree and first-class Conflict objects in the store.

Sync: push and pull against a Hub

$ sorrel remote add origin http://127.0.0.1:3000
$ sorrel push                      # negotiate missing objects, upload, advance ref
$ sorrel pull                      # fetch refs, download closure, verify ids

Push seeds the local snapshot closure, asks the Hub which objects are missing, uploads only those, and advances the remote ref with fast-forward and closure checks. Pull verifies every downloaded object's content id before trusting it.

Workflows, policy, slices

$ sorrel workflow validate         # parse + check sorrel.workflow.yml
$ sorrel workflow run <job>        # execute locally, gated by Core policy
$ sorrel policy evaluate ...       # Core policy decision for an action
$ sorrel grant create ...          # record a real Core grant decision
$ sorrel slice create ...          # slice manifest for a subproject

Full walkthroughs live in the repository: DEMO.md (local flow) and SYNC.md (push/pull against sorrel-hub).