fix: merge-todo treats ## Removed as a deletion - #50
Merged
Merged
Conversation
key_of took the whole "- ID: TF-x (removed …)" suffix, and split_todo gave the entire ## Removed blob one key (the first tombstone's ID), so a tombstone never matched the live entry. The driver kept the other side's live copy as "only they have it" and resurrected it — seen live when a rebase of the housekeeping commit restored three already-removed todos. - key_of: first whitespace token; ## Removed always head:Removed - a live entry whose ID sits in the other side's Removed set is not emitted - two changed Removed bodies union by tombstone ID instead of conflicting Data: drop resurrected live sections for 4d8ae2/76e7fb/2877ca (tombstones remain); keep live 985164 (this task) and drop its false v1.0.7 tombstone. No duplicate - ID: lines remain. Smoke covers delete/keep in both directions and the tombstone union.
CI job todo-merge-audit failed on this PR: ids_at captured the whole "- ID: TF-x (removed …)" line as one identity, while removed_at already took the TF- token. Deleting the stale 985164 tombstone while keeping the live entry therefore looked like losing an entry named for the entire parenthetical string. Tokenize ids_at the same way. Smoke keeps the live ID and drops only the twin tombstone; the real merge commit now reports STATUS: pass.
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
hooks/merge-todocould not treat a## Removedtombstone as a deletion of the same live entry.key_oftook the whole- ID: TF-x (removed …)suffix, andsplit_todogave the entire Removed blob a single key (the first tombstone’s ID). The driver’s “only one side has it → keep it” rule therefore kept the other side’s live copy and resurrected it.This was observed live: rebasing the housekeeping commit onto PR #49 invoked the driver and restored three already-removed todos, leaving four duplicated
- ID:lines onmain.key_ofuses the first whitespace token;## Removedis alwayshead:Removed.Data cleanup: resurrected live sections for
4d8ae2/76e7fb/2877cadropped (tombstones remain); live985164kept (this task) and its false v1.0.7 tombstone dropped.uniq -don- ID:is empty.TaskFlow traceability
TaskFlowDocs/2026-09-22-merge-todo-removed/TF-20260918-985164hooks/merge-todo,hooks/smoke-test,TaskFlowDocs/todo.md, task documentsmainhkwuks/TaskFlow(origin)Verification
bash hooks/smoke-test—ALL SMOKE PASSEDgit diff --check— cleanquick_validate.py skills/taskflow→Skill is valid!; no skill file is touchedTaskFlowDocs/2026-09-22-merge-todo-removed/plan.md,## Verification / ReviewBeyond the suite:
bash -non both changed hooks; delete/keep fixtures in both directions and a dual-tombstone union are covered by the new smoke section; existing merge-driver sections (disjoint adds, one-sided edit, double-edit conflict, install idempotence) stay green.Review boundaries
todo.mdorigin(hkwuks/TaskFlow), targetingmainKnown limitations
task remove’sTask:gate can still be bypassed by rewritingTask:toNot promoted.first (Notes: gate-only is the wrong fix; left out of this PR).## Removedbodies that both change still take the union path by design (parallel removes are ordinary).