test(eval): scope danger warnings to answered routes; re-accept metadata debt at 0.6 - #176
Conversation
…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>
There was a problem hiding this comment.
💡 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".
…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>
|
Addressed both review notes in 14b129f: Exempt non-grounded refusals (thread 2): confirmed 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. |
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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".
|
Reviewed the P2 fixes (mirror-refusal + persisted-string detection). One correctness concern on the latest commit ( The string branch treats any non-empty warning string as danger: (typeof warning === "string" && warning.trim().length > 0) ||
(typeof warning === "object" && warning !== null && warning.severity === "danger")But Suggest matching only the canonical danger messages instead of any string. The two per-source danger messages are stable literals in // source-governance.ts
export const OUTDATED_SOURCE_WARNING_MESSAGE = "One or more supporting sources are marked outdated.";
export const POOR_EXTRACTION_WARNING_MESSAGE = "One or more supporting sources have poor extraction quality.";
const dangerMessages = new Set([OUTDATED_SOURCE_WARNING_MESSAGE, POOR_EXTRACTION_WARNING_MESSAGE]);
export const isDangerSourceGovernanceMessage = (m: string) => dangerMessages.has(m.trim());
// rag-eval-cases.ts predicate
return metadataWarnings(row.metadata).some((warning) =>
typeof warning === "object" && warning !== null
? (warning as { severity?: unknown }).severity === "danger"
: typeof warning === "string" && isDangerSourceGovernanceMessage(warning),
);Note I have this precise version implemented and green (tsc + eslint + prettier + a negative test proving a |
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>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Pushed the precise-matching version in 23aa990 (branch had settled). It matches only the canonical danger messages ( |
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
* 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>
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 isnone. On a refusal that is the correct reader signal ("no source-backed evidence — do not act"), not a governance failure. Butsource_governance_danger_failure_ratecounted it, so 9 correctly-declined out-of-scope questions (coffee machine, air fryer, DKA-insulin, …) failed the gate.sourceGovernanceDangerFailuresForAnswerhelper 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_raterose 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.max_review_required_rate: 0.6, expiry unchanged (2026-07-31), with rationale recorded.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_rate0.867 (< 0.9), one prompt-injection false-positive (unsupported-prompt-injection-citation-forgereturned 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.ts8/8 ·typecheckclean ·eslintclean · full liveeval:quality:releaseconfirmed items 1 & 2.🤖 Generated with Claude Code