Skip to content

fix: drop the >80%-broken-locators full re-research retry#97

Merged
DenysKuchma merged 1 commit into
mainfrom
fix/researcher-drop-broken-ratio-retry
Jul 20, 2026
Merged

fix: drop the >80%-broken-locators full re-research retry#97
DenysKuchma merged 1 commit into
mainfrom
fix/researcher-drop-broken-ratio-retry

Conversation

@DavertMik

Copy link
Copy Markdown
Contributor

Problem

Trace d9fd5d5a14aba27bc86cf925f57dc8a1 spent 67s opening the New Step page, because the researcher researched the same URL twice — a researcher: /steps/new span containing a nested researcher span for the identical URL against the identical DOM:

researcher: /steps/new                       67s
  ├── invoke_agent  28s   ← full research report (58 locators, 4 containers)
  └── researcher: /steps/new                 35s   ← re-research, SAME url, SAME DOM
        ├── invoke_agent  21s   ← report regenerated from scratch
        └── invoke_agent  13s   ← fixBrokenSections

Two of the four containers were imprecise: 'nav' matched more than one element (testLocators requires count === 1) and '.detail.detail-view-resizable' matched zero. Those cascade to their child locators, which get marked broken without ever being tested — inflating brokenRatio past 0.8 and 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 what fixBrokenSections does by continuing the existing conversation instead of regenerating. It ran anyway, 13s later, and is what actually fixed things.

Fix

Delete the brokenRatio > 0.8 retry (8 lines). Broken locators fall through to Stage 3 fixBrokenSections, the mechanism built for them. brokenCount/brokenRatio had 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 fixBrokenSections will 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 brokenRatio branch and not the other two, but a debug-log replay would confirm it outright.

Testing

  • bun test tests/unit/ — 808 pass, 0 fail
  • bun test tests/integration/ — 63 pass, 0 fail
  • bun run check:fix — clean

🤖 Generated with Claude Code

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>
@DenysKuchma
DenysKuchma merged commit e764055 into main Jul 20, 2026
3 checks passed
@DenysKuchma
DenysKuchma deleted the fix/researcher-drop-broken-ratio-retry branch July 20, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants