A worktree is a checked-out tree on disk, with its per-call state in one append-only <wt>/.be/wtlog. The goal is cheap, disposable worktrees over one hard-to-break Store — a machine needs only one store per upstream repo, and every extra worktree is just a dir pointing back. The method: row 0's base get anchors the store, later get/post rows track the branch and tip, Sniff stamps each file it touches with the row's timestamp, and POST reads those stamps back to classify files at commit time.
Per-wt state — base branch, base tip, and pending PATCH parents — lives in <wt>/.be/wtlog; the current branch is the latest get row's ?branch, never a fixed field, so switching just appends a get row.
<wt>/.be/ is the store dir itself, beside the wt files; wtlog row 0 is a get rooted at file:<wt>/.be/<project>.<wt>/.be is a FILE whose first get row points at the primary store; Sniff follows it and shares the pool.get sets cur's branch — a checkout/clone, or an explicit be get ?branch; a commit (be post 'msg') advances the WORKTREE only, the branch tip moves only by an explicit be post ?branch, and a bare be get FFs the wt to the tip yet keeps the branch.
Every command runs against a context URI — //worktree/path?rev — the versioned cwd; there is no argv relay (the old --at coordinate is gone, no dogs are spawned anymore).
.be/, read wtlog row 0 for the base branch (see Nav).?rev context reads repo objects and ignores the wt files; verbs are free to drop context parts that don't apply.
Every sniff row stamps each file it touched with the row's ts via utimensat; at commit time POST reads each file's mtime, finds the owning row, and decides KEEP vs REWRITE in selective or implicit (commit-all) mode.
get, or owned by a get/post row — baseline content, in both modes.patch row (merged bytes) or a put row (current bytes) — new content, in both modes.put named it; REWRITE in implicit (git commit -a).be put <path> first.Branches are mkdir-cheap, so the idiom is to fork preventively: mint a sub-branch before anything speculative, experiment freely, then bring the result home as one squash — there is never a reason to stash.
be put ?./feat/exp && be get ?./feat/exp before risky work; a dead end drops with be delete -r ?./feat/exp.git stash are both unnecessary (see Store).be patch ?./feat/exp weaves the whole chain into the parent's wt, then be post '#feat' makes one commit.