diff --git a/dist/claude-code/structured-coding/scripts/checkpoints.py b/dist/claude-code/structured-coding/scripts/checkpoints.py index 0f482ca..4f0baf5 100644 --- a/dist/claude-code/structured-coding/scripts/checkpoints.py +++ b/dist/claude-code/structured-coding/scripts/checkpoints.py @@ -12,6 +12,10 @@ # Installed helpers must not create files in the published skill tree. sys.dont_write_bytecode = True +# Import by location rather than relying on sys.path[0], which is absent under +# python3 -P. This import is above main()'s try, so failing here would exit +# non-zero without the empty result a hook must always return. +sys.path.insert(0, str(Path(__file__).resolve().parent)) from continuity import ( # noqa: E402 HOSTS, MAX_INPUT, diff --git a/dist/codex/structured-coding/scripts/checkpoints.py b/dist/codex/structured-coding/scripts/checkpoints.py index 0f482ca..4f0baf5 100644 --- a/dist/codex/structured-coding/scripts/checkpoints.py +++ b/dist/codex/structured-coding/scripts/checkpoints.py @@ -12,6 +12,10 @@ # Installed helpers must not create files in the published skill tree. sys.dont_write_bytecode = True +# Import by location rather than relying on sys.path[0], which is absent under +# python3 -P. This import is above main()'s try, so failing here would exit +# non-zero without the empty result a hook must always return. +sys.path.insert(0, str(Path(__file__).resolve().parent)) from continuity import ( # noqa: E402 HOSTS, MAX_INPUT, diff --git a/dist/structured-coding-claude-code.zip b/dist/structured-coding-claude-code.zip index c6f736d..4c1e872 100644 Binary files a/dist/structured-coding-claude-code.zip and b/dist/structured-coding-claude-code.zip differ diff --git a/dist/structured-coding-codex.zip b/dist/structured-coding-codex.zip index da25c1e..37668e9 100644 Binary files a/dist/structured-coding-codex.zip and b/dist/structured-coding-codex.zip differ diff --git a/scripts/test_continuity.py b/scripts/test_continuity.py index 7ee8fcd..3a159c3 100644 --- a/scripts/test_continuity.py +++ b/scripts/test_continuity.py @@ -196,6 +196,26 @@ def test_a_previous_release_binding_still_loads_with_its_digest_intact(self): self.assertEqual(runtime.digest(runtime.encoded(loaded)), digest_before) self.assertEqual(path.read_bytes(), legacy) + @unittest.skipIf(sys.version_info < (3, 11), "-P and PYTHONSAFEPATH are 3.11+") + def test_every_runtime_script_imports_without_a_path_default(self): + """A hook launched under python3 -P must still reach its shared helpers. + + The import sits above main()'s try, so failing there exits non-zero + without the empty result a hook is required to return. Older interpreters + have no safe-path mode, so the failure cannot arise there.""" + skill = hook_install.ROOT / "structured-coding/scripts" + for name in ("continuity", "checkpoints", "standards"): + with self.subTest(script=name): + result = subprocess.run( + [sys.executable, "-P", "-c", + "import importlib.util,sys;" + f"spec=importlib.util.spec_from_file_location({name!r}," + f" {str(skill / f'{name}.py')!r});" + "m=importlib.util.module_from_spec(spec);" + "spec.loader.exec_module(m)"], + capture_output=True, text=True) + self.assertEqual(result.returncode, 0, result.stderr) + def test_fixture_disables_git_background_maintenance(self): """Housekeeping locks otherwise appear mid-test in whole-tree comparisons.""" for key, expected in (("maintenance.auto", "false"), ("gc.auto", "0")): diff --git a/structured-coding/scripts/checkpoints.py b/structured-coding/scripts/checkpoints.py index 0f482ca..4f0baf5 100755 --- a/structured-coding/scripts/checkpoints.py +++ b/structured-coding/scripts/checkpoints.py @@ -12,6 +12,10 @@ # Installed helpers must not create files in the published skill tree. sys.dont_write_bytecode = True +# Import by location rather than relying on sys.path[0], which is absent under +# python3 -P. This import is above main()'s try, so failing here would exit +# non-zero without the empty result a hook must always return. +sys.path.insert(0, str(Path(__file__).resolve().parent)) from continuity import ( # noqa: E402 HOSTS, MAX_INPUT,