Skip to content

fix: merge-todo treats ## Removed as a deletion - #50

Merged
hkwuks merged 2 commits into
mainfrom
fix/merge-todo-removed
Sep 22, 2026
Merged

hkwuks merged 2 commits into
mainfrom
fix/merge-todo-removed

Conversation

@hkwuks

@hkwuks hkwuks commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Summary

hooks/merge-todo could not treat a ## Removed tombstone as a deletion of the same live entry. key_of took the whole - ID: TF-x (removed …) suffix, and split_todo gave 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 on main.

  • key_of uses the first whitespace token; ## Removed is always head:Removed.
  • A live entry whose ID is in the other side’s Removed set is not emitted (deletion wins).
  • Two changed Removed bodies union by tombstone ID instead of conflicting.

Data cleanup: resurrected live sections for 4d8ae2 / 76e7fb / 2877ca dropped (tombstones remain); live 985164 kept (this task) and its false v1.0.7 tombstone dropped. uniq -d on - ID: is empty.

TaskFlow traceability

  • Task: TaskFlowDocs/2026-09-22-merge-todo-removed/
  • Todo item: TF-20260918-985164
  • Scope: hooks/merge-todo, hooks/smoke-test, TaskFlowDocs/todo.md, task documents
  • Base branch: main
  • Target repository: hkwuks/TaskFlow (origin)

Verification

  • bash hooks/smoke-testALL SMOKE PASSED
  • git diff --check — clean
  • Relevant Skill/plugin validation — quick_validate.py skills/taskflowSkill is valid!; no skill file is touched
  • Results recorded in the TaskFlow Plan — TaskFlowDocs/2026-09-22-merge-todo-removed/plan.md, ## Verification / Review

Beyond the suite: bash -n on 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

  • No secrets or opaque remote payloads included
  • No unrelated task or user files changed — only the merge driver, its smoke section, this task’s documents, and the duplicate-ID cleanup in todo.md
  • Remote/base assumptions are stated — pushed to origin (hkwuks/TaskFlow), targeting main
  • Known limitations and follow-ups are documented below

Known limitations

  • task remove’s Task: gate can still be bypassed by rewriting Task: to Not promoted. first (Notes: gate-only is the wrong fix; left out of this PR).
  • If one side deletes an entry and the other also edits the live body, deletion wins and the edit is dropped rather than conflicted. Not observed; preferable to resurrection.
  • Two ## Removed bodies that both change still take the union path by design (parallel removes are ordinary).

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.
@hkwuks
hkwuks merged commit e9d4c3c into main Sep 22, 2026
6 checks passed
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.

1 participant