?/project funny ref + no-? retargets umbrella main
Two defects on jab's POST push-target resolution, one theme (the URI ref/path slot picks the wrong remote ref). *A.* jab post ssh://host/path?/project builds a receive-pack update for refs/heads//project — a doubled slash git rejects as a "funny refname" (refusing to update funny ref 'refs/heads//beagle' remotely); per URI ?/project is the absolute project trunk and the trunk is named as the project, so it must resolve to refs/heads/project, but jab splices the raw post-? text /project (absolute-marker / and all) into refs/heads/<X>, leaking the /. *B.* Dropping ? (jab post ssh://host/path/project) puts project in the path, leaves the ref unspecified, and jab silently retargets the *umbrella* refs/heads/main (an unrelated history) instead of the path's project or a clear refusal — a cross-project footgun the FF gate masks only by accident. Fix: resolve ?/project to the trunk branch, never emit an empty ref segment, and never silently push cur onto an unrelated main. Push path is GIT-013; wire alias documented at keeper/REFADV.c §"Wire mapping". Method: Issues.
~/journal/beagle, remote ~/src/journal): jab post ssh://localhost/src/journal?/beagle → refusing to update funny ref 'refs/heads//beagle' remotely + JS exception: wire.push: ref update rejected — refs/heads//beagle funny refname.jab post ssh://localhost/src/journal/beagle → JS exception: POSTNOFF: remote refs/heads/main is not an ancestor of cur; local cur 59e4ac27 (ahead 1, parent 2a35dbd1) IS a fast-forward over remote beagle main 2a35dbd1, but jab compared it to the umbrella ~/src/journal main 172a8688 ("snapshot 25Jun26", unrelated lineage) → the refusal is a wrong-target artifact, not a real non-FF.?/project = absolute project trunk (trunk named as project, ?/beagle → refs/heads/beagle); the leading / is an absolute marker, not part of the branch name. An empty ? means trunk (→main); NO ? slot means cur — it must not become "push cur onto the umbrella main".keeper/REFADV.c:65 documents the sole wire alias: ? → refs/heads/main, ?<X> → refs/heads/<X> — X must already be a resolved branch name; jab hands it /beagle (defect A) or falls through to bare main on a project path (defect B).jab post <remote>?/PROJ resolves to refs/heads/PROJ (strip the absolute-marker /) and pushes that project trunk, FF-only as today.refs/heads//…, trailing /) is refused before the wire write with a clear jab error, never sent for git to reject as a funny refname.? URI whose path names a project/submodule does not silently push cur onto the umbrella refs/heads/main; it targets that project's ref or refuses with a clear "no branch selected — use ?/PROJ" message.be/ shared wire/URI code), not native C keeper; native be is unaffected here.GIT-015 comments, greppable, ticket-coded ≤64-char commit.? (trunk→main), ?branch, ?/project/branch, detached ?<sha>.? URI text onto refs/heads/; the absolute form ?/project keeps its leading /, so normalization of ?/project → project-trunk branch is missing on the jab push path.?, the path segment is not classified as a project selector, so the target ref defaults to the umbrella main (?-empty alias) instead of the project trunk or an error.refs/heads/<X> so any future resolver slip fails loud in jab, not opaquely at git.relate.resolveRef("/project") → refs/heads/project asserted in test/put/wire-refguard (unit over the shared resolver — the one push-path ref builder).?/project (absolute trunk) to refs/heads/project on the jab push path. — landed 234b0f54; now shared/relate.js resolveRef (absolute-marker strip).//, trailing /) throws POSTREF before the wire. — landed 234b0f54 (relate.js), tested in test/put/wire-refguard.test/ hits nothing); add a hermetic no-? jab post <host-path> case asserting the refusal, never a push onto the umbrella main.?-less host URI refuses POSTNOREF: no branch selected — use ?/PROJ (relate.relate hasQuery gate; post.js ~129 sets hasQuery only on a ? marker). — landed 234b0f54/c12f6d4b.?→main, ?branch, ?/project/branch map correctly. — test/put/wire-refguard covers the resolveRef table; wire bucket green.be/shared/wire.js wire.push vs a URI/refs resolver module) before touching it.? semantics with the user if a project path should ever auto-select its trunk vs always require ?.cp -a of be/, which copies the .be redirect verbatim → a non-self-contained tree that mis-reports put status. Create fix worktrees via be get, not cp -a.234b0f54 ("remote post issues fixed", be/ trunk), consolidated into shared/relate.js by GIT-016 c12f6d4b: defect A (absolute-marker strip → refs/heads/project), the POSTREF empty-segment guard, defect B (POSTNOREF refusal, no silent umbrella-main retarget).