worktree-linker¶
Provenance¶
- Source:
.spec/spexcode/spec-cli/source-of-truth/worktree-linker/spec.md - Source SHA-256:
e995fe51380f02a39ac7003dabb9bd108d0783f4a41ba1861eae4af63a7f0578
raw source¶
A governed session's work is identified by its global record (its node, the live status, and the
worktree_path that holds the actual .spec/code change). The linker = enumerate the global store →
read each governed record → derive that worktree's real .spec proposal against main → overlay. Composable:
.spec stays in-tree, so adopting SpexCode needs no restructure, and the worktree stays pristine.
expanded spec¶
A governed session's record ([[state]]/[[runtime]]) carries what identifies its work: the node it
proposes changes to (the authoritative ref it was bound to — the branch slug, with its -<id4> suffix,
falls back only when the record names none), the live status, and the worktree_path. The linker
reads the record, then derives the per-node overlay (ops) the board renders. The session set comes from
ENUMERATING the global store (filtered to governed:true), not from git worktree list — so an unmanaged
or scratch worktree never lands on the board.
An overlay op answers ONE question — what would merging this worktree change in .spec on main, and did
THIS branch do it — so an op must satisfy two conditions at once, each killing its own phantom class:
- It differs from main's current tip (the proposal half). The op set and each op's TYPE come from the
working tree's diff against main's tip, so ops always speak in merge terms: a node main already has reads
edited, never a spuriousadded, and content byte-equal to main is no op at all. This is what keeps a foreign-base branch honest — a branch whose fork point predates the.spectree (an adopter's CR-review branch built on an upstream head plus a commit restoring.spec) previously reported the ENTIRE tree asaddedwhile its content was identical to main — and it likewise dissolves the stale ops of a worktree whose work has already LANDED on main. - The branch touched it since its fork point (the attribution half —
git merge-basewith main). A worktree that is merely behind an advanced main made no change of its own; diffing against main alone would render main's newer post-fork content as phantom edits/deletes the worktree never made. Fork-point attribution keeps every genuine branch change — committed and uncommitted/dirty alike, that distinction unchanged — while pure behind-main staleness contributes nothing.
The overlay memo is keyed on exactly the inputs that can move the answer: fork point + worktree HEAD + the
.spec working-tree signature + main's tip — the last because a merge landing identical content must
dissolve the ops it just made moot; the recompute a main advance triggers stays cheap because every diff is
.spec-scoped.
This lives inside the [[portable-layout]] seam (layout.ts): the linker is the half that, given the
enumerated governed records, attaches node id + session + status + overlay to each. Keeping the session's
runtime state OUT of the worktree (in the global store) is what lets the same .spec tree stay in-tree and
canonical on main while a session layers ephemeral, session-scoped state on top without polluting history —
the worktree carries no SpexCode file at all, so there is nothing per-session to gitignore.