Skip to content

Check_four_filter

FieldValue
TypeSkill Resource
Source~/.copilot/skills/legal/scripts/check_four_filter.py
DescriptionNot specified

Source Content

#!/usr/bin/env python3
"""Check a drafted legal document for the Four-Filter house rule: any
superlative or absolute-motive language ("willful", "egregious", "always",
"never", ...) must sit next to a supporting fact — an exhibit reference, a
dated fact, a [CITATION NEEDED]/[SOURCE] tag, or another specific factual
detail in the same sentence or paragraph. Unsupported superlatives are the
classic Defamation/Perjury filter failure: a claim about the other side's
state of mind or an absolute pattern that the drafter cannot actually prove.
This does not replace human judgment on the full Four-Filter check (Factual,
Defamation, Perjury, Admission) — it enforces the mechanically checkable
slice: superlative/absolute language paired with a supporting fact.
Usage: check_four_filter.py <document.md> [<document2.md> ...]
Exit 0 = every flagged term has a nearby supporting fact.
Exit 1 = at least one occurrence has no nearby supporting fact.
Exit 2 = usage/file error.
"""
import re
import sys
# Superlative / absolute-motive words that make a factual or state-of-mind
# claim stronger than plain narration. This list is necessarily incomplete —
# extend it as new patterns show up in review. Matched case-insensitively,
# word-boundary bounded so "reckless" doesn't also match "recklessness"-only
# false positives (it will match both, which is fine — both need support).
SUPERLATIVES = [
"willful", "willfully", "wilful", "egregious", "egregiously",
"always", "never", "flagrant", "flagrantly", "malicious", "maliciously",
"intentionally", "deliberately", "deliberate", "outrageous", "outrageously",
"reckless", "recklessly", "fraudulent", "fraudulently", "blatant", "blatantly",
"systematic", "systematically", "relentless", "relentlessly",
"callous", "callously", "unconscionable", "vindictive", "vindictively",
"premeditated", "knowingly", "in bad faith", "bad-faith",
]
# Signals that count as "a supporting fact nearby": exhibit refs, dated facts,
# explicit sourcing tags, invoice/case/paragraph numbers, or dollar amounts.
SUPPORT_PATTERNS = [
r"\[CITATION NEEDED\]",
r"\[SOURCE[^\]]*\]",
r"\[VERIFY[^\]]*\]",
r"\[FILL IN[^\]]*\]",
r"\bExhibit\s+[A-Z0-9]+\b",
r"\bEx\.\s?[A-Z0-9]+\b",
r"\b\d{4}-\d{2}-\d{2}\b", # ISO date
r"\b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|"
r"Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|"
r"Dec(?:ember)?)\.?\s+\d{1,2},?\s+\d{4}\b", # "March 15, 2026"
r"\$[\d,]+(?:\.\d{2})?", # dollar amount
r"\bparagraph\s+\d+\b",
r"\bsee\s+(?:supra|infra)\b",
r"\b(?:invoice|email|letter|receipt|contract|order)\s+(?:dated|no\.|#)\s*\S+",
]
SUPPORT_RE = re.compile("|".join(SUPPORT_PATTERNS), re.IGNORECASE)
TERM_RE = re.compile(
r"\b(" + "|".join(re.escape(w) for w in SUPERLATIVES) + r")\b",
re.IGNORECASE,
)
# How far around the term (in characters) counts as "same sentence/paragraph".
WINDOW = 200
def paragraph_bounds(text: str, pos: int) -> tuple[int, int]:
"""Return the start/end offsets of the blank-line-delimited paragraph
containing pos, so support anywhere in the paragraph counts."""
start = text.rfind("\n\n", 0, pos)
start = 0 if start == -1 else start + 2
end = text.find("\n\n", pos)
end = len(text) if end == -1 else end
return start, end
def check_file(path: str) -> int:
fail = 0
try:
text = open(path, encoding="utf-8").read()
except OSError as e:
print(f"ERROR: cannot read {path}: {e}", file=sys.stderr)
return 2
for m in TERM_RE.finditer(text):
p_start, p_end = paragraph_bounds(text, m.start())
w_start = max(p_start, m.start() - WINDOW)
w_end = min(p_end, m.end() + WINDOW)
window_text = text[w_start:w_end]
if not SUPPORT_RE.search(window_text):
line = text.count("\n", 0, m.start()) + 1
print(f"{path}:{line}: '{m.group(1)}' has no nearby supporting "
f"fact (exhibit, dated fact, dollar amount, or "
f"[CITATION NEEDED]/[SOURCE]/[VERIFY] tag)")
fail = 1
return fail
def main() -> int:
if len(sys.argv) < 2:
print("Usage: check_four_filter.py <document.md> [<document2.md> ...]",
file=sys.stderr)
return 2
worst = 0
any_flagged = False
for path in sys.argv[1:]:
result = check_file(path)
if result == 2:
return 2
if result == 1:
any_flagged = True
worst = max(worst, result)
if not any_flagged:
print("✅ every superlative/absolute term has a nearby supporting fact")
return 0
return 1
if __name__ == "__main__":
raise SystemExit(main())