Summary
The trackingLock pattern in src/core/budgetManager.ts only serializes calls that await the lock before it is replaced. Two concurrent calls entering track() simultaneously both read the same lock Promise and both proceed to the critical section.
Affected File
src/core/budgetManager.ts
async track(cost: number): Promise<void> {
await this.trackingLock;
this.trackingLock = (async () => {
// two concurrent calls can reach here simultaneously
this.totalSpent += cost;
})();
}
Suggested Fix
Use a proper mutex library (e.g., async-mutex) or Node.js AsyncLock to guarantee mutual exclusion in the critical section.
Severity
High
Summary
The
trackingLockpattern insrc/core/budgetManager.tsonly serializes calls that await the lock before it is replaced. Two concurrent calls enteringtrack()simultaneously both read the same lock Promise and both proceed to the critical section.Affected File
src/core/budgetManager.tsSuggested Fix
Use a proper mutex library (e.g.,
async-mutex) or Node.jsAsyncLockto guarantee mutual exclusion in the critical section.Severity
High