diff --git a/hermes_cli/plugin_validate_private_imports.py b/hermes_cli/plugin_validate_private_imports.py index 6122c094eb..7432c7297e 100644 --- a/hermes_cli/plugin_validate_private_imports.py +++ b/hermes_cli/plugin_validate_private_imports.py @@ -130,7 +130,8 @@ def _is_own_module_path(module: str, local: set[str]) -> bool: def _private_target(module: str, name: str, core: frozenset, local: set[str]) -> str: """The dotted target to report, or "" when the import is public, local or not Hermes's.""" target = f"{module}.{name}" if name else module - hermes = module.split(".")[0] in core and module not in local and not _is_own_module_path(module, local) + own = _is_own_module_path(module, local) or bool(name) and _is_own_module_path(target, local) + hermes = module.split(".")[0] in core and module not in local and not own public = target in _PUBLIC or f"{module}:{name}" in _PUBLIC \ or (module in _PUBLIC and not name.startswith("_")) # ``from gateway.platforms import base`` too return target if hermes and not public else "" diff --git a/tests/hermes_cli/test_plugin_validate_private_imports.py b/tests/hermes_cli/test_plugin_validate_private_imports.py index 88cbb424ea..209a42856d 100644 --- a/tests/hermes_cli/test_plugin_validate_private_imports.py +++ b/tests/hermes_cli/test_plugin_validate_private_imports.py @@ -140,6 +140,7 @@ def test_documented_session_helper_and_own_install_path_fallback_are_not_flagged " from . import _db\n" " except ImportError:\n" " import plugins.memory.openltm._db as _db\n" + " from plugins.memory.openltm import _db\n" " from hermes_cli.gateway_client import _session_ticket\n" " return get_session_env, _db, _session_ticket\n" ), @@ -149,7 +150,7 @@ def test_documented_session_helper_and_own_install_path_fallback_are_not_flagged [warning] = _private_warnings(validate_plugin_dir(plugin)) sites = warning.split("release): ", 1)[1].split(". Use ctx.*")[0].split("; ") - assert sites == ["__init__.py:7 hermes_cli.gateway_client._session_ticket"], sites + assert sites == ["__init__.py:8 hermes_cli.gateway_client._session_ticket"], sites def test_private_method_calls_on_core_handles_warn_but_own_helpers_do_not(tmp_path): diff --git a/tests/tools/test_plugin_guard.py b/tests/tools/test_plugin_guard.py index 43af9827ac..0f90d2e92e 100644 --- a/tests/tools/test_plugin_guard.py +++ b/tests/tools/test_plugin_guard.py @@ -1004,6 +1004,8 @@ class TestProcKeyAndBytecodeShapes: ("probe.py", 'print(Path("/proc/self").read_text())\n', "proc_access", "high"), ("probe.py", '(Path("/proc/self/cgroup"), Path("/proc/1/cmdline"))\n', "proc_access", "high"), ("writer.py", 'Path("/proc/self/cgroup").write_text("x")\n', "proc_access", "high"), + ("writer.py", 'open("/proc/self/comm", "r+").write("w")\n', "proc_access", "high"), + ("rename.sh", 'printf worker > "/proc/self/comm"\n', "proc_access", "high"), ("keys.py", f'API_KEY = "phx_{_FAKE_KEY_BODY}"\n', "hardcoded_secret", "critical"), ("keys.py", f'api_key = "phc_{_FAKE_KEY_BODY}"; token = "a8f3k2m9q7w1z5x0c4v6b8n2"\n', "hardcoded_secret", "critical"), diff --git a/tools/plugin_guard_context.py b/tools/plugin_guard_context.py index 6777d5e91c..98d6aef327 100644 --- a/tools/plugin_guard_context.py +++ b/tools/plugin_guard_context.py @@ -790,7 +790,7 @@ _BENIGN_PROC_LEAVES = frozenset({ "sched", "schedstat", "oom_score"}) _PROC_PATH = re.compile(r"/proc/(?:self|\d+)(?:/([\w.-]*))?") _PROC_WRITE = re.compile( - r"write_text|write_bytes|\.write\s*\(|open\s*\([^)\n]{0,300}?['\"][rbt]*[wax+][rbt+]*['\"]|O_WRONLY|O_RDWR|>\s*/proc/|\btee\b") + r"write_text|write_bytes|\.write\s*\(|open\s*\([^)\n]{0,300}?['\"][rbt]*[wax+][rbt+]*['\"]|O_WRONLY|O_RDWR|>\s*['\"]?/proc/|\btee\b") def is_own_proc_read(finding: Finding, line: str) -> bool: