The 15s `scheduleMergeRetry` sweep was silently re-skipping in-review
tasks whose `mergeActive` entry leaked from a wedged prior attempt
(uncaught error inside `drainMergeQueue`, restart between push and
finally, etc.). FN-002, FN-004, FN-3898, FN-3899 all sat in in-review
until the 15-min maintenance loop logged "Auto-recovered: eligible
in-review task re-enqueued for merge".
Two changes:
* `reconcileStaleMergeActive()` runs before each 15s sweep. Any
`mergeActive` taskId that isn't in `mergeQueue` and isn't the
`activeMergeTaskId` is treated as leaked and dropped, so the next
enqueue actually pushes through.
* The `task:moved → in-review` immediate handoff (`wireAutoMerge`) now
logs every skip reason instead of returning silently, clears its own
stale `mergeActive` entry before enqueueing, and identifies the task
in its catch-block warning. `internalEnqueueMerge` also warns when a
leaked entry causes a skip — the next regression won't be invisible.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>