Files
periscope/backend/pinscopex/library_gate.py
T
micheleandCursor 30aaf55de6 Ship DeepSeek roadmap P0-5/P2 integrations.
Smoke simple_project offline, reviewer shortest_path, library promotion
gate, PDF drop logs, and per-stage cache hit-rate helper — without
touching Layout placement packing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-12 15:48:39 +02:00

42 lines
1.5 KiB
Python

"""Shared-library promotion gates for extracted IC JSON."""
from __future__ import annotations
import hashlib
import json
from typing import Any
def pintable_checksum(pintable: list[Any]) -> str:
"""Stable hash of pin number+name pairs (order-independent)."""
rows: list[tuple[str, str]] = []
for pin in pintable or []:
if isinstance(pin, dict):
num = str(pin.get("number") or "").strip()
name = str(pin.get("name") or "").strip()
else:
num = str(getattr(pin, "number", "") or "").strip()
name = str(getattr(pin, "name", "") or "").strip()
if num:
rows.append((num, name))
payload = json.dumps(sorted(rows), separators=(",", ":"))
return hashlib.sha256(payload.encode("utf-8")).hexdigest()[:16]
def should_promote_extraction(data: dict) -> tuple[bool, str]:
"""Return (ok, reason). Reject empty / tiny pintables from shared library."""
pins = data.get("pintable") or []
if not isinstance(pins, list) or len(pins) == 0:
return False, "empty pintable"
if len(pins) < 2:
return False, "pintable has fewer than 2 pins"
# Require at least one named pin so a number-only stub cannot poison the library.
named = 0
for pin in pins:
name = pin.get("name") if isinstance(pin, dict) else getattr(pin, "name", None)
if name and str(name).strip() and str(name).strip() != "~":
named += 1
if named == 0:
return False, "pintable has no named pins"
return True, pintable_checksum(pins)