fix: add logging on rejected transcript paths and platform-native path test

- _count_human_messages() now logs a WARNING via _log() when a
  non-empty transcript_path is rejected by the validator, making
  silent auto-save failures diagnosable via hook.log
- Add test for platform-native paths (backslashes on Windows) to
  verify _validate_transcript_path works cross-platform
- Add test verifying the warning log is emitted on rejection

Refs: MemPalace/mempalace#809
This commit is contained in:
BLUDATA\marcio.heiderscheidt
2026-04-13 14:18:09 -03:00
parent 0f217f7c80
commit f7d703fd5b
2 changed files with 26 additions and 1 deletions
+5 -1
View File
@@ -65,7 +65,11 @@ def _validate_transcript_path(transcript_path: str) -> Path:
def _count_human_messages(transcript_path: str) -> int:
"""Count human messages in a JSONL transcript, skipping command-messages."""
path = _validate_transcript_path(transcript_path)
if path is None or not path.is_file():
if path is None:
if transcript_path:
_log(f"WARNING: transcript_path rejected by validator: {transcript_path!r}")
return 0
if not path.is_file():
return 0
count = 0
try:
+21
View File
@@ -462,6 +462,27 @@ def test_count_rejects_traversal_path():
assert _count_human_messages("../../etc/passwd") == 0
def test_count_logs_warning_on_rejected_path(tmp_path):
"""_count_human_messages should log a warning when a non-empty path is rejected."""
with patch("mempalace.hooks_cli.STATE_DIR", tmp_path):
with patch("mempalace.hooks_cli._log") as mock_log:
_count_human_messages("../../etc/passwd")
mock_log.assert_called_once()
assert "rejected" in mock_log.call_args[0][0].lower()
def test_validate_transcript_accepts_platform_native_path(tmp_path):
"""Validator accepts platform-native paths (backslashes on Windows, slashes on Unix)."""
session_file = tmp_path / "projects" / "abc123" / "session.jsonl"
session_file.parent.mkdir(parents=True)
session_file.touch()
# Use the OS-native string representation (backslashes on Windows)
result = _validate_transcript_path(str(session_file))
assert result is not None
assert result.suffix == ".jsonl"
assert result.is_file()
def test_stop_hook_rejects_injected_stop_hook_active(tmp_path):
"""stop_hook_active with shell injection string should not cause issues."""
transcript = tmp_path / "t.jsonl"