From bfc904b3c2a9ebdbdfc04cd31fc77c5852be23e8 Mon Sep 17 00:00:00 2001 From: wjarvis mos-comms Date: Sun, 19 Jul 2026 21:04:45 -0500 Subject: [PATCH] test(mosaic): enforce framework skill portability --- packages/mosaic/package.json | 2 +- .../framework_skill_portability_unittest.py | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 packages/mosaic/src/lease-broker/framework_skill_portability_unittest.py diff --git a/packages/mosaic/package.json b/packages/mosaic/package.json index 12a6b879..b6a37282 100644 --- a/packages/mosaic/package.json +++ b/packages/mosaic/package.json @@ -25,7 +25,7 @@ "lint": "eslint src", "typecheck": "tsc --noEmit", "test": "vitest run --passWithNoTests && pnpm run test:framework-shell", - "test:framework-shell": "python3 src/lease-broker/daemon_deadline_unittest.py && python3 src/lease-broker/normative_fragments_unittest.py && python3 src/lease-broker/receipt_challenge_unittest.py && python3 src/lease-broker/context_recovery_unittest.py && python3 src/lease-broker/recovery_runtime_unittest.py && python3 src/lease-broker/recovery_b1_adversarial_unittest.py && python3 src/mutator-gate/runtime_tools_unittest.py && python3 src/mutator-gate/runtime_launch_guard_unittest.py && python3 framework/tools/lease-broker/check-runtime-launches.py --root ../.. && bash framework/tools/codex/test-pr-diff-context.sh" + "test:framework-shell": "python3 src/lease-broker/daemon_deadline_unittest.py && python3 src/lease-broker/normative_fragments_unittest.py && python3 src/lease-broker/receipt_challenge_unittest.py && python3 src/lease-broker/context_recovery_unittest.py && python3 src/lease-broker/recovery_runtime_unittest.py && python3 src/lease-broker/recovery_b1_adversarial_unittest.py && python3 src/lease-broker/framework_skill_portability_unittest.py && python3 src/mutator-gate/runtime_tools_unittest.py && python3 src/mutator-gate/runtime_launch_guard_unittest.py && python3 framework/tools/lease-broker/check-runtime-launches.py --root ../.. && bash framework/tools/codex/test-pr-diff-context.sh" }, "dependencies": { "@mosaicstack/brain": "workspace:*", diff --git a/packages/mosaic/src/lease-broker/framework_skill_portability_unittest.py b/packages/mosaic/src/lease-broker/framework_skill_portability_unittest.py new file mode 100644 index 00000000..a8b74df9 --- /dev/null +++ b/packages/mosaic/src/lease-broker/framework_skill_portability_unittest.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +"""RED-first framework-firewall and portability contracts for shipped skills.""" + +from __future__ import annotations + +import importlib.util +import re +import unittest +from pathlib import Path + + +MOSAIC = Path(__file__).parents[2] +SKILLS = MOSAIC / "framework/skills" +REFRESH_SKILL = SKILLS / "mosaic-context-refresh/SKILL.md" +GATE_PATH = MOSAIC / "framework/tools/lease-broker/mutator-gate.py" +OPERATOR_HOME = re.compile(r"/home/[^/\s]+/") +RECOVERY_PLACEHOLDER = "/absolute/path/to/mosaic/tools/lease-broker/recover-context.py" +CONSTRUCTION_PLACEHOLDER = "/absolute/path/to/mosaic-context-refresh-construction.json" + + +def load_gate(): + spec = importlib.util.spec_from_file_location("framework_skill_portability_gate", GATE_PATH) + if spec is None or spec.loader is None: + raise RuntimeError("unable to load mutator gate") + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +GATE = load_gate() + + +class FrameworkSkillPortabilityTest(unittest.TestCase): + def test_shipped_framework_skills_contain_no_operator_home_path(self) -> None: + offenders = [ + str(path.relative_to(SKILLS)) + for path in SKILLS.rglob("SKILL.md") + if OPERATOR_HOME.search(path.read_text(encoding="utf-8")) + ] + self.assertEqual(offenders, []) + + def test_shipped_recovery_template_resolves_to_a_literal_install_path_and_admits(self) -> None: + source = REFRESH_SKILL.read_text(encoding="utf-8") + self.assertIn(RECOVERY_PLACEHOLDER, source) + self.assertIn(CONSTRUCTION_PLACEHOLDER, source) + resolved_recovery = "/opt/mosaic/tools/lease-broker/recover-context.py" + resolved_construction = "/opt/mosaic/recovery/construction.json" + command = ( + source.replace(RECOVERY_PLACEHOLDER, resolved_recovery) + .replace(CONSTRUCTION_PLACEHOLDER, resolved_construction) + .split("```bash\n", 1)[1] + .split("\n```", 1)[0] + ) + self.assertEqual( + GATE.recovery_invocation_name( + {"tool_name": "Bash", "tool_input": {"command": command}}, + Path(resolved_recovery), + ), + GATE.RECOVERY_TOOL, + ) + + +if __name__ == "__main__": + unittest.main()