Skip to content

Conversation

@viamin
Copy link
Owner

@viamin viamin commented Dec 28, 2025

Document root causes of duplicate tasks appearing in Asana after sync,
particularly for shopping lists with repeated item titles. Key findings:

  • Title matching fallback in find_matching_item_in returns first match
  • Completed tasks from last 7 days are included in matching pool
  • Wrong pairing leaves legitimate items unmatched, creating duplicates

Proposes phased solutions: exclude completed items from title matching,
strengthen sync ID preference, and add per-project configuration.

Document root causes of duplicate tasks appearing in Asana after sync,
particularly for shopping lists with repeated item titles. Key findings:

- Title matching fallback in find_matching_item_in returns first match
- Completed tasks from last 7 days are included in matching pool
- Wrong pairing leaves legitimate items unmatched, creating duplicates

Proposes phased solutions: exclude completed items from title matching,
strengthen sync ID preference, and add per-project configuration.
Document the compounding problem where sync IDs are not added
during updates (update_ids_for_existing: false by default).
This causes title-matched items to never graduate to ID matching,
perpetuating wrong matches on every sync.

Also document "zombie task" reactivation - when a new active task
title-matches a completed task, the completed task gets reactivated
because the update payload includes completed: false.

Updated recommendations to include Option 6: always add sync IDs
when title matching succeeds.
When update_item is called on items that were matched by title rather
than by sync ID, automatically add sync IDs so future syncs use ID
matching instead of fragile title matching.

This fixes issue #149 by ensuring that:
1. Items matched by title "graduate" to ID matching after first sync
2. Future syncs won't accidentally match wrong items with same title
3. The problem doesn't compound across sync cycles

Detection is simple: if external_task doesn't have our service's ID,
it must have been matched by title. We then add the sync ID.

Applied to: Asana, OmniFocus, Reclaim, Reminders services.
Google Tasks uses a different pattern (one-way sync) and doesn't
need this change.
Only allow title matching if NEITHER item has a sync_id for the other
service. This prevents items already linked to other items from being
"stolen" by new items via title matching.

Combined with Option 6 (adding sync IDs on title match), this ensures:
- First sync: title matching works for new items
- Future syncs: ID matching used (reliable)
- New duplicate titles: create new tasks, don't hijack existing pairs

Updated investigation document with implementation details and
scenarios table showing expected behavior.

Fixes #149
@viamin viamin force-pushed the claude/investigate-issue-149-tzjgW branch 2 times, most recently from 8c26436 to 84074f1 Compare December 29, 2025 07:38
Add comprehensive tests for the changes made to fix issue #149:

Option 7 tests (spec/lib/base/sync_item_spec.rb):
- Test find_matching_item_in with ID matching
- Test title matching when neither item has sync ID
- Test that items with sync IDs are excluded from title matching
- Test shopping list scenario (new item should not match old linked item)
- Test first-time sync and subsequent syncs

Option 6 tests (spec/lib/asana/update_item_spec.rb, spec/lib/reminders/update_item_spec.rb):
- Test sync IDs are added when item was matched by title
- Test sync IDs are NOT added when item was matched by ID
- Test update_ids_for_existing option still works
- Test pretend mode and API failure cases
@viamin viamin force-pushed the claude/investigate-issue-149-tzjgW branch from 84074f1 to ce742dd Compare December 29, 2025 08:03
Add comprehensive test coverage for the project-change code path:
- When external task has different project than Asana task, calls addProject API
- After project change, moves task to correct section
- When addProject API fails, returns failure message and skips section move
- When move_task_to_section fails, returns the error
- When external task has no project, skips project change logic
- When projects match, skips project change logic
Use block form for respond_to? stub to handle any argument,
including RSpec's internal matcher check. Move stubs into each
context where external_task is defined.
@viamin viamin merged commit cdf9543 into main Dec 30, 2025
4 checks passed
@viamin viamin deleted the claude/investigate-issue-149-tzjgW branch December 30, 2025 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants