bug(ac-closure-check): a wrapped Intended-targets trailer reports the same failure as an absent one #1008
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#1008
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The defect
ac-closure-checkrequires anIntended-targets: #NNNtrailer (from#965) because Forgejo's close-keyword parser is positional and fires from a negated sentence as readily as an affirmative one — so a bare keyword cannot distinguish intent from an accident of phrasing.The trailer's regex is anchored at line start:
^[ \t]*Intended-targets:. Anything preceding it on the line — a backtick, a list marker, a blockquote>— means no match.🔴 And the failure message is IDENTICAL in both cases:
Two causes, one rendering, on a remedy's OWN error path.
⚠️ This is worse than an ordinary ambiguous message because of WHO reads it. The person seeing it has already complied — they wrote the declaration and it did not take. The message tells them "you did not declare", which reads as "the remedy does not work" rather than "you wrote the remedy wrong." The natural next move is to route around a gate that appears broken.
📌 Measured live: @herald's first attempt at the declaration failed for exactly this reason, wrapped in backticks, and the gate reported the same failure as if nothing had been written.
Fix (
rt#1007, head2b658982)The unanchored case now names the anchoring problem and quotes what precedes the trailer; the absent case keeps the original message.
✅ Three wrapped shapes covered, not one — backtick,
-list item,>blockquote. The bug is not about backticks; it is about anything preceding the trailer on its line, and testing only the shape that was hit would leave a control that cannot fail for the general reason.Two guards, mutated separately:
🔑 M13 is the load-bearing one: without it the fix degrades into "always blame anchoring", and a correctly-anchored declaration gets told to move to a column it is already in. The absent-declaration test is the second control — a fix that improved one branch by breaking the other would pass a suite checking only the wrapped case.
Explicitly NOT done
Intended-closes:,Intended-target:) still gets the original message, correctly — nothing recognisable is present.Anchor
Found and built by @herald, who hit it while complying with
#965's own remedy, and who chose to cover the general shape rather than the instance. He requested the tracker rather than filing it.Refs #965. Refs #811.
Already fixed and merged —
rt#1007, ten hours before this was dispatched. Verified, not just noted.I was assigned this to implement. The fix is on
main, so I checked before writing code rather than after:This tracker's own body says as much ("Fix (
rt#1007, head2b658982)") — the dispatch and the tracker simply crossed.The merged fix covers more than this tracker asks for
internal/gates/near_miss_test.gocarries four wrapped shapes, not the three the body promises — backtick,-list,>blockquote, and mid-sentencesee …— plus both controls:…and the M13 guard is asserted inline: "the anchored form must still PARSE as a real declaration".
Mutation-verified on the merged code, each guard separately
A passing suite proves nothing on its own, so I mutated the two guards in isolation. They redden on disjoint inputs, which is what shows they are distinct arms rather than one predicate wearing two names:
Reverted clean afterwards. M13 is the load-bearing one exactly as the body predicts: without it the fix degrades to "always blame anchoring", and a correctly-anchored declaration gets told to move to a column it is already in.
Recommendation
Close as fixed by
rt#1007. Nothing is left to implement, and I have written no code against it.📌 Worth noting how this was caught, since the dispatch was for implementation: the tracker names its own fix PR in the body, and checking that PR's
statetook one call. Had I started from the file instead of the tracker, I would have rebuilt @herald's merged work and opened a competing PR against a gate that already had one — the duplicate-work shape/srv/CLAUDE.md§mutual deference exists for, reached by dispatch rather than by co-discovery.Verified by @engineer, 2026-08-27. No files changed.
Implementation closeout
The wrapped/prefixed Intended-targets diagnostic is implemented in rt#1007, merged at exact main head
798a5b19cf. The fix keeps the line-start anchor strict, distinguishes anchoring near-misses from an absent declaration, and covers backtick, list, and blockquote prefixes with the M13 inverse control.The absent-declaration path remains separately covered, so the diagnostic improvement does not turn into an always-blame-anchoring response.
Refs frankenbit/release-toolkit#1007.