# CorpusFetch Method Slice (Zero-Prose Python Stdlib Reference) # Canonical Residual: https://corpusfetch.com/c/how-must-an-instance-bound-extractive-summarization-when-context-includes-adversarial-framing.md # Remnant Warrant: https://corpusfetch.com/c/how-must-an-instance-bound-extractive-summarization-when-context-includes-adversarial-framing.warrant.json # Markdown SHA-256: f3ddd2d39bd20c7cf3c092249488a148067d01fc2dd24569263c7f00fcf621b1 # Code AST SHA-256: 8db19cbbe809f8216caee16f3ad7697bff33ceed969ff32ba5917374fbcb0c07 # Verified Classes: ExtractionVerdict, ExtractionSummary, ExtractionPolicy, ExtractionManifest, ExtractiveFramingGuard # Defensive Guards: 0 fail-closed invariants (zero external deps) from dataclasses import dataclass from enum import Enum, auto import hashlib import json class ExtractionVerdict(Enum): NO_EXTRACTION = auto() BALANCED_EXTRACTION = auto() SELECTION_BIAS_DETECTED = auto() FRAGMENT_QUOTE_MINED = auto() @dataclass(frozen=True) class ExtractionSummary: summary_id: str is_extractive: bool coverage_pro_ratio: float coverage_con_ratio: float coverage_neutral_ratio: float qualifiers_stripped_count: int source_prominence_aligned_with_extraction: bool @dataclass(frozen=True) class ExtractionPolicy: min_balance_ratio: float max_acceptable_qualifier_strip: int @dataclass(frozen=True) class ExtractionManifest: verdict: ExtractionVerdict directive: str manifest_digest: str class ExtractiveFramingGuard: @staticmethod def _hash(data: str) -> str: return hashlib.sha256(data.encode("utf-8")).hexdigest() @classmethod def evaluate_summary( cls, summary: ExtractionSummary, policy: ExtractionPolicy ) -> ExtractionManifest: # Gate 1: Not extractive if not summary.is_extractive: digest = cls._hash(json.dumps({ "summary": summary.summary_id, "type": "ABSTRACTIVE" }, sort_keys=True)) return ExtractionManifest( verdict=ExtractionVerdict.NO_EXTRACTION, directive=f"PROCEED: Summary {summary.summary_id} is abstractive.", manifest_digest=digest ) # Gate 2: Qualifier stripping if summary.qualifiers_stripped_count > policy.max_acceptable_qualifier_strip: return ExtractionManifest( verdict=ExtractionVerdict.FRAGMENT_QUOTE_MINED, directive=f"FLAG: {summary.qualifiers_stripped_count} qualifiers stripped in {summary.summary_id}.", manifest_digest=cls._hash(f"QUOTE_MINED:{summary.summary_id}") ) # Gate 3: Coverage balance pro = summary.coverage_pro_ratio con = summary.coverage_con_ratio if pro > 0 and con >= 0: balance = min(pro, con) / max(pro, con) if max(pro, con) > 0 else 1.0 if balance < policy.min_balance_ratio: return ExtractionManifest( verdict=ExtractionVerdict.SELECTION_BIAS_DETECTED, directive=f"FLAG: Extraction balance {balance:.2f} < {policy.min_balance_ratio:.2f}.", manifest_digest=cls._hash(f"BIAS:{summary.summary_id}") ) # Gate 4: Prominence alignment if summary.source_prominence_aligned_with_extraction: # The extraction followed source prominence, potential positional bias digest = cls._hash(json.dumps({ "summary": summary.summary_id, "prominence_aligned": True }, sort_keys=True)) return ExtractionManifest( verdict=ExtractionVerdict.BALANCED_EXTRACTION, directive=f"PROCEED_WITH_CAUTION: Summary {summary.summary_id} follows source prominence.", manifest_digest=digest ) # Gate 5: Balanced digest = cls._hash(json.dumps({ "summary": summary.summary_id, "pro": f"{pro:.3f}", "con": f"{con:.3f}", "neutral": f"{summary.coverage_neutral_ratio:.3f}" }, sort_keys=True)) return ExtractionManifest( verdict=ExtractionVerdict.BALANCED_EXTRACTION, directive=f"PROCEED: Summary {summary.summary_id} balanced.", manifest_digest=digest )