fix(scripts): unblock production sync preseed parity#2399
Conversation
Production has sync docs where google.calendarlist was stored as an
object ({"0": row}) instead of an array, which crashed preseed inventory.
Revoked tokens, leftover nested watches, and dry-run missing_connection noise were blocking production preseed parity. Keep real duplicates and live orphan calendars/events as blockers. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…rate Co-authored-by: Cursor <cursoragent@cursor.com>
Isolate bad events/users, purge corrupt Sync docs, reproject after upserts, add heartbeats plus host runner/watchdog scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
Enqueue deferred reproject from the per-user finally block so events upserted before a migration failure still get occurrence rows. Reject non-finite --concurrency values with a clear CLI error instead of crashing runPool with an invalid array length.
- Merge per-worker migrate counts under an async mutex to avoid lost increments when concurrency > 1 - Write preseed heartbeats at startup and phase boundaries so the remote watchdog does not false-alert during long inventory/purge work - Handle missing or malformed heartbeat timestamps without crashing the watchdog script
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Dry-run deletes corrupt events
- Added a deleteCorrupt option to findByProviderIdentitySafe and pass deleteCorrupt: !dryRun from findExistingProviderEvent so dry-run passes report corrupt events without deleting them.
You can send follow-ups to the cloud agent here.
| # Finished successfully — clear dedupe and exit. | ||
| if [[ -f "${SUCCESS}" ]]; then | ||
| rm -f "${DEDUPE}" | ||
| exit 0 |
There was a problem hiding this comment.
Watchdog ignores active preseed runs
High Severity
The watchdog exits immediately when SUCCESS.json exists, before checking preseed.pid or heartbeat freshness. Reruns (documented as idempotent) do not remove the prior success marker, so a new --apply can run for hours while cron treats the job as finished and skips stale-heartbeat alerts. A later failed run also leaves the old success file, so failures can be masked the same way.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit a1c7e5a. Configure here.
| id: skip.id, | ||
| detail: `dry-run: ${skip.detail}`, | ||
| }); | ||
| } else if (STATE_EXPLAINED.has(skip.category)) { |
There was a problem hiding this comment.
Apply parity blocks dormant accounts
Medium Severity
Dry-run now treats state missing_connection as a warning, but --apply still classifies it as blocking. Users skipped in connections for missing_refresh_token (revoked/dormant Google accounts) still hit state missing_connection and fail parity even when dry-run passed, which can abort run-preseed.sh after partial writes.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit a1c7e5a. Configure here.
Fall back to DISCORD_DEPLOY_WEBHOOK_URL, always write watchdog.log, and heartbeat during legacy collection load so the 15m stale detector stays honest. Co-authored-by: Cursor <cursoragent@cursor.com>
Wrap onProgress in try/catch so heartbeat or other progress handler errors cannot reject parallel workers or skip deferred reprojection.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Heartbeat rate uses wrong elapsed
- The delta rate now divides events since the last heartbeat by the interval since the last callback, while the fallback average still uses total phase elapsed time.
You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit f37aeba. Configure here.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_01c0ab7b-dd95-4c8b-888d-ecf5fe8b1120) |


Summary
google.calendarlist/eventsobjects in inventory/migrate.missing_connectionfindings as warnings so production preseed can pass parity for migratable users.Test plan
bun test:scripts -- packages/scripts/src/commands/inventory-legacy-sync/inventory.test.ts packages/scripts/src/commands/preseed-sync/parity.test.tsMade with Cursor