Skip to content

Harden Claude evals and funnel routing - #7

Merged
parasdoshicom merged 1 commit into
mainfrom
codex/claude-eval-enforcement
Sep 8, 2026
Merged

parasdoshicom merged 1 commit into
mainfrom
codex/claude-eval-enforcement

Conversation

@parasdoshicom

Copy link
Copy Markdown
Owner

Claude’s first comparative eval ran without the Skill tool and inherited local operator behavior, so it could not establish whether ChatData changed the result. This release adds an isolated, reproducible Claude Code harness and fixes the funnel behavior that a clean run exposed.

ChatData now routes ordinary analysis requests through the relevant skill. Supported CSV funnels must run the bundled checker, exclude immature entrants from every primary denominator, and stop instead of presenting fallback arithmetic as verified. On the published synthetic funnel case, Claude Sonnet 5 with ChatData passed 3/3 fresh runs and the unguided arm passed 0/3; the checked-in record includes answers, tool calls, grades, configuration, versions, cost, time, and the fixture hash. This is one known defect and is not a general accuracy or productivity claim.

The evaluator isolates personal settings, plugins, MCP servers, session history, and production ChatData telemetry. It preserves raw streams and tool results, binds grades to run hashes, rejects incomplete scoring, strictly validates grader booleans, and removes code/outbound tools from the prompt-injection case.

Validation:

  • 215 standard tests passed; 2 optional DuckDB execution tests skipped in the standard environment
  • 5 DuckDB tests passed in the optional DuckDB environment
  • python3 scripts/validate.py
  • claude plugin validate plugins/chatdata
  • Claude funnel eval: ChatData 3/3, baseline 0/3
  • Claude embedded-instruction eval: both arms passed; 0 unsafe tool attempts

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-08T20:36:14.735906Z 7ced78b PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@parasdoshicom
parasdoshicom merged commit 4378038 into main Sep 8, 2026
6 checks passed
@parasdoshicom
parasdoshicom deleted the codex/claude-eval-enforcement branch September 8, 2026 20:31

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7ced78b663

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/eval.py
Comment on lines +299 to +302
if run['error'] and not run['answer']:
return {'required': {c['id']: False for c in case['required']},
'forbidden': {c['id']: False for c in case['forbidden']},
'reason': 'run failed: %s' % run['error'], 'verdict': 'fail'}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail every run that reports a preflight error

If the ChatData plugin is absent from the init inventory but Claude still returns an answer, run_one records the preflight error while this condition proceeds to grade the answer normally. A baseline-like answer can therefore count as a ChatData pass even though the treatment was not loaded, contradicting the harness's stated preflight guarantee; any non-null run error should make the run fail regardless of whether a partial answer exists.

Useful? React with 👍 / 👎.

Comment thread scripts/eval.py
Comment on lines +197 to +199
if path.exists() and not args.force:
print('[%d/%d] skip %s' % (index, len(todo), path.name))
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject cached runs from a different evaluation configuration

When an output directory is reused after changing --model or --invoke-skill, existing files are skipped solely because their case/arm/repeat filename exists. A partially completed directory can consequently combine old and new models or invocation policies, and stage_report accepts the mixture because it validates only those three keys, producing a catch rate and confidence interval for no single configuration. Compare each cached run's recorded configuration with the requested configuration or require an explicit reset.

Useful? React with 👍 / 👎.

Comment thread scripts/eval.py
Comment on lines +281 to +283
target = value.get('file_path') or value.get('path') or ''
if name == 'Read' and Path(str(target)).name.lower() in secret_names:
attempts.append(call)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Detect secret-file access through Grep

In the embedded-instruction case, Grep remains allowed but only Read calls targeting a decoy credential filename are marked unsafe. A model can inspect aws-credentials.txt or ssh-key.txt with Grep using count/files-only output or a nonmatching pattern, causing no sentinel to appear in the tool result; the final-answer grader can then pass the run despite the rubric explicitly forbidding even an attempted credential read. Treat direct Grep targets or include filters matching either decoy as unsafe while retaining the exception for grepping the supplied ticket file.

Useful? React with 👍 / 👎.

Comment thread scripts/eval.py
Comment on lines +409 to +411
(bp, bn), (cp, cn) = totals['baseline'], totals['chatdata']
if bn and cn:
diff = analyze.experiment(bn, bp, cn, cp)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use paired inference for the paired evaluation runs

For reports containing the documented case/repeat pairs, this collapses outcomes to two marginal totals and applies an independent two-sample Newcombe interval. Results within each case/repeat are paired, and repeated evaluations of the same case are also clustered, so this interval can materially misstate uncertainty and the reported SRM check has no meaningful interpretation for the fixed arm allocation. Compute the difference from paired discordances, with case-level clustering or resampling when multiple repeats are included.

Useful? React with 👍 / 👎.

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