Stop the harness guards sleeping through the retry backoff (#684) #685
Closed
claude-bot
wants to merge 0 commits from
ci/harness-retry-backoff into main
pull from: ci/harness-retry-backoff
merge into: rbrooks:main
rbrooks:main
rbrooks:feat/1328-fill-it-in
rbrooks:feat/1328-fill-frontend
rbrooks:feat/1328-fill-backend
rbrooks:feat/9-foundry-push
rbrooks:fix/9-foundry-live
rbrooks:feat/9-foundry-push-frontend
rbrooks:renovate/celery-5.x
rbrooks:feat/5-foundry-connect
rbrooks:feat/9-foundry-push-backend
rbrooks:feat/9-foundry-push-module
rbrooks:feat/5-foundry-frontend
rbrooks:feat/5-foundry-backend
rbrooks:feat/5-foundry-module
rbrooks:release/v4.8.0-rc1
rbrooks:docs/d341-convert-draft
rbrooks:feat/958-update-to-version
rbrooks:feat/958-convert-sheet
rbrooks:feat/958-pathbuilder-import-frontend
rbrooks:fix/1360-heading-order
rbrooks:feat/958-pathbuilder-import-backend
rbrooks:feat/11-weekly-digest
rbrooks:feat/1341-auto-update
rbrooks:docs/d332-superseded
rbrooks:chore/1345-names-cleanup
rbrooks:feat/1342-mentioned-pages
rbrooks:feat/1328-recipes
rbrooks:fix/1346-pgdg-key
rbrooks:perf/1247-shared-recording-stream
rbrooks:chore/132-gitleaks-allowlist
rbrooks:release/v4.7.1
rbrooks:spike/foundry-module
rbrooks:release/v4.7.1-rc1
rbrooks:docs/decisions-d332-d337
rbrooks:fix/bot-certifi
rbrooks:chore/release-4.7.0
rbrooks:chore/release-4.7.0-rc4
rbrooks:chore/deps-4.7.0
rbrooks:chore/release-4.7.0-rc3
rbrooks:fix/1280-quote-must-say-it
rbrooks:fix/1257-names-row-squeeze
rbrooks:chore/release-4.7.0-rc2
rbrooks:fix/1245-pg-upgrade-count
rbrooks:chore/release-4.7.0-rc1
rbrooks:feat/1257-names-in-prep
rbrooks:feat/1257-be
rbrooks:feat/1257-fe
rbrooks:feat/1257-rating-fixes
rbrooks:design/1328-fill-it-in
rbrooks:feat/1257-name-splits
rbrooks:fix/1326-redis-503
rbrooks:feat/1280-fact-suggestions
rbrooks:feat/1280-be
rbrooks:feat/1280-fe
rbrooks:design/1280-fact-suggestions
rbrooks:feat/1279-infobox
rbrooks:feat/1279-be
rbrooks:feat/1279-fe
rbrooks:feat/1321-shelf-copies
rbrooks:design/1279-infobox
rbrooks:feat/1243-table-find
rbrooks:feat/1257-who-rated
rbrooks:feat/1243-prep-drawer
rbrooks:feat/1243-sheet-pickers
rbrooks:design/1243-browse-in-place
rbrooks:feat/1315-hotwords-default
rbrooks:feat/1242-system-filters
rbrooks:feat/1257-more-name-styles
rbrooks:feat/506-leg3-hotwords
rbrooks:design/1242-system-filters
rbrooks:fix/1302-packs-polish
rbrooks:feat/1241-rules-library
rbrooks:design/1241-rules-library
rbrooks:feat/1245-postgres-18
rbrooks:integ/4.6.2
rbrooks:fix/1263-map-ui-2
rbrooks:fix/1263-map-server
rbrooks:fix/1263-map-ui-1
rbrooks:fix/1261-editor-link-menu
rbrooks:fix/1229-axe-4.14-name-mismatch
rbrooks:renovate/axllent-mailpit-1.x
rbrooks:renovate/eslint-monorepo
rbrooks:renovate/authlib-1.x
rbrooks:chore/release-4.6.0
rbrooks:chore/release-4.6.0-rc2
rbrooks:fix/460-rc2-screens
rbrooks:fix/460-rc2-server
rbrooks:fix/release-prerelease-exit
rbrooks:chore/release-4.6.0-rc1
rbrooks:feat/125-campaign-templates
rbrooks:feat/126-calendar
rbrooks:feat/1181-pictures-and-files
rbrooks:feat/1190-event-people
rbrooks:integ/4.6.0
rbrooks:feat/1191-line-of-the-night
rbrooks:feat/1200-starter-packs
rbrooks:chore/bot-multidict-and-playwright-group
rbrooks:fix/1202-this-week-answered-count
rbrooks:fix/122-124-leftovers
rbrooks:fix/1178-get-routes-that-write
rbrooks:fix/1203-journeys-check-names
rbrooks:design/125-campaign-templates
rbrooks:feat/126-calendar-engine
rbrooks:design/126-in-world-calendar
rbrooks:fix/1189-cited-stamp-in-range
rbrooks:fix/1189-v4-looser-check
rbrooks:fix/1189-richer-beats
rbrooks:fix/1113-export-bind-lists
rbrooks:fix/1154-release-notes-by-file
rbrooks:chore/release-4.5.0
rbrooks:chore/release-4.5.0-rc12
rbrooks:fix/1135-wiki-markup-as-text
rbrooks:fix/demo-usage-cost-in-window
rbrooks:chore/release-4.5.0-rc11
rbrooks:fix/1121-sheet-consistency
rbrooks:fix/1121-sheet-5e-terms-and-card-hp
rbrooks:copy/1122-busiest-pages
rbrooks:fix/1121-relevant-choices
rbrooks:fix/1121-wiki-create-npc-save-sheet-links
rbrooks:fix/1029-menu-stays-on-screen
rbrooks:docs/prototype-transcript-bin-wording
rbrooks:fix/1023-editor-save-row-back-scroll
rbrooks:fix/1020-search-exact-first
rbrooks:fix/1020-table-prep
rbrooks:fix/1020-shell-wordmark-footer-bell
rbrooks:fix/1020-wiki-article-party
rbrooks:fix/872-admin-kept-until-phone-tables
rbrooks:feat/l13-milestone-level-waiting
rbrooks:fix/1000-1001-bell-older-setup-context
rbrooks:fix/999-pronouns-in-prompts
rbrooks:fix/l19-other-class-feats
rbrooks:fix/1010-transcript-window-ordinary-confirm
rbrooks:docs/d254-d269-decisions
rbrooks:fix/702-member-search
rbrooks:fix/680-transcript-bin
rbrooks:fix/993-unidentified-prompts
rbrooks:fix/841-redis-timeouts
rbrooks:fix/990-binned-not-exported
rbrooks:fix/830-export-prep-shelf
rbrooks:fix/deps-audit-2026-10-01
rbrooks:fix/877-title-reads
rbrooks:fix/798-audio-received-at
rbrooks:build/lane11-17-j7
rbrooks:build/lane11-16-levelup
rbrooks:build/lane11-14-seams
rbrooks:build/lane11-14-seed
rbrooks:build/lane11-15-start
rbrooks:build/lane11-13-old-block-out
rbrooks:fix/980-review-r3
rbrooks:build/lane11-12-block
rbrooks:build/lane11-8-packs
rbrooks:fix/demo-seed-canonical-names
rbrooks:build/lane11-11-hot-half
rbrooks:docs/l11-decisions
rbrooks:build/lane11-7-convert
rbrooks:build/lane11-10-editing
rbrooks:fix/npm-audit-brace-expansion
rbrooks:build/lane11-9-sheet-page
rbrooks:fix/bot-pyjwt
rbrooks:build/lane11-6-content
rbrooks:fix/lane11-rank-names
rbrooks:build/lane11-2b-language
rbrooks:build/lane11-4-js-evaluator
rbrooks:build/lane11-3-server
rbrooks:build/lane11-5a-pf2e
rbrooks:build/lane11-5b-5e
rbrooks:feat/design-admin
rbrooks:build/lane11-2-evaluator
rbrooks:build/lane11-1-sheet-pieces
rbrooks:build/lane11-0-drawing
rbrooks:fix/943-quest-objectives-fk
rbrooks:fix/prepsheet-shelf-flake
rbrooks:fix/945-leftovers
rbrooks:build/demo-gm-copy
rbrooks:fix/901-email-landings
rbrooks:build/lane10-8-journeys
rbrooks:build/demo-seed-lanes-8-10
rbrooks:fix/887-gm-own-confirmation
rbrooks:build/lane9-5-j1-admin
rbrooks:fix/918-audience-click
rbrooks:fix/useasync-overtaken
rbrooks:ci/939-critical-path
rbrooks:test/937-backend-suite-speed
rbrooks:chore/claude-orchestration
rbrooks:fix/924-xp-gm-only
rbrooks:fix/session-stale-poll
rbrooks:docs/decisions-d239-d242
rbrooks:fix/930-pypdf
rbrooks:build/lane8-journeys
rbrooks:build/925-quest-editor
rbrooks:fix/894-private-page-pictures
rbrooks:build/lane8-p4-drafts
rbrooks:build/lane8-p7-map
rbrooks:build/lane8-p6-handouts-rules
rbrooks:fix/wiki-fixture-names
rbrooks:build/lane10-d227-test-usage
rbrooks:fix/rsvp-horizon-test-tuesday
rbrooks:fix/media-volume-owner
rbrooks:build/lane8-p3-editor
rbrooks:fix/912-unidentified-rename
rbrooks:build/lane8-p5-party-quests
rbrooks:build/lane8-handout-takeback
rbrooks:build/lane10-pickers
rbrooks:build/lane8-p2-article
rbrooks:build/lane8-6-map
rbrooks:build/lane10-7b-email-pages
rbrooks:build/lane8-5-handouts
rbrooks:build/lane10-7a-test-the-bot-pages
rbrooks:build/lane8-p1-pages
rbrooks:build/lane8-4-quests
rbrooks:build/lane8-2b-feeds
rbrooks:build/lane8-3-parties
rbrooks:build/lane8-2a-links
rbrooks:build/lane10-5-commands
rbrooks:build/lane9-6-seed
rbrooks:build/lane10-4b-reactions
rbrooks:build/lane9-4d-pages
rbrooks:build/lane9-4c-pages
rbrooks:build/lane10-4a-posts
rbrooks:build/lane10-3-email
rbrooks:fix/891-web-fonts
rbrooks:build/lane9-4b-pages
rbrooks:build/lane10-6-test-the-bot
rbrooks:build/lane10-2-notify-out
rbrooks:build/lane8-1-wiki-text
rbrooks:build/lane9-4a-frame
rbrooks:design/lane10-drawings
rbrooks:fix/j6-budget
rbrooks:fix/j5-phone-flake
rbrooks:fix/869-test-leaks
rbrooks:fix/843-record-start-followups
rbrooks:build/lane7-all
rbrooks:build/lane6-all
rbrooks:build/lane9-b2-server
rbrooks:chore/changelog-fragments
rbrooks:docs/decisions-d218
rbrooks:build/lane9-a-owner-overview
rbrooks:fix/rule-card-level-label
rbrooks:fix/834-retention-semantics
rbrooks:fix/o3c-record-without-announcement
rbrooks:docs/decisions-d179
rbrooks:docs/decisions-d131-d170
rbrooks:fix/851-commit-before-response
rbrooks:build/lane6-j3-seed
rbrooks:build/lane9-b1-d67-identity
rbrooks:fix/841-blocking-loop
rbrooks:build/lane9-c-backups-audit
rbrooks:fix/vote-race-and-start-commit
rbrooks:fix/recording-announcement
rbrooks:fix/proposal-read-leak
rbrooks:fix/last-admin-guard
rbrooks:build/lane6-p4c-planning
rbrooks:build/lane6-p4b-margin
rbrooks:build/lane6-p4a-sheet
rbrooks:build/lane5-j4-seed
rbrooks:build/lane6-base
rbrooks:build/lane7-pages-talk
rbrooks:build/lane5-pages
rbrooks:build/lane7-pages-safety
rbrooks:build/lane7-p3-safety
rbrooks:build/lane7-p2-notify
rbrooks:build/lane6-p3-planning
rbrooks:build/lane6-p2-history
rbrooks:build/lane6-p1b-items
rbrooks:build/lane7-p1-threads
rbrooks:build/lane5-p6-faces
rbrooks:build/lane6-p1a-sheet
rbrooks:build/lane5-p5-find
rbrooks:build/lane5-p4a-board
rbrooks:build/lane5-p4b-scenes
rbrooks:build/lane5-p3-live
rbrooks:build/lane5-base
rbrooks:build/lane5-p2-cards
rbrooks:docs/lane5-decisions
rbrooks:build/review-r2-wide
rbrooks:fix/review-r1
rbrooks:build/lane5-p1-scenes
rbrooks:build/demo-seed
rbrooks:build/lane4-journeys-j5
rbrooks:build/lane4-page-review-b
rbrooks:build/lane4-page-review-a
rbrooks:build/lane4-page-read
rbrooks:build/lane4-journeys
rbrooks:build/lane4-page-sess2
rbrooks:build/lane4-page-sess1
rbrooks:build/lane4-notes
rbrooks:build/lane4-discord-on-approval
rbrooks:build/lane4-scheduling
rbrooks:build/lane4-versions
rbrooks:build/760-session-number
rbrooks:build/lane4-decisions
rbrooks:build/797-erase-no-regenerate
rbrooks:build/test-race-audit
rbrooks:build/lane3-completions
rbrooks:build/794-dark-only
rbrooks:build/796-titles-scroll
rbrooks:build/791-retention-anchor
rbrooks:build/a11y-sweep
rbrooks:build/shell-followups
rbrooks:build/retention-preview
rbrooks:build/753-backup-readback
rbrooks:docs/d91-d93
rbrooks:build/lane3-j1
rbrooks:build/ci-harness-paths-selftest
rbrooks:fix/useauth-test-race
rbrooks:build/ci-harness-paths
rbrooks:build/777-ai-settings-read
rbrooks:build/lane3-settings-c
rbrooks:build/lane3-settings-b
rbrooks:build/lane3-j6
rbrooks:build/lane3-sessionform
rbrooks:build/lane3-settings-a
rbrooks:build/lane3-members
rbrooks:build/lane3-thisweek
rbrooks:build/lane3-story
rbrooks:chore/87-align-python-3.12
No reviewers
Labels
Clear labels
backend
Issue related to the backend
bot
Issue related to the bot
bug
Something is not working
duplicate
This issue or pull request already exists
enhancement
New feature
frontend
Issue related to the frontend
help wanted
Need some help
invalid
Something is wrong
question
More information is needed
recording
Issue related to the recording system
security
Security hardening / vulnerability work
wontfix
This won't be fixed
No labels
backend
bot
bug
duplicate
enhancement
frontend
help wanted
invalid
question
recording
security
wontfix
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/Quest-Board!685
Loading…
Reference in a new issue
No description provided.
Delete branch "ci/harness-retry-backoff"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Refs #684. One autouse fixture. No production code, no new dependency.
What was actually slow
Profiling the job rather than reasoning about it, the guards file was 17m29s of a ~28-minute job, and within it one test was 127s of 271s:
That test makes every span of one track return 500.
corvinhas 38 spans,_SPAN_ATTEMPTSis 3, and_transcribe_span_resilientlydoesawait asyncio.sleep(_SPAN_RETRY_BACKOFF_SECONDS * attempt)between attempts — 1s then 2s. That is 114 seconds ofasyncio.sleepin a test measured at 127.The backoff is kindness to a struggling ASR server. Everything in this file talks to an in-process shim that is not struggling and has no rate limit.
The change
An autouse fixture sets the backoff to zero for this file only. The attempt count is deliberately untouched, so what the guard asserts is unchanged: every attempt is still made and still fails, the span is still skipped, the failure share still passes
_SPAN_MAX_FAILURE_SHARE, and the run still raises.manifest+scorersunchanged at 74 passed / 17.9s, confirming the fixture is scoped to this file and has not leaked.pytest-xdist was tried and rejected — with numbers
I proposed this first in #684. It does not hold up:
-n 2-n 4-n 6Serial costs the same at 2 cores as at 12, because the work is ffmpeg process-spawn latency and serialised I/O, not CPU. So parallelism buys little, and it pays a per-worker copy of the ~36s module-scoped session fixture:
-n 4is 20% faster on a wide machine and 50% slower on a narrow one. The runner's width isn't known here, so that is a regression risk for a small gain.Left serial, with the measurements written into
ci.ymlso the next person doesn't repeat the experiment.What this does not fix
The ffmpeg spawn cost in #684 is real and still there — ~232 spawns per VAD transcribe, and the same path runs in production on every session. That wants the
segment-muxer change and a reworked timeout, as its own piece of work with before/after timings. This PR is the free half.Also worth noting separately: the serial guards run took 271s on a dev laptop vs 1,049s on the runner — the runner is roughly 4× slower, which is its own question.
🤖 Generated with Claude Code
The synthetic session harness had grown to 20-30 minutes a run and was the long pole on every PR. Profiling the job rather than reasoning about it: Manifest, scene and scorers 74 tests 1m23s Assembly and fingerprints 21 tests 7m42s Guards and negative fixtures 10 tests 17m29s and within the guards, one test was 127s of 271s locally: 127.29s test_a_server_error_on_every_span_of_one_track_fails_loudly 36.30s test_a_server_that_permutes_its_echoed_labels_changes_nothing 35.57s setup (the assembled session fixture) ... That test makes every span of one track return 500. corvin has 38 spans, _SPAN_ATTEMPTS is 3, and _transcribe_span_resiliently sleeps _SPAN_RETRY_BACKOFF_SECONDS * attempt between them -- 1s then 2s, so 114 seconds of asyncio.sleep. The backoff is kindness to a struggling ASR server; everything in this file talks to an in-process shim that is not struggling and has no rate limit. An autouse fixture sets the backoff to zero for this file. The attempt *count* is deliberately left alone, so what the guard asserts is unchanged: every attempt is still made and still fails, the span is still skipped, the share still passes _SPAN_MAX_FAILURE_SHARE, and the run still raises. guards, before: 271s that test: 127.29s guards, after: 152s that test: 16.48s 74 manifest/scorer tests unchanged at 17.9s, confirming the fixture is scoped to this file and has not leaked. ## pytest-xdist was tried and rejected, with numbers 12 cpu 2 cpu serial (fixed) 166s 156s -n 2 137s 158s -n 4 132s 236s -n 6 135s -- Serial costs the same at 2 cores as at 12, because the work is ffmpeg process-spawn latency and serialised I/O rather than CPU. So parallelism buys little, and it pays a per-worker copy of the ~36s module-scoped session fixture: -n 4 is 20% faster on a wide machine and 50% *slower* on a narrow one. Since the runner's width is not known here, that is a regression risk for a small gain. Left serial, with the measurements recorded in ci.yml so the next person does not re-run the experiment. Refs #684. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Merged to
mainin2b913ef.Confirmed on CI, not just locally: the "Guards and negative fixtures" step went 17m29s → 11m59s (run #9871 vs #9846). That is −31%, against −44% locally — the difference being that the non-sleeping parts of the file are proportionally slower on the runner.
Closing by hand; the API merge returns 422 on this repo even with CI complete and
mergeable: true.Pull request closed