refactor(persistence): migrate bridge events file to canonical atomic-write util (DC-104) [glm-grade=A]
CI / Test & Lint (push) Canceled after 0s
CI / Security audit (push) Canceled after 0s

writeEvents() in scripts/stripe-license-bridge.js drops its private
tmp+writeFileSync+rename copy (no fsync, Date.now() tmp names) and
delegates to src/utils/atomic-write.js atomicWriteJSON (exclusive-create
tmp, fsync, rename, parent-dir fsync, 0600). stripe-events.json is the
Stripe webhook idempotency log - a torn write silently drops event-ids,
so a Stripe retry re-runs delivery (duplicate license email; combined
with a torn fulfillment record, a duplicate key mint). readEvents is
JSON.parse-only, so the canonical serializer's trailing-newline drop is
unobservable. Sole writer confirmed by grep. +2 DC-104 pins: full
recordEvent->eventSeen dedupe cycle (0600/complete JSON/zero-leftovers)
and 8-step back-to-back mutation parse-complete check. 121 suites /
2778 tests green.

Judge: GLM-5.3 round-1 A (deleg_e8e1f9d0), URN urn:ump:frwh34wtlsunsymok6pzyujyehq6ikpvadypmsg7ndk7jjvzrp5a
This commit is contained in:
Hermes
2026-08-23 01:57:20 -07:00
parent 6f8fac142f
commit 3c04a740e4
2 changed files with 66 additions and 4 deletions
@@ -105,6 +105,7 @@ const fs = require('fs');
const path = require('path');
const { generateCodes, loadSecret } = require('../license-keygen');
const platformPaths = require('../platform-paths');
const { atomicWriteJSON } = require('../src/utils/atomic-write');
const catalog = require('../src/billing/catalog');
const invoice = require('../src/billing/invoice');
const { createFulfillmentStore, DELIVERY_LEASE_MS } = require('../src/billing/fulfillment-store');
@@ -220,10 +221,11 @@ function readEvents() {
}
function writeEvents(state) {
// Atomic write: tmp + rename.
const tmp = `${EVENTS_FILE}.tmp.${process.pid}.${Date.now()}`;
fs.writeFileSync(tmp, JSON.stringify(state, null, 2) + '\n', { mode: 0o600 });
fs.renameSync(tmp, EVENTS_FILE);
// Canonical atomic writer (DC-099/DC-104): exclusive-create tmp + fsync +
// rename + parent-dir fsync, 0600. Replaces the private tmp+rename copy —
// a torn stripe-events.json silently drops event-ids, which makes a
// Stripe retry re-run delivery (duplicate license email / duplicate key).
atomicWriteJSON(EVENTS_FILE, state, { mode: 0o600 });
}
function recordEvent(eventId, meta) {