From 31aa4d4e9db6bfde55a80dea527c8d6c525e2473 Mon Sep 17 00:00:00 2001 From: ayushcodes10 Date: Fri, 11 Sep 2026 15:13:45 +0530 Subject: [PATCH] Keep the git hook rebuild root inside the repo Team setup documents committing the graphify output directory, and .graphify_root lives inside it, so its contents are checkout controlled. Both generated git hooks read that file and pass its value straight to _rebuild_code with no bound, so a value planted there by a forked PR could point the rebuild, and therefore what it reads and what it writes back into that same committed directory, at a location outside the repository the hook runs in. Both rebuild bodies now only adopt the saved root when it resolves inside the working tree the hook is running from, falling back to the repo top otherwise. Fixes #3265. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_017qfdzgbA5KedGEjD1AayNh --- graphify/hooks.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/graphify/hooks.py b/graphify/hooks.py index dbd2fb46d..174014b0d 100644 --- a/graphify/hooks.py +++ b/graphify/hooks.py @@ -188,7 +188,17 @@ try: if _saved.exists(): _txt = _saved.read_text(encoding='utf-8-sig').strip() if _txt: - _root = Path(_txt) + _candidate = Path(_txt) + try: + _cwd = Path.cwd().resolve() + _resolved = _candidate.resolve() + _in_repo = _resolved == _cwd or _cwd in _resolved.parents + except OSError: + _in_repo = False + if _in_repo: + _root = _candidate + else: + print(f'[graphify hook] ignoring out-of-repo .graphify_root: {_txt}') _rebuild_code(_root, changed_paths=changed, force=_force) # Refresh the work-memory lessons doc when saved Q&A outcomes exist # (best-effort; never fails the hook). @@ -250,7 +260,17 @@ try: if _saved.exists(): _txt = _saved.read_text(encoding='utf-8-sig').strip() if _txt: - _root = Path(_txt) + _candidate = Path(_txt) + try: + _cwd = Path.cwd().resolve() + _resolved = _candidate.resolve() + _in_repo = _resolved == _cwd or _cwd in _resolved.parents + except OSError: + _in_repo = False + if _in_repo: + _root = _candidate + else: + print(f'[graphify] ignoring out-of-repo .graphify_root: {_txt}') _rebuild_code(_root, force=_force) # Refresh the work-memory lessons doc when saved Q&A outcomes exist # (best-effort; never fails the hook).