feat(evaluation): post-generation citation and support audit (ADR-0016 increment 6) - #26
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
audit.enabled: false). The ADR itself explicitly lists the additional cost and latency as a negative consequence.extract_citationssilently filtered out malformed bracketed citations, makingwell_formed=Falseunreachable in the auditor. Citation extraction was split intoextract_citation_candidates, which does not filter candidates and is used by the auditor.Details
evaluation/audit_ports.py: introducesAnswerClaim,DeterministicCitationCheck,SemanticSupportResult,ClaimAudit,AuditResult, theAuditOutcome,SupportVerdict, andTemporalStatusenums, and theSemanticSupportVerifierandAnswerRewriterprotocols. ReusesModelIdentityfromjudge_ports.py(Increment 5).evaluation/citation_audit.py: implements deterministic sentence segmentation using a regex that correctly avoids splitting references such as"Art. 1º", per-citation checks, and the complete audit orchestration.temporal_statusis alwaysUNKNOWNfor now because no reliable temporal corpus is available yet.generation/openai_semantic_verifier.pyandgeneration/openai_answer_rewriter.py. They reuseragas.llms.InstructorLLMonly as a structured-completion wrapper—not the RAGAS metrics—and follow the same caching and rate-limiting pattern used by the project’s other adapters.generation/auditing_answer_generator.py: a decorator that implements the existingAnswerGeneratorport. The calling logic inanswer_harness.pyandrun.pyremains unchanged; only the generator construction inrun.pychanges conditionally.evaluation/audit_metrics.py: adds malformed-citation, nonexistent-citation, out-of-context citation, uncited-claim, and unsupported-claim rates, as well as rewrite rate, rewrite success rate, and abstention rate—all computed deterministically fromAuditResult.run.py: adds a newauditconfiguration section, disabled by default.build_run_recordalways declaresaudit_enabled,audit_provider, andaudit_model.generation/citation_parsing.py, shared by both the generator and the auditor.Out of scope (deferred and documented in the code)
false_abstention_rate, which requires human-labeled data.run.py. It remains configuration-driven and disabled by default.Test plan
uv run pytest— 405 passed, 20 integration tests deselecteduv run mypy src tests— no issues found in 170 source filesuv run python scripts/quality_gate.py— all checks pass: linting, formatting, architecture, MCP, governance, typing, tests, security/Bandit, and dependencies/pip-auditgrepfor_extract_citationsandmetrics/auditacrosssrc/andtests/— no orphaned references