feat(system): S68 bonus: commons datetime deprecation fix + HERALD update (#163)

* feat(system): STATUS.md update

Co-Authored-By: @devpulse <devpulse@aipass>

* feat(system): S68 night shift: test log isolation + audit fixes (zero scanner output)

Co-Authored-By: @devpulse <devpulse@aipass>

* feat(system): S68 bonus: commons datetime deprecation fix + HERALD update

Co-Authored-By: @devpulse <devpulse@aipass>

---------

Co-authored-by: @devpulse <devpulse@aipass>
This commit is contained in:
AIPass
2026-03-31 16:27:13 -07:00
committed by GitHub
co-authored by @devpulse
parent c4377cc2e5
commit f2eefc3d39
24 changed files with 164 additions and 27 deletions
+8 -4
View File
@@ -2,7 +2,7 @@
> The living record. What happened, what's changing, what matters.
**Last updated:** 2026-03-31 | **Session:** 67 | **PRs merged:** 158
**Last updated:** 2026-03-31 | **Session:** 68 | **PRs merged:** 158 (PR #162 pending)
---
@@ -18,6 +18,9 @@
## Recent Sessions
### S68 — Night Shift: Zero Log Scanner Output (2026-03-31)
Autonomous night shift executed FPLAN-0161. Log scanner went from 981 errors / 1805 warnings / 2000 failures to absolute zero. Clean-slate approach: archived all logs, ran 15 branches fresh (3,425 tests, 0 failures), triaged — 100% of noise was test-generated. Built test log isolation system: AIPASS_TEST_LOG_DIR env var in 14 conftest.py files + prax config/load.py check. Fixed 4 audit items: api magic number + list_providers, trigger errors detail crash + branch_log_events help. PR #162. 22 files changed.
### S67 — Plan Cleanup, APLAN Template, Log Scanner (2026-03-31)
Major housekeeping session. Closed 8 devpulse root plans (DPLAN-0078/0080/0081/0083/0085/0088, FPLAN-0152/0154). Created APLAN (Audit Plan) template and registered with flow — standardized format with Quick Status table, Open/Resolved checkboxes, owner-split todos, Dispatch Log, and TTS Listen section. 15 agents reformatted all branch audits to the new standard simultaneously. System baseline established: 104 open items across 15 branches, 110 resolved. 4 GREEN (API, CLI, Daemon, Skills), 11 YELLOW, 0 RED. Built log_scanner_v1.py (tool #21) — scans all branch log directories for errors, warnings, and failures with Rich output. Full scan baseline: 981 errors, 1805 warnings, 2000 failures (mostly test-generated and stale). Investigated FPLAN auto-close gap — templates have the instruction but agents don't follow through. Strengthened close instruction in FPLAN template. Verified 20 potential night shift items — only 5 confirmed still open (api x2, backup x1, trigger x2). Backup audit updated from 18 to 12 open items after agent investigation confirmed 6 items already done. Deny rules expanded to catch cd && git bypass pattern. Local prompt updated with drone git workflow section. Night shift designed: DPLAN-0089 (clean-slate strategy) and FPLAN-0161 (8-phase master plan for zero-error goal). PR #158 merged.
@@ -52,14 +55,15 @@ Every branch, every standard, 100%. Seven agents deployed overnight. PR #137 (16
| Plan | Subject | Status |
|------|---------|--------|
| DPLAN-0089 | Night shift: system log cleanup design | Ready for execution |
| FPLAN-0161 | Night shift: 8-phase master plan | Ready for execution |
| DPLAN-0089 | Night shift: system log cleanup design | Complete |
| FPLAN-0161 | Night shift: 8-phase master plan | Phases 1-7 complete, PR #162 pending |
| 15 branch audits | Living docs (APLAN format) | 104 open, 110 resolved |
## Key Milestones
| Date | Milestone |
|------|-----------|
| 2026-03-31 | Zero log scanner output — test log isolation system built (S68 night shift) |
| 2026-03-31 | APLAN template — standardized branch audits across 15 branches |
| 2026-03-31 | Log scanner built — system-wide error/warning/failure visibility |
| 2026-03-31 | Night shift planned — 8-phase log cleanup for zero-error baseline |
@@ -89,7 +93,7 @@ Branches: 15
Standards: 32
Tests: 3,410+
PRs merged: 158
Sessions: 67
Sessions: 68
Compliance: 100%
Diagnostic tools: 21
Open audit items: 104
+1 -1
View File
@@ -2,7 +2,7 @@
> Auto-generated by `drone @prax status sync`. Do not edit manually.
**Last sync:** 2026-03-31 01:59
**Last sync:** 2026-03-31 03:57
**Summary:** 9 operational | 0 in-progress | 0 not started
---
+8 -1
View File
@@ -15,9 +15,16 @@
# =============================================
"""Shared pytest fixtures for ai_mail tests"""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
from unittest.mock import MagicMock
@@ -48,6 +48,7 @@ GENERATION_ENDPOINT = f"{OPENROUTER_BASE_URL}/generation"
# Default configuration values
DEFAULT_GENERATION_CHECK_DELAY = 2 # seconds to wait before querying metrics
DEFAULT_REQUEST_TIMEOUT = 30 # seconds for HTTP request timeout
# =============================================
@@ -148,7 +149,7 @@ def get_generation_metrics(generation_id: str, api_key: str) -> Optional[Dict[st
GENERATION_ENDPOINT,
params={"id": generation_id},
headers=headers,
timeout=30
timeout=DEFAULT_REQUEST_TIMEOUT
)
# Check response status
+4 -1
View File
@@ -140,10 +140,13 @@ def validate_key(args: List[str]):
def list_providers():
"""Orchestrate list providers workflow"""
from aipass.api.apps.handlers.config.provider import PROVIDER_DEFAULTS
header("Available Providers")
console.print()
console.print(" - openrouter")
for provider_name in sorted(PROVIDER_DEFAULTS):
console.print(f" - {provider_name}")
console.print()
+8
View File
@@ -16,6 +16,14 @@
# =============================================
"""Shared pytest fixtures for api tests"""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import importlib
import logging
import sys
+8 -1
View File
@@ -1,8 +1,15 @@
"""Shared pytest fixtures for backup branch tests."""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import pytest
import shutil
import sys
import tempfile
from collections.abc import Generator
from pathlib import Path
from unittest.mock import MagicMock
+7
View File
@@ -7,6 +7,13 @@
# =============================================
"""Shared pytest fixtures for CLI tests."""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import pytest
+8 -1
View File
@@ -15,9 +15,16 @@
#@Meta header not seedgo standards
"""Shared pytest fixtures for daemon tests"""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
from unittest.mock import MagicMock
+7 -1
View File
@@ -1,9 +1,15 @@
"""Shared pytest fixtures for drone tests."""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import json
import logging
import shutil
import tempfile
from pathlib import Path
from typing import Generator
from unittest.mock import MagicMock
+8 -1
View File
@@ -1,8 +1,15 @@
"""Shared pytest fixtures for flow tests"""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import pytest
import json
import shutil
import tempfile
from pathlib import Path
from typing import Generator
from unittest.mock import MagicMock, patch
+8 -1
View File
@@ -7,10 +7,17 @@
# =============================================
"""Shared pytest fixtures for memory tests."""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import json
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
from unittest.mock import MagicMock
@@ -29,6 +29,7 @@ Usage:
import json
import logging
import os
logger = logging.getLogger(__name__)
from pathlib import Path
from typing import Dict, Any
@@ -64,6 +65,11 @@ def get_system_logs_dir() -> Path:
Central aggregation: all branches log here for system-wide monitoring.
Per-module logs use get_module_logs_dir() for local debugging.
"""
test_log_dir = os.environ.get("AIPASS_TEST_LOG_DIR")
if test_log_dir:
p = Path(test_log_dir) / "system"
p.mkdir(parents=True, exist_ok=True)
return p
global _system_logs_dir_cache
if _system_logs_dir_cache is None:
repo_root = _find_repo_root()
@@ -87,6 +93,11 @@ def get_module_logs_dir(module_name: str) -> Path:
Returns:
Path to the module's branch-root logs directory
"""
test_log_dir = os.environ.get("AIPASS_TEST_LOG_DIR")
if test_log_dir:
p = Path(test_log_dir) / module_name
p.mkdir(parents=True, exist_ok=True)
return p
# Standard: src/aipass/{module}/logs
branch_dir = ECOSYSTEM_ROOT / module_name
if branch_dir.exists():
+7
View File
@@ -11,6 +11,13 @@
Provides infrastructure mocking so test modules can import prax code
without triggering real logging, file watching, or CLI dependencies.
"""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import sys
import pytest
+2
View File
@@ -49,6 +49,8 @@ def _fresh_import_load(monkeypatch, tmp_path):
monkeypatch.setattr(load_mod, "PRAX_LOGGER_CONFIG_FILE", prax_json_dir / "prax_logger_config.json")
# Reset the lazy cache so get_system_logs_dir() re-resolves
monkeypatch.setattr(load_mod, "_system_logs_dir_cache", None)
# Clear test log redirect so tests exercise real path resolution
monkeypatch.delenv("AIPASS_TEST_LOG_DIR", raising=False)
return load_mod
+8 -1
View File
@@ -8,9 +8,16 @@
# Modified: 2026-03-05
# =============================================
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
+7
View File
@@ -1,4 +1,11 @@
"""Shared test fixtures for spawn test suite."""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import json
import shutil
@@ -7,13 +7,18 @@
# =============================================
import json
import os
from pathlib import Path
from datetime import datetime, timezone
from typing import Dict, List, Any, Optional
import inspect
# Infrastructure
_LOG_FILE = Path(__file__).parent.parent.parent.parent / "logs" / "json_handler.log"
# Infrastructure — redirect to temp dir during tests
_test_log_dir = os.environ.get("AIPASS_TEST_LOG_DIR")
if _test_log_dir:
_LOG_FILE = Path(_test_log_dir) / "trigger" / "json_handler.log"
else:
_LOG_FILE = Path(__file__).parent.parent.parent.parent / "logs" / "json_handler.log"
def _log_warning(msg: str) -> None:
@@ -158,6 +158,11 @@ def handle_command(command: str, args: list) -> bool:
remaining = args[1:]
return handle_command(subcommand, remaining)
# Help gate — catch --help passed as direct command
if command in ['--help', '-h', 'help']:
print_help()
return True
# Handle direct subcommands
if command not in ["start", "stop", "status", "reset"]:
return False
+15 -6
View File
@@ -19,6 +19,7 @@ Phase 5: Suppress triggers source fix pipeline (email + fix status tracking)
Architecture: Module orchestrates, error_registry handler manages data
"""
import json
import sys
import time
from pathlib import Path
@@ -84,12 +85,15 @@ def _parse_args(args: list) -> dict:
def _find_by_id_or_fp(identifier: str) -> Optional[dict]:
"""Look up error by fingerprint (prefix ok) or short ID field."""
entry = get_entry(identifier)
if entry:
return entry
for entry in query(limit=1000):
if entry.get("id") == identifier:
try:
entry = get_entry(identifier)
if entry:
return entry
for entry in query(limit=1000):
if entry.get("id") == identifier:
return entry
except (json.JSONDecodeError, KeyError, TypeError) as exc:
logger.warning("Failed to look up error '%s': %s", identifier, exc)
return None
@@ -238,7 +242,12 @@ def _cmd_detail(console, args: list) -> bool:
error("Missing error ID or fingerprint", suggestion="Usage: drone @trigger errors detail <id_or_fingerprint>")
return True
entry = _find_by_id_or_fp(args[0])
try:
entry = _find_by_id_or_fp(args[0])
except (json.JSONDecodeError, TypeError, KeyError) as exc:
error(f"Failed to read error registry: {exc}", suggestion="Registry may be corrupted — try 'drone @trigger errors list' first")
return True
if not entry:
error(f"Error not found: {args[0]}", suggestion="Try a fingerprint prefix, full fingerprint, or short ID")
return True
+8 -1
View File
@@ -14,9 +14,16 @@
# =============================================
"""Shared pytest fixtures for cortex tests"""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import pytest
import shutil
import tempfile
from pathlib import Path
from typing import Generator
+3 -3
View File
@@ -13,7 +13,7 @@ Data retrieval and mutation for spatial room commands: enter, look, decorate, vi
Returns structured dicts for module-layer rendering.
"""
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Dict, Any
from aipass.prax.apps.modules.logger import system_logger as logger
@@ -52,7 +52,7 @@ def get_room_enter_data(room_name: str) -> Dict[str, Any]:
"SELECT COUNT(*) FROM posts WHERE room_name = ?", (room_name,)
).fetchone()[0]
cutoff = (datetime.utcnow() - timedelta(hours=48)).strftime("%Y-%m-%dT%H:%M:%SZ")
cutoff = (datetime.now(timezone.utc) - timedelta(hours=48)).strftime("%Y-%m-%dT%H:%M:%SZ")
recent_count = conn.execute(
"SELECT COUNT(*) FROM posts WHERE room_name = ? AND created_at > ?",
(room_name, cutoff),
@@ -205,7 +205,7 @@ def get_visitors_data(room_name: str) -> Dict[str, Any]:
result["error"] = f"Room '{room_name}' not found"
return result
cutoff = (datetime.utcnow() - timedelta(hours=48)).strftime("%Y-%m-%dT%H:%M:%SZ")
cutoff = (datetime.now(timezone.utc) - timedelta(hours=48)).strftime("%Y-%m-%dT%H:%M:%SZ")
# Primary source: explicit room visits
visit_rows = conn.execute(
+7 -1
View File
@@ -19,8 +19,14 @@ The Commons - Test Configuration
Provides pytest fixtures for database setup, teardown,
and test isolation using temporary databases.
"""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
from pathlib import Path
import pytest
+7
View File
@@ -15,6 +15,13 @@
# =============================================
"""Skills test configuration."""
import os
import tempfile
# Redirect prax logs to temp directory during tests
# Must be set before any prax imports to catch logger initialization
if "AIPASS_TEST_LOG_DIR" not in os.environ:
os.environ["AIPASS_TEST_LOG_DIR"] = tempfile.mkdtemp(prefix="aipass_test_logs_")
import importlib
import logging