ponytail / audit / review: "Replacement: nothing" hides what a deletion leaves behind in the surviving code
ponytail's rules say "Deletion over addition", and ponytail-audit / ponytail-review phrase every delete: finding as "Replacement: nothing." That's true for the behaviour. It isn't true for the diff: removing a region leaves obligations in the code that stays.
Hit this while removing a dead UI variant (an unused layout branch of a list card component, plus a helper module only that branch used) in a React/TypeScript app. Each of these mattered, and none is covered by the skills:
- The rationale lived in the deleted branch. A long comment explaining a past accessibility fix sat on the branch being removed; the surviving branch only said "see the reasoning above". Plain deletion leaves a dangling pointer and loses the reason.
- Tests were pinned to the deleted variant. Two accessibility tests rendered only the dead variant. Deleting them along with it silently drops coverage of a variant that actually ships; they had to be retargeted, not removed.
- A
ponytail:marker lived inside the removed helper, its ceiling meaningful only for the deleted path. - "No other caller" had to include dynamic props (spread / conditionally set), and the prop itself could only go once a single value remained.
Adjacent, but not the same
- #679 asks for a whole-tree caller check before
delete:, including tests. That's point 4, and I agree with it. This issue is the other direction: what the surviving code points into the removed region, and what has to move with it. - #640 is about not deleting what nobody asked for. This is about deleting correctly when it was asked.
Suggested
In skills/ponytail/SKILL.md, next to "Deletion over addition" (L60), one line:
A deletion is done when nothing surviving points at the gap. Before removing a region, search the code that stays for references into it: call sites (including spread/dynamic props), comments that say "see above/below", tests that exercise only the removed path,
ponytail:markers inside it. Move or retarget each.
In skills/ponytail-audit/SKILL.md (L19) and skills/ponytail-review/SKILL.md (L23), let Replacement name those obligations instead of implying "nothing" is always literal:
delete:dead code, unused flexibility, speculative feature. Replacement: nothing, or the obligations it leaves (e.g. "move rationale comment at L92 to L185; retarget 2 tests").
Checked against current main today: the rule at L60 and the delete: lines in audit (L19) and review (L23) are unchanged.
Happy to open the PR if useful.
Source: DietrichGebert/ponytail