REBASE 2026-07-15: the shape inventory shrinks — ?/libdog/.jab/JS-101 (absolute dot-chain) and ?.libdog/.jab/JS-101 (relative) both die with the dot-branch (URI-016 d5, SUBS-054); the replacement shapes are the wtlog pin rows ///path/to/sub?proj_branch#pin and ///path/to/sub/?branch#base. The unify-on-one-parsed-type goal stands and gets easier.
Branch paths in be/ JS are handled by ad-hoc string surgery at every
call site; three recorded shapes leak verbatim into display, so
status labels the same branch three ways at three depths: plain
?JS-101 (primary wt), absolute ?/libdog/.jab/JS-101 (mounted
sub), relative ?.libdog/.jab/JS-101 (sub-of-sub, title-stripped
rows). Unify on ONE parsed type { title, branch: [segments] } and
ONE helper module; no string concat or manual parsing at call sites.
shared/branch.js (SUBS-048) is an ORPHANED string codec — nothing
requires it; every call site grew its own indexOf/slice surgery.
Composers: submount.js:114 syntheticBranch (manual slice surgery;
writes the absolute sub-anchor shape at :233/:283/:325),
store.js:626 keyURI/refKey, relate.js:29 resolveRef (refs/heads/X
KEEPS the title — disagrees with serve.js:45 which advertises the
title-STRIPPED branch), status.js:365 "?"+rawQuery verbatim,
refs.js:34, head.js report, get.js ?<branch>#<tip> wtlog rows.
Parsers: wtlog.js:36 stripProject + refOf (&-chain), store.js:588
stripProj (byte-identical duplicate of stripProject) + resolveRef's
3-way fuzzy match + shaOf's /proj/branch/<sha> split, get.js:92
query.slice(1).split("/"), wire.js:135 refs/heads/ strip,
post.js resolveTarget, delete.js:330, patch/fetchleg.js.
Related: SUBS-040 dot-branch tracking, SUBS-023 synthetic-name
get (wontfix), Submodules wiki, BE-011 segment-array path law.
{ title: "abc", branch: [".libdog",
".jab", "JS-101"] }; plain { title: "proj", branch:
["feature"] }; trunk branch: []. Dots stay ON the segments.status shows ONE branch label shape at every depth.refs/heads/<rel>, the serve.js
form); relate.js adopts it.?feature for a primary wt,
absolute ?/<title>/.<parent>.../<branch> for a mounted sub.fromWireRef/isTrunk/display + 3-shape round-trip unit test
kill stripProject
fuzzy resolveRef match, shaOf's split
delete.js, head.js, patch/fetchleg.js
/project →
refs/heads/project) + raw-segment POSTREF guard; the codec's
split/merge collapses those. Push/advertise wire refs still
disagree; amending that test needs an explicit user ruling.