BEE-020: port be's log: view — ?<rev>, submodule descent, ticket links in summaries

Now
OPEN
Sev
MED
Ask
gritzko
Rep
///bee
On1
LITE-007
On2
LITE-020
See
BEE-006
See
BEE-003

view/log.js was ported from be/views/log/log.js under LITE-007/LITE-020 and carries the row shape, the grey off-spine rows and the hidden commit <hex> click target. Three legs of the be view never arrived: the ?<ref> tip form (log:?main), the LOG-002/SUBS-045 SUBMODULE descent (log:<sub>/<path> logs the sub's OWN history and its rows still click), and the BRO-012 ticket-code split (a BEE-012 in a commit summary is an F token that opens the ticket). Today bee log dog/INDEX.md from quickjab prints NOTHING, bee log ?main prints nothing, and a ticket code in a summary is dead text. This ticket lands the three, bee-style: ?<rev> like cat/list/tree, the mount table for the sub, the door for the ticket.

Input

Context

Measured 2026-08-16 with ~/src/quickjab/build/bin/bee (jsrc = ~/src/bee, HEAD b3b14e1); the be source is ~/src/journal/be/views/log/log.js (= ~/src/beagle-ext/views/log/log.js), its tests ~/src/journal/be/test/log/{links,sub,subnav,ticketmemo,nonspine.js}.

Goals

The be log: contract, spelled the bee way, through the ONE view shape (arg, opts) -> hunks so CLI, pager and http get it together.

Constraints

WIP

Design decisions

Proposed by the planning session; the agent confirms or amends with a reason.

  1. ?<rev> over be's #frag: bee's views spell a revision as ?<rev> (cat, list, tree), the count is <n> (LITE-045); # is the permalink/anchor character in bee. #N/#hashlet are NOT ported.
  2. Spine stays ord-0 (git first-parent, LITE-020); be's newest-timestamp mainline rule (log.js:254:eo) is a be DAG quirk, not git's, and bee's spine test pins first-parent parity.
  3. The DESCENT is mnt.deepest(root + "/" + rel), the same probe http.js:510:dX uses; the view re-roots from and the arg, then runs unchanged. The banner is log <arg as typed>.
  4. The row's ambient: the U target stays commit <hex> (a verb line the door already opens); the HUNK carries pos: { repo, path } of the repo it walked and the pager hands it to open(target, pos) — door.openTarget takes a pos today (door.js:471:WK). http already runs the view inside the re-rooted pos (http.js:524:dX) and pathIn gives a hexlet no prefix (http.js:183:dX) — so a sub page's commit <hex> href lands in the PARENT: fix by prefixing the hexlet with pg.prefix and re-rooting <prefix>/<hexlet> in the URL parser, or leave and open a ticket. Agent picks, states why.
  5. Ticket spans: EVERY F token the lexer mints in a summary becomes an F span, unresolved or not (the door refuses at follow time with words; http refUrl yields no href for a miss). Cheaper than be's per-row resolve (LOG-005 had to memoize it) and consistent with how a cat page treats refs. Off-spine rows keep grey Q for the rest of the row, the F keeps its own slot.
  6. DROPPED (orchestrator, 2026-08-16): an unknown path stays an EMPTY log, exit 0 — test/index/run.sh:181:ZR ("git says nothing either") and :320 are earlier rulings and were not to be edited; the pathThere refusal was reverted, test/logport L6/port-6 pin the empty answer. gritzko may reopen; the refusal is a 10-line re-add.

Amendments the implementation forced:

  1. logQuery needed NO change: the <n> split is orthogonal to the URI slots, so ?<rev> lands in log()'s own rd.argSplit (view/log.js:322:eo) and logQuery's target passes through verbatim. The banner stays the spelling typed, as ruled.
  2. rd.argSplit THROWS on a name the URI leaf refuses (a raw space: a b.txt), which would have cost such a file its log. log() falls back to "the arg is all path" — http.js:198:dX's own out. cat/list/tree still throw for such a name; not this ticket's to fix (Blockers 3).
  3. log <path>?<rev> needs a SIEVE, not just a seed: the index holds every tip ever brought up, and fileLog is a path_hl prefix scan over all of them. The tip's own CPAR closure (ancestry uncapped, no rewrite) filters the revs — paid only when a ?<rev> is given, so the bare form's cost is exactly what it was.

TODOs

Blockers and bummers

  1. RESOLVED by dropping decision 6 (see above). *DECISION 6 vs two existing pins.* test/index/run.sh:181:ZR ("an unknown path is simply an empty log (git says nothing either)", log nosuch/file.txt -> rc 0, no bytes) and test/index/run.sh:320:ZR ("a partial absent at HEAD is an empty log, not an error", log old.c where gone/old.c was deleted at HEAD). Both are behavioural pins, not --plain byte pins, and both say the opposite of goal 4 / decision 6. Left UNTOUCHED; JSRCindex is red because of them and nothing else. R5 also exposes a real gap of its own: resolve.pick matches the TIP tree only, so a DELETED file named by a partial resolves nowhere and now gets the refusal instead of its two revisions — worth its own ticket either way.
  2. A ?<rev> bring-up leaves that branch's rows in the index for good, so a LATER bare log <path> lists revisions off it. Pre-existing (a branch switch + bee index does the same), but log ?<ref> makes it a one-command trap. The sieve of amendment 9 could be applied to the bare form too — with a CPAR-only closure (membership, no ODB read) it costs no object reads — but that is a walk at query time, which the constraints forbid here. Ticket-worthy.
  3. rd.argSplit throwing on a raw space means bee cat "a b.txt" / list / tree refuse a name log now serves. One try in read.js would settle it for all four; out of scope.

Outcome

$ cd ~/src/quickjab && bee log 3 dog/INDEX.md --plain ca7e2386 Sat15 DOG-038: reStructuredText tokenizer — RSTT over .rst, RST stays Rust dog (Victor Grishchenko) 1c07623b Fri14 DOG-035: pup run ToC — sparse page index, "TC"-tagged 7-byte trailer dog (Victor Grishchenko) 1c8c4583 Thu13 DOG-032: tunable mempage length dog (Victor Grishchenko)

$ cd ~/src/bee && bee log 2 ?main --plain b3b14e13 19:42 switch to a compact(er) backward-compatible permalink syntax (Victor Grishchenko) ce5a9e9a 19:14 prettify bee see code (Victor Grishchenko)

and the fixture, from the parent, descending into the submodule:

$ bee log --plain sub 697dc664 03Jan23 s2 tip (T) cca8319c 02Jan23 s1 bump (T) b57fc386 01Jan23 s0 seed (T) $ bee log --plain 'f.txt?side' 2be5f10e 04Feb23 sx side edit (T) efe4ed46 03Feb23 TKT-12: parent edit (T) dc976337 01Feb23 p0 seed (T) $ bee log --plain nosuch.c JS exception: log: there is no nosuch.c (rc 1, stdout empty)