fix(prax): AIPL polyglot log leak — path resolver fix + regression tests (DPLAN-0125 Track G)

Root cause: get_module_logs_dir() last fallback unconditionally created
src/aipass/{name}/logs/ for any unknown module, causing external projects
(AIPL polyglot) running with AIPASS_HOME set to pollute the AIPass src tree
with src/aipass/unknown_branch/logs/*.

Fix (already committed in 3c5ac29):
- Check AIPASS_CALLER_CWD env var (set by drone during cross-project dispatch,
  DPLAN-0121) and walk up to the caller's project root (.git/pyproject.toml)
- Final fallback: system_logs/external/{module_name} — never create unknown
  dirs in the AIPass source tree
- Added inspect.stack() auto-detection when module_name is not provided
- Added _warn_routing() helper for lazy prax logger access (avoids circular
  imports — logger.py imports load.py at module level)

This PR:
- Regression tests: test_unknown_module_routes_to_system_logs_external and
  test_aipass_caller_cwd_routes_to_caller_project (both green)
- Cleanup: moved 27 leaked AIPL polyglot logs from src/aipass/unknown_branch/
  to /tmp/aipl_leaked_logs/ for AIPass Developer review; removed directory
- bypass.json: architecture + documentation exemptions for tests/test_config.py

CC @polyglot: AIPL-side logger config may need AIPASS_CALLER_CWD set during
cross-project dispatch so logs route to ~/Projects/AIPL/ correctly. The fix
is transparent if drone sets AIPASS_CALLER_CWD; no AIPL changes required for
the basic fix, but explicit env var support improves log placement accuracy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
AIOSAI
2026-04-14 13:28:06 -07:00
co-authored by Claude Sonnet 4.6
parent 2e41b75fe9
commit efc0056be8
2 changed files with 38 additions and 4 deletions
+11 -1
View File
@@ -3,9 +3,19 @@
"version": "2.0.0",
"created": "2026-03-07T22:43:24.315842",
"description": "Standards bypass configuration for prax branch",
"last_updated": "2026-03-24"
"last_updated": "2026-04-14"
},
"bypass": [
{
"file": "tests/test_config.py",
"standard": "documentation",
"reason": "Test functions follow pytest naming conventions (test_*). Docstrings on test functions are non-standard in this codebase — only new tests added in DPLAN-0125 Track G have them. Pre-existing 36 functions comply with project test style."
},
{
"file": "tests/test_config.py",
"standard": "architecture",
"reason": "Test files live in tests/ by convention, not in the 3-layer apps/ structure. This is a false positive for the test directory."
},
{
"file": "apps/modules/logger.py",
"standard": "cli",
+27 -3
View File
@@ -149,12 +149,36 @@ class TestGetModuleLogsDir:
assert result.name == "logs"
assert result.exists()
def test_creates_logs_dir_for_new_branch(self, mock_prax_infrastructure, monkeypatch, tmp_path):
def test_unknown_module_routes_to_system_logs_external(self, mock_prax_infrastructure, monkeypatch, tmp_path):
"""Unknown modules must NOT create dirs in ECOSYSTEM_ROOT (log-leak regression)."""
load_mod = _fresh_import_load(monkeypatch, tmp_path)
result = load_mod.get_module_logs_dir("newbranch")
monkeypatch.setattr(load_mod, "_find_repo_root", lambda: tmp_path)
monkeypatch.delenv("AIPASS_CALLER_CWD", raising=False)
result = load_mod.get_module_logs_dir("unknown_branch")
# Must route to system_logs/external/, NOT create src/aipass/unknown_branch/
assert result == tmp_path / "system_logs" / "external" / "unknown_branch"
assert result.exists()
assert result.is_dir()
assert result.name == "logs"
# Verify ECOSYSTEM_ROOT is not polluted
assert not (tmp_path / "unknown_branch").exists()
def test_aipass_caller_cwd_routes_to_caller_project(self, mock_prax_infrastructure, monkeypatch, tmp_path):
"""Regression: AIPASS_CALLER_CWD directs logs to caller project root, not ECOSYSTEM_ROOT."""
load_mod = _fresh_import_load(monkeypatch, tmp_path)
monkeypatch.setattr(load_mod, "_find_repo_root", lambda: tmp_path)
# Set up a mock caller project with a .git marker
caller_project = tmp_path / "caller_project"
caller_project.mkdir()
(caller_project / ".git").mkdir()
caller_cwd = str(caller_project / "src" / "polyglot")
monkeypatch.setenv("AIPASS_CALLER_CWD", caller_cwd)
result = load_mod.get_module_logs_dir("polyglot")
# Must resolve to caller project's logs/, not ECOSYSTEM_ROOT
assert result == caller_project / "logs" / "polyglot"
assert result.exists()
assert result.is_dir()
# ECOSYSTEM_ROOT must not be polluted
assert not (tmp_path / "polyglot").exists()
# =============================================