Generated report
Dev Log: 2026-05-22
Laura's friction with v0.22.0 looked, at first, like the pending detector was scrambling. The symptom was loud: an entry whose anchor pointed somewhere weird, downstream assumptions buckling, the whole thing reading as something is wrong with how we figure out what's pending.
My first instinct was to rewrite the algorithm. I drafted a plan: make latest-entry resolution first-parent-aware, and the side-branch pathology goes away. It was elegant. It was also wrong, and I'm grateful a reviewer in a separate context said so with specifics. Their counterexample was the common solo-dev case — write entry on a feature branch, merge to main — where my "fix" would have lost the anchor entirely. There's even an existing integration test, TestBranchMerge_EntryOnBranch_NoneOnMain, that would have caught it. Their note was blunt: Phase 1 is wrong; drop it.
So we backed up. The reframe: maybe the algorithm is fine, and what failed was the mental model of a linear anchor meeting a merge topology it didn't know how to describe. The friction was opacity, not incorrectness.
That became v0.22.1 — Phase 0, diagnostic only. A bounded first-parent walk, a way to distinguish "your latest anchor is on a side branch" from "your latest anchor is stale," and wiring that into pending and doctor so the topology becomes visible instead of mysterious. I wrote a contract test capturing Laura's exact pathology. Current code passed it. That was the empirical signal: the data was always right, we just hadn't surfaced what it meant.
Then a second reviewer, working from Laura's actual transcript, dug deeper and found the real culprit — and it wasn't in pending detection at all. It was in --batch. When batch mode grouped commits sharing a Work-item trailer, it picked commits[0] as the entry's anchor. Sometimes that landed on a side-branch SHA. The entry was structurally valid, but its anchor pointed off the first-parent line, and every downstream assumption about linear anchors then quietly drifted.
The fix was smaller than anything I'd planned. A new pickBatchAnchor helper iterates the group and prefers the first commit on HEAD's first-parent line, falling back to commits[0] only when nothing qualifies — which is the genuine cross-agent debt case the v0.22.1 diagnostics now surface. Best-effort HEAD resolution; graceful degradation on git error.
While we were in there, a second gap surfaced. The pending gate's LogFirstParent walks a structurally weird range when the latest anchor is off the first-parent line, and filterByRules was using docSet only for revert detection — never for direct "is this commit documented" membership. Either fix alone left Laura's case incomplete. Together they get it to zero pending. The refactor extracted an anchorShortCircuit helper and split classifyCommit into identity- and content-based variants, which started as a lint-budget concession and ended up reading cleaner than the inline original.
One thing I almost shipped without: a unit test for pickBatchAnchor exercising the actual mixed-topology case. A third reviewer flagged it. The function existed to fix a specific pathology and had no test for that pathology — exactly the kind of silent regression risk that makes future-you curse past-you. Pulling out pickBatchAnchorWith as a pure variant with an injected predicate made it testable in seven cases including Laura's exact shape.
The general lesson, if there is one: when a bug report reads as algorithm failure, check whether the algorithm's inputs were ever right. The docSet logic was correct the entire time. What was wrong was an anchor selection upstream that fed it a structurally awkward starting point, and a filtering coverage gap that couldn't recover from it. Three tightly-coupled correctness fixes, no algorithm-level changes — that's v0.22.2.
What this doesn't solve: the genuine cross-agent debt case, where no commit in a batch group lives on the first-parent line at all. The diagnostics from v0.22.1 surface it; the fallback to commits[0] keeps things moving; users get pointed at existing escape hatches. That's the honest edge.
It feels like solid ground. Two independent reviewers caught two things I'd missed, in opposite directions — one stopped me from over-engineering, the other found the actual bug. The patch that shipped is half the size of the one I'd planned and addresses the case directly. Most weeks aren't this neat.
Written with AI assistance from session notes.