Skip to content

fix(core): stop FAL polling after timeout - #392

Merged
steipete merged 1 commit into
steipete:mainfrom
vincent-peng:codex/fix-fal-timeout
Aug 31, 2026
Merged

fix(core): stop FAL polling after timeout#392
steipete merged 1 commit into
steipete:mainfrom
vincent-peng:codex/fix-fal-timeout

Conversation

@vincent-peng

Copy link
Copy Markdown
Contributor

Summary

  • clear the FAL transcription deadline after the subscription settles
  • abort local queue requests, status polling, and retry delays when the deadline expires
  • add deterministic regression coverage for successful, failed, timed-out, polling, and retry paths

Root cause

transcribeWithFal raced fal.subscribe() against a 10-minute timer without clearing the losing timer. A successful one-shot CLI invocation could therefore remain alive until that timer fired.

When the timer won, Promise.race rejected the caller but did not cancel the losing subscription. The internal FAL client could continue polling while the provider chain moved on to Deepgram.

The deadline still begins after upload, matching the existing behavior. Aborting stops local fetches and timers; it does not cancel an already-submitted remote FAL job.

Verification

  • pnpm -s vitest run tests/transcription.fal-client.test.ts tests/transcription.whisper.test.ts — 2 files, 52 tests passed
  • pnpm -s check — 556 files passed, 29 skipped; 3,018 tests passed, 43 skipped
  • pnpm -s build — passed
  • built-module smoke with mocked FAL HTTP — returned done, reported zero active Timeout resources, and exited in 0.07 seconds
  • parallel review swarm — no material regression, security/privacy, performance/reliability, or contract findings

@clawsweeper

clawsweeper Bot commented Aug 19, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@clawsweeper clawsweeper Bot added merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Aug 19, 2026
@clawsweeper

clawsweeper Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codex review: needs real behavior proof before merge. Reviewed August 26, 2026, 5:04 AM ET / 09:04 UTC.

ClawSweeper review

What this changes

The PR clears FAL transcription deadlines and propagates cancellation through queue polling and retry waits.

Merge readiness

Blocked until real behavior proof from a real setup is added - 3 items remain

The focused cancellation repair has no concrete correctness finding, but it still needs real FAL-provider evidence before merge.

Priority: P2
Reviewed head: 77eb0dff9f2b970f45927c1d5bb39772609bd939

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The implementation and regression coverage look sound, but real provider-boundary behavior has not yet been shown.
Proof confidence 🦪 silver shellfish (2/6) Needs real behavior proof before merge: The PR body reports unit checks and a mocked-HTTP smoke only; add redacted after-fix output from a real FAL queue showing local polling stops and the process exits, without exposing API keys, endpoints, or audio metadata. Updating the PR body should trigger re-review; otherwise ask a maintainer to comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Verification

Check Result Evidence
Real behavior Needs proof Needs real behavior proof before merge: The PR body reports unit checks and a mocked-HTTP smoke only; add redacted after-fix output from a real FAL queue showing local polling stops and the process exits, without exposing API keys, endpoints, or audio metadata. Updating the PR body should trigger re-review; otherwise ask a maintainer to comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed 5 items Current-main behavior: Current main races the FAL subscription against a timer without clearing the timer or cancelling the subscription; the PR adds both cleanup and abort propagation.
Patch review: One abort signal is passed through FAL submission, status polling, response retrieval, and retry delays, while the deadline is cleared in a finally block.
Regression coverage: Added fake-timer coverage checks deadline cleanup, cancellation of polling, and cancellation during retry backoff.
Findings None None.
Security None None.

How this fits together

FAL is a transcription provider in Summarize Core: audio is uploaded, submitted to FAL’s queue, then polled for text. This path controls local timers and fetches when a transcription attempt completes or times out.

flowchart LR
A[Audio input] --> B[FAL upload]
B --> C[FAL queue submission]
C --> D[Status polling and retry waits]
D --> E{Result or deadline}
E -->|Completed| F[Extracted transcript]
E -->|Timed out| G[Abort local fetches and timers]
G --> H[Provider workflow continues]
Loading

Before merge

  • Add real behavior proof - Needs real behavior proof before merge: The PR body reports unit checks and a mocked-HTTP smoke only; add redacted after-fix output from a real FAL queue showing local polling stops and the process exits, without exposing API keys, endpoints, or audio metadata. Updating the PR body should trigger re-review; otherwise ask a maintainer to comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
  • Resolve merge risk (P1) - A real FAL queue has not yet demonstrated that an in-flight provider request observes the abort and that local polling stops before process exit.
  • Complete next step (P2) - Real contributor proof is the remaining merge gate; there is no discrete repair for an automated worker to make.
Agent review details

Security

None.

Review metrics

Metric Value Why it matters
Patch size 194 added, 39 removed across 4 files The patch changes the FAL client and transcription deadline path together with focused coverage.
Production versus tests production +46/-10, tests +148/-29 The cancellation implementation is accompanied by polling, retry, failure, success, and timeout regression cases.

Merge-risk options

Maintainer options:

  1. Add provider-boundary proof (recommended)
    Post a redacted after-fix run against a real FAL queue showing that deadline expiry ends local polling and the process can exit.
  2. Accept mock-only coverage
    A maintainer may explicitly accept the remaining provider-boundary uncertainty if real FAL proof is impractical.

Technical review

Best possible solution:

Retain the shared abort path and add a redacted real FAL queue trace showing deadline-triggered local cancellation, stopped polling, and clean process exit.

Do we have a high-confidence way to reproduce the issue?

Yes—current source and fake-timer coverage define a high-confidence path: settle or time out an FAL subscription and inspect whether local timers and polling/retry waits remain active. Real provider-boundary reproduction is still absent.

Is this the best way to solve the issue?

Yes—the shared abort signal plus a finally-cleared deadline is the narrowest maintainable repair for lingering timers and local FAL polling.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 861fa4a90ead.

Labels

Label justifications:

  • P2: The repair addresses a provider-specific path that can keep the CLI process alive or continue local polling after timeout.
  • merge-risk: 🚨 availability: The PR changes timeout, abort, retry, and polling behavior on an external transcription-provider path.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body reports unit checks and a mocked-HTTP smoke only; add redacted after-fix output from a real FAL queue showing local polling stops and the process exits, without exposing API keys, endpoints, or audio metadata. Updating the PR body should trigger re-review; otherwise ask a maintainer to comment @clawsweeper re-review. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Evidence

What I checked:

Likely related people:

  • Peter Steinberger: Git blame attributes the current main timeout and polling implementation to the v0.21.11 baseline commit. (role: current FAL baseline author in reachable history; confidence: medium; commits: 1dcbff752de7; files: packages/core/src/transcription/whisper/fal.ts, packages/core/src/transcription/whisper/fal-client.ts)

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Add a redacted real FAL queue trace showing deadline-triggered local abort, stopped polling, and clean process exit.

Rating scale

Score Internal tier Crab rank Meaning
6/6 S 🦀 challenger crab Exceptional readiness
5/6 A 🦞 diamond lobster Very strong readiness
4/6 B 🐚 platinum hermit Good normal PR; ordinary maintainer review
3/6 C 🦐 gold shrimp Useful, but confidence is limited
2/6 D 🦪 silver shellfish Proof or implementation needs work
1/6 F 🧂 unranked krab Not merge-ready
N/A NA 🌊 off-meta tidepool Rating does not apply

Overall follows the weaker of proof and patch quality.
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

Workflow

  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

History

Review history (7 earlier review cycles)
  • reviewed 2026-08-19T22:21:12.465Z sha 77eb0df :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-22T06:12:40.031Z sha 77eb0df :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-23T05:03:21.273Z sha 77eb0df :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-24T01:19:55.352Z sha 77eb0df :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-24T20:17:38.085Z sha 77eb0df :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-25T12:10:21.415Z sha 77eb0df :: needs real behavior proof before merge. :: none
  • reviewed 2026-08-25T12:52:31.425Z sha 77eb0df :: needs real behavior proof before merge. :: none

@steipete

Copy link
Copy Markdown
Owner

Triage recommendation: LAND. I reproduced the timer leak and validated this patch against real FAL HTTP using a locally generated synthetic speech recording. No source repair was needed.

Current main transcribed the synthetic sentence correctly but retained one referenced ten-minute deadline timer. With this PR's two production files compiled into the core package, the same real upload → queue → polling → result path returned the sentence and retained zero deadline timers. The baseline harness explicitly cleared its leaked timer after recording it so the diagnostic run could exit.

Additional live checks:

  • Aborted a real in-flight queue status fetch through createFalClient.subscribe(): the request received the signal and rejected with the same abort reason; status-call count stayed at 1 after a 1.2-second observation window.
  • Exercised the production transcribeWithFal() deadline callback with only the harness's timer wait shortened from 600,000 ms to 800 ms. The real queue returned an in-progress response, the function rejected with FAL transcription timeout, status-call count stayed at 1 for another 1.2 seconds, and zero deadline timers remained. HTTP was not mocked; the production timeout constant/source was unchanged.

Redacted output:

main:    activeDeadlines=1; transcript matched synthetic recording
patched: activeDeadlines=0; transcript matched synthetic recording
abort:   signalSeen=true; matchedAbort=true; statusCalls=1 -> 1
deadline: matchedTimeout=true; statusCalls=1 -> 1; activeDeadlines=0

Validation: Node 24.20.0; core build and targeted TypeScript compilation passed; the two focused regression suites passed all 52 tests. Local execution reused the existing installed dependency tree (Vitest 4.1.10); the PR's existing exact-head CI checks are green. Codex autoreview of 77eb0dff9f2b970f45927c1d5bb39772609bd939 was scoped-clean at its default P0 threshold.

This proves local cancellation and cleanup, not remote job cancellation; an already-submitted FAL job remains remote, as documented in the PR. No merge performed. Suggested landing changelog: “FAL transcription: clear settled deadlines and stop local queue polling and retries after timeout (#392, thanks @vincent-peng).” Preserve Co-authored-by: Vincent Peng <mail@vincentpeng.me> when squashing.

@steipete
steipete marked this pull request as ready for review August 31, 2026 08:45
@clawsweeper

clawsweeper Bot commented Aug 31, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@steipete
steipete merged commit 92dcbeb into steipete:main Aug 31, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 availability 🚨 Merging this PR could cause crashes, hangs, restart loops, stalls, or process outages. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants