captain-hook: ⚡️ Coalesce reviews before spawn and skip recorded correction anchors - #272
Merged
Merged
Conversation
yasyf
force-pushed
the
perf/review-pipeline-coalescing
branch
from
October 3, 2026 03:49
e9cc285 to
692c27a
Compare
…ection anchors Claude-Session-Id: 95aa46a7-b92a-4c7f-80dc-775333ed92a9
Context: The detach admission regression patched process-global Popen, so enrollment consumed the stub before either detach. Summary: Freeze enrollment and assert both attempts are detach calls with failure breadcrumbs. Motivation: Verify claim release through the intended failure path across the Linux and macOS CI shards. Details: Add an enrolled stub, check pending-fd argv, and count the two detach-failed log entries.
yasyf
force-pushed
the
perf/review-pipeline-coalescing
branch
from
October 3, 2026 06:17
692c27a to
2e1d2a3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Claim pending SessionStart/SessionEnd review work before starting a child, preserving one running pass plus at most one queued follow-up per transcript directory. Prepare correction evidence only for anchors without a ledger row matching their exact
(session_id, event_uuid), sharing one lazily opened ledger handle per scan.Why
Every eligible SessionStart or SessionEnd detached a Python review child before pending/repo-lock coalescing. A child that lost the lock had already paid for interpreter startup, imports, and
git remote get-url. Earlier live evidence included 1,161replay-*review child logs in one cache tree.When a transcript changed,
prepare_corrections→harvest_pairs→BoundedGitalso revisited historical anchors already recorded in the correction ledger, with a budget of up to 84 Git subprocesses per call.What changed
captain_hook/review/pipeline.py: Claim the transcript directory’s pending-pass flock before enrollment or origin lookup. Skip spawning when a queued pass already covers that directory. Hand the locked descriptor to the child, which explicitly callsLOCK_UNand then closes it upon acquiring the repo lock. This admits a follow-up even while the parent still holds its descriptor copy.captain_hook/review/cli.py: Accept--pending-fdand forward it tospawn_session.captain_hook/review/settings.py: AddReviewPathswith onlydb_pathfor guard admission. Keep fullReviewSettingsvalidation inside the child’s recording boundary, so malformed reviewer settings still reach a child that records the failure.captain_hook/review/scan.py: AddCorrectionLedger, opening one handle lazily per scan and closing it on exit. Batch recorded-anchor checks with one lookup per distinct session in each batch, matching both session and event UUID before correction preparation or Git work. Schedule lookups from the preparation thread onto the existing event loop withrun_coroutine_threadsafe, withoutasyncio.runin this path.captain_hook/snapshots/review.py: Reuse that ledger handle inrecord_correction_drafts; the corrections library permits one engine per ledger file per process.tests/test_review_pipeline.py: Add 5 pending-admission tests and update descriptor-handoff assertions.tests/test_snapshot_review_consumers.py: Add 3 rescan tests with preparation and Git-call counters; update callers to pass the ledger or recorded-anchor lookup.tests/snapshot_review_helpers.py: StubCorrectionLedger.recordedin the shared fixture.CHANGELOG.md: Record spawn coalescing and recorded-correction filtering under Unreleased → Fixed.Tests
The 5 tests in
tests/test_review_pipeline.py::TestPendingAdmissioncover:HOOKS_REVIEW_JUDGE_CONCURRENCYstill spawns 1 recording child.The 3 tests in
tests/test_snapshot_review_consumers.pycover:event_uuidremains eligible for preparation.No local pytest run because the host was saturated. CI grades these assertions.
Notes
Stop sweeps remain keyed by each worktree’s cwd hash. Re-keying them by repository is deferred because it would add an origin lookup to the Stop path.