Skip to content

Fix token_audit.py false-positive detectors - #1

Open
EdbertChan wants to merge 3 commits into
mainfrom
plan/fix-token-audit-py-false-positive-detectors
Open

Fix token_audit.py false-positive detectors#1
EdbertChan wants to merge 3 commits into
mainfrom
plan/fix-token-audit-py-false-positive-detectors

Conversation

@EdbertChan

@EdbertChan EdbertChan commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Summary

token_audit.py now trusts Claude’s structured is_error flag, preventing ordinary output or tool names containing “error” from being reported as failures.

Read and edit paths now normalize both file_path and path, preserving genuine redundant-read detection without conflating missing or different files.

Review Claim

Approve the corrected tool-error and redundant-read classifications while preserving the audit report’s existing output schema.

Review Lane

behavior

Review Unit

validation-policy

Safety Invariant

Only detector classification logic changes. Existing report headings, line formats, and consumer-facing output structure remain unchanged.

Slice Rationale

Both false positives originate in the same audit function and share one focused regression suite, so they form one locally reviewable correction.

Non-goals

  • No changes to other detectors, pricing, or session scanners.
  • No new report sections or output fields.
  • No changes outside token_audit.py and its existing test file.

Test Plan

Test Plan
  • python3 -m unittest discover -s skills/reflect/scripts/tests -v — 29 tests passed, including false and genuine errors plus repeated and distinct alias paths.

Revert Plan

Revert Plan
  • Safe to revert? Yes; reverting restores the previous detector behavior.
  • Revert command: git revert <PR merge commit SHA>
  • Post-revert steps: None
  • Data migration? No

Note

Low Risk
Classification-only changes in reflect audit scripting and tests; no auth, data, or consumer-facing API changes beyond more accurate counts.

Overview
Fixes false positives in Claude session token_audit for tool failures and redundant reads, without changing report headings or line formats.

Tool errors now count only tool_result blocks with is_error strictly True, tracked in a dedicated list instead of synthetic __ERROR__: entries on the tool-call sequence—so benign result text or odd tool names no longer inflate the error count.

Redundant reads resolve file identity via a shared _claude_file_path() that accepts file_path or path, normalizes with os.path.normpath, and skips reads with no path; Edit/Write use the same helper so alias keys still participate in “edited since” logic.

Reviewed by Cursor Bugbot for commit 581c377. Bugbot is set up for automated code reviews on this repo. Configure here.

EdbertChan and others added 3 commits August 15, 2026 08:25
Claude tool errors were converted into synthetic __ERROR__-prefixed tool names and then rediscovered by prefix matching. Track error results directly from boolean is_error fields so ordinary output and tool names cannot collide with the detector.

Normalize both supported file_path and path inputs before redundant-read comparisons. This keeps repeated reads detectable without collapsing different valid files into the same None key.

Add regression coverage for false/absent error flags, genuine errors, repeated alias-path reads, and distinct alias-path reads.
…— Auditing a real session transcript with `token_audit.py` reported "19

tool errors" and "1 redundant read" that were mostly or entirely wrong
on manual inspection. Two separate bugs were traced by an independent
review pass (not yet verified against the actual current source -- read
it first):
1. The tool-error detector matches on a substring (e.g. checking whether
   some string like "error" appears in tool-result content) instead of
   reading the transcript's actual structured `is_error` flag on each
   tool_result block. This flags normal tool output that merely mentions
   the word "error" (e.g. in file content, log lines, or a status
   message) as if the tool call itself failed.
2. The redundant-read detector has a filename-normalization bug: it
   appears to produce `None` or `(None, None)` for some inputs when
   extracting/normalizing the file path from a Read tool call, which
   breaks path-equality comparisons across reads and produces spurious
   "redundant read" matches (or misses real ones -- confirm which,
   empirically, by writing the repro first).
Review claim: both detectors now key off the transcript's actual
structured data (the real `is_error` flag; a correctly normalized file
path) instead of a substring/lossy heuristic, and a real session
transcript that previously mis-flagged both cases no longer does.
Review lane: behavior
Safety invariant: This only changes detection logic inside
`token_audit.py`; it must not change the script's output format/schema
in a way that breaks other tooling that consumes its output (check for
other callers/consumers of this script's output before changing shape).
Slice rationale: Both bugs live in the same script and were found in the
same review pass; if the repo's own conventions call for splitting them
into two separate reviewable changes once you see the actual diff size,
do that instead of forcing one combined change.
Goal: `token_audit.py` no longer flags a normal tool result that merely
contains the word "error" as a tool error, and no longer produces
spurious redundant-read matches (or misses) caused by a broken filename
normalization.
Motivation: A recent real audit run on a genuine session transcript
reported these two findings, and manual inspection showed both were
false positives -- undermining trust in every future run of this
report until fixed.
Implementation details: |
  Read the actual current source of `token_audit.py` first -- treat the
  bug descriptions above as a starting hypothesis from an independent
  review pass, not verified ground truth; confirm the exact mechanism
  by reading the real code and, ideally, reproducing against a real or
  realistic session transcript fixture before changing anything.
  For the tool-error detector: find wherever it currently classifies a
  tool call as failed, and change it to read the transcript's actual
  `is_error` field on the relevant tool_result content block instead of
  any substring/keyword match.
  For the redundant-read detector: find the file-path normalization
  function used to compare Read calls, and fix whatever produces `None`
  or `(None, None)` for valid inputs -- likely a missing case in
  extracting the path argument, or an unsafe attribute/key access that
  silently returns None instead of raising or handling the actual input
  shape.
Non-goals: Does not change any other detector or report section in
`token_audit.py`. Does not add new detectors. Does not touch other
scripts in this repo unless the fix genuinely requires it (e.g. a
shared helper both detectors call into).
Acceptance criteria:
- A new test (or fixture-based repro, matching however this repo
  already tests scripts in this directory -- check for an existing
  pattern first) that constructs a minimal transcript where a tool
  result's content happens to contain the word "error" but its real
  `is_error` field is false/absent, asserting the tool-error detector
  does NOT flag it -- proven failing before the fix, passing after.
- A second test proving the tool-error detector still correctly flags a
  transcript entry whose `is_error` field is genuinely true (no
  regression in real detection).
- A third test proving the redundant-read detector's path normalization
  no longer returns None/(None, None) for the specific input shape that
  broke it, with a case showing two reads of the literal same file are
  still correctly detected as redundant, and two reads of genuinely
  different files are not.
- Test and fix committed together, following this repo's own existing
  commit/PR conventions (read any CONTRIBUTING/CLAUDE.md-equivalent
  docs, or infer from recent commit history, before assuming Invoker's
  specific PR-body schema applies here -- this is a different repo).

Exit code: 0
Invoker-Finalize-Id: a59b419c-ab0a-4ca5-83c8-863a5502efc9
…tectors/g1.t1.a-aa6657970-d0039e5d — Auditing a real session transcript with `token_audit.py` reported "19

tool errors" and "1 redundant read" that were mostly or entirely wrong
on manual inspection. Two separate bugs were traced by an independent
review pass (not yet verified against the actual current source -- read
it first):
1. The tool-error detector matches on a substring (e.g. checking whether
   some string like "error" appears in tool-result content) instead of
   reading the transcript's actual structured `is_error` flag on each
   tool_result block. This flags normal tool output that merely mentions
   the word "error" (e.g. in file content, log lines, or a status
   message) as if the tool call itself failed.
2. The redundant-read detector has a filename-normalization bug: it
   appears to produce `None` or `(None, None)` for some inputs when
   extracting/normalizing the file path from a Read tool call, which
   breaks path-equality comparisons across reads and produces spurious
   "redundant read" matches (or misses real ones -- confirm which,
   empirically, by writing the repro first).
Review claim: both detectors now key off the transcript's actual
structured data (the real `is_error` flag; a correctly normalized file
path) instead of a substring/lossy heuristic, and a real session
transcript that previously mis-flagged both cases no longer does.
Review lane: behavior
Safety invariant: This only changes detection logic inside
`token_audit.py`; it must not change the script's output format/schema
in a way that breaks other tooling that consumes its output (check for
other callers/consumers of this script's output before changing shape).
Slice rationale: Both bugs live in the same script and were found in the
same review pass; if the repo's own conventions call for splitting them
into two separate reviewable changes once you see the actual diff size,
do that instead of forcing one combined change.
Goal: `token_audit.py` no longer flags a normal tool result that merely
contains the word "error" as a tool error, and no longer produces
spurious redundant-read matches (or misses) caused by a broken filename
normalization.
Motivation: A recent real audit run on a genuine session transcript
reported these two findings, and manual inspection showed both were
false positives -- undermining trust in every future run of this
report until fixed.
Implementation details: |
  Read the actual current source of `token_audit.py` first -- treat the
  bug descriptions above as a starting hypothesis from an independent
  review pass, not verified ground truth; confirm the exact mechanism
  by reading the real code and, ideally, reproducing against a real or
  realistic session transcript fixture before changing anything.
  For the tool-error detector: find wherever it currently classifies a
  tool call as failed, and change it to read the transcript's actual
  `is_error` field on the relevant tool_result content block instead of
  any substring/keyword match.
  For the redundant-read detector: find the file-path normalization
  function used to compare Read calls, and fix whatever produces `None`
  or `(None, None)` for valid inputs -- likely a missing case in
  extracting the path argument, or an unsafe attribute/key access that
  silently returns None instead of raising or handling the actual input
  shape.
Non-goals: Does not change any other detector or report section in
`token_audit.py`. Does not add new detectors. Does not touch other
scripts in this repo unless the fix genuinely requires it (e.g. a
shared helper both detectors call into).
Acceptance criteria:
- A new test (or fixture-based repro, matching however this repo
  already tests scripts in this directory -- check for an existing
  pattern first) that constructs a minimal transcript where a tool
  result's content happens to contain the word "error" but its real
  `is_error` field is false/absent, asserting the tool-error detector
  does NOT flag it -- proven failing before the fix, passing after.
- A second test proving the tool-error detector still correctly flags a
  transcript entry whose `is_error` field is genuinely true (no
  regression in real detection).
- A third test proving the redundant-read detector's path normalization
  no longer returns None/(None, None) for the specific input shape that
  broke it, with a case showing two reads of the literal same file are
  still correctly detected as redundant, and two reads of genuinely
  different files are not.
- Test and fix committed together, following this repo's own existing
  commit/PR conventions (read any CONTRIBUTING/CLAUDE.md-equivalent
  docs, or infer from recent commit history, before assuming Invoker's
  specific PR-body schema applies here -- this is a different repo).
@cursor

cursor Bot commented Aug 15, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_78303f2b-e8f7-4090-a863-aad8d33b8c46)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant