From c29c5b3632323fce734b6a210e71d82152dabd86 Mon Sep 17 00:00:00 2001 From: Tanisha Aberdeen <32620895+aliasunder@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:32:33 -0400 Subject: [PATCH 1/6] fix(review): filter self-negating findings the model labels not actionable The non-finding filter missed a class where the model self-labels a finding as "not actionable" or "not a defect" but the selection pipeline posts it anyway (observed on dev-site #63). Add SELF_NEGATING_TITLE regex matching "not actionable", "not a defect", "not a real issue/bug/problem" anywhere in the title, and extend CONFIRMATION_SCENARIO_SUFFIX with "not a defect" end-anchor. 553 tests (11 new). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../__tests__/filter-non-findings.test.ts | 86 +++++++++++++++++++ src/review/filter-non-findings.ts | 7 +- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/review/__tests__/filter-non-findings.test.ts b/src/review/__tests__/filter-non-findings.test.ts index 53fa293..0861898 100644 --- a/src/review/__tests__/filter-non-findings.test.ts +++ b/src/review/__tests__/filter-non-findings.test.ts @@ -463,4 +463,90 @@ describe("filterNonFindings", () => { expect(result).toEqual({ findings: [finding], droppedAsNonFinding: 0 }) }) + + // --- Self-negating titles (observed on dev-site #63) --- + + it("drops a finding whose title contains 'not actionable' (observed on dev-site #63)", () => { + const finding = makeFinding({ + title: "Edge-case navigation race — not actionable", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) + + it("drops a finding whose title contains 'not a defect'", () => { + const finding = makeFinding({ + title: "Deferred script ordering — not a defect", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) + + it("drops a finding whose title contains 'not a real issue'", () => { + const finding = makeFinding({ + title: "Theoretical type coercion — not a real issue", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) + + it("drops a finding whose title contains 'not a real bug'", () => { + const finding = makeFinding({ + title: "Config ordering sensitivity — not a real bug", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) + + it("drops a finding whose failure_scenario ends with 'Not a defect.'", () => { + const finding = makeFinding({ + failure_scenario: + "Both scripts attach before any user navigation, so pageviews are covered. Not a defect.", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) + + // --- Self-negating: passthrough cases --- + + it("keeps a finding whose title contains 'actionable' without 'not'", () => { + const finding = makeFinding({ + title: "Actionable race condition in the retry loop", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [finding], droppedAsNonFinding: 0 }) + }) + + it("keeps a finding whose failure_scenario mentions 'defect' mid-sentence", () => { + const finding = makeFinding({ + failure_scenario: + "The defect causes silent data loss when the buffer overflows.", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [finding], droppedAsNonFinding: 0 }) + }) + + it("keeps a finding whose title contains 'not a' in a non-negating context", () => { + const finding = makeFinding({ + title: "Return type is not a promise but callers await it", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [finding], droppedAsNonFinding: 0 }) + }) }) diff --git a/src/review/filter-non-findings.ts b/src/review/filter-non-findings.ts index b3c8122..4aa028e 100644 --- a/src/review/filter-non-findings.ts +++ b/src/review/filter-non-findings.ts @@ -19,6 +19,10 @@ const CONFIRMATION_PREFIX = /** Declarative confirmation titles — "…is correct" / "…is accurate" — end-anchored. */ const CONFIRMATION_TITLE_SUFFIX = /\bis\s+(?:correct|accurate)\s*\.?\s*$/i +/** Self-negating title — the model reports then retracts in the same title. */ +const SELF_NEGATING_TITLE = + /\bnot (?:actionable|a defect|a (?:real )?(?:issue|bug|problem))\b/i + /** Prior-finding resolution confirmations — "Prior bot finding addressed: …" * — start-anchored with a required resolution verb, so real findings about * prior-comment handling ("Prior bot comments cap drops newest…") survive. */ @@ -29,7 +33,7 @@ const CONFIRMATION_TITLE_PREFIX = * ("…No bug here.", "…my analysis was wrong.") — self-referential verdicts * that never legitimately end a failure description. */ const CONFIRMATION_SCENARIO_SUFFIX = - /(?:\bno bug(?: here)?|\banalysis was wrong)\s*\.?\s*$/i + /(?:\bno bug(?: here)?|\bnot a defect|\banalysis was wrong)\s*\.?\s*$/i /** Start-of-field signal shared by title, failure_scenario, and suggestion: * an explicit non-finding prefix or a separator-anchored confirmation phrase. */ @@ -46,6 +50,7 @@ const isNonFinding = (finding: Finding): boolean => { if (hasNonFindingSignal(title)) return true if (CONFIRMATION_TITLE_SUFFIX.test(title)) return true if (CONFIRMATION_TITLE_PREFIX.test(title)) return true + if (SELF_NEGATING_TITLE.test(title)) return true if (hasNonFindingSignal(failureScenario)) return true if (CONFIRMATION_SCENARIO_SUFFIX.test(failureScenario)) return true if (finding.suggestion && hasNonFindingSignal(finding.suggestion.trim())) { From c347f3ac60749123ff4c747d4e6401baf5e5a024 Mon Sep 17 00:00:00 2001 From: Tanisha Aberdeen <32620895+aliasunder@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:38:54 -0400 Subject: [PATCH 2/6] fix(review): handle grammatical 'an' before vowel in self-negating title regex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SELF_NEGATING_TITLE required article 'a' before 'issue', missing the grammatically correct 'not an issue' — a more natural model output than 'not a issue'. Changed `a` to `an?` so both forms are caught. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/review/__tests__/filter-non-findings.test.ts | 10 ++++++++++ src/review/filter-non-findings.ts | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/review/__tests__/filter-non-findings.test.ts b/src/review/__tests__/filter-non-findings.test.ts index 0861898..b85aa8b 100644 --- a/src/review/__tests__/filter-non-findings.test.ts +++ b/src/review/__tests__/filter-non-findings.test.ts @@ -506,6 +506,16 @@ describe("filterNonFindings", () => { expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) }) + it("drops a finding whose title contains 'not an issue' (grammatical 'an' before vowel)", () => { + const finding = makeFinding({ + title: "Config ordering sensitivity — not an issue", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) + it("drops a finding whose failure_scenario ends with 'Not a defect.'", () => { const finding = makeFinding({ failure_scenario: diff --git a/src/review/filter-non-findings.ts b/src/review/filter-non-findings.ts index 4aa028e..8d17ccb 100644 --- a/src/review/filter-non-findings.ts +++ b/src/review/filter-non-findings.ts @@ -21,7 +21,7 @@ const CONFIRMATION_TITLE_SUFFIX = /\bis\s+(?:correct|accurate)\s*\.?\s*$/i /** Self-negating title — the model reports then retracts in the same title. */ const SELF_NEGATING_TITLE = - /\bnot (?:actionable|a defect|a (?:real )?(?:issue|bug|problem))\b/i + /\bnot (?:actionable|a defect|an? (?:real )?(?:issue|bug|problem))\b/i /** Prior-finding resolution confirmations — "Prior bot finding addressed: …" * — start-anchored with a required resolution verb, so real findings about From 3bd933e6371f31788e4c6b6d41138fa429072852 Mon Sep 17 00:00:00 2001 From: Tanisha Aberdeen <32620895+aliasunder@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:43:02 -0400 Subject: [PATCH 3/6] style: drop stale anchoring claim from isNonFinding doc comment The comment said "start- and end-anchored patterns" but the new SELF_NEGATING_TITLE regex uses word boundaries, not position anchors. The individual regex constants already document their anchoring. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/review/filter-non-findings.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/review/filter-non-findings.ts b/src/review/filter-non-findings.ts index 8d17ccb..3ccc31b 100644 --- a/src/review/filter-non-findings.ts +++ b/src/review/filter-non-findings.ts @@ -41,9 +41,8 @@ const hasNonFindingSignal = (text: string): boolean => { return NON_FINDING_PREFIX.test(text) || CONFIRMATION_PREFIX.test(text) } -/** Checks title, failure_scenario, and suggestion against start- and - * end-anchored patterns that signal the model reported a non-finding - * rather than a real defect. */ +/** Checks title, failure_scenario, and suggestion for patterns that + * signal the model reported a non-finding rather than a real defect. */ const isNonFinding = (finding: Finding): boolean => { const title = finding.title.trim() const failureScenario = finding.failure_scenario.trim() From 3ed4552b5825371cf0d6e3203d44c16ea2b87b6a Mon Sep 17 00:00:00 2001 From: Tanisha Aberdeen <32620895+aliasunder@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:49:15 -0400 Subject: [PATCH 4/6] test(review): cover 'problem' alternative in SELF_NEGATING_TITLE regex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The regex alternation `(?:issue|bug|problem)` had tests for 'issue' and 'bug' but none for 'problem' — removing it from the alternation would have gone undetected. Adds a drop test for "not a problem" in a title. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/review/__tests__/filter-non-findings.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/review/__tests__/filter-non-findings.test.ts b/src/review/__tests__/filter-non-findings.test.ts index b85aa8b..a0eeb8a 100644 --- a/src/review/__tests__/filter-non-findings.test.ts +++ b/src/review/__tests__/filter-non-findings.test.ts @@ -516,6 +516,16 @@ describe("filterNonFindings", () => { expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) }) + it("drops a finding whose title contains 'not a problem'", () => { + const finding = makeFinding({ + title: "Unhandled rejection in cleanup — not a problem", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) + it("drops a finding whose failure_scenario ends with 'Not a defect.'", () => { const finding = makeFinding({ failure_scenario: From 4ef37bb89de42b905819d5e4a227380593ba5cd2 Mon Sep 17 00:00:00 2001 From: Tanisha Aberdeen <32620895+aliasunder@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:57:47 -0400 Subject: [PATCH 5/6] fix(review): anchor self-negating patterns and extend scenario suffix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address bot review findings: - SELF_NEGATING_TITLE now requires a separator or end-of-title after the phrase, so qualified retractions survive ("not a bug on X but Y") - CONFIRMATION_SCENARIO_SUFFIX extended with the full self-negating set (not actionable, not a(n) (real) issue/bug/problem) — not just "not a defect" - README Non-finding filter section updated with the new patterns - Test name cleaned of external PR reference 558 tests (3 new passthrough + scenario suffix tests). Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 3 +- .../__tests__/filter-non-findings.test.ts | 41 +++++++++++++++++-- src/review/filter-non-findings.ts | 7 ++-- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 833f332..7284adf 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,8 @@ Models sometimes report "findings" that conclude the code is fine — titled `N/ - its **title**, **failure_scenario**, or **suggestion** starts with a non-finding signal — `N/A`, `not applicable`, `placeholder`, or a separator-delimited confirmation phrase (`none — …`, `not a finding — …`, `no failure — …`, `no concrete failure scenario — …`, `no bug — …`, `no (further) action needed — …`, `no change needed — …`) - its **title** ends with a declarative confirmation — `…is correct` or `…is accurate` — or starts with a prior-finding resolution confirmation — `Prior (bot) finding(s) addressed/resolved/fixed …` -- its **failure_scenario** ends with a leaked conclusion — `…no bug` / `…no bug here` or `…analysis was wrong` +- its **title** contains a self-negating phrase followed by a separator or end-of-title — `…not actionable`, `…not a defect`, `…not a(n) (real) issue/bug/problem` +- its **failure_scenario** ends with a leaked conclusion — `…no bug` / `…no bug here`, `…not actionable` / `…not a defect` / `…not a(n) (real) issue/bug/problem`, or `…analysis was wrong` The patterns are deliberately anchored to the start or end of a field, so real findings survive: a scenario like "No failure occurs until the third retry…" or "None of the guards catch this input" never matches. Dropped counts are logged per run (`non-finding filter applied to model output`). diff --git a/src/review/__tests__/filter-non-findings.test.ts b/src/review/__tests__/filter-non-findings.test.ts index a0eeb8a..f75e270 100644 --- a/src/review/__tests__/filter-non-findings.test.ts +++ b/src/review/__tests__/filter-non-findings.test.ts @@ -464,9 +464,9 @@ describe("filterNonFindings", () => { expect(result).toEqual({ findings: [finding], droppedAsNonFinding: 0 }) }) - // --- Self-negating titles (observed on dev-site #63) --- + // --- Self-negating titles --- - it("drops a finding whose title contains 'not actionable' (observed on dev-site #63)", () => { + it("drops a finding whose title ends with 'not actionable'", () => { const finding = makeFinding({ title: "Edge-case navigation race — not actionable", }) @@ -560,7 +560,18 @@ describe("filterNonFindings", () => { expect(result).toEqual({ findings: [finding], droppedAsNonFinding: 0 }) }) - it("keeps a finding whose title contains 'not a' in a non-negating context", () => { + it("keeps a finding whose title qualifies the negation with a continuation", () => { + const finding = makeFinding({ + title: + "Record leak is not a bug on single-threaded builds but races under concurrency", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [finding], droppedAsNonFinding: 0 }) + }) + + it("keeps a finding whose title contains 'not a' outside the alternation set", () => { const finding = makeFinding({ title: "Return type is not a promise but callers await it", }) @@ -569,4 +580,28 @@ describe("filterNonFindings", () => { expect(result).toEqual({ findings: [finding], droppedAsNonFinding: 0 }) }) + + // --- Self-negating scenario suffixes --- + + it("drops a finding whose failure_scenario ends with 'Not actionable.'", () => { + const finding = makeFinding({ + failure_scenario: + "The boundary exists to cover this path. Not actionable.", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) + + it("drops a finding whose failure_scenario ends with 'Not a real issue.'", () => { + const finding = makeFinding({ + failure_scenario: + "After re-tracing, the check handles this correctly. Not a real issue.", + }) + + const result = filterNonFindings([finding]) + + expect(result).toEqual({ findings: [], droppedAsNonFinding: 1 }) + }) }) diff --git a/src/review/filter-non-findings.ts b/src/review/filter-non-findings.ts index 3ccc31b..3ad0ca4 100644 --- a/src/review/filter-non-findings.ts +++ b/src/review/filter-non-findings.ts @@ -19,9 +19,10 @@ const CONFIRMATION_PREFIX = /** Declarative confirmation titles — "…is correct" / "…is accurate" — end-anchored. */ const CONFIRMATION_TITLE_SUFFIX = /\bis\s+(?:correct|accurate)\s*\.?\s*$/i -/** Self-negating title — the model reports then retracts in the same title. */ +/** Self-negating title — requires a separator or end-of-title after the + * phrase so qualified retractions survive ("not a bug on X but Y…"). */ const SELF_NEGATING_TITLE = - /\bnot (?:actionable|a defect|an? (?:real )?(?:issue|bug|problem))\b/i + /\bnot (?:actionable|a defect|an? (?:real )?(?:issue|bug|problem))\s*(?:[—–:.-]|$)/i /** Prior-finding resolution confirmations — "Prior bot finding addressed: …" * — start-anchored with a required resolution verb, so real findings about @@ -33,7 +34,7 @@ const CONFIRMATION_TITLE_PREFIX = * ("…No bug here.", "…my analysis was wrong.") — self-referential verdicts * that never legitimately end a failure description. */ const CONFIRMATION_SCENARIO_SUFFIX = - /(?:\bno bug(?: here)?|\bnot a defect|\banalysis was wrong)\s*\.?\s*$/i + /(?:\bno bug(?: here)?|\bnot (?:actionable|a defect|an? (?:real )?(?:issue|bug|problem))|\banalysis was wrong)\s*\.?\s*$/i /** Start-of-field signal shared by title, failure_scenario, and suggestion: * an explicit non-finding prefix or a separator-anchored confirmation phrase. */ From 43ad1f6cab7da6891cc4b0ea473a95c485b586d0 Mon Sep 17 00:00:00 2001 From: Tanisha Aberdeen <32620895+aliasunder@users.noreply.github.com> Date: Fri, 4 Sep 2026 15:06:53 -0400 Subject: [PATCH 6/6] fix(docs): update anchoring claim to reflect separator-delimited patterns The summary sentence claimed all patterns are "anchored to the start or end of a field" but SELF_NEGATING_TITLE is separator-delimited mid-field. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7284adf..e3ebf34 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Models sometimes report "findings" that conclude the code is fine — titled `N/ - its **title** contains a self-negating phrase followed by a separator or end-of-title — `…not actionable`, `…not a defect`, `…not a(n) (real) issue/bug/problem` - its **failure_scenario** ends with a leaked conclusion — `…no bug` / `…no bug here`, `…not actionable` / `…not a defect` / `…not a(n) (real) issue/bug/problem`, or `…analysis was wrong` -The patterns are deliberately anchored to the start or end of a field, so real findings survive: a scenario like "No failure occurs until the third retry…" or "None of the guards catch this input" never matches. Dropped counts are logged per run (`non-finding filter applied to model output`). +The patterns are deliberately anchored (start-of-field, end-of-field, or separator-delimited) so real findings survive: a scenario like "No failure occurs until the third retry…" or "None of the guards catch this input" never matches. Dropped counts are logged per run (`non-finding filter applied to model output`). ## Unknown-file filter