#!/usr/bin/env python3 # SPDX-License-Identifier: AGPL-3.0-only # Copyright (c) 2026 sol pbc """Provider runtime start-command architecture gate. Provider runtime process lifecycle is owned by the supervisor reconciler. Production code must not reintroduce Callosum lifecycle commands that ask the supervisor to start bundled local or Parakeet directly. The production allowlist is intentionally empty. A new production violation should fail immediately. """ from __future__ import annotations import argparse import ast import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent OWNER_FILES: frozenset[str] = frozenset() ALLOWLIST: dict[tuple[str, str], int] = {} START_EVENTS: frozenset[str] = frozenset({"start_local", "start_parakeet"}) FORBIDDEN_FUNCTION_NAMES: frozenset[str] = frozenset( { "_handle_supervisor_start_local", "_handle_supervisor_start_parakeet", "_request_local_server_start", "_request_parakeet_server_start", } ) def _is_owner(rel: Path) -> bool: return rel.as_posix() in OWNER_FILES def _is_test_file(rel: Path) -> bool: return ( "tests" in rel.parts or rel.name == "conftest.py" or (rel.name.startswith("test_") and rel.suffix == ".py") ) def discover_modules(root: Path) -> list[Path]: scope = root / "solstone" if not scope.is_dir(): return [] found: list[Path] = [] for path in sorted(scope.rglob("*.py")): rel = path.relative_to(root) if "__pycache__" in rel.parts: continue if _is_test_file(rel) or _is_owner(rel): continue found.append(rel) return found class _Bindings: def __init__(self) -> None: self.callosum_send_names: set[str] = {"callosum_send"} self.callosum_modules: set[str] = set() def _collect_bindings(tree: ast.AST) -> _Bindings: bindings = _Bindings() for node in ast.walk(tree): if isinstance(node, ast.Import): for alias in node.names: if alias.name == "solstone.think.callosum": bindings.callosum_modules.add(alias.asname or alias.name) elif isinstance(node, ast.ImportFrom): if node.module == "solstone.think.callosum": for alias in node.names: if alias.name == "callosum_send": bindings.callosum_send_names.add(alias.asname or alias.name) elif node.module == "solstone.think": for alias in node.names: if alias.name == "callosum": bindings.callosum_modules.add(alias.asname or alias.name) return bindings def _dotted_name(node: ast.AST) -> str | None: if isinstance(node, ast.Name): return node.id if isinstance(node, ast.Attribute): base = _dotted_name(node.value) if base: return f"{base}.{node.attr}" return None def _constant_str(node: ast.AST | None) -> str | None: if isinstance(node, ast.Constant) and isinstance(node.value, str): return node.value return None def _call_arg_or_kw(call: ast.Call, index: int, name: str) -> str | None: if len(call.args) > index: value = _constant_str(call.args[index]) if value is not None: return value for keyword in call.keywords: if keyword.arg == name: return _constant_str(keyword.value) return None def _is_callosum_send_call(call: ast.Call, bindings: _Bindings) -> bool: func = call.func if isinstance(func, ast.Name): return func.id in bindings.callosum_send_names if not isinstance(func, ast.Attribute) or func.attr != "callosum_send": return False if isinstance(func.value, ast.Name) and func.value.id in bindings.callosum_modules: return True return _dotted_name(func) == "solstone.think.callosum.callosum_send" def _is_emit_call(call: ast.Call) -> bool: return isinstance(call.func, ast.Attribute) and call.func.attr == "emit" def _forbidden_start_call(call: ast.Call, bindings: _Bindings) -> bool: if not (_is_callosum_send_call(call, bindings) or _is_emit_call(call)): return False return ( _call_arg_or_kw(call, 0, "tract") == "supervisor" and _call_arg_or_kw(call, 1, "event") in START_EVENTS ) def _forbidden_message_dict(node: ast.Dict) -> str | None: values: dict[str, str] = {} for key, value in zip(node.keys, node.values): key_str = _constant_str(key) value_str = _constant_str(value) if key_str is not None and value_str is not None: values[key_str] = value_str if values.get("tract") == "supervisor" and values.get("event") in START_EVENTS: return values["event"] return None def scan_source(source: str, filename: str = "") -> list[tuple[int, str, str]]: tree = ast.parse(source, filename=filename) bindings = _collect_bindings(tree) findings: list[tuple[int, str, str]] = [] for node in ast.walk(tree): if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): if node.name in FORBIDDEN_FUNCTION_NAMES: findings.append( ( node.lineno, "provider_start_handler", node.name, ) ) elif isinstance(node, ast.Call) and _forbidden_start_call(node, bindings): findings.append( ( node.lineno, "provider_start_command", "supervisor provider start Callosum command", ) ) elif isinstance(node, ast.Dict): event = _forbidden_message_dict(node) if event is not None: findings.append( ( node.lineno, "provider_start_message", f"supervisor {event} message literal", ) ) findings.sort() return findings def scan_file(path: Path) -> list[tuple[int, str, str]]: return scan_source(path.read_text(encoding="utf-8"), filename=str(path)) def count_violations(root: Path) -> dict[tuple[str, str], int]: counts: dict[tuple[str, str], int] = {} for rel in discover_modules(root): for _lineno, kind, _detail in scan_file(root / rel): key = (rel.as_posix(), kind) counts[key] = counts.get(key, 0) + 1 return counts def evaluate( root: Path, allowlist: dict[tuple[str, str], int], ) -> tuple[list[str], list[str], list[str]]: over: list[str] = [] stale: list[str] = [] tracked: list[str] = [] counts = count_violations(root) for key in sorted(set(counts) | set(allowlist)): count = counts.get(key, 0) allowed = allowlist.get(key, 0) rel, kind = key if count > allowed: over.append(f"{rel}: {kind} count {count} exceeds allowed {allowed}") elif count < allowed: stale.append(f"{rel}: {kind} count {count} below allowed {allowed}") elif allowed: tracked.append(f"{rel}: {count}/{allowed} {kind} (allowlisted)") return over, stale, tracked def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser(description="Provider start-command lint") parser.add_argument( "--root", type=Path, default=ROOT, help="Repository root to scan (defaults to the checkout root).", ) args = parser.parse_args(argv) over, stale, tracked = evaluate(args.root, ALLOWLIST) if tracked: print("provider-start-commands: known violations (allowlisted):") for line in tracked: print(f" {line}") print() if over or stale: print("provider-start-commands: violations:", file=sys.stderr) for line in over: print(f" {line}", file=sys.stderr) for line in stale: print(f" stale allowlist: {line}", file=sys.stderr) print( "Provider runtime launches must be driven by durable reconciliation, " "not supervisor start Callosum commands.", file=sys.stderr, ) return 1 print("provider-start-commands: pass") return 0 if __name__ == "__main__": raise SystemExit(main())