BRO-030: unified quad status reporter (track·base·patch·wt vs root)

Now:
DONE

Input

Context

File status and divergence reporting is a per-verb zoo: status prints /wiki/Dirty nouns, PATCH prints applied/merged/mod/conflict (/wiki/PATCH §Reporting), GET/POST print their own rows, and ahead/behind is a separate post/miss listing. The unified model is specced in /wiki/Status: per path a quad of relations . X + — columns track/base/patch/wt, each vs root = LCA(track, base) — colored blue/green/yellow/orange; bold = staged, red = conflicted; commit ahead/behind uses the same relations one level up.

Goals

One reporter module renders quad rows; every verb report (status, get, post, patch) emits through it, and the old vocabularies retire everywhere at once.

Constraints

WIP

Design decisions

TODOs

-v the reporter module: shared/quad.js (ULOG columns, k-way merge, LCA root, commit quads) + view/quadrender.js + theme.QUAD_SGR; unit test test/quad/model.js green (in work/BRO-030) -v collapse rule: patch column = newest-wins union over the absorbed theirs trees (later wtlog row shadows) -v mov/rmv pairing: the dst row's path column spells src#dst (quadrender.fileRow) -v degenerate roots: detached → track=pin; no-LCA → throw "broken tree"; track-less → track:=base -v ASCII canon RULED 2026-07-17: plain = .xov, staged wt char UPPERCASE, conflict !; tty may use Unicode (✗ + ↑) + bold/red — model+renderer+model-test converted -v wire the verbs behind --quad: status / patch / post / get all landed green, one e2e test each -v QUAD IS THE DEFAULT (ruled 2026-07-17): all four sweeps landed — ~40 cases converted, every quad derivation matched observation; the sweeps caught /todo/PATCH/PATCH-014 and a stale-glyph behind/ahead miscount in status.js (fixed) -v row deban (RULED: wiki/PATCH, bangs retired): patchRowUri writes ?<sha> (no !); 8 WHOLE goldens debanged; arg-side alignment split to PATCH-015 -v the default flip LANDED in all four verbs: gates dropped, legacy emission deleted (status ROW_ORDER/divergence/summary zoo, patch applied/merged banner, post legacy banner, get checkout rows + sub relay); status also landed the tok-span sink integration (per-char column tags Y/W/E + new I orange / J bold-orange / M red, U nav, put/del buttons) -v full suite: 71/75 run.sh green + all units; the 4 reds are pre-existing (bro/color, bro/view, dag/remoteindex fail identically in a pristine clone; get/http is a parallel-port flake, green serial) - the detached-post report shows no .o.. commit row (track=pin) — keep a fallback confirmation row? needs a ruling (pinned in test/post/file golden meanwhile) - detached-wt post report has no commit row (track=pin) — legacy confirmation row gone; keep a fallback row? needs a ruling - point /wiki/Dirty at /wiki/Status once the flip lands

Blockers and bummers

Outcome

All work sits UNCOMMITTED in work/BRO-030 (per the no-VC-ops rule) awaiting inspection/merge: new shared/quad.js, view/quadrender.js, test/quad/model.js; modified shared/wtlog.js (PATCH-014 read fix), verbs/{get,patch,post}, views/status/status.js, view/theme.js, test/CMakeLists.txt (+quad/model), ~45 test files converted to the quad default.