Address 15 PR review findings: WorkspaceKeeper, AccountConfigPatch, detachWatcher
HIGH fixes:
- appview URL was only updated when non-None; now always synced from accountConfig
- try_build_entry now returns Some(entry without metadata) on transient decrypt failure
instead of None, preventing spurious workspace disappearance
- detachWatcher() added to workspace store; route.lazy.tsx cleanup calls it on unmount
so live updates survive re-navigation without a flash-to-empty
MEDIUM fixes:
- AccountConfigPatch with tri-state appviewUrl (string | null | absent) replaces
Partial<AccountConfig> footgun; updateAccountConfig, settings page, SDK types updated
- add_account_config_tests: two new integration tests (preserve untouched fields,
explicit null clears appviewUrl)
- useWorkspaces: module-level bootstrapPromise dedup prevents N parallel listWorkspaces
calls from N concurrent hook mounts
- optimistic workspace insert in createWorkspace before SSE echo arrives
- Zeroizing<X25519PrivateKey> return type on private_key_bytes() for key hygiene
- resolveForeignWorkspace WASM binding deleted (leaked group key to JS)
- accurate deadlock comment in apply_keyring_to_workspace_keeper
LOW fixes:
- spurious mut on opake guard in download_from_grant / resolve_identity / resolve_grant_metadata
- member_entries field removed from WorkspaceEntry (internal leak of raw JSON)
- set_default_appview_url deleted (dead method, replaced by accountConfig path)
- accountConfig heartbeat hook comment updated in events_controller