What is the proposed change?
Create hypothesis_engine/tools/signal_a_validator.js exporting validateSignalA(url) → {valid: bool, downgrade_to: 'D'|null, reason: str}. Allow list (valid Signal A): any host ending in .gov, .gov.uk, .gov.us; courts.* and judiciary.* TLDs; contractsfinder.service.gov.uk, find-tender.service.gov.uk, ted.europa.eu, sam.gov; doi.org, pubmed.ncbi.nlm.nih.gov, arxiv.org with /abs/ path; ons.gov.uk, eurostat.ec.europa.eu, oecd.org/data; bankofengland.co.uk/statistics. Deny list (downgrade to D): bbc.com, reuters.com, ft.com, wsj.com, nytimes.com, theguardian.com, techcrunch.com, *.substack.com, medium.com, twitter.com, x.com, linkedin.com posts, any *.blog.* path, any vendor marketing domain matching */(product|features|pricing|case-studies)/. Default for unmatched: downgrade_to='D' with reason 'unrecognized_primary_source'. Wire into evidence_search.js wherever a candidate signal_a_url is about to be persisted: if validateSignalA(url).valid === false, set signal_d_url instead and log {original_intent: 'A', downgraded_reason: result.reason}.
Expected effect
Recorded signal_a_url fields across the existing hypothesis corpus will fail the validator at a non-zero rate (>5%). New runs will see fewer Signal A claims and a proportional increase in Signal D — graduation will become slightly harder for hypotheses that previously relied on news-article Signal A.
Falsifier — what would prove this wrong?
Run the validator over all existing rows where signal_a_url is non-null. If the fail rate is <5%, S107 Fix 4 was already enforced by prompt alone and the validator is redundant — delete it. If the fail rate is >70%, the allow list is too narrow — broaden before merging. Acceptable range: 10-50% fail.
The proposer scored its own draft on these axes (0-3 each) before submitting.
Disposition
Rejected by filter_score. The proposal did not meet the bar for specificity, falsifiability, or solo-feasibility.