Tags: drag a tag onto another to merge (confirm above 20 items, Undo) #1111

Open
opened 2026-10-05 07:36:51 +00:00 by kayg · 4 comments
Owner

Owner decisions (2026-10-05 grill)

Drag a tag onto another tag in the sidebar to merge: every item tagged with the source gets the target, the source tag disappears, and Undo restores everything exactly. More than 20 items: confirm first ("Merge #a into #b? 1,035 items"), then run with progress. 20 or fewer: merge at once with an Undo toast. Same durable rewrite engine as rename (#rename issue). Keyboard and screen-reader path: ⋯ → "Merge into…" with a tag picker. Touch: long-press drag. The owner's immediate use: typo tags (dailyiving, dailyiiving, dailylivibg → dailyliving).

## Owner decisions (2026-10-05 grill) Drag a tag onto another tag in the sidebar to merge: every item tagged with the source gets the target, the source tag disappears, and Undo restores everything exactly. More than 20 items: confirm first ("Merge #a into #b? 1,035 items"), then run with progress. 20 or fewer: merge at once with an Undo toast. Same durable rewrite engine as rename (#rename issue). Keyboard and screen-reader path: ⋯ → "Merge into…" with a tag picker. Touch: long-press drag. The owner's immediate use: typo tags (dailyiving, dailyiiving, dailylivibg → dailyliving).
Author
Owner

Started tags-1110 and tags-1111 on job/tags-1110. Base SHA: 27644444a9. Extending the existing tag rewrite path with durable exact Undo, bounded background progress, and shared Notes writer serialization. No pushes or deploys.

Started tags-1110 and tags-1111 on job/tags-1110. Base SHA: 27644444a91dad244073113b0ec8ec7a61f2a212. Extending the existing tag rewrite path with durable exact Undo, bounded background progress, and shared Notes writer serialization. No pushes or deploys.
Author
Owner

Started work on branch job/tags-1110 from dev at base SHA 27644444a9. Implementing tag drag-to-merge with the same durable rewrite worker as #1110, preserving hierarchy and exact Undo, then I will commit atomic increments and report gate output here.

Started work on branch job/tags-1110 from dev at base SHA 27644444a91dad244073113b0ec8ec7a61f2a212. Implementing tag drag-to-merge with the same durable rewrite worker as #1110, preserving hierarchy and exact Undo, then I will commit atomic increments and report gate output here.
Author
Owner

Finding and fix: the 1,000-entry merge and crash-recovery tests initially failed because their reduced files_index fixture omitted the hash column required by Tags reconciliation. The fixture now matches the query contract. Focused evidence: cargo test -p calternal-tags rewrite::tests -- --test-threads=1 → 3 passed; 0 failed, covering merge, process restart, byte-identical Undo, and an edit between batches.

Finding and fix: the 1,000-entry merge and crash-recovery tests initially failed because their reduced files_index fixture omitted the hash column required by Tags reconciliation. The fixture now matches the query contract. Focused evidence: cargo test -p calternal-tags rewrite::tests -- --test-threads=1 → 3 passed; 0 failed, covering merge, process restart, byte-identical Undo, and an edit between batches.
Author
Owner

Finding and fix during #1110/#1111 implementation:

  • Evidence: the >20 confirmation was first checked from the current Index at enqueue time. A queued operation could wait while source counts changed. The worker now reconciles under the shared Home/Notes writer locks and repeats the threshold check before saving the durable plan. A stale unconfirmed merge is rejected before any source write.
  • Evidence: the existing synchronous /api/v1/tags/rename could interleave between resumable batches because the new worker releases locks per source. Enqueue and Undo now use the same lock order, and the synchronous compatibility route rejects while a rewrite job is active. Notes edits still use the same per-User mutex and are reconciled/journaled per source.
  • Tests include a 1,000-tag Markdown rewrite with a Daily Log entry and Task Markdown, process reopen/resume, exact Undo, and concurrent edits to both processed and pending sources. Browser coverage will exercise the confirmation boundary and Undo against the real production build.
Finding and fix during #1110/#1111 implementation: - Evidence: the >20 confirmation was first checked from the current Index at enqueue time. A queued operation could wait while source counts changed. The worker now reconciles under the shared Home/Notes writer locks and repeats the threshold check before saving the durable plan. A stale unconfirmed merge is rejected before any source write. - Evidence: the existing synchronous `/api/v1/tags/rename` could interleave between resumable batches because the new worker releases locks per source. Enqueue and Undo now use the same lock order, and the synchronous compatibility route rejects while a rewrite job is active. Notes edits still use the same per-User mutex and are reconciled/journaled per source. - Tests include a 1,000-tag Markdown rewrite with a Daily Log entry and Task Markdown, process reopen/resume, exact Undo, and concurrent edits to both processed and pending sources. Browser coverage will exercise the confirmation boundary and Undo against the real production build.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#1111
No description provided.