Short Summary
Critical race condition in agent cost accounting due to non-atomic multi-table updates in server/src/core/heartbeat.ts (lines 964–1000). Concurrent agent runs can cause inconsistent financial state and budget enforcement bypass under process crashes or interleaving writes.
Steps to Reproduce
Configure an agent with:
maxConcurrentRuns > 1
heartbeat scheduling enabled
budget enforcement enabled
Trigger multiple concurrent agent executions that generate token/cost usage simultaneously.
During execution, force a process interruption or crash between:
agentRuntimeState update
agents.spentMonthlyCents update
Observe database state after restart.
Check:
agentRuntimeState.totalCostCents
costEvents
agents.spentMonthlyCents
Notice that:
agentRuntimeState and costEvents may contain updated spend values
agents.spentMonthlyCents remains stale
Trigger another agent run.
Observe that budget enforcement in:
server/src/acp-server.ts line ~134
incorrectly permits additional runs because it reads under-counted spend data
Vulnerable Code
File:
server/src/core/heartbeat.ts
Lines:
964–1000
Current implementation performs three independent writes without a transaction:
// update runtime state
await db.update(agentRuntimeState).set({
totalCostCents: sql... + ${additionalCostCents}
});
// insert immutable cost event
await db.insert(costEvents).values({
costCents: additionalCostCents
});
// update monthly spend counter
await db.update(agents).set({
spentMonthlyCents: sql... + ${additionalCostCents}
});
Expected Behavior
Cost accounting updates should be fully atomic.
The following operations should either all succeed together or all rollback together:
updating agentRuntimeState
inserting costEvents
updating agents.spentMonthlyCents
Budget enforcement should always observe strongly consistent financial state even under concurrent executions or process failures.
No partial accounting state should be visible.
Actual Behavior
The system performs multiple financial state mutations independently without transactional guarantees.
Under concurrent execution or crashes:
accounting state becomes inconsistent
denormalized counters drift
budget enforcement reads stale values
agents may continue running after exceeding configured budgets
This creates a financial integrity and policy enforcement vulnerability.
Environment
- OS: Windows 11, Linux, macOS
- Runtime: Node.js 20+
- Package Manager: pnpm
- Database: PostgreSQL / Embedded PostgreSQL
- Deployment Mode: local_trusted / production
- Concurrency:
maxConcurrentRuns > 1
- GitMesh Version: Community Edition
Additional Context
Impact
budget enforcement bypass
inconsistent financial accounting
runaway LLM spending
audit log inconsistency
corrupted denormalized counters
policy enforcement drift
Root Cause
The implementation performs multi-table financial state updates outside a database transaction.
Because concurrent agent execution is supported (maxConcurrentRuns), write interleaving and crash windows can produce partially committed accounting state.
Recommended Fix
Wrap all related accounting mutations inside a single database transaction.
Suggested fix:
await db.transaction(async (tx) => {
await tx.update(agentRuntimeState).set({
totalCostCents: sql... + ${additionalCostCents},
});
if (additionalCostCents > 0 || hasTokenUsage) {
await tx.insert(costEvents).values({
...
});
}
if (additionalCostCents > 0) {
await tx.update(agents).set({
spentMonthlyCents: sql... + ${additionalCostCents},
});
}
});
Short Summary
Critical race condition in agent cost accounting due to non-atomic multi-table updates in server/src/core/heartbeat.ts (lines 964–1000). Concurrent agent runs can cause inconsistent financial state and budget enforcement bypass under process crashes or interleaving writes.
Steps to Reproduce
Configure an agent with:
maxConcurrentRuns > 1
heartbeat scheduling enabled
budget enforcement enabled
Trigger multiple concurrent agent executions that generate token/cost usage simultaneously.
During execution, force a process interruption or crash between:
agentRuntimeState update
agents.spentMonthlyCents update
Observe database state after restart.
Check:
agentRuntimeState.totalCostCents
costEvents
agents.spentMonthlyCents
Notice that:
agentRuntimeState and costEvents may contain updated spend values
agents.spentMonthlyCents remains stale
Trigger another agent run.
Observe that budget enforcement in:
server/src/acp-server.ts line ~134
incorrectly permits additional runs because it reads under-counted spend data
Vulnerable Code
File:
server/src/core/heartbeat.ts
Lines:
964–1000
Current implementation performs three independent writes without a transaction:
// update runtime state
await db.update(agentRuntimeState).set({
totalCostCents: sql
... + ${additionalCostCents}});
// insert immutable cost event
await db.insert(costEvents).values({
costCents: additionalCostCents
});
// update monthly spend counter
await db.update(agents).set({
spentMonthlyCents: sql
... + ${additionalCostCents}});
Expected Behavior
Cost accounting updates should be fully atomic.
The following operations should either all succeed together or all rollback together:
updating agentRuntimeState
inserting costEvents
updating agents.spentMonthlyCents
Budget enforcement should always observe strongly consistent financial state even under concurrent executions or process failures.
No partial accounting state should be visible.
Actual Behavior
The system performs multiple financial state mutations independently without transactional guarantees.
Under concurrent execution or crashes:
accounting state becomes inconsistent
denormalized counters drift
budget enforcement reads stale values
agents may continue running after exceeding configured budgets
This creates a financial integrity and policy enforcement vulnerability.
Environment
maxConcurrentRuns > 1Additional Context
Impact
budget enforcement bypass
inconsistent financial accounting
runaway LLM spending
audit log inconsistency
corrupted denormalized counters
policy enforcement drift
Root Cause
The implementation performs multi-table financial state updates outside a database transaction.
Because concurrent agent execution is supported (maxConcurrentRuns), write interleaving and crash windows can produce partially committed accounting state.
Recommended Fix
Wrap all related accounting mutations inside a single database transaction.
Suggested fix:
await db.transaction(async (tx) => {
await tx.update(agentRuntimeState).set({
totalCostCents: sql
... + ${additionalCostCents},});
if (additionalCostCents > 0 || hasTokenUsage) {
await tx.insert(costEvents).values({
...
});
}
if (additionalCostCents > 0) {
await tx.update(agents).set({
spentMonthlyCents: sql
... + ${additionalCostCents},});
}
});