"""Explicit local module compatibility candidate; no target code execution.""" import base64 import hashlib import json import posixpath import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path[:0] = [str(ROOT / "packages/core")] from chameleon_core.module_resolution import POLICY, resolve_relative_import from chameleon_core.repository_capture import verify_package from derived_overlay import validate_overlay def parse_module_source(original): if len(original) > 262144: raise ValueError("MODULE_SOURCE_BUDGET") parsed = subprocess.run(["node", str(ROOT / "scripts/module_references.mjs")], input=original, capture_output=True, timeout=10, check=False, cwd=ROOT) if parsed.returncode or len(parsed.stdout) > 100000: raise ValueError("MODULE_SYNTAX_UNSUPPORTED") evidence = json.loads(parsed.stdout) if evidence["source_sha256"] != hashlib.sha256(original).hexdigest() or evidence["dynamic_imports"]: raise ValueError("MODULE_DYNAMIC_OR_SOURCE_MISMATCH") return evidence def build_module_overlay(package, importer, *, policy): if policy != POLICY: raise ValueError("EXPLICIT_MODULE_POLICY_REQUIRED") files = verify_package(package) if importer not in files or not importer.endswith((".js", ".mjs")): raise ValueError("CAPTURED_IMPORTER_REQUIRED") original = files[importer] if len(original) > 12000: raise ValueError("MODULE_OVERLAY_BUDGET") evidence = parse_module_source(original) inventory = {name: {"sha": record["git_blob_sha"], "size": record["bytes"]} for name, record in package["repository"]["files"].items()} edits, plans = [], [] for reference in evidence["references"]: plan = resolve_relative_import(importer, reference["specifier"], inventory) if plan["status"] != "RESOLVED": raise ValueError("MODULE_" + plan["status"]) target = plan["matches"][0]["path"] relative = posixpath.relpath(target, posixpath.dirname(importer) or ".") if not relative.startswith("."): relative = "./" + relative start, end = reference["start_byte"], reference["end_byte"] if hashlib.sha256(original[start:end]).hexdigest() != reference["literal_sha256"]: raise ValueError("MODULE_LITERAL_BINDING") plans.append(plan) if relative != reference["specifier"]: edits.append((start, end, json.dumps(relative).encode())) if not edits: raise ValueError("MODULE_NO_REWRITE_NEEDED") after = original for start, end, replacement in reversed(edits): after = after[:start] + replacement + after[end:] overlay = {"version": "derived-file-v1", "source_digest": package["digest"], "path": importer, "before_sha256": hashlib.sha256(original).hexdigest(), "after_base64": base64.b64encode(after).decode(), "after_sha256": hashlib.sha256(after).hexdigest(), "operator": POLICY} validate_overlay(overlay, package) return {"overlay": overlay, "syntax": evidence, "resolutions": plans, "scope": "One-file explicit module policy; all behavior and delivery checks still required"}