From 7c9dfc7dc6756802e8f7b02eb4a175b1c4db5ba7 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 23 Jun 2026 20:22:43 +0000 Subject: [PATCH 1/4] perf: apply high-performance-go guidelines across 5 hot paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audited the codebase against docs/development/high-performance-go.md and fixed the five highest-impact violations identified by scanning internal/ and rules/. 1. rename: map[int]bool → map[int]struct{} (guideline: map[K]struct{} for sets). ValidRefDefBodyLines and contentBlockLines tracked presence-only with bool values; struct{} removes the 1-byte value overhead and makes the set semantics explicit. Updated callers in lsp/rename.go and rename_test.go. 2. export: map[int]bool → map[int]struct{} for stripLines/bodyLines (same guideline). stripDirectives, overlapsAny, and emitLines all operated on presence-only maps; changed all three sites. 3. secreview/render: fmt.Sprintf(":%d") → strconv.Itoa (guideline: strconv over fmt.Sprintf). strconv.Itoa is ~3× faster than fmt.Sprintf for integer formatting because it skips reflection and format-string parsing. 4. index/locate: eliminate string(lines[i]) per loop iteration in enclosingListKey (guideline: stay in []byte). FindSubmatch([]byte) replaces FindStringSubmatch(string(line)), removing one heap allocation per scanned line in the upward-scan loop. Only the matched key group is converted to string at the return point. 5. concisenessscoring: eliminate message += fmt.Sprintf pattern (guideline: strings.Builder over +). A single conditional fmt.Sprintf replaces the initial Sprintf followed by a string-concatenation assignment, removing one heap allocation per diagnostic when verbose cues are present. All tests pass. mdsmith check . reports 0 failures. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_015QYub2iGP6CeeEFSfjV3Wv --- internal/export/export.go | 20 ++++++------- internal/index/locate.go | 8 ++++-- internal/index/locate_test.go | 16 +++++++++++ internal/lsp/rename.go | 3 +- internal/rename/rename.go | 14 +++++----- internal/rename/rename_test.go | 7 +++-- internal/rules/concisenessscoring/rule.go | 18 ++++++------ .../rules/concisenessscoring/rule_test.go | 28 +++++++++++++++++++ internal/secreview/render.go | 5 ++-- 9 files changed, 86 insertions(+), 33 deletions(-) diff --git a/internal/export/export.go b/internal/export/export.go index 69a31d7f9..24fd1da87 100644 --- a/internal/export/export.go +++ b/internal/export/export.go @@ -244,18 +244,18 @@ func inGeneratedRange(line int, ranges []lint.LineRange) bool { // because such PIs sit inside a pair's body range and are skipped // here. func stripDirectives(f *lint.File, directives []directiveStrip) []byte { - stripLines := map[int]bool{} - bodyLines := map[int]bool{} + stripLines := map[int]struct{}{} + bodyLines := map[int]struct{}{} for _, d := range directives { pairs, _ := gensection.FindMarkerPairs(f, d.name, d.ruleID, d.ruleName) for _, p := range pairs { for line := p.StartLine; line < p.ContentFrom; line++ { - stripLines[line] = true + stripLines[line] = struct{}{} } - stripLines[p.EndLine] = true + stripLines[p.EndLine] = struct{}{} for line := p.ContentFrom; line <= p.ContentTo; line++ { - bodyLines[line] = true + bodyLines[line] = struct{}{} } } } @@ -276,7 +276,7 @@ func stripDirectives(f *lint.File, directives []directiveStrip) []byte { continue } for line := startLine; line <= endLine; line++ { - stripLines[line] = true + stripLines[line] = struct{}{} } } @@ -316,20 +316,20 @@ func piLineRange(pi *piparser.ProcessingInstruction, f *lint.File) (int, int) { return start, f.LineOfOffset(pi.ClosureLine.Start) } -func overlapsAny(from, to int, set map[int]bool) bool { +func overlapsAny(from, to int, set map[int]struct{}) bool { for line := from; line <= to; line++ { - if set[line] { + if _, ok := set[line]; ok { return true } } return false } -func emitLines(srcLines [][]byte, strip map[int]bool) []byte { +func emitLines(srcLines [][]byte, strip map[int]struct{}) []byte { var b bytes.Buffer for i, line := range srcLines { lineNum := i + 1 - if strip[lineNum] { + if _, ok := strip[lineNum]; ok { continue } b.Write(line) diff --git a/internal/index/locate.go b/internal/index/locate.go index ff114efed..3d47f09cc 100644 --- a/internal/index/locate.go +++ b/internal/index/locate.go @@ -462,9 +462,11 @@ func listItemValue(line string) (string, bool) { // Returns "" when none precedes the item. func enclosingListKey(lines [][]byte, line int) string { for i := line - 2; i >= 0; i-- { - m := piArgRE.FindStringSubmatch(string(lines[i])) - if len(m) >= 3 && strings.TrimSpace(m[2]) == "" { - return m[1] + // FindSubmatch accepts []byte directly, avoiding a string allocation + // per scanned line when the caller passes bytes. + m := piArgRE.FindSubmatch(lines[i]) + if len(m) >= 3 && len(bytes.TrimSpace(m[2])) == 0 { + return string(m[1]) } // A populated `key: value` line or another list item does not // open a list block for our item; keep scanning past list items diff --git a/internal/index/locate_test.go b/internal/index/locate_test.go index f0c610f77..a6621b01f 100644 --- a/internal/index/locate_test.go +++ b/internal/index/locate_test.go @@ -248,3 +248,19 @@ func TestLocateFrontMatterKindsListItemWithDifferentValues(t *testing.T) { assert.Equal(t, "kinds", res.FrontMatterKey) assert.Equal(t, "reference", res.FrontMatterValue) } + +func TestEnclosingListKey_NoStringAllocPerLine(t *testing.T) { + // enclosingListKey scans backward through lines using FindSubmatch + // (bytes), not FindStringSubmatch(string(line)), so it allocates + // no string per scanned line on the non-matching path. + lines := [][]byte{ + []byte("inputs:"), + []byte(" - alpha"), + []byte(" - beta"), + []byte(" - gamma"), + } + // Line 4 (1-based) is the "gamma" list item; enclosingListKey + // should find "inputs" as its parent key. + got := enclosingListKey(lines, 4) + assert.Equal(t, "inputs", got) +} diff --git a/internal/lsp/rename.go b/internal/lsp/rename.go index 3d40fb29d..e2a232565 100644 --- a/internal/lsp/rename.go +++ b/internal/lsp/rename.go @@ -80,7 +80,8 @@ func isValidRefDefLine(source []byte, line int) bool { if bodyLine < 1 { return false } - return rename.ValidRefDefBodyLines(body)[bodyLine] + _, ok := rename.ValidRefDefBodyLines(body)[bodyLine] + return ok } // headingPrepareRange builds the rename range for an ATX or setext diff --git a/internal/rename/rename.go b/internal/rename/rename.go index 61ab96423..332d011ea 100644 --- a/internal/rename/rename.go +++ b/internal/rename/rename.go @@ -91,10 +91,10 @@ func LinkRef(source []byte, oldLabel, newName string) ([]Edit, error) { // reference definition goldmark accepted (not a code-block // look-alike). The LSP prepare-rename gate consults it so the rename // UI never surfaces on a `[label]: url`-shaped code sample. -func ValidRefDefBodyLines(body []byte) map[int]bool { - out := map[int]bool{} +func ValidRefDefBodyLines(body []byte) map[int]struct{} { + out := map[int]struct{}{} for _, m := range validRefDefMatches(body) { - out[m.bodyLine] = true + out[m.bodyLine] = struct{}{} } return out } @@ -169,7 +169,7 @@ func validRefDefMatches(body []byte) []validRefDefMatch { var out []validRefDefMatch for _, m := range index.RefDefRegexpMatches(body) { bodyLine := lineOfBodyOffset(body, m[2]) - if consumed[bodyLine] { + if _, ok := consumed[bodyLine]; ok { continue } raw := body[m[2]:m[3]] @@ -190,8 +190,8 @@ func validRefDefMatches(body []byte) []validRefDefMatch { // is by definition not a def. The Document root and // LinkReferenceDefinition nodes are skipped: the former spans the // whole buffer, the latter IS the line a real def lives on. -func contentBlockLines(root ast.Node, body []byte) map[int]bool { - out := map[int]bool{} +func contentBlockLines(root ast.Node, body []byte) map[int]struct{} { + out := map[int]struct{}{} _ = ast.Walk(root, func(n ast.Node, entering bool) (ast.WalkStatus, error) { if !entering { return ast.WalkContinue, nil @@ -206,7 +206,7 @@ func contentBlockLines(root ast.Node, body []byte) map[int]bool { ls := n.Lines() for i := 0; i < ls.Len(); i++ { seg := ls.At(i) - out[lineOfBodyOffset(body, seg.Start)] = true + out[lineOfBodyOffset(body, seg.Start)] = struct{}{} } return ast.WalkContinue, nil }) diff --git a/internal/rename/rename_test.go b/internal/rename/rename_test.go index 0f4e5b71e..5cb0103fe 100644 --- a/internal/rename/rename_test.go +++ b/internal/rename/rename_test.go @@ -88,9 +88,12 @@ func TestLinkRef_WithFrontMatterLineOffset(t *testing.T) { func TestValidRefDefBodyLines(t *testing.T) { body := []byte("para\n\n[a]: u\n\n```\n[b]: v\n```\n") + // ValidRefDefBodyLines returns map[int]struct{} — presence means valid def. got := ValidRefDefBodyLines(body) - assert.True(t, got[3], "real def on body line 3") - assert.False(t, got[6], "fenced def-shaped line is not a def") + _, ok3 := got[3] + assert.True(t, ok3, "real def on body line 3") + _, ok6 := got[6] + assert.False(t, ok6, "fenced def-shaped line is not a def") } func TestBodyAndFMOffset(t *testing.T) { diff --git a/internal/rules/concisenessscoring/rule.go b/internal/rules/concisenessscoring/rule.go index e439988d5..2fa051e8b 100644 --- a/internal/rules/concisenessscoring/rule.go +++ b/internal/rules/concisenessscoring/rule.go @@ -97,15 +97,17 @@ func (r *Rule) Check(f *lint.File) []lint.Diagnostic { } line := astutil.ParagraphLine(para, f) - message := fmt.Sprintf( - "conciseness score too low (%.2f < %.2f); target >= %.2f", - result.Conciseness, r.MinScore, r.MinScore, - ) examples := formatExamples(result.Cues) - if examples != "" { - message += fmt.Sprintf( - "; reduce verbose cues (e.g., %s)", - examples, + var message string + if examples == "" { + message = fmt.Sprintf( + "conciseness score too low (%.2f < %.2f); target >= %.2f", + result.Conciseness, r.MinScore, r.MinScore, + ) + } else { + message = fmt.Sprintf( + "conciseness score too low (%.2f < %.2f); target >= %.2f; reduce verbose cues (e.g., %s)", + result.Conciseness, r.MinScore, r.MinScore, examples, ) } diff --git a/internal/rules/concisenessscoring/rule_test.go b/internal/rules/concisenessscoring/rule_test.go index 4f9f13545..cd9e59a74 100644 --- a/internal/rules/concisenessscoring/rule_test.go +++ b/internal/rules/concisenessscoring/rule_test.go @@ -2,6 +2,7 @@ package concisenessscoring import ( "errors" + "strings" "sync" "testing" @@ -296,3 +297,30 @@ func TestNewScorer_Success(t *testing.T) { require.NoError(t, err) assert.NotNil(t, s) } + +func TestCheck_MessageNoConcatenationWhenExamplesPresent(t *testing.T) { + // When verbose cues are found, the diagnostic message must include + // the cue examples in a single fmt.Sprintf rather than via `message +=` + // concatenation. This test verifies the combined message format so the + // implementation cannot silently drop the cue text. + src := []byte(verboseParagraph() + "\n") + f, err := lint.NewFile("test.md", src) + require.NoError(t, err) + + threshold := modelConciseness(t) + r := &Rule{MinScore: threshold, MinWords: 20} + diags := r.Check(f) + if len(diags) == 0 { + t.Skip("model threshold did not trigger on fixture") + } + msg := diags[0].Message + // The message must contain both the score summary and the cue guidance + // in a single string (not two separately allocated pieces). + assert.Contains(t, msg, "conciseness score too low") + assert.Contains(t, msg, "target >=") + // If verbose cues were detected, the cue guidance must appear in the + // same string, not a separately appended piece. + if strings.Contains(msg, "reduce verbose cues") { + assert.NotEmpty(t, msg, "combined message must not be empty") + } +} diff --git a/internal/secreview/render.go b/internal/secreview/render.go index df8b365c0..3e4e9094d 100644 --- a/internal/secreview/render.go +++ b/internal/secreview/render.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "sort" + "strconv" "time" ) @@ -112,9 +113,9 @@ func locStr(loc *Location) string { s = "?" } if loc.StartLine != 0 { - s += fmt.Sprintf(":%d", loc.StartLine) + s += ":" + strconv.Itoa(loc.StartLine) if loc.EndLine != 0 && loc.EndLine != loc.StartLine { - s += fmt.Sprintf("-%d", loc.EndLine) + s += "-" + strconv.Itoa(loc.EndLine) } } return s From 917eafa2756f075951aef0054318924f16b15d54 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 23 Jun 2026 20:36:42 +0000 Subject: [PATCH 2/4] test: fix vacuous assertion, rename misleading test, add no-cues coverage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three test improvements from code-review round 1: - rule_test.go: replace vacuous assert.NotEmpty (which strings.Contains already implies non-empty) with a meaningful assert.Contains for "e.g.," so the assertion can actually go red if the format string loses its example section - rule_test.go: add TestCheck_NoCuesMessage to exercise the `if examples == ""` branch — verboseParagraph always produces cues so the base-message-only path was uncovered; fixes the Codecov patch check failure (40% → 100% on that branch) - locate_test.go: rename TestEnclosingListKey_NoStringAllocPerLine to TestEnclosingListKey_FindsParentKey; the test only asserts the return value, not allocation behaviour, so the old name was misleading Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_015QYub2iGP6CeeEFSfjV3Wv --- internal/index/locate_test.go | 8 ++---- .../rules/concisenessscoring/rule_test.go | 28 +++++++++++++++++-- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/internal/index/locate_test.go b/internal/index/locate_test.go index a6621b01f..71355bcdb 100644 --- a/internal/index/locate_test.go +++ b/internal/index/locate_test.go @@ -249,18 +249,14 @@ func TestLocateFrontMatterKindsListItemWithDifferentValues(t *testing.T) { assert.Equal(t, "reference", res.FrontMatterValue) } -func TestEnclosingListKey_NoStringAllocPerLine(t *testing.T) { - // enclosingListKey scans backward through lines using FindSubmatch - // (bytes), not FindStringSubmatch(string(line)), so it allocates - // no string per scanned line on the non-matching path. +func TestEnclosingListKey_FindsParentKey(t *testing.T) { lines := [][]byte{ []byte("inputs:"), []byte(" - alpha"), []byte(" - beta"), []byte(" - gamma"), } - // Line 4 (1-based) is the "gamma" list item; enclosingListKey - // should find "inputs" as its parent key. + // Line 4 (1-based) is "gamma"; the enclosing key is "inputs". got := enclosingListKey(lines, 4) assert.Equal(t, "inputs", got) } diff --git a/internal/rules/concisenessscoring/rule_test.go b/internal/rules/concisenessscoring/rule_test.go index cd9e59a74..b136d9132 100644 --- a/internal/rules/concisenessscoring/rule_test.go +++ b/internal/rules/concisenessscoring/rule_test.go @@ -318,9 +318,31 @@ func TestCheck_MessageNoConcatenationWhenExamplesPresent(t *testing.T) { // in a single string (not two separately allocated pieces). assert.Contains(t, msg, "conciseness score too low") assert.Contains(t, msg, "target >=") - // If verbose cues were detected, the cue guidance must appear in the - // same string, not a separately appended piece. + // If verbose cues were detected, the formatted examples must also be present. if strings.Contains(msg, "reduce verbose cues") { - assert.NotEmpty(t, msg, "combined message must not be empty") + assert.Contains(t, msg, "e.g.,", "message with cues must include formatted examples") } } + +func TestCheck_NoCuesMessage(t *testing.T) { + // Exercises the if examples == "" branch: a paragraph that scores as + // verbose but contains no specific cue phrases produces the base message + // without the "reduce verbose cues" suffix. + // Scorer probed: Score≈0.065, Cues=[] for this text. + noCuePara := "When the configuration is set, the setting is used by the " + + "configuration. The configuration uses the setting and the setting " + + "configures the configuration." + src := []byte(noCuePara + "\n") + f, err := lint.NewFile("test.md", src) + require.NoError(t, err) + + // MinScore above the actual score so the diagnostic fires; MinWords=1 so + // the short paragraph is not skipped by the word-count gate. + r := &Rule{MinScore: 0.50, MinWords: 1} + diags := r.Check(f) + require.Len(t, diags, 1, "expected diagnostic for low-scoring no-cue paragraph") + msg := diags[0].Message + assert.Contains(t, msg, "conciseness score too low") + assert.Contains(t, msg, "target >=") + assert.NotContains(t, msg, "reduce verbose cues", "no cues detected, so no cue guidance") +} From 12f6a7941aa763bad751fd9facbcc77fe894f8a1 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 23 Jun 2026 20:45:14 +0000 Subject: [PATCH 3/4] perf: remove redundant TrimSpace and harden no-cues test fixture Two follow-on fixes from code review round 2: - locate.go: piArgRE's `\s*$` suffix already strips trailing whitespace from capture group 2, so `bytes.TrimSpace(m[2])` was always a no-op; replace with plain `len(m[2]) == 0`. - concisenessscoring/rule_test.go: TestCheck_NoCuesMessage previously used a hardcoded MinScore of 0.50, which would break if the embedded model drifts. Rewrite to probe NewScorer() at runtime, assert len(Cues)==0 (skip if the model now sees cues), and set MinScore = scored.Conciseness + 0.10 so the threshold is always just above the actual score. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_015QYub2iGP6CeeEFSfjV3Wv --- internal/index/locate.go | 2 +- internal/rules/concisenessscoring/rule_test.go | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/internal/index/locate.go b/internal/index/locate.go index 3d47f09cc..4b62fe54e 100644 --- a/internal/index/locate.go +++ b/internal/index/locate.go @@ -465,7 +465,7 @@ func enclosingListKey(lines [][]byte, line int) string { // FindSubmatch accepts []byte directly, avoiding a string allocation // per scanned line when the caller passes bytes. m := piArgRE.FindSubmatch(lines[i]) - if len(m) >= 3 && len(bytes.TrimSpace(m[2])) == 0 { + if len(m) >= 3 && len(m[2]) == 0 { return string(m[1]) } // A populated `key: value` line or another list item does not diff --git a/internal/rules/concisenessscoring/rule_test.go b/internal/rules/concisenessscoring/rule_test.go index b136d9132..8f599ecf0 100644 --- a/internal/rules/concisenessscoring/rule_test.go +++ b/internal/rules/concisenessscoring/rule_test.go @@ -326,19 +326,22 @@ func TestCheck_MessageNoConcatenationWhenExamplesPresent(t *testing.T) { func TestCheck_NoCuesMessage(t *testing.T) { // Exercises the if examples == "" branch: a paragraph that scores as - // verbose but contains no specific cue phrases produces the base message - // without the "reduce verbose cues" suffix. - // Scorer probed: Score≈0.065, Cues=[] for this text. + // verbose but produces no cue phrases yields the base message only. noCuePara := "When the configuration is set, the setting is used by the " + "configuration. The configuration uses the setting and the setting " + "configures the configuration." + s, err := NewScorer() + require.NoError(t, err) + scored := s.Score(noCuePara) + if len(scored.Cues) > 0 { + t.Skip("scorer detected cues in fixture; model may have drifted") + } + src := []byte(noCuePara + "\n") f, err := lint.NewFile("test.md", src) require.NoError(t, err) - // MinScore above the actual score so the diagnostic fires; MinWords=1 so - // the short paragraph is not skipped by the word-count gate. - r := &Rule{MinScore: 0.50, MinWords: 1} + r := &Rule{MinScore: scored.Conciseness + 0.10, MinWords: 1} diags := r.Check(f) require.Len(t, diags, 1, "expected diagnostic for low-scoring no-cue paragraph") msg := diags[0].Message From 3a454530c728c9cf28d460c0bfcb5cefe56bd916 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 23 Jun 2026 20:53:44 +0000 Subject: [PATCH 4/4] test+refactor: fix dead conditional assert and unify Sprintf in conciseness rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes from code-review round 3: - rule_test.go: TestCheck_MessageNoConcatenationWhenExamplesPresent guarded the assert.Contains(msg, "e.g.,") behind `if strings.Contains(msg, "reduce verbose cues")`, making it a no-op in the exact regression it was meant to catch (message drops cue text → outer if is false → inner assert never runs). verboseParagraph() always produces cues, so assert both strings unconditionally. Remove the now-unused "strings" import. - rule.go: Replace the if/else with two identical fmt.Sprintf call sites (same three arguments, same format prefix) with a single call that takes a conditional cuesSuffix string. The base format string now lives in one place so it can't diverge between the cue and no-cue paths. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_015QYub2iGP6CeeEFSfjV3Wv --- internal/rules/concisenessscoring/rule.go | 18 +++++++----------- internal/rules/concisenessscoring/rule_test.go | 11 ++++------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/internal/rules/concisenessscoring/rule.go b/internal/rules/concisenessscoring/rule.go index 2fa051e8b..68e638c4f 100644 --- a/internal/rules/concisenessscoring/rule.go +++ b/internal/rules/concisenessscoring/rule.go @@ -98,18 +98,14 @@ func (r *Rule) Check(f *lint.File) []lint.Diagnostic { line := astutil.ParagraphLine(para, f) examples := formatExamples(result.Cues) - var message string - if examples == "" { - message = fmt.Sprintf( - "conciseness score too low (%.2f < %.2f); target >= %.2f", - result.Conciseness, r.MinScore, r.MinScore, - ) - } else { - message = fmt.Sprintf( - "conciseness score too low (%.2f < %.2f); target >= %.2f; reduce verbose cues (e.g., %s)", - result.Conciseness, r.MinScore, r.MinScore, examples, - ) + var cuesSuffix string + if examples != "" { + cuesSuffix = "; reduce verbose cues (e.g., " + examples + ")" } + message := fmt.Sprintf( + "conciseness score too low (%.2f < %.2f); target >= %.2f%s", + result.Conciseness, r.MinScore, r.MinScore, cuesSuffix, + ) diags = append(diags, lint.Diagnostic{ File: f.Path, diff --git a/internal/rules/concisenessscoring/rule_test.go b/internal/rules/concisenessscoring/rule_test.go index 8f599ecf0..74e728a07 100644 --- a/internal/rules/concisenessscoring/rule_test.go +++ b/internal/rules/concisenessscoring/rule_test.go @@ -2,7 +2,6 @@ package concisenessscoring import ( "errors" - "strings" "sync" "testing" @@ -314,14 +313,12 @@ func TestCheck_MessageNoConcatenationWhenExamplesPresent(t *testing.T) { t.Skip("model threshold did not trigger on fixture") } msg := diags[0].Message - // The message must contain both the score summary and the cue guidance - // in a single string (not two separately allocated pieces). + // The message must contain both the score summary and the cue guidance. assert.Contains(t, msg, "conciseness score too low") assert.Contains(t, msg, "target >=") - // If verbose cues were detected, the formatted examples must also be present. - if strings.Contains(msg, "reduce verbose cues") { - assert.Contains(t, msg, "e.g.,", "message with cues must include formatted examples") - } + // verboseParagraph always triggers cue detection; both must be present. + assert.Contains(t, msg, "reduce verbose cues") + assert.Contains(t, msg, "e.g.,", "message with cues must include formatted examples") } func TestCheck_NoCuesMessage(t *testing.T) {