fix: TODO batch — grader honesty, cost reporting, curated changelog#11
Conversation
…behavior-based negative control - LLMGrader: grading errors and missing per-assertion results are now skipped (not failed) and warned about on stderr, so grader failures never masquerade as agent failures. - Workspace resolution for file-based checks is shared between the deterministic and LLM graders and warns (once per run dir) when it falls back to guessing from the output directory layout. - fix-failing-tests negative-control: reword the grader-run-dependent 'output contains the source code' assertion to the behavior that matters (file read and displayed/described). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rated changelog - benchmark.json: per-config cost_usd mean/stddev and per-agent cost deltas; report gains a Cost (USD) column (table and markdown). - validate: classify_assertion() reports which assertions match no deterministic pattern and will be graded by the LLM rubric, instead of that happening silently at run time. - CHANGELOG.md: restore curated pre-0.4 entries (PSR-style headings); semantic-release now runs in insertion-only update mode with vendored templates that render commit summary lines only — no more commit bodies or Co-Authored-By trailers leaking into the changelog. - Version is single-sourced from pyproject.toml (PSR version_variables removed; __init__ falls back to 0.0.0 when not installed). - TODO.md: tick everything done in this batch and items verified already done on main. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces several improvements to the evaluation framework, including adding a 'Cost (USD)' column to benchmark reports, documenting and validating assertion patterns, and gracefully skipping (rather than failing) assertions when the LLM grader fails or drops them. It also refactors versioning to single-source from pyproject.toml and configures python-semantic-release with custom templates to prevent git trailers from leaking into the changelog. Feedback on the changes suggests normalizing assertion texts (e.g., lowercasing and stripping trailing periods) before matching them against the LLM grader's response to make the matching process more robust against minor formatting variations.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| returned_texts.add(r["text"]) | ||
| for a in assertions: | ||
| if a not in returned_texts: | ||
| results.append( | ||
| AssertionResult( | ||
| text=a, | ||
| passed=False, | ||
| evidence="LLM grader did not return a result for this assertion", | ||
| method="llm", | ||
| ) | ||
| missing = [a for a in assertions if a not in returned_texts] |
There was a problem hiding this comment.
The LLM grader matching is currently doing an exact string match (a not in returned_texts). LLMs frequently make minor formatting changes to the assertion texts in their JSON responses, such as changing casing, adding/removing trailing periods, or normalizing whitespace. This can cause assertions to be falsely classified as missing and skipped.
We should normalize both the returned texts and the assertions (e.g., lowercasing, stripping whitespace, and removing trailing periods) before performing the membership check to make the matching much more robust.
| returned_texts.add(r["text"]) | |
| for a in assertions: | |
| if a not in returned_texts: | |
| results.append( | |
| AssertionResult( | |
| text=a, | |
| passed=False, | |
| evidence="LLM grader did not return a result for this assertion", | |
| method="llm", | |
| ) | |
| missing = [a for a in assertions if a not in returned_texts] | |
| returned_texts.add(r["text"].lower().strip().rstrip('.')) | |
| missing = [a for a in assertions if a.lower().strip().rstrip('.') not in returned_texts] |
There was a problem hiding this comment.
Done in 1e52852: normalization helper (lowercase, collapse whitespace, strip trailing period) applied to both sides of the membership check.
LLMs echo assertions with minor drift (casing, trailing periods, whitespace); exact-match made those falsely count as missing results. Addresses Gemini review on PR #11. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
Works through the actionable items in TODO.md (skipping the subagent-evals generalization, which is deliberately deferred):
Grader honesty (fix)
LLMGrader.grade: grading errors and missing per-assertion results are now skipped with a stderr warning instead of counted as failures, so grader problems never masquerade as agent failures.fix-failing-testsnegative-control: the grader-run-dependent "output contains the source code" assertion is reworded to the behavior that matters (file read and displayed/described; not modified and no tests run are separate assertions).Cost + validate (feat)
benchmark.jsongains per-configcost_usdmean/stddev and per-agent cost deltas;reportshows a Cost (USD) column in both table and markdown formats. Old benchmark/timing files without the field still load.validatenow classifies every assertion (classify_assertion, the same routing the deterministic grader uses) and lists the ones that will fall through to the LLM rubric, instead of that happening silently at run time.Changelog / release hygiene
v0.4.0~1), converted to PSR-style## vX.Y.Z (date)headings so PSR's update-mode dedup check recognizes them.mode = "update"with an insertion flag; default PSR templates render summary lines only (no commit bodies / Co-Authored-By trailers). Verified end-to-end in a throwaway clone (new release inserted at the flag, summary lines only, curated history untouched, no duplicate sections).pyproject.toml(PSRversion_variablesremoved;__init__.pyfalls back to0.0.0when not installed).--show-evidence,--version, init scaffold, assertion-pattern docs).Testing
pytest: 232 passed (includes the free-tier e2e pipeline test)ruff check+ruff format --check: cleanfeat:commit🤖 Generated with Claude Code