BEE-001 ruled that bee knows a repo BY ITS PATH and made bee install refuse a linked worktree, the tell being <gitdir>/commondir. The OTHER registration door was left open: index() calls track(ctx.repo, opts.home) on its own (index/index.js:924), so a bare bee run inside a worktree registers that worktree. $HOME/.config/bee/repos now carries /home/gritzko/src/bee, /home/gritzko/src/bee2 and /home/gritzko/src/bee3 — ONE repository in three checkouts, each with its own lane — so every ordinary filename in a cross-repo ref resolves three times, reaches the chooser, and http paints it PLAIN. The fix follows BEE-001's own ruling: when the path handed in is a linked worktree, register and index THE ORIGINAL — the main worktree named by commondir (index/refs.js:37) — if it is not registered yet.
The symptom is a page full of dead names: /bee-journal/todo/LITE/LITE-045.mkd paints render/html.js, main.js, door.js, theme.js as plain text while ticket codes on the same page link, because a ticket lives in ONE repo and a filename lives in three.
bee2 and bee3 are git worktree checkouts of bee: .git is a gitfile, the gitdir is /home/gritzko/src/bee/.git/worktrees/bee2, and each carries its OWN lane (<gitdir>/be/*.lite2.idx) — so each answers the fan-out on its own.door.resolvePartial("render/html.js") in that page's ambient returns three rows (bee, bee2, bee3); html.js returns six (mark/ and render/ in each checkout).seatOf therefore answers {rels} — the LITE-015 chooser — and http.js:228 (if (seat === null || seat.rels) return null) drops every multi-hit to plain painted text, so a reader sees no link at all rather than a choice.merge.js:163 linkedWorktree(gitdir) is the existing probe and it guards install ONLY; index/index.js:924 track() has no such gate, which is how the two lines got written.index/refs.js:37 commonDir(gitdir) already resolves a linked gitdir to the main one — the original's root is that path with /.git stripped, no git shell-out needed.index/mount.js list() dedups by realpath alone, and its under() deliberately rules /src/bee2 NOT inside /src/bee, so nothing folds a worktree family at resolve time either.Registration names the ORIGINAL, so one repository is one registry line, one lane and one answer in the cross-repo fan-out.
bee index, and a bare bee inside a linked worktree, register the MAIN worktree and never the linked path, saying which repo they took.bee install and this path agree on one behaviour: BEE-001's refusal words, or the same silent redirect — gritzko's call, stated in the ticket before it lands.render/html.js on a ///bee-journal page links to /bee/render/html.js.git worktree add checkout, registered from inside the linked one.<gitdir>/commondir, read through index/refs.js commonDir.$HOME/.config/bee/repos is the USER's file — a run may append, and must not silently delete lines a person put there.test/index, test/first, test/http, test/click stay green.index/track REDIRECT rather than refuse: a bare bee inside a worktree
must keep working, and registering the original is what the reader meant.mount.js folds a family to one mount),
never by rewriting the user's file behind their back.install is the verb you
TYPE, so a repo that is not the one bee would take is worth a word; the
refusal now NAMES the original (commondir), so the next move is a copy-
paste. index and the bare run are incidental and redirect in silence,
save one phrase on the summary line. Flip it to a silent redirect if you
would rather install just do the right thing — one if in merge.js.///bee/x.js still resolves while the
reader stands in bee2 — a name that followed the root would break it.linkedWorktree + the original's root land where both doors reach them (merge.js install and index/index.js)index()'s track redirects to the original root; opts.track === false still writes nothing2b5aa65 already shares itinstall reconciled with the redirect (BEE-001's refusal words kept, and now naming the original)mount.js folds a worktree family to ONE mount, ambient checkout first, else the main worktreetest/index, test/first, test/http, test/click green — and the other 22 suites with themhttp.js:228 has no chooser URL to link to — that is a separate ticket, not this one.2b5aa65 had already pointed indexDir at the COMMON gitdir, so the family shares one lane and only the REGISTRY duplicated. Pinned by a check all the same.mainOf costs one stat (plus a small read for a gitfile) per registry line per mount.list() call — the file's own "re-read per call, no git at all" budget, but it is a new syscall on a hot path.bee never writes it again, and the fold hides it.Landed in an isolated worktree, uncommitted — gritzko commits.
index/index.js: linkedWorktree (moved from merge.js), gitdirOf, origin, mainOf; bringUp's track takes origin(ctx.gitdir) || ctx.repo and the summary says registered <original>.index/mount.js: fold() in list() — a worktree family is ONE mount, the ambient checkout when the reader is in one, else the first line, under that line's name.merge.js: the local probe retires; the refusal stands and names the original. README.mkd: the mount-table line, the index bullet, the install one.test/worktree/run.sh + fanout.js: 27 checks — the redirect, the bare run, the lane, the refusal, and the fan-out over a clean AND a legacy registry.git archive HEAD build): the registry took wt, render/html.js answered 2 rows and seatOf gave {rels}; 7 of 9 shell checks failed.bee bee2 bee3 in a TEMP registry, render/html.js -> 3 rows + CHOOSER at HEAD, 1 row + a seat after.