{
  "schema": "ccsi/research-spotcheck-verifier/v1",
  "filename": "verify.py",
  "note": "Save the `source` field as verify.py, then run: python3 verify.py research_pack_spotcheck.json",
  "source": "#!/usr/bin/env python3\n\"\"\"verify.py \u2014 reimplement the seller's grading rule and falsify the claim.\n\nGrading rule: ccsi/evidence-collapse v3. The literals below are generated\nfrom the seller's OWN grader, so this verifier runs the SAME rule, not a\nlookalike \u2014 a buyer can recompute the paid count, not merely re-read a claim.\n\nFalsifiable claim (from the seller):\n  \"Ten agents quoting one source collapse to ONE evidence path; two agents with\n   distinct measured claims stay TWO. Agreement count is not a truth grade.\"\n\nRun:  python3 verify.py fixtures.json\nPrints, per fixture, the number of independent paths the rule finds. Check it\nagainst the advertised expectation. If ten echoes do NOT collapse to one path,\nthe advertised rule is false and you have paid nothing.\n\"\"\"\nimport json\nimport re\nimport sys\n\n# --- the rule, exactly as advertised ---------------------------------------\n# frozenset(('a', 'about', 'above', 'across', 'after', 'again', 'all', 'also', 'an', 'and', 'any', 'are', 'as', 'at', 'be', 'before', 'below', 'between', 'both', 'but', 'by', 'can', 'could', 'did', 'do', 'does', 'during', 'each', 'few', 'for', 'from', 'further', 'had', 'has', 'have', 'her', 'here', 'his', 'how', 'i', 'if', 'in', 'into', 'is', 'it', 'its', 'just', 'least', 'less', 'more', 'most', 'my', 'not', 'of', 'on', 'once', 'only', 'or', 'other', 'our', 'over', 'own', 'same', 'should', 'so', 'some', 'such', 'than', 'that', 'the', 'their', 'then', 'there', 'they', 'this', 'to', 'too', 'under', 'very', 'was', 'we', 'were', 'what', 'when', 'where', 'which', 'while', 'who', 'whom', 'why', 'will', 'with', 'would', 'you',)) and '(https?://[\\\\w.-]+/[\\\\w./%#?=-]*|[\\\\w-]+(?:\\\\.[\\\\w-]+)+/[\\\\w./%#?=-]+|\\\\b10\\\\.\\\\d{4,9}/[\\\\w./:-]+|@[A-Za-z0-9_]+|\\\\b[A-Z][A-Za-z]+(?:\\\\s+[A-Z][A-Za-z]+){0,3}\\\\s+(?:paper|report|study|benchmark|dataset)\\\\b)' are generated from the canonical grader\n# (moltbook_prospect) at build time \u2014 do NOT hand-edit; they must be IDENTICAL to\n# the rule the paid grade runs, or this verifier is a different rule wearing the\n# same name (the defect this generation closes).\nSTOP = frozenset(('a', 'about', 'above', 'across', 'after', 'again', 'all', 'also', 'an', 'and', 'any', 'are', 'as', 'at', 'be', 'before', 'below', 'between', 'both', 'but', 'by', 'can', 'could', 'did', 'do', 'does', 'during', 'each', 'few', 'for', 'from', 'further', 'had', 'has', 'have', 'her', 'here', 'his', 'how', 'i', 'if', 'in', 'into', 'is', 'it', 'its', 'just', 'least', 'less', 'more', 'most', 'my', 'not', 'of', 'on', 'once', 'only', 'or', 'other', 'our', 'over', 'own', 'same', 'should', 'so', 'some', 'such', 'than', 'that', 'the', 'their', 'then', 'there', 'they', 'this', 'to', 'too', 'under', 'very', 'was', 'we', 'were', 'what', 'when', 'where', 'which', 'while', 'who', 'whom', 'why', 'will', 'with', 'would', 'you',))\n\n\ndef tokens(text):\n    words = re.findall(r\"[a-z0-9]+\", (text or \"\").lower())\n    return frozenset(w for w in words if len(w) > 2 and w not in STOP)\n\n\ndef jaccard(a, b):\n    if not a or not b:\n        return 0.0\n    return len(a & b) / len(a | b)\n\n\ndef named_sources(text):\n    # Shared artifacts that create correlation. The SOURCE KEY is normalized\n    # (scheme stripped, trailing slash dropped, case folded) so the same source\n    # matches across renderings \u2014 a bare host-with-path cites the same artifact\n    # as its https:// form, plus DOIs, @handles, and a named paper/report/study.\n    found = re.findall('(https?://[\\\\w.-]+/[\\\\w./%#?=-]*|[\\\\w-]+(?:\\\\.[\\\\w-]+)+/[\\\\w./%#?=-]+|\\\\b10\\\\.\\\\d{4,9}/[\\\\w./:-]+|@[A-Za-z0-9_]+|\\\\b[A-Z][A-Za-z]+(?:\\\\s+[A-Z][A-Za-z]+){0,3}\\\\s+(?:paper|report|study|benchmark|dataset)\\\\b)', text or \"\")\n    norm = []\n    for m in found:\n        s = re.sub(r\"^https?://\", \"\", m.strip().lower()).rstrip(\"/\")\n        norm.append(s.rstrip(\".,;:)]}\"))  # a trailing sentence period is not the URL\n    return frozenset(s for s in norm if s)\n\n\ndef independent_paths(rows, threshold=0.45):\n    \"\"\"Union-find over near-duplicate text, shared named source, or shared thread.\"\"\"\n    n = len(rows)\n    parent = list(range(n))\n\n    def find(x):\n        while parent[x] != x:\n            parent[x] = parent[parent[x]]\n            x = parent[x]\n        return x\n\n    def union(a, b):\n        ra, rb = find(a), find(b)\n        if ra != rb:\n            parent[rb] = ra\n\n    toks = [tokens(r.get(\"content\") or r.get(\"title\") or \"\") for r in rows]\n    srcs = [named_sources((r.get(\"content\") or \"\") + \" \" + (r.get(\"title\") or \"\"))\n            for r in rows]\n    # A shared CONVERSATION THREAD is correlation too: many rows in one thread\n    # are one conversation. An empty thread id is NOT a link (absence is not a\n    # shared conversation).\n    thr = [str(r.get(\"thread\") or r.get(\"source_id\") or \"\") for r in rows]\n    for i in range(n):\n        for j in range(i + 1, n):\n            if (toks[i] and toks[j] and jaccard(toks[i], toks[j]) >= threshold) \\\n                    or (srcs[i] and srcs[j] and (srcs[i] & srcs[j])) \\\n                    or (thr[i] and thr[i] == thr[j]):\n                union(i, j)\n    groups = {}\n    for i in range(n):\n        groups.setdefault(find(i), []).append(i)\n    return len(groups)\n\n\ndef main():\n    if len(sys.argv) < 2:\n        print(\"usage: python3 verify.py fixtures.json\")\n        return 2\n    data = json.load(open(sys.argv[1]))\n    ok = True\n    for name, fx in data[\"fixtures\"].items():\n        got = independent_paths(fx[\"rows\"], data.get(\"threshold\", 0.45))\n        want = fx[\"expect_independent_paths\"]\n        verdict = \"PASS\" if got == want else \"FAIL\"\n        if got != want:\n            ok = False\n        print(f\"[{verdict}] {name}: rule found {got} independent paths; \"\n              f\"expected {want} ({len(fx['rows'])} rows)\")\n    print(\"\\nAll fixtures behaved as advertised.\" if ok else\n          \"\\nThe advertised rule FAILED a fixture. Do not buy.\")\n    return 0 if ok else 1\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n",
  "generator": {
    "tool": "tools/build_spotcheck.py",
    "file_sha256": "a984c1fe4466001165628490db30eadda6e219ebae047c696d552a341e06ba46",
    "revision": "d8a9c8e050bd1c2f32aa66ce195b73cd9a87fda4",
    "dirty": false,
    "executes_steps": [
      "python3 tools/build_spotcheck.py --out research_pack_spotcheck.json"
    ],
    "note": "the tool that composed this kit; its verifier literals are generated from moltbook_prospect's rule at this same revision"
  },
  "rule_source": {
    "tool": "tools/moltbook_prospect.py",
    "file_sha256": "ea3ec831f715bbcb7de6be650dc87cf1f467eca9e88bcf5f807338f163840a1e",
    "revision": "d8a9c8e050bd1c2f32aa66ce195b73cd9a87fda4",
    "dirty": false,
    "note": "the canonical grader whose rule the shipped verifier's literals are generated from \u2014 names WHICH rule, not a claim that it is the right rule"
  }
}
