be put is O(N²) — re-preps + rewrites the whole wtlog per argThe 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.