Make deep backfill's Phase C (orphan-contact discovery) opt-in#21
Open
DiscoBard wants to merge 1 commit into
Open
Make deep backfill's Phase C (orphan-contact discovery) opt-in#21DiscoBard wants to merge 1 commit into
DiscoBard wants to merge 1 commit into
Conversation
Deep backfill's Phase C iterates the user's contacts and calls
GetOrCreateConversation for every phone number. Google Messages treats
that call as a thread-creation: for each contact lacking a prior
thread, an empty SMS thread is created on the user's phone.
For users running deep backfill primarily to sync existing history,
that side effect is unwanted -- it produces dozens of new "blank"
threads on the device with no way to undo individually.
Make Phase C opt-in via a new env var:
OPENMESSAGES_BACKFILL_DISCOVER_ORPHANS=1
When unset (default), deepBackfill runs Phases A (folder pagination)
and B (per-conversation messages) only and logs an informational line
explaining the gate. When set to a truthy value, behavior is unchanged
from the current default.
- internal/app/backfill.go: add orphanContactDiscoveryEnabled() helper;
gate Phase C call with informational log line on the off path
- internal/app/backfill_test.go: add TestOrphanContactDiscoveryEnabled
with truthy/falsy parsing cases; add TestDeepBackfillSkipsPhaseCWhen
OptOut to assert the default-off path produces no contact-discovery
side effects; opt the existing Phase C tests in via t.Setenv
- README.md: document the new env var with the side-effect warning
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
DeepBackfillruns three phases:discoverFromContactscallsGetOrCreateConversationfor every contact's phone number to surface threads not visible from folder listingsPhases A and B are pure history reads. Phase C has a write-shaped side effect: Google Messages treats
GetOrCreateConversationas a thread-creation, so for each contact without a prior thread, an empty SMS thread is created on the user's phone. A user with several dozen contacts who runs deep backfill ends up with several dozen blank conversations they have to delete by hand.This PR keeps Phase C available but makes it opt-in via a new env var:
Default behavior changes from "Phase C runs on every deep backfill" to "Phase C runs only when explicitly enabled." Users who want the orphan-discovery behavior get it back with one env var; users running deep backfill purely as a history sync no longer get unintended new threads.
Implementation
internal/app/backfill.go— addorphanContactDiscoveryEnabled()helper (parses1/true/yes/on, case- and whitespace-tolerant). Gate the Phase C call indeepBackfill()on this. Off-path logs an informational line referencing the env var.internal/app/backfill_test.go:TestOrphanContactDiscoveryEnabled— table-driven coverage of the parser (truthy, falsy, mixed case, whitespace, unrecognized values)TestDeepBackfillSkipsPhaseCWhenOptOut— asserts no contact-discovery side effects on the default-off path (no contacts checked, no orphan conversations stored)TestDeepBackfillContactDiscovery,TestDeepBackfillContactDiscoverySkipsAlreadySeen,TestDeepBackfillGetOrCreateError— opt in viat.Setenvsince they specifically exercise Phase CREADME.md— document the new env var with a clear warning about the empty-thread side effectTest plan
go build ./...— cleango test ./internal/app/ ./internal/client/— passes (existing + new helper test + new opt-out regression test)OPENMESSAGES_BACKFILL_DISCOVER_ORPHANS=1, confirm previous behavior is preservedCompat
No API change. Default behavior changes; users relying on Phase C running automatically will need to set the env var. The off-path log line tells them exactly what to do.
🤖 Generated with Claude Code