feat: online verification, node removals, and knowledge browser
CI / quality (push) Canceled after 0s
CI / quality (push) Canceled after 0s
Adds claim-bound online evidence records and citation verification scripts, node removal transport/adapter, retrieval benchmark and owner-review tooling, GraphCanvas/SourceDetail knowledge browser UI, and the ingest handoff helper. Bumps the agents/gewu pack to the online-verification branch.
This commit is contained in:
1 parent
a3156f4e08
commit
78033bb830
83 files changed
+13476
-1051
No files matched your search
@@ -0,0 +1,111 @@
|
||||
from scripts.review_benchmark_candidates import review
|
||||
|
||||
from gewu.domain.validation import assertion_digest
|
||||
|
||||
|
||||
def _inputs():
|
||||
extractions = {
|
||||
"extract-1": {
|
||||
"extraction_id": "extract-1",
|
||||
"source_revision_id": "source-1",
|
||||
"blocks": [{"block_id": "block-1", "page": 1, "normalized_text": "The sky is blue."}],
|
||||
}
|
||||
}
|
||||
item = {
|
||||
"source_stage": "review",
|
||||
"storage_state": "evaluated; needs-review",
|
||||
"evaluation": {"status": "needs-review", "eligible_for_auto_accept": False},
|
||||
"proposal": {
|
||||
"proposal_id": "proposal-1",
|
||||
"revision": 1,
|
||||
"operations": [
|
||||
{
|
||||
"node": {
|
||||
"claims": [
|
||||
{
|
||||
"claim_id": "claim-1",
|
||||
"text": "The sky is blue.",
|
||||
"evidence": [
|
||||
{
|
||||
"source_revision_id": "source-1",
|
||||
"extraction_id": "extract-1",
|
||||
"assertion_digest": assertion_digest("The sky is blue."),
|
||||
"quote": "The sky is blue.",
|
||||
"locator": {
|
||||
"block_id": "block-1",
|
||||
"start": 0,
|
||||
"end": 16,
|
||||
"page": 1,
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
return [item], extractions
|
||||
|
||||
|
||||
def test_valid_evidence_does_not_clear_protected_owner_review():
|
||||
items, extractions = _inputs()
|
||||
|
||||
result = review(items, extractions, input_sha256="b" * 64)
|
||||
|
||||
assert result["summary"]["evidence_bindings_valid"] == 1
|
||||
assert result["items"][0]["recommendation"] == "defer"
|
||||
assert result["summary"]["owner_decisions_written"] == 0
|
||||
assert result["summary"]["canonical_records_written"] == 0
|
||||
|
||||
|
||||
def test_invalid_quote_recommends_revision_without_mutating_input():
|
||||
items, extractions = _inputs()
|
||||
items[0]["proposal"]["operations"][0]["node"]["claims"][0]["evidence"][0]["quote"] = (
|
||||
"The sky is green."
|
||||
)
|
||||
original = items[0]["proposal"]["operations"][0]["node"]["claims"][0]["evidence"][0]["quote"]
|
||||
|
||||
result = review(items, extractions, input_sha256="c" * 64)
|
||||
|
||||
assert result["items"][0]["recommendation"] == "revise-candidate"
|
||||
assert "QUOTE_SPAN_MISMATCH" in result["items"][0]["claims"][0]["issues"]
|
||||
assert (
|
||||
items[0]["proposal"]["operations"][0]["node"]["claims"][0]["evidence"][0]["quote"]
|
||||
== original
|
||||
)
|
||||
|
||||
|
||||
def test_missing_evidence_is_reported_for_each_claim():
|
||||
items, extractions = _inputs()
|
||||
items[0]["proposal"]["operations"][0]["node"]["claims"][0]["evidence"] = []
|
||||
|
||||
result = review(items, extractions, input_sha256="d" * 64)
|
||||
|
||||
assert result["items"][0]["claims"][0]["issues"] == ["CLAIM_EVIDENCE_REQUIRED"]
|
||||
assert result["items"][0]["recommendation"] == "revise-candidate"
|
||||
|
||||
|
||||
def test_assertion_digest_is_bound_to_the_exact_claim_text():
|
||||
items, extractions = _inputs()
|
||||
evidence = items[0]["proposal"]["operations"][0]["node"]["claims"][0]["evidence"][0]
|
||||
evidence["assertion_digest"] = "0" * 64
|
||||
|
||||
result = review(items, extractions, input_sha256="e" * 64)
|
||||
|
||||
assert "ASSERTION_DIGEST_MISMATCH" in result["items"][0]["claims"][0]["issues"]
|
||||
|
||||
|
||||
def test_supersession_edges_are_copied_to_advisory_ledger():
|
||||
items, extractions = _inputs()
|
||||
edge = {"relation": "corrects", "source": "old-node", "target": "new-node"}
|
||||
items[0]["source_stage"] = "supersession"
|
||||
items[0]["proposal"]["operations"].append({"edge": edge})
|
||||
|
||||
result = review(items, extractions, input_sha256="e" * 64)
|
||||
|
||||
row = result["items"][0]
|
||||
assert row["recommendation"] == "defer"
|
||||
assert row["supersession_edges"] == [edge]
|
||||
assert row["supersession_edges_preserved"] == 1
|
||||
Reference in new issue
Block a user