Issue #3618443: Closing a hole reads the party's blocks before asking whether there is a hole
Consolidation is asked of every claim that changed what an order holds, and the ordinary answer is that there is nothing to do: the party is already in one run, or was put into one by the claim before. Reaching that answer used to cost a read of every block the party sits in.
VenuePlacementProvider::consolidate() built the party's context and read its blocks, and only then handed the party to the strategy, whose first act is to answer NULL when the party sits in fewer than two fragments. That test is made from the party's own places and needs no read of what is free.
The change. SeatingStrategyInterface::couldSitBetter() asks that question from the anchors alone, before anything is read. Together answers it with the three tests it already made first, and consolidate() now delegates its own guards to it. The provider asks it of the whole party before grouping, and of each group after, and reads only where the answer is yes.
Measured, kernel, twelve-seat fixture, memoized reads cleared: a party already sitting together costs 4 statements on 1.x and 3 here. The one that goes is the candidates read over the slot's seat rows, and it is the only one of the four whose cost grows with the size of the house; the three that remain are the party reading its own places. On a hall that is one row the count is what moves, on a stadium it is the rows examined.
Unchanged: which parties are consolidated, and how. It is the same test, asked before the read instead of after it.
SeatTogetherTest::testPartyAlreadyTogetherIsNotTouched already said in its docblock that this case "has to cost nothing" and never asserted it. It does now, as a budget. Confirmed to fail against unpatched 1.x (4 is not less than or equal to 3) and to pass with the change.
AI-Generated: Yes (Claude Code was used to draft the issue summary and to write the code, the documentation and the test on this merge request. I review and run the work before it is merged.)