PR #227 review, P1. Two `git.status` invocations against different
repositories were ordered by which `rev-parse` returned first, not by
which the user asked for last.
`git.status` started an UNVERSIONED `rev-parse`, and the generation was
minted later, inside `start_status`, which runs from that lookup's
completion callback. So invoke status in repo A, then repo B: if B's
root resolved first and A's resolved second, A claimed the NEWER
generation and replaced B. The counter that exists to make the newest
INVOCATION win instead made the slowest SUBPROCESS win --- and it did it
silently, since both requests looked well-formed.
The fix is the ordering, not a new check:
* `reserve_generation()` is called at the point the user ASKS ---
`git.status` after its early returns and before the spawn, `g` at the
keypress. An invocation that starts no work reserves nothing, so it
cannot invalidate one already in flight.
* `start_status` takes the reserved generation as a PARAMETER instead of
minting its own, so the value survives the round trip through the root
lookup.
* The root-lookup completion is now `pmacs.git._deliver_root`, and it
drops a superseded result before any effect: no status spawn, no
`state.root` write, and no status-line message. A message from an
invocation the user has already replaced is as wrong as a panel from
one, and the previous shape would have written both.
Exposed for the same reason `_deliver_status` is exposed: the contract
is about completions arriving in an order the caller did not choose, and
no arrangement of real subprocess timing can guarantee two `rev-parse`
runs finish in a chosen order.
Witness: `g6_21_a_superseded_root_lookup_does_not_spawn_its_status`
drives two real invocations, then completes their ROOT LOOKUPS out of
order --- newer first, older second --- and asserts the superseded one
spawns nothing at all, comparing the status-spawn count before and
after. `g6_17` cannot see this: it drives the STATUS completions out of
order, by which point the generation each carries is already fixed.
Bite: restoring the old ordering (mint on arrival, no staleness check)
fails `g6_21` and nothing else. A test that merely hoped for the bad
subprocess order would have passed on the broken code about half the
time, which is why this one drives the completion directly.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai