Same week, four products
If you treat this as one regression you will keep "fixing" the wrong file
A healthy generate this week, bc525b08-…, proved the scrape path still works. Listings completed, geocode, risk profiles, Free gate isFullReport: false, AI ~45s, save. The FEMA/EPA stacks are failovers. Two POST compare 429 lines in that log are React Strict Mode remounts, not a dead queue.
GitHub vs what actually landed
The last four PRs are the wrong suspects
"Working 3 to 4 PRs back" lands on PR 61, merged 25 Aug, dark-mode CSS on home report pages. It did not touch Inngest, compare plan resolution, or queue recovery. Everything after that on GitHub is naming, lint, knowledge tracking, and an incomplete Free honor.
How we kept making it louder
Each "fix" treated a symptom as the whole bug
- 10 Aug. Credit-settlement work added
stepRun hooks inside processHomeReportGeneration. The Inngest wrappers kept calling the processor with no step. Fine while Firecrawl was fast.
- 20 Aug. The earlier briefing already named the 429-as-success path. Progress treated a conflict as a new run and sat on a queued orphan for 20 minutes.
- 21 Aug. PR 56 flipped that. 429 became a hard error. Missing event id failed the row immediately, racing the original dispatch.
starting was ignored. The worker still ran as one HTTP request.
- 25 Aug. RBAC landed on main as a naked commit. Code required
admin_role. Migration v19 was a separate human step. Until it ran, staff lookup 500'd. The worker throws before scrape. Inngest retries. You see start 500 while nothing is "stuck" in the listing code.
- 27 Aug. PR 62 stuffed a Free-plan API change into a knowledge PR and stopped at the resolver. The banner still lied. Credits still drained. Same week the worker 500s showed up, so 62 ate the blame.
- Same week, this chat. Reconnecting 429 onto a claimed-then-dead
starting row made the hang visible. Redispatching live starting after 30s could start a second scrape on a Redfin job that was still going. That is why it kept "breaking again" after each patch.
The Inngest hole was always there
Before 3c17e09 the function was async ({ event }) => processHomeReportGeneration({ generationId, userId }). No step.run. One request owns listing fetch, geocode, risk, AI, save. Inngest's start timeout is shorter than a Redfin failover. Retries look like 500s. The first invocation keeps writing listings. That is the log you already saw: dca11265-… then bc525b08-… scraping while start failed.
v19 is not optional for this code
loadProfileStaffFields selects is_admin, admin_role. isAdminForUserId runs at the top of the home runner. A missing column is a PostgREST 500, not a false. Until the retry-on-missing-column path in PR 66, that throw killed the job. Navbar access used the same select, which is why the admin 500 and the worker 500 arrived together.
On PR 66, not merged
What 3c17e09 already changed
PR 66 is still titled as chat coverage. The recovery commit is on that head. Updating the PR is a push to Absterrg0:main. It is not a merge to upstream/main.