test(agent): enumerate the orientations instead of patching them one by one
Three consecutive rounds found the same rule broken in a different orientation — content after the pointer, then content before it in the same sentence — because each round's cases only covered the direction that round was about, and each fix was then tested only in the direction I had just thought of. A fourth patch was not the answer; the missing thing was a harness. TestBareAbovePointerOrientations crosses every pointer form with every position content can occupy: alone, before in the same sentence, before in its own sentence, on its own line, as a list item, after in each of those, and behind a filler opener. 36 cells, one assertion — bare IFF there is no content — and each cell first asserts the input really is a pointer, so a mistyped fixture fails loudly instead of passing vacuously. It earned itself immediately: three cells failed on the first run, and the bug was mine and shipped. clauseBoundaryChars gained the em dash last round, and the cut did start = k + 1 — but LastIndexAny returns the BYTE index of the boundary rune, and an em dash is three bytes. "Done — as shown above." sliced mid-rune, left a stray continuation byte in the remainder that no trim removes, and a genuinely bare pointer stopped being recovered. Now advances by the rune's width. Break-check: sixteen mutations, each killed by a named test, control survives. Two had to be reformulated after the harness started failing mutations that were only "killed" by breaking the build — including the one for this very fix.
This commit is contained in:
+7
-1
@@ -3,6 +3,7 @@ package agent
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"gitea.stevedudenhoeffer.com/steve/majordomo/llm"
|
||||
)
|
||||
@@ -190,7 +191,12 @@ func bareAbovePointer(t string) bool {
|
||||
}
|
||||
start := 0
|
||||
if k := strings.LastIndexAny(t[:loc[0]], clauseBoundaryChars); k >= 0 {
|
||||
start = k + 1
|
||||
// k is the BYTE index of the boundary rune's first byte, and one of
|
||||
// those runes is a 3-byte em dash — k+1 would slice into the middle of
|
||||
// it and leave a stray continuation byte in the remainder, which then
|
||||
// never trims away and makes a genuinely bare pointer look occupied.
|
||||
_, w := utf8.DecodeRuneInString(t[k:])
|
||||
start = k + w
|
||||
}
|
||||
rest := strings.TrimSpace(t[:start]) + " " + strings.TrimSpace(t[loc[1]:])
|
||||
return bareRemainderRe.MatchString(strings.Trim(rest, pointerResidueCutset))
|
||||
|
||||
Reference in New Issue
Block a user