From 93ea53c4d53cd898c1c43fbdcd07f0552c0ba6d1 Mon Sep 17 00:00:00 2001 From: jinon86 Date: Wed, 5 Aug 2026 17:31:54 +0900 Subject: [PATCH] fix(memory): resolve ccc_secure_fs from the installed hook tree (#952) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The distill committer loads ccc_local_memory_transaction.py through spec_from_file_location, so ~/.claude/hooks/ is never placed on sys.path. The `from ccc_secure_fs import ...` fallback therefore only resolves on nodes that also expose telegram_bot (an editable bridge install), and every other node falls through to `parents[1]/utils/secure_fs.py` — a path that does not exist in the installed layout. Probe the sibling ccc_secure_fs.py first, keeping the source-checkout path as the second candidate. Verified on sogyo (no telegram_bot on the system interpreter): before: FileNotFoundError .../utils/secure_fs.py after: module loads Source-checkout layout still loads; tests/test_local_memory_transaction.py 13 passed. Co-Authored-By: Claude Opus 5 --- bridge/memory/local_memory_transaction.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/bridge/memory/local_memory_transaction.py b/bridge/memory/local_memory_transaction.py index b894387f..5aa8a779 100644 --- a/bridge/memory/local_memory_transaction.py +++ b/bridge/memory/local_memory_transaction.py @@ -36,8 +36,24 @@ _fsync_directory, ensure_private_directory, ) - except ModuleNotFoundError: # Direct execution from a source checkout. - secure_fs_source = Path(__file__).resolve().parents[1] / "utils/secure_fs.py" + except ModuleNotFoundError: + # Two layouts reach this point: + # * installed hook tree - setup.sh copies this module and + # ccc_secure_fs.py side by side into ~/.claude/hooks/, but that + # directory is not on sys.path when the distill committer loads us + # via spec_from_file_location. The `ccc_secure_fs` import above + # therefore only resolves on nodes that also expose telegram_bot. + # * source checkout - bridge/memory/ next to bridge/utils/. + # Probe the sibling copy first so standalone installs stop falling + # through to a path that does not exist. + secure_fs_candidates = ( + Path(__file__).resolve().parent / "ccc_secure_fs.py", + Path(__file__).resolve().parents[1] / "utils/secure_fs.py", + ) + secure_fs_source = next( + (path for path in secure_fs_candidates if path.is_file()), + secure_fs_candidates[-1], + ) secure_fs_spec = importlib.util.spec_from_file_location( "ccc_secure_fs", secure_fs_source,