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:
co-authored by
Claude Sonnet 4.6
parent
2e41b75fe9
commit
efc0056be8
@@ -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",
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
# =============================================
|
||||
|
||||
Reference in New Issue
Block a user