fix: drop the >80%-broken-locators full re-research retry#97
Merged
Conversation
Researching a page could take twice as long as needed: when more than 80% of parsed locators failed validation, research() discarded the finished report and recursively re-ran the whole generation. A single imprecise container selector marks every child locator broken without testing it (the cascade in research()), so the ratio crossed 0.8 easily. In trace d9fd5d5a14aba27bc86cf925f57dc8a1 this turned one page into 67s: 28s report, 3s gate, 21s regenerated report, 13s fix. The regenerated report only corrected two container selectors -- which is exactly what fixBrokenSections already does, and it ran anyway. Broken locators now fall through to fixBrokenSections. The catastrophe guards (nothing parsed, every container broken) still retry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5 tasks
DenysKuchma
approved these changes
Jul 17, 2026
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.
Problem
Trace
d9fd5d5a14aba27bc86cf925f57dc8a1spent 67s opening the New Step page, because the researcher researched the same URL twice — aresearcher: /steps/newspan containing a nestedresearcherspan for the identical URL against the identical DOM:Two of the four containers were imprecise:
'nav'matched more than one element (testLocatorsrequirescount === 1) and'.detail.detail-view-resizable'matched zero. Those cascade to their child locators, which get marked broken without ever being tested — inflatingbrokenRatiopast0.8and tripping the guard that threw away a usable 28s report.The regenerated report only swapped
'nav'→'.mainnav-menu-body'and'.detail.detail-view-resizable'→'.detail-view-resizable'. That's a container correction — precisely whatfixBrokenSectionsdoes by continuing the existing conversation instead of regenerating. It ran anyway, 13s later, and is what actually fixed things.Fix
Delete the
brokenRatio > 0.8retry (8 lines). Broken locators fall through to Stage 3fixBrokenSections, the mechanism built for them.brokenCount/brokenRatiohad no other consumers, and the cascade stops mattering because it was their only input.Expected: 67s → ~41s on affected pages, with no nested research span.
Trade-off
If a page's DOM is genuinely stale when researched, the deleted 3s sleep + regeneration could recover where
fixBrokenSectionswill now repair against that same stale DOM. The two catastrophe guards — nothing parsed, every container broken — still retry, so only the partially-valid case changes behavior.Note for the reviewer
The trace doesn't record which retry branch fired, so I inferred it from the 3.243s gap between the first report finishing and the retry starting (3s sleep + locator testing) plus the container evidence. It fits the
brokenRatiobranch and not the other two, but a debug-log replay would confirm it outright.Testing
bun test tests/unit/— 808 pass, 0 failbun test tests/integration/— 63 pass, 0 failbun run check:fix— clean🤖 Generated with Claude Code