Skip to content

Reserve daily run slots atomically under concurrent events - #12

Open
Prerit-112 wants to merge 1 commit into
theschoolofai:mainfrom
Prerit-112:fix/concurrent-run-ceiling-race
Open

Prerit-112 wants to merge 1 commit into
theschoolofai:mainfrom
Prerit-112:fix/concurrent-run-ceiling-race

Conversation

@Prerit-112

Copy link
Copy Markdown

Summary

  • admit_run() checked max_runs_per_day / daily_budget against the window ledger, but the run was only recorded after runtime.run() finished.
  • Concurrent process() calls could all observe count/spend = 0 and all start runs, so the daily ceilings did not hold under overlap — a control that looks correct sequentially but fails when events arrive together.
  • Fix: atomically reserve a run slot (and daily-budget remainder when set) under the event-store lock at admit time; settle actual spend after the run without double-counting.

What breaks (before)

  1. Subscription with max_runs_per_day=1.
  2. Fire several overlapping relevant events (asyncio.gather on engine.process).
  3. Observe multiple runs and zero (or too few) max_runs_per_day refusals — the ceiling is bypassed.

Fix

  • EventStore.window_try_admit_run — check ceilings and reserve count / reserved USD in one locked section.
  • EventStore.window_settle_run — replace reserved budget with metered spend (count already reserved).
  • AutonomyGovernor.admit_run / settle_run + engine path updated accordingly; failed runs refund reserved budget but keep the consumed slot.

Test plan

  • pytest tests/test_autonomy_governor.py — includes new concurrent ceiling test; red before fix on that case, green after
  • Sequential max_runs_per_day still bounds runs and records refusals
  • Sequential daily_budget still caps the window and shrinks effective per-run budget
  • Concurrent events with max_runs_per_day=1 → exactly one run and three max_runs_per_day refusals
  • Self-trigger, source rate limit, triage ceiling, liveness, and morning-report tests still pass
  • Reviewer: confirm diff has no .env, tokens, credentials, or local EA wiring
  • Reviewer: optional — concurrent daily_budget stress (same pattern as max_runs) if desired beyond the unit test

No secrets, real messages, or API keys in this diff.

…one ceiling.

admit_run checked the window ledger then recorded after the run finished, so overlapping process() calls all saw count zero and blew past max_runs_per_day and daily_budget.

Co-authored-by: Cursor <cursoragent@cursor.com>
@theschoolofai

Copy link
Copy Markdown
Owner

Session 16 — graded

Score: 0.

Duplicate of #3, filed 2026-08-09 against this one's 08-12. Same daily-ceiling race, same files, same atomic-reservation fix.

@theschoolofai

Copy link
Copy Markdown
Owner

Session 16 — regraded ✅

Score: +100. The verdict below stands: this is a duplicate of an earlier filing (or, for glc_v5 #23, an enhancement rather than a defect), and it is recorded as such.

What has changed is the credit. On review, the work here was genuinely done: the bug was found independently, the reproduction is real and the fix is sound. Losing a race you had no way of seeing is not a reason to earn nothing, so this is credited at the full 100 even though it does not carry the first-to-file claim.


Original assessment, unchanged:

Duplicate of #3, filed 2026-08-09 against this one's 08-12. Same daily-ceiling race, same files, same atomic-reservation fix.

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