feat(corroboration): approval_action decision fn + kill-switch (INV-COR2/COR4, X11 Phase 2)

- HALACHA_CORROBORATION_AUTO_APPROVE config (default ON, Dafna validated 2026-06-01)
- approval_action(agg, has_overruled): overruled→demote, corroborated→approve, else None
- 4 offline unit tests; Phase 2 plan + TaskMaster #75

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-01 04:34:23 +00:00
parent 391b025e8a
commit df007784c9
5 changed files with 385 additions and 3 deletions

View File

@@ -44,3 +44,24 @@ def test_aggregate_negative_blocks():
def test_aggregate_below_threshold():
agg = cor.aggregate([_link("d1","followed")], min_cites=2)
assert agg["corroborated"] is False # single source insufficient (INV-COR4)
# --- Phase 2: approval decision (INV-COR2/COR4) ---
def test_approval_action_corroborated_approves():
agg = {"positive_sources": 2, "has_negative": False, "corroborated": True}
assert cor.approval_action(agg, has_overruled=False) == "approve"
def test_approval_action_overruled_demotes_even_if_corroborated():
# overruled outranks any positive count (INV-COR2 strong form)
agg = {"positive_sources": 3, "has_negative": True, "corroborated": False}
assert cor.approval_action(agg, has_overruled=True) == "demote"
def test_approval_action_single_source_noop():
agg = {"positive_sources": 1, "has_negative": False, "corroborated": False}
assert cor.approval_action(agg, has_overruled=False) is None
def test_approval_action_negative_nonoverruled_noop():
# distinguished blocks approval but does not demote (no overruled)
agg = {"positive_sources": 2, "has_negative": True, "corroborated": False}
assert cor.approval_action(agg, has_overruled=False) is None