SUBS-039/LOG-002 taught the be/ JS READ views to DESCEND into a mounted
sub when the query path falls there (jab log:be logs the sub's OWN history,
correct). But a descended view still emits its per-row / per-leaf nav URIs
STORE-AGNOSTIC — WITHOUT the descent prefix. The pager re-dispatches each nav
URI as a fresh jab <uri> FROM ITS OWN CWD — the SAME base the original call
used (ctx.repo == be.find(cwd), core/loop.js:269). So an emitted URI's path
must be expressed RELATIVE TO THAT BASE, exactly like the original log:<path>
arg; a bare commit:?<sha> names a sub object the base store can't resolve →
dead nav. The quantity to prepend is NOT an absolute top-wt path but the DESCENT
DELTA relative to ctx.repo — precisely the joinPrefix accumulation
descendSub computes and THROWS AWAY. This keeps links cwd-INVARIANT: from the
journal root the link must read commit:be?<sha>, but cd be && jab log: has
base = the be sub itself, descends nothing, so the link must STAY
commit:?<sha> — prepending be there would be WRONG. Worse still, the TARGET
read views (commit:, blob:, tree:, size:) do NOT descend a <sub> prefix
at all (sub-blind — only log learned descendSub), so even a correctly
base-relative commit:be?<sha> won't round-trip yet. This is the READ-side twin
of SUBS-039 (the state-verb path-delegation primitive): a descended read view
must (a) emit URIs prefixed by the descent delta relative to ctx.repo, and (b)
the target read view must DESCEND that prefix from the same base before
resolving. Scope be/ JS; parent DIS-058; see Submodules, BRO-006; method
Issues.
jab = beagle/build/bin/jab):
jab log:be row 1 → a715b0d3 07:21 SUBS-044: … — the be SUB's own
commit (correct, per LOG-002).U click-target is the QUERY form with the FULL 40-hex
sha and NO path — commit:?a715b0d3604deac807d6262279e2ed48f968cac8
(verified via jab log:be --tlv). log.js:359 const uri = "commit:?" +
sha; builds it store-agnostic, unchanged by descendSub (LOG-002
Outcome even notes "appendRow is store-agnostic, unchanged").jab commit:?a715b0d3 (from the journal ROOT, same base as the log call)
→ JS exception: COMMITNONE, rc=1 — the sub sha is NOT in the base store.cd be && jab commit:?a715b0d3 → renders (rc=0). So the click-through
fails ONLY because the emitted URI dropped the descent prefix; correct is
commit:be?<sha> FROM the root (and unprefixed commit:?<sha> from be).core/loop.js:269 repo = be.find() re-roots at the pager's OWN
cwd (the invocation base), then the target view opens store.open(repo.
storePath, repo.project) (e.g. commit.js resolveSlot(k, repo, …)). The
emitted URI must be relative to THAT base — cwd-invariant, not absolute-top.log.js has descendSub (:406);
commit.js/blob.js/tree.js/size.js never split a <sub> prefix (grep:
no descendSub/mountWtDir there). tree.js even navs a 160000 gitlink
row to blob:<name> (→ BLOBFAIL), never into the sub.status, diff, ls/lsr) prefix names at emit
under prefix — AUDIT whether their nav/open targets (not just the visible
column) also carry the full path, or share this defect.jab log:<sub> rows nav to commit:<sub>?<sha>
and jab commit:<sub>?<sha> (from root) renders == cd <sub> && jab
commit:?<sha>.commit: first; then blob:/tree:/size:)
DESCEND a <sub>/… mount prefix to the sub store before resolving — reusing
the SAME split-at-mount primitive, not a per-view re-roll.be/ JS only. REUSE the existing seam: log.js::descendSub /
core/recurse.js (isMount/mountWtDir/joinPrefix) — do NOT hand-roll a
second gitlink/.be probe. Prefer factoring ONE shared read-side
resolveRepoForPath(repo, path) → {repo, rest, prefix} that log already
needs and commit/blob/tree/size can share (the read twin of
SUBS-039's delegatePath).log:<sub> row's U target, feed it
back from the parent root, assert it renders the sub commit (RED today:
COMMITNONE). Preserve LOG-001 spine/grey + BRO-006 U links.be where it prefixes (confirm what C's
graf/LOG.c emits for a sub row's U target — parity target, not a guess).{subRepo,
restPath, subPrefix}. log.js replaces its private descendSub with it and
RE-PREFIXES the emitted commit: target with subPrefix; commit/blob/
tree/size call it on their own path arg before resolving.commit:<sub>?<sha> vs
commit:<sub>/?<sha> — pick the one the target descender + native parity
accept; verify the banner/?query/#frag split still parses (new URI).tree's gitlink-row nav (blob:<name> → descend the
sub, or a commit:<sub>?<pin> link) here or split to a tree follow-up —
prefer the smallest change that makes the log→commit round-trip green, then
fan the same primitive out.be/test/log/subnav (be-js-log-subnav) — the log:<sub> U
round-trip from the parent root; RED COMMITNONE pre-fix, GREEN after.36b1aec0:
core/recurse.js::resolveRepoForPath (:83); log.js re-prefixes emitted
targets with the descent delta (log.js:369,497-501).commit: descends the <sub> prefix (commit.js:428-436, first consumer);
tree: too (tree.js:203).blob:/size: still sub-blind — verified live 2026-07-07: jab blob:be/main.js
from the journal root → BLOBNONE (blob.js descends via k.descendPath only,
size.js likewise); wire both through resolveRepoForPath.status/diff/ls recursors' nav/open targets (not just the visible
path column) for the same unprefixed-URI defect.d80bdb5c.core/recurse.js — coordinate so read + write share ONE splitter,
not two. The target views being sub-blind is the bulk of the work (the log
emit-prefix alone is a 1-line change but is INERT until commit: descends).be's sub-row U target format first — this is a parity fix,
not an invention.36b1aec0 ("SUBS-045: log submodule handling"):
core/recurse.js::resolveRepoForPath + prefixed log emit + commit:/tree:
descent + test/log/subnav; the same commit carried SUBS-043's declared-subs
classify gate.blob:/size: still sub-blind (live: jab
blob:be/main.js from root → BLOBNONE) + the status/diff/ls nav-target audit.</content> </invoke>