fix(desktop): enforce observer archive policy reconciliation on internal builds#1923
Merged
Merged
Conversation
4290f11 to
3b14c18
Compare
…nal builds Internal builds unconditionally reconcile the kind-24200 owner_p DB subscription every startup, ignoring stale localStorage markers. OSS builds are a pure no-op — the Settings toggle is the only mutation path. Reconciliation is identity-scoped and must succeed before ArchiveSyncManager opens relay listeners, closing the startup race where ephemeral observer frames were permanently lost. Settings toggle uses tri-state policy (unresolved / locked / OSS): disabled while unresolved, fail-closed on flag error, OFF only when policy is positively known as OSS. Checked state reflects actual DB subscription, never synthesized from policy. Compiled-flag Rust test reads an independently supplied runtime expected value; dual-compile Just recipe is committed and wired into CI, proving both clean (false) and internal (true) states on every run. Identity-scoped readiness is exposed as a pure isReconciledFor helper so the gate can be unit-tested directly instead of shadowed by a test-local variable. Settings toggle states (unresolved/internal/OSS) and the post- reconciliation subscription path are covered by a Playwright E2E spec, registered in the smoke project so it actually runs. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
3b14c18 to
5fc3160
Compare
wesbillman
reviewed
Jul 16, 2026
wesbillman
left a comment
Collaborator
There was a problem hiding this comment.
The reconciliation ordering, identity-scoped gate, internal/OSS policy split, Settings tri-state behavior, and test coverage look correct. I found no code blocker. I am withholding approval because the head is currently 7 commits behind main; please rebase and rerun CI, then I can give the final approval against the current merge base.
wesbillman
approved these changes
Jul 16, 2026
atishpatel
added a commit
that referenced
this pull request
Jul 16, 2026
…adata * origin/main: feat: add invite QR and mobile direct join (#1957) feat: open add community from deep links (#1970) fix(desktop): enforce observer archive policy reconciliation on internal builds (#1923) feat(desktop): streamline nostr identity pairing (#1974) feat(desktop): ensure starter channels during onboarding (#1937) test(desktop): make omission-preservation test discriminate on instructions (#1988) fix(desktop): omission must not wipe team persona_ids/instructions (#1985) # Conflicts: # Cargo.lock
This was referenced Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
24200exists in theowner_pDB subscription on every startup, regardless of stalelocalStoragemarkers ("0"or"1"). A prior opt-out can no longer suppress the observer archive — the DB row is authoritative for internal policy.ArchiveSyncManagertears down before the new identity's reconciliation completes. The gate is exposed as a pureisReconciledForhelper, directly unit-testable without React mount infra.useDeferredStartup) and must complete beforeArchiveSyncManageropens relay listeners, closing the startup race where kind24200frames were permanently lost.undefined= unresolved,true= locked,false= OSS): disabled while unresolved, fail-closed on flag error, OFF only when policy is positively known as OSS.checkedreflects actual DB state, never synthesized from policy.desktop-tauri-test-compiled-flagsJust recipe proves both clean (false) and internal (true) compiled states, wired into CI afterdesktop-tauri-test.observer_archive_default_enabled,agent_metric_archive_default_enabled,merge_save_subscription_kinds, andremove_save_subscription_kind. A Playwright spec covers Settings toggle states (unresolved/internal/OSS) and asserts archive sync reaches the subscription path post-reconciliation, exercising the realAppShellgate wiring; registered in thesmokeproject.Related: buzz-releases#62 (PR pipeline env var parity + validation guard)
Changed files
desktop/src/features/local-archive/useObserverArchiveSeed.tshasExplicitChoiceremoved from deps. Hook storesreconciledPubkey; identity-scoped readiness delegates to exported pureisReconciledFor.desktop/src/features/local-archive/useObserverArchiveSeed.test.mjsArchiveSyncManager+ real reconciler with deferred promise; identity transition and rejection tests assert against the real exportedisReconciledFor.desktop/src/features/local-archive/ui/LocalArchiveSettingsCard.tsxundefined/true/false). Toggle disabled while unresolved or policy-locked. Fail-closed on flag error.checkedreflects actual DB state. Guard insidehandleObserverToggle.desktop/src/features/local-archive/archiveSyncManager.tsready = truedefault onuseArchiveSync— single caller must pass explicitly.desktop/src/app/AppShell.tsxuseArchiveSyncgated on success. Metric seed stays deferred.desktop/src/testing/e2eBridge.tsobserver_archive_default_enabled,agent_metric_archive_default_enabled,merge_save_subscription_kinds,remove_save_subscription_kindwith configurable mock policy, plus an IPC call counter forlist_save_subscriptionsused by the E2E reconciliation-gate assertion.desktop/tests/helpers/bridge.tsobserverArchiveDefaultEnabledmock option.desktop/tests/e2e/observer-archive-policy.spec.tslist_save_subscriptionsis reached only after successful reconciliation. Registered inplaywright.config.ts'ssmokeproject.desktop/src-tauri/src/commands/observer_archive.rs#[ignore]d and readsBUZZ_TEST_EXPECTED_OBSERVER_ARCHIVE_DEFAULTat runtime, panicking if unset, so it can't silently no-op.desktop/src/shared/api/tauriArchive.tsobserverArchiveDefaultEnableddocstring to describe policy enforcement (not auto-seeding).Justfiledesktop-tauri-test-compiled-flagsrecipe, running the focused Rust test under both clean and internal-flag compilations..github/workflows/ci.ymldesktop-tauri-test-compiled-flagsinto the desktop Tauri CI job afterdesktop-tauri-test.