be put is O(N²) — re-preps + rewrites the whole wtlog per arg
The JS (jab) be put path... handler (be/verbs/put/put.js) processed each path arg independently: for EVERY arg it re-ran stage.prep (a whole working-tree wtScan + the baseline tree read twice) AND commitOps→appendAndAssign (read the whole wtlog, then rewrite the whole wtlog). So be put todo/*/*.mkd (517 matches) "starts anew for each file" — O(N²) in the wtlog rewrite plus O(N×tree) rescans. The JS-side perf analogue of PUT-003's native "per-path, not aggregated".
jab put todo/*/*.mkd runs far too long, as if it restarts per file.putRun (put.js) looped for (uri of pathUris) putOne(...); putOne did a fresh stage.prep(repo, wtlog.open(repo), k) + commitOps PER arg.stage.prep scans the ENTIRE wt (classify.wtScan: recursive readdir + lstat) and reads the baseline tree twice — none of it arg-specific, redone N times.appendAndAssign reads the whole wtlog (ulog.each) then rewrites it whole (ulog.write → temp + rename) for EACH arg → O(N²) log rewrites.be put completes in well under a second.put: rows/skips, same wtlog rows, the mtime==row-ts restamp invariant intact; keep the be/ put suite green (Issues).stage.prep + wtlog.open above the pathUris loop; reuse one engine for every file/dir/move arg (native runs one PUTStage snapshot over all args).putOne no longer commits: it classifies against the shared engine and RETURNS its ops; putRun concatenates them and calls commitOps ONCE for the batch.appendAndAssign left as-is (now called once) — the batching, not an in-place append, removes the O(N²); minimal-diff, lower risk.commitOps in putRun.beagle/build/bin/be (the harness SEED + BIN) vanished mid-session; ran cases directly with the build-trace native seeder + build/bin/jab (sanctioned seed, TEST-003 secondary axis).1b7c9934 (be/, 2026-07-06; the commit's own message — "Thanks to PUT-007, this was staged and posted by jab" — was staged BY the fix; wtlog: put verbs/put/put.js → post ?#1b7c9934): be/verbs/put/put.js — putRun preps the staging engine once and batches all args into one commitOps; putOne takes the shared engine and returns ops. After: 120 files 0.28s (12.7×), 240 files 0.30s (41×), flat across N (O(N²)→O(N)); correct row counts. Green: put/{bare,file,dir,move,unchanged,dir-clean-unstamped,ref-create, ref-set,ref-set-sha}, sub/{bareput,bareput-nested}, uri011/put-nav-bind, put/wire-refguard.