Read a company's site once, however many people it names - #63
Merged
Conversation
The runaway behind #61 and #62. A crawl of accenture.com returns 57 people; each becomes a `refresh_research` card; each card queued another crawl of the same page, which returned the same 57. Production reached 226 pending crawls of that one URL and 81 of toptal.com before it was stopped. The per-person cooldown in #62 could not catch this, and the samples said so plainly: cooldowns stayed at zero while pending crawls climbed 227 to 426. Every one of those 57 people was new, so none of them had any research history to be cooled down against. The cooldown was the right mechanism for the wrong axis — it bounds how often one person is re-researched, and the amplification is per *site*. `enqueue` has supported a dedupe key since 0007, and the index behind it deliberately covers only pending and running jobs so a key frees itself when the job finishes. `POST /prospects/by-url` has passed one from the start. Neither approval path ever did, which is why one route could not queue a host twice and another could queue it 226 times. Both approval paths now pass the same key that route uses — `crawl:<host>` without `www.` — because two paths deduping under different keys do not deduplicate against each other, which is the whole point. Keyed on the host rather than the URL, so `example.com` and `https://www.example.com/` are the one crawl they actually are. The cards still all clear; only the duplicate crawls collapse. Emptying the queue was never the problem. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
The actual runaway behind #61 and #62.
A crawl of accenture.com returns 57 people. Each becomes a
refresh_researchcard. Each card queued another crawl of the same page, which returned the same 57.Production before it was stopped:
Why #62 did not catch it
The per-person cooldown was the right mechanism on the wrong axis. It bounds how often one person is re-researched; the amplification is per site. Every one of those 57 people was brand new, so none had any research history to be cooled down against.
The samples said so plainly — cooldowns flat at zero while pending crawls climbed:
The fix
enqueuehas supported a dedupe key since migration 0007, and the index behind it covers only pending and running jobs, so a key frees itself the moment the job finishes — it suppresses duplicates, never future work.POST /prospects/by-urlhas passed one from the start. Neither approval path ever did. That is why one route could not queue a host twice while another queued it 226 times.Both approval paths now pass the same key that route uses —
crawl:<host>, withoutwww.— because two paths deduping under different keys do not deduplicate against each other, which is the entire point. Keyed on host rather than URL soexample.comandhttps://www.example.com/are the one crawl they actually are.The cards still all clear. Emptying the queue was never the problem.
Verification
bun test— 1369 pass, 0 fail across 90 filestypecheckandformat:checkcleanProd state while this lands
auto_approve_internalpaused onwsp_04wz5p9…— the loop is stopped🤖 Generated with Claude Code