| 294 | } |
| 295 | |
| 296 | function saveState(state: IngestState): void { |
| 297 | // F6 (Codex finding 6): tmp+rename atomic write so a crash mid-write |
| 298 | // never leaves a truncated/corrupt state file. Matches the pattern |
| 299 | // in gstack-gbrain-sync.ts:saveSyncState. |
| 300 | try { |
| 301 | mkdirSync(dirname(STATE_PATH), { recursive: true }); |
| 302 | const tmp = `${STATE_PATH}.tmp.${process.pid}`; |
| 303 | writeFileSync(tmp, JSON.stringify(state, null, 2), "utf-8"); |
| 304 | renameSync(tmp, STATE_PATH); |
| 305 | } catch (err) { |
| 306 | console.error(`[state] write failed: ${(err as Error).message}`); |
| 307 | } |
| 308 | } |
| 309 | |
| 310 | // ── File hash + change detection ─────────────────────────────────────────── |
| 311 | |