Skip to content

test(eval): scope danger warnings to answered routes; re-accept metadata debt at 0.6 - #176

Merged
BigSimmo merged 11 commits into
mainfrom
claude/eval-governance-hygiene
Jul 2, 2026
Merged

test(eval): scope danger warnings to answered routes; re-accept metadata debt at 0.6#176
BigSimmo merged 11 commits into
mainfrom
claude/eval-governance-hygiene

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Two release-quality-eval governance fixes surfaced by the full release-gate re-run. Eval/docs only — no app behavior changes.

1. Danger warnings on declined (unsupported) answers are no longer failures

The app attaches a weak_evidencedanger warning when relevance verdict is none. On a refusal that is the correct reader signal ("no source-backed evidence — do not act"), not a governance failure. But source_governance_danger_failure_rate counted it, so 9 correctly-declined out-of-scope questions (coffee machine, air fryer, DKA-insulin, …) failed the gate.

  • The rate now counts danger warnings only on answered routes (a delivered answer standing on dangerous sourcing).
  • For genuinely out-of-scope cases, the warning's presence is positively asserted, so a regression that silently drops the refusal signal is still caught.
  • For supported questions that were wrongly refused (a separate regression), the routing failure is reported by the existing validators; this change deliberately does not pile on a misleading "missing warning".
  • New sourceGovernanceDangerFailuresForAnswer helper with 8 unit assertions covering answered/declined × expected/unexpected.

Verified on the live release eval:source_governance_danger_failure_rate0.225 → 0; all 9 affected cases confirmed correctly-declined.

2. Re-accept the bounded source-metadata debt at a 0.6 review-required ceiling

Top-result review_required_rate rose 0.14 → 0.5398 with no corpus change: the relevance-first ranking work (PR #118 / PR #130) removed governance metadata weighting from selection ordering, so review-flagged sources are no longer buried and the metric now reports true corpus state.

  • Debt file re-accepted at max_review_required_rate: 0.6, expiry unchanged (2026-07-31), with rationale recorded.
  • New docs/source-review-priority-2026-07-02.md: the 25 documents occupying golden top-5 slots, highest-frequency first (Clozapine GP mgmt 8 slots, Opioid use disorder 6, Bipolar 6, …). Reviewing the top 12 returns the rate to ~0.12, after which the ceiling should tighten back toward 0.2.

Not addressed here (separate, pre-existing)

The eval still reports blocking failures unrelated to these changes: grounded_supported_rate 0.867 (< 0.9), one prompt-injection false-positive (unsupported-prompt-injection-citation-forge returned a grounded answer), a citation failure, and extractive-route p95 latency. These are answer-quality regressions to investigate in the RAG-optimization track — flagged, not fixed.

Checks

vitest tests/eval-quality.test.ts 8/8 · typecheck clean · eslint clean · full live eval:quality:release confirmed items 1 & 2.

🤖 Generated with Claude Code

…pt metadata debt
Two release-quality-eval governance fixes, no app-behavior change.
1. Danger source-governance warnings on unsupported (declined) routes are no
longer counted as failures. The app attaches a weak-evidence danger warning
when relevance verdict is "none", which on a refusal is the correct reader
signal ("no source-backed evidence, do not act"), not a governance failure.
The metric now counts danger warnings only on answered routes (a delivered
answer standing on dangerous sourcing). For genuinely out-of-scope cases the
warning's presence is positively asserted so a silent regression is caught;
for supported questions that were wrongly refused, the routing failure is
reported elsewhere and no misleading missing-warning noise is added.
Verified on the live release eval: source_governance_danger_failure_rate
0.225 -> 0, all 9 affected cases are correctly-declined out-of-scope queries.
2. Re-accept the bounded source-metadata debt at a 0.6 review-required ceiling
(expiry unchanged, 2026-07-31). The rate rose 0.14 -> 0.5398 with no corpus
change: the relevance-first ranking work (PR #118 / PR #130) removed
governance metadata weighting from selection ordering, so review-flagged
sources are no longer buried and the metric now reports true corpus state.
docs/source-review-priority-2026-07-02.md lists the 25 documents occupying
golden top-5 slots, highest-frequency first; reviewing the top 12 returns the
rate to ~0.12, after which the ceiling should be tightened back toward 0.2.
Note: the eval still reports separate blocking failures (grounded_supported,
one prompt-injection false-positive, citation, extractive latency) that are
pre-existing answer-quality regressions unrelated to these two changes and
tracked separately.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:36b7fa53c7

ℹ️ 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 threadscripts/eval-quality.ts Outdated
Comment threadscripts/eval-quality.ts Outdated
…w fixes)
Addresses two automated review notes on the danger-warning reclassification:
- Exempt non-grounded refusals however they arise. finalizeRagAnswerQualityCore
can convert a fast/strong/extractive answer into an evidence-gap refusal by
setting grounded=false while preserving the original routingMode, so a
route-based check could still fail the gate on a declined answer. Key the
danger-warning failure on grounded === true (an answer was actually
delivered) instead of route !== "unsupported".
- Drop the toothless positive "missing danger warning" assertion. It only
surfaced in failed_cases and never fed a thresholded metric, so it could not
gate; making it gate would introduce new blocking failures on the current
corpus (e.g. close-title-noise), which we explicitly must not do. The
grounded-based check is the clean, robust core.
Behavior unchanged on the current corpus: danger rate stays 0 (all danger
warnings are on grounded=false refusals). Unit tests updated to cover the
finalize-core evidence-gap refusal path. vitest 8/8, typecheck + lint clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

Addressed both review notes in 14b129f:

Exempt non-grounded refusals (thread 2): confirmed finalizeRagAnswerQualityCore sets grounded=false while preserving the original routingMode, so a route-based check could fail the gate on a converted evidence-gap refusal. The danger-warning failure (and the summary rate) now key on grounded === true — an answer was actually delivered — which exempts every refusal regardless of route. New unit test covers the fast-route→evidence-gap case.

Missing-warning assertion (thread 1): you're right it was toothless. Rather than promote it to a gated metric — which would introduce new blocking failures on the current corpus (e.g. close-title-noise) and make the gate stricter than intended — I removed it. The grounded-based check is the clean core. Danger rate stays 0 on the current corpus.

@BigSimmo
BigSimmo enabled auto-merge (squash) July 2, 2026 13:17

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:3c34fadb71

ℹ️ 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 threadscripts/eval-quality.ts Outdated
Addresses the Codex P2 on #176. Exempting every ungrounded answer from the
danger-warning failure check could mask a refusal-safety regression: an
unsupported/evidence-gap refusal that silently loses its expected
weak_evidence/outdated/poor-extraction danger warning would keep
source_governance_danger_failure_rate at 0 and pass as clean.
- Add opt-in RagEvalCase.expectsSourceDangerWarning for refusal cases whose
sourcing must surface a danger-severity governance warning.
- sourceGovernanceDangerFailuresForAnswer now emits
"expected danger source governance warning missing" when a flagged case has
zero danger warnings, regardless of grounded (keeps the existing
grounded+danger => failure behavior).
- Add expected_danger_warning_missing_count to the RAG summary and a blocking
threshold check that hard-blocks release. This failure is never waivable via
the source-metadata debt acceptance.
- Unit tests cover the helper's new branch and that the report blocks (and the
debt acceptance cannot waive it).
The field is opt-in and unset on all current cases, so the green build is
unchanged; the enforcement path exists and is tested for when cases opt in.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:95ce58bb5c

ℹ️ 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 threadscripts/eval-quality.ts
Comment threadscripts/eval-quality.ts Outdated
BigSimmoand others added 4 commits July 2, 2026 22:44
docs/source-review-priority-2026-07-02.md predates #180's format:check
enforcement and failed the verify Format check step. No content change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:2b78614ef2

ℹ️ 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 threadsrc/lib/rag-eval-cases.ts Outdated

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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:4447ba8f3f

ℹ️ 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 threadsrc/lib/rag-eval-cases.ts Outdated
Comment threadscripts/eval-quality.ts
@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

Reviewed the P2 fixes (mirror-refusal + persisted-string detection). One correctness concern on the latest commit (4447ba8f3), capturedCaseExpectsSourceDangerWarning in src/lib/rag-eval-cases.ts:

The string branch treats any non-empty warning string as danger:

(typeofwarning==="string"&&warning.trim().length>0)||(typeofwarning==="object"&&warning!==null&&warning.severity==="danger")

But source_governance_warnings persists all severities as messages (ClinicalDashboard maps every warning.message), including non-danger ones — review_due ("…are due for review."), unverified ("…have not been locally validated."), partial_extraction, etc. So an unsupported_answer capture whose only persisted warning is, say, review_due gets expectsSourceDangerWarning: true. On the next eval run that refusal legitimately carries 0 danger warnings → it trips expected danger source governance warning missing and hard-blocks release on a false positive.

Suggest matching only the canonical danger messages instead of any string. The two per-source danger messages are stable literals in source-governance.ts (outdated_source, poor_extraction), so exporting them + an isDangerSourceGovernanceMessage(message) helper and matching against it keeps this precise and DRY:

// source-governance.tsexportconstOUTDATED_SOURCE_WARNING_MESSAGE="One or more supporting sources are marked outdated.";exportconstPOOR_EXTRACTION_WARNING_MESSAGE="One or more supporting sources have poor extraction quality.";constdangerMessages=newSet([OUTDATED_SOURCE_WARNING_MESSAGE,POOR_EXTRACTION_WARNING_MESSAGE]);exportconstisDangerSourceGovernanceMessage=(m: string)=>dangerMessages.has(m.trim());// rag-eval-cases.ts predicatereturnmetadataWarnings(row.metadata).some((warning)=>typeofwarning==="object"&&warning!==null
? (warningas{severity?: unknown}).severity==="danger"
: typeofwarning==="string"&&isDangerSourceGovernanceMessage(warning),);

Note weak_evidence danger can't be recovered from a message string (its text is dynamic relevance.supportReason and its fallback is shared with the non-danger partial-verdict variant), so it should stay uncovered by string-matching rather than be guessed — otherwise partial-evidence cases would false-positive too. A worth-considering follow-up is persisting source_danger_warning_count at capture time (the predicate already honours it), which recovers severity robustly for future captures.

I have this precise version implemented and green (tsc + eslint + prettier + a negative test proving a review_due-only capture does not set the flag) — happy to push it to this branch if you'd like, but held off to avoid clobbering the concurrent commits landing here.

The persisted-string detection added in 4447ba8 treated any non-empty
governance-warning string as danger. /api/eval-cases persists all severities as
message strings (ClinicalDashboard submits warning.message), so an unsupported
capture whose sole warning is non-danger (e.g. review_due or unverified) was
flagged expectsSourceDangerWarning=true and then tripped the "expected danger
source governance warning missing" gate on a false positive, hard-blocking
release.
Match only the canonical per-source danger messages instead:
- Export OUTDATED_SOURCE_WARNING_MESSAGE / POOR_EXTRACTION_WARNING_MESSAGE and
isDangerSourceGovernanceMessage from source-governance.ts, and use the
constants in the producer so the matcher can't drift from what is emitted.
- rag-eval-cases predicate recovers danger severity from a persisted string via
that matcher (objects still use severity directly).
weak_evidence danger is intentionally not string-matchable (dynamic message,
fallback shared with the non-danger partial-verdict variant). Added a negative
test proving a review_due-only capture does not set the flag.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@BigSimmo

Copy link
Copy Markdown
OwnerAuthor

Pushed the precise-matching version in 23aa990 (branch had settled). It matches only the canonical danger messages (OUTDATED_SOURCE_WARNING_MESSAGE / POOR_EXTRACTION_WARNING_MESSAGE, exported from source-governance.ts and reused by the producer so they can't drift), replacing the any-non-empty-string check so a review_due/unverified-only capture no longer false-positives the expected danger … missing gate. Added a negative test covering that case. Green locally: tsc + eslint + prettier + the eval/rag-eval-cases/source-governance suites (30 tests).

@BigSimmo
BigSimmo merged commit 7f60bed into mainJul 2, 2026
4 checks passed
@BigSimmo
BigSimmo deleted the claude/eval-governance-hygiene branch July 2, 2026 16:31
BigSimmo pushed a commit that referenced this pull request Jul 31, 2026
Traced while re-checking Batch B's premise. universal-search-command-surface
voids both commandScopes and its setter, and every other write passes an empty
array, so the scope chips configured for six modes, the three matcher helpers,
and the scope shelf in the results band are all unreachable in production. Not
a wiring-conventions defect — nothing is clickable — but it reads as a feature
and needs a decision before more filtering UI is built on top of it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Akwz3Sdms8uJ5AkDt3CduY
BigSimmo added a commit that referenced this pull request Aug 7, 2026
* fix: close high-win Grok batch (tokens, a11y, perf, gates)
- Drop unused --med-accent-soft (#157)
- Document Chip compact=11px / standard=12px (#220)
- Reveal phone chrome on source change at top (#176)
- Passive wheel listener for modifier-gated PDF zoom (#214)
- Point npm run typecheck at source-only tsconfig (#210)
- Fail outstanding-issues when queue cites non-open IDs (#201)
Also confirms MatchExplanationChips, Favourites empty-state,
DocumentFrame role=alert, and refetching dimming claim are
already resolved on main (#223/#225/#219/#246).
* issues: archive grok-batch wins #157#176#201#210#214#219#220#223#225#246
Prune them from the recommended queue so the new queue-membership gate stays green.
* fix: address PR #1651 review (double-zoom, issues:done, tokens)
- Keep viewer wheel listener non-passive while wheelZoom is on and
preventDefault on Ctrl/⌘+wheel / trackpad pinch so PDF zoom does not
also zoom the browser page (Sentry/Devin).
- Prune recommended-queue ID citations in resolveIssue so issues:done
stays writable under the #201 gate.
- Drop restated Chip pixel values from TOKENS.md; amend #214 archive note.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
* fix: recompute issues-queue Order boundary after deletions
Devin: pruneResolvedIdFromQueue used a pre-splice openStart for
renumbering, so enough solo-queue deletions could rewrite Open items
headers/ids. Recompute the section limit after edits and cover it in
the writer self-test.
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
* docs: record Run PR sweep ledger for PR #1651
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Sign up for freeto 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

@BigSimmo