Ctrl K
ComunidadGuías…

scripts/p3j-env-schema-poc.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
"""P3-J: diff static BUTLER_* stubs from code vs reference.md (report-only by default)."""
from __future__ import annotations

import os
import re
import subprocess
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]

WHITELIST = (
    re.compile(r"^BUTLER_NONEXISTENT_KEY"),
    re.compile(r"^BUTLER_SMOKE_"),
    re.compile(r"^BUTLER_HOOK_"),
    re.compile(r"^BUTLER_TEST_"),
    re.compile(r"^BUTLER_WECHAT_.*_SIM$"),
    re.compile(r"^BUTLER_MODEL$"),
)

IGNORE_EXACT = frozenset({
    "BUTLER_PY",
    "BUTLER_PYTHON",
    "BUTLER_NAME",
    "BUTLER_ONLY",
    "BUTLER_BLOCKED_PROJECT_TOOLS",
    "BUTLER_FOO",
})


def _reference_keys() -> tuple[set[str], list[str]]:
    text = (ROOT / "docs/config/reference.md").read_text(encoding="utf-8")
    exact: set[str] = set()
    prefixes: list[str] = []
    for line in text.splitlines():
        if not re.match(r"\s*\| `BUTLER_", line):
            continue
        for tok in re.findall(r"BUTLER_[A-Z0-9_*]+", line):
            if tok.endswith("*"):
                prefixes.append(tok[:-1])
            else:
                exact.add(tok)
    return exact, prefixes


def _code_keys() -> set[str]:
    proc = subprocess.run(
        ["rg", "-o", r"BUTLER_[A-Z0-9_]+", "butler/", "scripts/"],
        cwd=ROOT,
        capture_output=True,
        text=True,
        check=False,
    )
    out: set[str] = set()
    for line in proc.stdout.splitlines():
        m = re.search(r"BUTLER_[A-Z0-9_]+", line)
        if m:
            out.add(m.group(0))
    return out


def _ignored(key: str) -> bool:
    if key in IGNORE_EXACT or key.endswith("_"):
        return True
    return any(p.match(key) for p in WHITELIST)


def main() -> int:
    strict = os.environ.get("P3J_SCHEMA_STRICT", "0").strip() in ("1", "true", "yes", "on")
    exact, prefixes = _reference_keys()
    code = _code_keys()

    def covered(key: str) -> bool:
        if key in exact:
            return True
        return any(key.startswith(p) for p in prefixes)

    stub_only = sorted(k for k in code if not _ignored(k) and not covered(k))
    print("=== P3-J env schema PoC ===")
    print(f"code_keys={len(code)} reference_exact={len(exact)} strict={strict}")
    print("stub_not_in_reference (first 40):")
    if stub_only:
        for k in stub_only[:40]:
            print(f"  {k}")
        if len(stub_only) > 40:
            print(f"  ... +{len(stub_only) - 40} more")
    else:
        print("  (none)")
    return 1 if strict and stub_only else 0


if __name__ == "__main__":
    sys.exit(main())