Home

mweinbach / agent-coworker

publicmweinbach/agent-coworker
Overview Code History Branches Pull requestsIssuesInsights
main
HomeOverview Code PRsIssues

fix: stop idle desktop state writes and de-flake the test suite

2 months ago

63a6444
Authored
mweinbach7/25/2026, 6:40:51 PM
Follow-up to 57003cf6/38a9dbd8, covering the churn those changes surfaced.

**Idle write storm.** The renderer rewrote the full desktop state file ~3x/sec
while the app sat idle. Two causes: the `provider_status` handler restamped
`providerStatusLastUpdatedAt` on every event even when the status was
byte-identical, and `persist()` had no idempotence, so any store churn that left
the persisted projection unchanged still wrote to disk and re-armed the 300ms
debounce. Timestamps only move on a real change now, and `persist()` skips the
write when the serialized projection matches the last one (the local UI cache is
still refreshed every flush, since it carries state `PersistedState` does not).

**Runtime verification.** `collectRuntimeTreeState` runs on every turn over ~38k
entries, so the walk now carries both the relative and absolute path down the
recursion instead of re-deriving each absolute with a split+join, and skips
re-validating paths it built itself.

**Backup prune race.** `create()` fires a background `pruneBackupsRoot` per
session, so sessions starting together swept the same tree concurrently and
raced each other's recursive removals -- `force` suppresses ENOENT, not the
EPERM/ENOTEMPTY a parallel delete produces. Prunes are chained per backups root;
queued runs still execute, and a failed prune no longer poisons those behind it.
Measured on the affected test: 3/30 failures before, 0/45 after.

**Test isolation.** The desktop suite now passes 1912/1912 in a single shared
process (was 6 failures); CI's per-file isolation had been hiding these.
- framer-motion's layout projection nodes kept a process-global frameloop
  re-scheduling after unmount, measuring a document the next file had torn down.
  Stubbed in the preload, keyed by `Bun.resolveSync` because `require.resolve`
  returns the CJS entry while components import the ESM one.
- The streamdown stub rendered children as text, so unrelated suites asserted
  against escaped markup; it renders string children as markup now.
- `product-analytics-apply` replaced the shared `localLogs` module, silently
  sending serverManager's diagnostics nowhere. Replaced with an injected
  `initProductAnalyticsImpl` seam, matching the repo's DI-factory convention.
- `research-view-layout` depended on ambient `preflightCreation` state, and the
  jsdom harness handed back a live requestAnimationFrame after teardown.

Verified: bun test (667 files), typecheck, lint, docs:check all clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Parent38a9dbd

12 files changed
  • apps/desktop/electron/services/productAnalytics.ts+5−1
  • apps/desktop/src/app/store.helpers/controlSocket.ts+14−2
  • apps/desktop/src/app/store.helpers/persistence.ts+22−0
  • apps/desktop/test/jsdomHarness.ts+7−4
  • apps/desktop/test/persistence-write-dedupe.test.ts+82−0
  • apps/desktop/test/product-analytics-apply.test.ts+33−40
  • apps/desktop/test/research-view-layout.test.tsx+5−1
apps/desktop/test/streamdown-props-stability.test.tsx
+15
−2
  • apps/desktop/test/workspace-settings-sync.harness.ts+4−0
  • src/coworkRuntime/integrity.ts+48−40
  • src/server/sessionBackup.ts+41−8
  • test/bun-test-setup.ts+151−0