why: blame view — per-token background shade keyed by ORIGIN commit, click → commitwhy:<path> VIEW (be/views/why/why.js) renders a file's tokens BACKGROUND-shaded
by their ORIGIN commit — hue = f(commit sha), one pale/pastel intensity, so the eye
reads "same origin = same colour". Every shaded run click-navigates to commit:?<sha40>.
Presentation over the EXISTING JS weave: shared/weave.js (fold/merge) + the WEAVE
step cursor's per-token inserter (origin commit id) — the SAME full-history
reconstruction patch.js already does. NOT a new engine, NOT a stub. why:<path>?<rev>
blames AS OF a rev; why:<path>?<a>..<b> colours ONLY that range's changes (incl
deletes). Named why, not blame. Method: Issues.
shared/weave.js binds the C WEAVENext/WEAVEMerge
builders as fold/merge (DIFF-010); imported by views/diff/diff.js +
verbs/patch/patch.js. The prior "be/ JS has no weave" premise was WRONG.beagle/js/cont.cpp:326-344, rewind()/next() + getters inserter, rms,
hasIn) yields each token's ORIGIN commit id (16-hex hi64 of the sha). No native change.patch.js ALREADY reconstructs a file's whole weave from its commit-history
closure — weave.fold linear (WEAVENext) + weave.merge at merge commits, layer
id weaveId(sha)=sha.slice(0,16) (patch.js:11-16,55-59). That IS the producer why reuses.diff.js:48 withUTarget appends a U-tagged run whose bytes
ARE the nav URI; the pager's _followRow (views/bro/pager.js:577) runs it via
driveSpell→pushView on Enter/click. Commit target shape is commit:?<sha40> (commit.js).:blame <path> in the pager degrades to ls (no blame verb;
core/loop.js:266 _isVerb gate → _viewDefault). ORTHOGONAL bug; registering why
makes :why <path> dispatch as a view. C ref: graf blame is itself weave presentation (Graf, BLAME-005).why:<path> view (be/views/why/why.js) that STEPS the file weave and emits, per
token/run, a background-shaded span whose hue = f(inserter commit sha), all at ONE pastel intensity.commit:?<sha40> U-target (map the 16-hex inserter id →
full sha via the closure map); Enter/click opens that commit (reuse withUTarget+_followRow).why:<path>?<rev> blames the file AS OF <rev> (scope to <rev>'s closure); a bare ?
/ no query → the current tip. SAME ref-parse convention as diff: (no hand-rolled parsing).why:<path>?<a>..<b> colours ONLY tokens changed in (a,b] — insertions (inserter∈range)
AND deletions (rms∈range, shown so deletes stay visible); the rest render plain.SCHEMES row + views/why/) so :why <path> dispatches as a view.shared/weave.js, the step cursor, and
patch.js's closure walk. Do NOT build a new attribution engine; do NOT land against a stub.why STEPS the weave (per-token inserter); it does NOT use emitDiff/emitFull
(those emit a 2-scope diff SIDE, not per-token origin). emitDiff stays diff:'s path.view/bro.js two-pass, aBg256 pastels 194/224/157/217,
BRO-009). BUT its bg channel is the tok32 2-bit side (eq/in/rm — 4 states only); many
commit hues need a WIDER channel — the one real design task (see Design).shared/ so patch and why share it.inserter = origin commit id (16-hex) is the shade key; keep an
id→sha40 map from the closure for the commit:?<sha40> U-target.side can't carry a hue. Options — (a) per-hunk palette +
a small per-run bg index in tok32 spare/custom bits, (b) the view resolves bg to ansi64 and feeds
pre-washed cells, (c) a why bg-mode in the renderer keyed off a per-run commit-hue. Pick one in the repro.?a..b: filter the step by inserter/rms ∈ (a,b]; deletes surface via the rm side.diff: ?<rev> / ?<a>..<b> convention (diff.js:447-462, resolveCommit); do NOT hand-roll.why:<fixture> — N tokens over M origin commits → M distinct pastel bg hues at
one intensity; each run's U-target is commit:?<sha40> of its inserter (golden on tok32+bg+U).shared/;
build the file weave for a rev (+ the id→sha40 map).be/views/why/why.js: step the weave, hue=f(inserter sha), emit bg-washed HUNK runs + commit:?<sha40> U-tags.view/bro.js.side (pick a Design option); render via the two-pass path.why:<path>?<rev>: scope to <rev>'s closure (diff: ref-parse); bare → current tip.why:<path>?<a>..<b>: colour only (a,b] changes incl deletes (inserter/rms filter).SCHEMES row + confirm :why <path> dispatches (not ls).side vs many hues) — a renderer-seam
design choice resolved in the repro, NOT a data dependency. The weave + attribution already exist.:blame→ls silent-degrade (loop.js unknown-bareword vs registry.js:30
"refuses" claim) is a real bug but not this view; file separately if we want it fixed.0d02e0e9 (be trunk, 2026-07-05): "WHY-001: blame view for the js ver" — be/views/why/why.js steps the weave, hue=f(inserter sha), commit:?<hashlet> click targets, ?<rev> + ?<a>..<b> scopes; help SCHEMES row; tests be/test/why/ (blame, range, wt).52e62b9c (same day): paler colors for older commits (age-blended pastel).#rrggbb leading run) — the view resolves the colour, not the 2-bit tok32 side channel.