"""Batch-2 fixture tests (no network). Run: python tests/test_batch2_patterns.py Batch-2 final scope: HEROKU + SUPABASE in canon src/key_patterns.py PATTERNS (fleet_update ships canon; patterns_extra is excluded from wave payload). REJECTED families asserted absent (doctrine: one label per key shape): CLERK — sk_(live|test)_ shape owned by canon STRIPE; second label = mislabel race on every real Stripe live key. BAIDU — bce-v3/ALTAK-{id}/{sig} is a per-request HMAC signature, not a reusable credential. Shape-ownership gate: each pos fixture must match EXACTLY ONE PATTERNS entry. Coupling gate: emitted prov must resolve in eternal_v10 (allowlist/PROVIDERS), else UNKNOWN -> DEAD terminal (KH_AWS graveyard lesson). Static parse only — eternal_v10 has module-level side effects + live HTTP in validate(). """ import os import sys HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.join(os.path.dirname(HERE), "src")) sys.path.insert(0, os.path.dirname(HERE)) FAILS = [] def check(name, cond, detail=""): if cond: print(f"ok {name}") else: print(f"FAIL {name} {detail}") FAILS.append(name) import key_patterns as K # noqa: E402 (canon, src tree) import patterns_extra as PE # noqa: E402 CANON = dict(K.PATTERNS) P = PE.EXTRA_PATTERNS # ---- fixtures (synthetic, valid shapes) ---- HEROKU_POS = "token=HRKU-AA" + ("aB3xY7zK9mQ2wR5t" * 4)[:58] + " done" HEROKU_NEG1 = "token=HRKU-BB" + ("aB3xY7zK9mQ2wR5t" * 4)[:58] HEROKU_NEG2 = "token=HRKU-AA" + "aB3xY7zK9m" # too short SUPABASE_POS = 'SB_TOKEN="sbp-1234567890abcdef1234567890abcdef12345678"' SUPABASE_NEG1 = "sbp-1234567890abcdef1234567890abcdef1234567" # 39 hex SUPABASE_NEG2 = "sbo-1234567890abcdef1234567890abcdef12345678" # wrong prefix CLERK_SHAPE = "sk_" + "live_" + "aB3xY7zK9mQ2wR5tN8vJ1cL4hF6dG0sA" BAIDU_SHAPE = "BCE_AK=bce-v3/ALTAK-aB3xY7zK9m/0123456789abcdef0123456789abcdef" SPECS = [ ("HEROKU", HEROKU_POS, [HEROKU_NEG1, HEROKU_NEG2]), ("SUPABASE", SUPABASE_POS, [SUPABASE_NEG1, SUPABASE_NEG2]), ] for name, pos, negs in SPECS: rx = CANON.get(name) if rx is None: check(f"{name}:in-canon", False, "missing from PATTERNS") continue check(f"{name}:pos", rx.search(pos) is not None, f"no match in {pos[:40]}") for i, neg in enumerate(negs): check(f"{name}:neg{i}", rx.search(neg) is None, f"false match in {neg[:40]}") # shape ownership: exactly one canon entry may match the pos fixture owners = [n for n, r in CANON.items() if r.search(pos)] check(f"{name}:shape-owned-once", owners == [name], f"pos fixture matched by {owners} — one label per key shape") # rejected families: no canon label, no extra label check("rejected:CLERK-not-in-canon", "CLERK" not in CANON) check("rejected:clerk-not-in-extras", "clerk" not in P) check("rejected:BAIDU-not-in-canon", "BAIDU" not in CANON) check("rejected:baidu-not-in-extras", "baidu" not in P) # clerk shape must stay owned by STRIPE alone stripe_owners = [n for n, r in CANON.items() if r.search(CLERK_SHAPE)] check("rejected:clerk-shape-stripe-only", "STRIPE" in stripe_owners and "CLERK" not in stripe_owners, f"owners={stripe_owners}") # baidu shape must not emit a credential label from canon batch-2 baidu_owners = [n for n, r in CANON.items() if n in ("HEROKU", "SUPABASE") and r.search(BAIDU_SHAPE)] check("rejected:baidu-no-batch2-hit", not baidu_owners, f"owners={baidu_owners}") # extras regression: kh_* intact, count floor check("regress:kh_google", "kh_google" in P and P["kh_google"].search("AIzaSy" + "A1234567890abcdefghijklmnopqrstuv"[:33]) is not None) check("regress:kh_grok", "kh_grok" in P and P["kh_grok"].search("xai-" + "aB3x" * 12) is not None) check("regress:count", len(P) >= 17, f"EXTRA_PATTERNS shrank: {len(P)}") # scan_text end-to-end (junk-фильтр + first-wins dedup): высокоэнтропийные # нециклические фикстуры должны пройти весь тракт и выдать prov-лейблы. import random as _rnd _r = _rnd.Random(20261006) _hex40 = "".join(_r.choice("0123456789abcdef") for _ in range(40)) _alnum58 = "".join(_r.choice("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-") for _ in range(58)) SB_E2E = 'SB_TOKEN="sbp-' + _hex40 + '"' HK_E2E = "HEROKU_API_KEY=HRKU-AA" + _alnum58 for _fix, _want in ((SB_E2E, "SUPABASE"), (HK_E2E, "HEROKU")): _got = K.scan_text(_fix) _provs = {p for p, _ in _got} check(f"scan_text:{_want}", _want in _provs, f"provs={sorted(_provs)}") _v = [v for p, v in _got if p == _want] check(f"scan_text:{_want}-value", bool(_v) and _v[0] in _fix, f"vals={_v}") # coupling gate: batch-2 provs resolvable in eternal_v10 (allowlist or PROVIDERS) import ast as _ast import re as _re _allow, _provs = None, set() for _p in (os.path.join(os.path.dirname(HERE), "src", "eternal_v10.py"), os.path.join(os.path.dirname(HERE), "eternal_v10.py")): if os.path.exists(_p): _src = open(_p, encoding="utf-8").read() _m = _re.search(r"if prov_name in \[([^\]]+)\]", _src) if _m: _allow = {s.strip().strip("'\"") for s in _m.group(1).split(",")} try: for _node in _ast.walk(_ast.parse(_src)): if isinstance(_node, (_ast.Assign, _ast.AnnAssign)): _tgt = _node.targets if isinstance(_node, _ast.Assign) else [_node.target] for _t in _tgt: if (isinstance(_t, _ast.Name) and _t.id == "PROVIDERS" and isinstance(_node.value, _ast.Dict)): for _k in _node.value.keys: if isinstance(_k, _ast.Constant) and isinstance(_k.value, str): _provs.add(_k.value) except SyntaxError: pass break if _allow is None and not _provs: check("coupling:allowlist-found", False, "eternal_v10 allowlist not parsed (no PROVIDERS)") else: for _name in ("HEROKU", "SUPABASE"): _resolved = (_allow and _name in _allow) or _name in _provs check(f"coupling:{_name}-resolvable", _resolved, f"{_name} absent -> UNKNOWN->DEAD destroys finds") print() if FAILS: print(f"BATCH2 FAILURES: {len(FAILS)}: {FAILS}") sys.exit(1) print("BATCH2 ALL GREEN")