patchscope.lca returns a stale (non-recent) merge base
patchscope.resolve pins the 3-way fork for be patch via lca(ours, theirs) (patchscope.js:139); patch.js:354 consumes sc.fork as the common base of the merge. But lca() walks theirs with a LIFO stack and returns the FIRST popped sha present in ancestorSet(ours) — DFS pop order has no relation to recency, so a diamond/merge history can hand back an older shared ancestor as the base. A too-old fork yields a noisier, wrong 3-way merge. Both walks are also uncapped. Method: Issues.
patchscope.js:101-119 lca(reader,a,b): DFS-pops b, returns the
first sha in ancestorSet(a) — pop order is arbitrary, not recency.
patchscope.js:104-105 says "BFS … in ts order isoverkill; a DFS that returns the first b-ancestor … is the merge base" — wrong: a DFS first-hit is NOT the most-recent common ancestor.
patchscope.js:82-100 ancestorSet: unbounded stack.pop() DFS over
commitParents, no WALK_CAP. lca adds a second unbounded DFS.
patch.js:354: treeMap(reader, sc.fork) is the 3-way base; a stalefork makes file-level merges take/keep the wrong side (noise/conflicts).
dag.js: ancestors BFS is WALK_CAP-bounded
(dag.js:30,43), the divergence is recency-ordered by commit ts.
lca() returns the MOST-RECENT common ancestor on a diamond/mergegraph (a recency-aware merge base), not a DFS first-hit.
be patch over a merged-side-branch history picks the recent base.lca returning undefined for no-shared-history (the caller
drops to an empty base — patchscope.js:122-123,139).
dag.js (WALK_CAP + ts recency already there) overa third local walk; keep the no-dag-cycle note honest if kept local.
{scope,branch,ours,theirs,fork} shape; scope to patchscope.js.
matching dag.js's parent-edge model (first-parent + merge parents).
dag.ancestors/dag.isAncestor (WALK_CAP-bounded) instead of
the local ancestorSet DFS, removing the unbounded-walk hazard.
test/js/patch/*: a merge-side-branch-then-patch
graph asserting lca returns the RECENT base, not the old ancestor.
dag.commitParents parent set matches patchscope's intent
(foster/rebase edges excluded — dag.js:18-24) before delegating.
shared/patchscope.js:101 lca is the DFS first-hit
(comment :104-105 still says "a DFS that returns the first b-ancestor … is the merge base"); ancestorSet:83 and lca are both uncapped stack.pop() walks.