Finding NODE-BILLING-04
File modules/billing/crons/billing.reconcile.js
runReconciliation() runs with no acquireLock/releaseLock, unlike the 3 sibling crons (dunningSweep, weeklyReset, extrasExpiration). Concurrent pods (rolling restart, overlap) each paginate all active subs and call stripe.subscriptions.retrieve() per sub → doubled Stripe API volume + duplicate billing.reconciliation.divergence alerts.
Fix Wrap in acquireLock({ name: 'billing.reconcile', ttlMs: 20*60*1000, holder })/releaseLock as in billing.dunningSweep.js:58-126.
Devkit Node clean audit 2026-05-29 (rev d42eb12). Verified real by an independent refute-by-default reviewer. Fix flows through /feature #N → /verify-qa → /pull-request-finalize.
Finding NODE-BILLING-04
File
modules/billing/crons/billing.reconcile.jsrunReconciliation()runs with noacquireLock/releaseLock, unlike the 3 sibling crons (dunningSweep, weeklyReset, extrasExpiration). Concurrent pods (rolling restart, overlap) each paginate all active subs and callstripe.subscriptions.retrieve()per sub → doubled Stripe API volume + duplicatebilling.reconciliation.divergencealerts.Fix Wrap in
acquireLock({ name: 'billing.reconcile', ttlMs: 20*60*1000, holder })/releaseLockas inbilling.dunningSweep.js:58-126.Devkit Node clean audit 2026-05-29 (rev d42eb12). Verified real by an independent refute-by-default reviewer. Fix flows through /feature #N → /verify-qa → /pull-request-finalize.