Merge pull request #61 from AIOSAI/feat/seedgo-standards-overhaul-session18

feat(seedgo): standards overhaul — meta AUDIT_SCOPE, JSON structure redesign, log two-tier
This commit is contained in:
AIPass
2026-03-17 00:47:26 -07:00
committed by GitHub
6 changed files with 345 additions and 262 deletions
@@ -1,26 +1,34 @@
# =================== AIPass ====================
# Name: json_structure_check.py
# Description: JSON Structure Standards Checker Handler
# Version: 2.0.0
# Version: 3.0.0
# Created: 2026-03-05
# Modified: 2026-03-05
# Modified: 2026-03-17
# =============================================
"""
JSON Structure Standards Checker Handler
Validates JSON handling patterns for pip packages:
- json_handler.py uses relative paths (not hardcoded absolute)
- Modules use json_handler for JSON operations (not direct json.load/dump)
- Branch detection via AIPASS_REGISTRY.json and BRANCH_REGISTRY.json
Validates three-JSON code wiring in modules and handlers.
For every .py file in apps/modules/ and apps/handlers/:
1. Must import json_handler from the branch's handlers/json package
2. Must call json_handler.log_operation() at least once
For json_handler.py itself (in a json/ directory):
- Validates handler config (relative paths, no hardcoded absolutes)
Entry points and other files outside modules/handlers are skipped.
"""
import re
import ast
import json
from pathlib import Path
from typing import Dict, List, Optional
# Audit scope: scan every .py file, not just entry point
AUDIT_SCOPE = "all_files"
def is_bypassed(file_path: str, standard: str, line: int | None = None, bypass_rules: list | None = None) -> bool:
"""Check if a violation should be bypassed"""
@@ -45,14 +53,29 @@ def check_module(module_path: str, bypass_rules: list | None = None) -> Dict:
"""
Check if module follows JSON structure standards.
For pip packages, validates:
1. json_handler.py uses relative paths (Path(__file__).resolve().parent)
2. json_handler.py does NOT use hardcoded absolute paths (BRANCH_ROOT, Path.home())
3. Modules use json_handler instead of direct json.load/dump
Routing:
a. json_handler.py in a json/ dir -> validate handler config
b. File in apps/modules/ -> check code wiring
c. File in apps/handlers/ -> check code wiring
d. Everything else (entry points) -> skip (not applicable)
Args:
module_path: Path to Python module to check
bypass_rules: Optional bypass rules
Returns:
dict with passed, checks, score, standard keys
"""
checks = []
path = Path(module_path)
if is_bypassed(module_path, 'json_structure', bypass_rules=bypass_rules):
return {
'passed': True,
'checks': [{'name': 'Bypassed', 'passed': True, 'message': 'Standard bypassed via .seedgo/bypass.json'}],
'score': 100,
'standard': 'JSON STRUCTURE'
}
if not path.exists():
return {
'passed': False,
@@ -61,9 +84,17 @@ def check_module(module_path: str, bypass_rules: list | None = None) -> Dict:
'standard': 'JSON STRUCTURE'
}
# Skip __init__.py files
if path.name == '__init__.py':
return {
'passed': True,
'checks': [{'name': 'JSON structure check', 'passed': True, 'message': '__init__.py file (skipped)'}],
'score': 100,
'standard': 'JSON STRUCTURE'
}
try:
with open(path, 'r', encoding='utf-8') as f:
content = f.read()
content = path.read_text(encoding='utf-8')
except Exception as e:
return {
'passed': False,
@@ -72,36 +103,166 @@ def check_module(module_path: str, bypass_rules: list | None = None) -> Dict:
'standard': 'JSON STRUCTURE'
}
if 'json_handler' in path.name and path.parent.name == 'json':
checks = check_json_handler_config(path, content, bypass_rules)
elif 'apps/modules' in str(path):
checks = check_module_json_files(path, content, bypass_rules)
path_str = str(path)
if not checks:
# --- Case (a): json_handler.py in a json/ directory ---
if 'json_handler' in path.name and path.parent.name == 'json':
checks = _check_json_handler_config(path, content, bypass_rules)
passed_count = sum(1 for c in checks if c['passed'])
total = len(checks)
score = int((passed_count / total * 100)) if total > 0 else 0
return {
'passed': score >= 75,
'checks': checks,
'score': score,
'standard': 'JSON STRUCTURE'
}
# --- Determine if the file is in modules/ or handlers/ ---
in_modules = 'apps/modules' in path_str or 'apps\\modules' in path_str
in_handlers = 'apps/handlers' in path_str or 'apps\\handlers' in path_str
# Exclude files inside the json/ handler directory itself (they ARE the
# json infrastructure, not consumers of it)
if in_handlers and path.parent.name == 'json':
return {
'passed': True,
'checks': [{'name': 'JSON structure check', 'passed': True, 'message': 'No JSON operations detected (skipped)'}],
'checks': [{'name': 'JSON structure check', 'passed': True,
'message': 'JSON handler infrastructure file (not applicable)'}],
'score': 100,
'standard': 'JSON STRUCTURE'
}
passed_checks = sum(1 for check in checks if check['passed'])
total_checks = len(checks)
score = int((passed_checks / total_checks * 100)) if total_checks > 0 else 0
overall_passed = score >= 75
# --- Cases (b) and (c): code wiring check ---
if in_modules or in_handlers:
checks = _check_code_wiring(path, content)
passed_count = sum(1 for c in checks if c['passed'])
total = len(checks)
score = int((passed_count / total * 100)) if total > 0 else 0
return {
'passed': passed_count == total,
'checks': checks,
'score': score,
'standard': 'JSON STRUCTURE'
}
# --- Case (d): file outside modules/ and handlers/ (entry point, etc.) ---
return {
'passed': overall_passed,
'checks': checks,
'score': score,
'passed': True,
'checks': [{'name': 'JSON structure check', 'passed': True,
'message': 'Not in modules/ or handlers/ (not applicable)'}],
'score': 100,
'standard': 'JSON STRUCTURE'
}
# ------------------------------------------------------------------
# Internal helpers
# ------------------------------------------------------------------
def _check_code_wiring(_path: Path, content: str) -> List[Dict]:
"""
Check that a module/handler file has the three-JSON wiring:
1. Imports json_handler
2. Calls json_handler.log_operation()
Returns a list of two check dicts.
"""
checks: List[Dict] = []
# Check 1: imports json_handler
# Matches patterns like:
# from aipass.seedgo.apps.handlers.json import json_handler
# from aipass.flow.apps.handlers.json import json_handler
# from ...handlers.json import json_handler
has_import = bool(
re.search(r'from\s+\S*\.json\s+import\s+json_handler', content)
or re.search(r'from\s+\S*json\s+import\s+json_handler', content)
or re.search(r'import\s+json_handler', content)
)
checks.append({
'name': 'json_handler import',
'passed': has_import,
'message': 'Imports json_handler' if has_import
else 'Missing json_handler import — add: from aipass.<branch>.apps.handlers.json import json_handler'
})
# Check 2: calls json_handler.log_operation()
has_log_operation = 'json_handler.log_operation' in content
checks.append({
'name': 'log_operation call',
'passed': has_log_operation,
'message': 'Calls json_handler.log_operation()' if has_log_operation
else 'Missing json_handler.log_operation() call — every module/handler must log operations'
})
return checks
def _check_json_handler_config(_handler_path: Path, content: str, _bypass_rules: list | None = None) -> List[Dict]:
"""
Check json_handler.py for library profile.
For pip packages:
- PASS if using relative paths (Path(__file__).resolve().parent)
- FAIL if using hardcoded absolute paths (Path.home(), BRANCH_ROOT, etc.)
"""
checks: List[Dict] = []
# Check 1: No hardcoded absolute paths
has_path_home = bool(re.search(r'Path\.home\(\)', content))
# Only flag _ROOT constants that use Path.home() (legacy pattern)
# Allow _ROOT = Path(__file__).resolve()... (relative, pip-safe)
has_branch_root = False
for line in content.split('\n'):
stripped = line.strip()
if stripped.startswith('#'):
continue
if re.search(r'\w+_ROOT\s*=', stripped) and 'Path.home()' in stripped:
has_branch_root = True
break
if has_path_home or has_branch_root:
issues = []
if has_path_home:
issues.append('Path.home()')
if has_branch_root:
issues.append('hardcoded _ROOT constant')
checks.append({
'name': 'No absolute paths',
'passed': False,
'message': f'Found {", ".join(issues)} — pip packages should use relative paths'
})
else:
checks.append({
'name': 'No absolute paths',
'passed': True,
'message': 'No hardcoded absolute paths (correct for pip packages)'
})
# Check 2: Uses relative path resolution
has_relative = bool(re.search(r'Path\(__file__\)', content)
or re.search(r'\.resolve\(\)', content)
or re.search(r'\.parent', content))
checks.append({
'name': 'Relative path resolution',
'passed': has_relative,
'message': 'Uses relative path resolution (Path(__file__).parent)' if has_relative
else 'Missing relative path resolution — should use Path(__file__).resolve().parent'
})
return checks
# ------------------------------------------------------------------
# Utility functions (used by other code in the audit system)
# ------------------------------------------------------------------
def _find_registry() -> Path:
"""Find AIPASS_REGISTRY.json by walking up from this file's location."""
current = Path(__file__).resolve().parent
for parent in [current] + list(current.parents):
for parent in [current, *list(current.parents)]:
candidate = parent / "AIPASS_REGISTRY.json"
if candidate.exists():
return candidate
@@ -169,123 +330,3 @@ def get_branch_path(branch_name: str) -> Optional[str]:
pass
return None
def check_json_handler_config(handler_path: Path, content: str, bypass_rules: list | None = None) -> List[Dict]: # noqa: ARG001
"""
Check json_handler.py for library profile.
For pip packages:
- PASS if using relative paths (Path(__file__).resolve().parent, etc.)
- FAIL if using hardcoded absolute paths (Path.home(), BRANCH_ROOT, etc.)
"""
checks = []
# Check 1: No hardcoded absolute paths
has_path_home = bool(re.search(r'Path\.home\(\)', content))
# Only flag _ROOT constants that use Path.home() (legacy pattern)
# Allow _ROOT = Path(__file__).resolve()... (relative, pip-safe)
has_branch_root = False
for line in content.split('\n'):
stripped = line.strip()
if stripped.startswith('#'):
continue
if re.search(r'\w+_ROOT\s*=', stripped) and 'Path.home()' in stripped:
has_branch_root = True
break
if has_path_home or has_branch_root:
issues = []
if has_path_home:
issues.append('Path.home()')
if has_branch_root:
issues.append('hardcoded _ROOT constant')
checks.append({
'name': 'No absolute paths',
'passed': False,
'message': f'Found {", ".join(issues)} — pip packages should use relative paths'
})
else:
checks.append({
'name': 'No absolute paths',
'passed': True,
'message': 'No hardcoded absolute paths (correct for pip packages)'
})
# Check 2: Uses relative path resolution
has_relative = bool(re.search(r'Path\(__file__\)', content) or
re.search(r'\.resolve\(\)', content) or
re.search(r'\.parent', content))
checks.append({
'name': 'Relative path resolution',
'passed': has_relative,
'message': 'Uses relative path resolution (Path(__file__).parent)' if has_relative
else 'Missing relative path resolution — should use Path(__file__).resolve().parent'
})
return checks
def check_module_json_files(module_path: Path, content: str, bypass_rules: list | None = None) -> List[Dict]:
"""
Check if module uses json_handler for JSON operations.
For library profile, just validates json_handler usage pattern.
"""
checks = []
uses_json_handler = 'json_handler' in content and ('from' in content or 'import' in content)
if not uses_json_handler:
json_check = check_json_handler_usage(content, str(module_path), bypass_rules)
if json_check:
checks.append(json_check)
return checks
# Module uses json_handler — that's correct
checks.append({
'name': 'json_handler usage',
'passed': True,
'message': 'Module uses json_handler for JSON operations'
})
return checks
def check_json_handler_usage(content: str, file_path: str, bypass_rules: list | None = None) -> Optional[Dict]:
"""
Check that modules use json_handler for JSON operations (not direct json.load/dump).
"""
try:
tree = ast.parse(content)
except SyntaxError:
return None
has_json_operations = False
has_json_handler_import = False
for node in ast.walk(tree):
if isinstance(node, ast.ImportFrom):
if node.module and 'json_handler' in node.module:
has_json_handler_import = True
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Attribute):
if (isinstance(node.func.value, ast.Name) and
node.func.value.id == 'json' and
node.func.attr in ['dump', 'load']):
has_json_operations = True
if not has_json_operations:
return None
if has_json_operations and not has_json_handler_import:
if is_bypassed(file_path, 'json_structure', bypass_rules=bypass_rules):
return None
return {
'name': 'json_handler usage',
'passed': False,
'message': 'Direct JSON operations detected (use json_handler for structured JSON management)'
}
return None
@@ -1,9 +1,9 @@
# =================== AIPass ====================
# Name: json_structure_content.py
# Description: JSON Structure Standards Content Handler
# Version: 1.0.0
# Version: 2.0.0
# Created: 2026-03-05
# Modified: 2026-03-05
# Modified: 2026-03-17
# =============================================
"""
@@ -13,74 +13,118 @@ Provides formatted JSON structure standards content.
Module orchestrates, handler implements.
"""
def get_json_structure_standards() -> str:
"""Return formatted JSON structure standards content with Rich markup
"""Return formatted JSON structure standards content with Rich markup.
Returns:
str: Formatted standards text with Rich styling
"""
lines = [
"[bold red]JSON STRUCTURE STANDARD[/bold red]",
"",
"[bold cyan]CORE PRINCIPLE:[/bold cyan] Operational JSON Output",
"",
"[yellow]RULE:[/yellow] Every module and handler produces operational JSON",
" output via json_handler. The CODE PATTERN is the standard --",
" not JSON file templates. Files auto-create on first use.",
"",
"─" * 70,
"",
"[bold cyan]THREE-JSON PATTERN:[/bold cyan]",
"",
"[bold]Every module gets 3 auto-created files:[/bold]",
" • [yellow]module_config.json[/yellow] - Settings, limits (small, stable)",
" • [yellow]module_data.json[/yellow] - Metrics, state (medium, periodic)",
" • [yellow]module_log.json[/yellow] - Operations history (auto-rotating)",
" Every module/handler gets 3 auto-created files:",
" [yellow]config.json[/yellow] - Settings, limits (small, stable)",
" [yellow]data.json[/yellow] - Metrics, state (medium, periodic)",
" [yellow]log.json[/yellow] - Operations history (auto-rotating)",
"",
"[yellow]RULE:[/yellow] Auto-created on first use - NEVER create manually",
" [bold]Location:[/bold] All JSON goes to [green]{branch}_json/[/green] at branch root",
" [dim]src/aipass/{branch}/{branch}_json/[/dim]",
" One directory, no splits.",
"",
"[bold cyan]USAGE (AUTO-DETECTION):[/bold cyan]",
" [dim]from aipass.seedgo.apps.handlers.json import json_handler[/dim]",
"─" * 70,
"",
" [dim]# Handler auto-detects calling module name:[/dim]",
" [dim]json_handler.log_operation(\"operation_name\", {\"key\": \"value\"})[/dim]",
"[bold cyan]REQUIRED CODE WIRING:[/bold cyan]",
"",
" [dim]# Creates module_config.json, module_data.json, module_log.json[/dim]",
" [dim]# Based on templates in apps/json_templates/default/[/dim]",
" This is the standard. This is what agents copy.",
"",
" [dim]from aipass.{branch}.apps.handlers.json import json_handler[/dim]",
"",
" [dim]# At end of main operations:[/dim]",
" [dim]json_handler.log_operation(\"operation_name\", {[/dim]",
" [dim] \"key\": \"value\",[/dim]",
" [dim] \"success\": True[/dim]",
" [dim]})[/dim]",
"",
" [bold]Example (flow branch):[/bold]",
" [dim]from aipass.flow.apps.handlers.json import json_handler[/dim]",
"",
" [dim]json_handler.log_operation(\"plan_created\", {[/dim]",
" [dim] \"command\": command,[/dim]",
" [dim] \"args\": args[/dim]",
" [dim]})[/dim]",
"",
" [yellow]Both the import AND the log_operation call are required.[/yellow]",
"",
"─" * 70,
"",
"[bold cyan]json_handler.py SETUP:[/bold cyan]",
"",
" Auto-detects branch via [dim]Path(__file__)[/dim]. Universal across branches:",
"",
" [dim]_BRANCH_ROOT = Path(__file__).resolve().parents[3][/dim]",
" [dim]_BRANCH_NAME = _BRANCH_ROOT.name[/dim]",
" [dim]JSON_DIR = _BRANCH_ROOT / f\"{_BRANCH_NAME}_json\"[/dim]",
"",
" [green]No per-branch customization needed.[/green]",
" Spawn ships the template, branches just copy it.",
"",
"─" * 70,
"",
"[bold cyan]SCORING:[/bold cyan]",
"",
" [bold]2 checks per module/handler:[/bold]",
" 1. [dim]json_handler[/dim] import present",
" 2. [dim]log_operation()[/dim] call present",
"",
" Both must pass. Score = compliant files / total files * 100",
"",
"─" * 70,
"",
"[bold cyan]WHAT'S CHECKED:[/bold cyan]",
"",
" [green]Checked:[/green]",
" [green]+[/green] Modules: [dim]apps/modules/*.py[/dim]",
" [green]+[/green] Handlers: [dim]apps/handlers/**/*.py[/dim]",
"",
" [red]Skipped:[/red]",
" [red]-[/red] [dim]__init__.py[/dim] files (structural, not functional)",
" [red]-[/red] Entry points (not required to wire JSON)",
" [red]-[/red] [dim]json_handler.py[/dim] itself (checked for path validation only)",
"",
"─" * 70,
"",
"[bold cyan]LOG ROTATION:[/bold cyan]",
"",
" Set [dim]max_log_entries[/dim] in config.json.",
" Handler auto-rotates when limit reached (FIFO).",
" Keeps most recent N entries.",
"",
"[bold cyan]LOG ROTATION (CRITICAL):[/bold cyan]",
" Set in config.json:",
" [dim]{[/dim]",
" [dim]\"config\": { \"max_log_entries\": 100 }[/dim]",
" [dim] \"config\": { \"max_log_entries\": 100 }[/dim]",
" [dim]}[/dim]",
"",
" • Handler auto-rotates when limit reached",
" • Keeps most recent N entries (FIFO)",
" • [yellow]⚠️ Prevents log explosion (drone logs hit 171KB/7001 entries)[/yellow]",
"─" * 70,
"",
"[bold cyan]LOG STRUCTURE:[/bold cyan]",
" Array of entries (NOT object with \"entries\" key):",
" [dim][[/dim]",
" [dim]{ \"timestamp\": \"...\", \"operation\": \"...\", \"data\": {...} }[/dim]",
" [dim]][/dim]",
"",
"[bold cyan]LOCATIONS:[/bold cyan]",
" • Package JSON: [dim]src/aipass/{module}/aipass_json/[/dim]",
" • Per-module: [dim]src/aipass/{module}/{module}_json/[/dim]",
"",
"[bold red]SETUP json_handler.py (MANDATORY):[/bold red]",
" [red]✗ DO NOT copy seedgo's handler without changing paths![/red]",
"",
" [green]✓ Update BRANCH_ROOT:[/green]",
" [dim]{BRANCH}_ROOT = Path(__file__).resolve().parents[N][/dim]",
"",
" [green]✓ Update JSON_DIR:[/green]",
" [dim]{BRANCH}_JSON_DIR = {BRANCH}_ROOT / \"{branch}_json\"[/dim]",
"",
" [green]✓ Update TEMPLATES_DIR:[/green]",
" [dim]JSON_TEMPLATES_DIR = {BRANCH}_ROOT / \"apps\" / \"json_templates\"[/dim]",
"",
" [yellow]Validate:[/yellow] Run standards checker on json_handler.py",
" [dim]Expected: 100/100 on JSON STRUCTURE standard[/dim]",
"",
"[bold cyan]SPECIAL JSONS:[/bold cyan]",
" • [bold]Registries:[/bold] Collections (AIPASS_REGISTRY.json)",
" • [bold]Custom:[/bold] Module-specific needs (no limit)",
" • [dim]Not part of three-JSON pattern[/dim]",
"[bold cyan]KEY WARNINGS:[/bold cyan]",
" [yellow]![/yellow] The CODE PATTERN is the template -- no json_templates/ directory",
" [yellow]![/yellow] JSON files auto-create on first log_operation() call",
" [yellow]![/yellow] Never create JSON files manually",
" [yellow]![/yellow] Both import AND log_operation required for compliance",
"",
"[bold cyan]REFERENCE:[/bold cyan]",
" [dim]See: seedgo standards pack (json_structure)[/dim]",
" [dim]See: src/aipass/seedgo/apps/standards/aipass/handlers/json/json_handler.py[/dim]",
" [dim]See: FPLAN-0056 (Three-JSON Pattern Redesign)[/dim]",
]
return "\n".join(lines)
@@ -1,16 +1,18 @@
# =================== AIPass ====================
# Name: log_structure_check.py
# Description: Log Structure Standards Checker Handler
# Version: 1.1.0
# Version: 1.2.0
# Created: 2026-03-06
# Modified: 2026-03-08
# Modified: 2026-03-17
# =============================================
"""
Log Structure Standards Checker Handler
Validates that AIPass modules follow hierarchical log placement:
every directory containing .py code should have a sibling logs/ directory.
Validates the two-tier logging model:
- system_logs/ at repo root (system-wide)
- logs/ at branch root only (per-branch)
No hierarchical logs/ at every nested directory.
No hardcoded absolute log paths.
"""
@@ -37,10 +39,10 @@ def is_bypassed(file_path: str, standard: str, bypass_rules: list | None = None)
def check_module(module_path: str, bypass_rules: list | None = None) -> Dict:
"""
Check module logging structure with hierarchical placement validation.
Check module logging structure against the two-tier model.
Checks:
1. Parent directory of file has a sibling logs/ directory (hierarchical placement)
1. logs/ directory exists at branch root (entry file's parent)
2. No hardcoded absolute log paths in source
3. No /home/ references in logging configuration
@@ -70,16 +72,16 @@ def check_module(module_path: str, bypass_rules: list | None = None) -> Dict:
'standard': 'LOG_STRUCTURE'
}
# Check 1: Hierarchical log placement — logs/ directory at the same level as the file
parent_dir = path.parent
logs_dir = parent_dir / "logs"
# Check 1: Branch-root log placement — logs/ directory at the branch root
branch_root = path.parent
logs_dir = branch_root / "logs"
has_logs_dir = logs_dir.is_dir()
checks.append({
'name': 'Hierarchical logs/ directory',
'name': 'Branch-root logs/ directory',
'passed': has_logs_dir,
'message': f'logs/ directory exists at {parent_dir}/'
'message': f'logs/ directory exists at branch root {branch_root}/'
if has_logs_dir
else f'Missing logs/ directory at {parent_dir}/ — hierarchical placement requires logs/ at every code level'
else f'Missing logs/ directory at branch root {branch_root}/ — two-tier model requires logs/ at branch root'
})
# Check 2-3: Scan file for hardcoded log paths
@@ -1,62 +1,57 @@
# =================== AIPass ====================
# Name: log_structure_content.py
# Description: Log Structure Standards Content Handler
# Version: 1.1.0
# Version: 1.2.0
# Created: 2026-03-06
# Modified: 2026-03-08
# Modified: 2026-03-17
# =============================================
"""
Log Structure Standards Content Handler
Provides formatted display of log structure standards for terminal output.
Describes the hierarchical log placement model where every directory
containing .py code has a sibling logs/ directory.
Describes the two-tier logging model: system_logs/ at repo root,
logs/ at branch root only.
"""
def get_log_structure_standards() -> str:
"""Return formatted log structure standards for display."""
lines = [
"[bold red]HIERARCHICAL LOG STRUCTURE[/bold red]",
"[bold red]TWO-TIER LOG STRUCTURE[/bold red]",
"",
"[yellow]CORE PRINCIPLE:[/yellow] Logs live where the code lives — every directory",
" containing .py files should have a sibling [bold]logs/[/bold] directory",
"[yellow]CORE PRINCIPLE:[/yellow] Two tiers, two locations. System-wide logs aggregate",
" at repo root; per-branch logs live at the branch root only.",
"",
"[bold cyan]DUAL LOGGING MODEL:[/bold cyan]",
" [green]1.[/green] [bold]system_logs/[/bold] at repo root — central aggregation ({branch}_{module}.log)",
" [green]2.[/green] [bold]logs/[/bold] at every code level — hierarchical local placement",
"[bold cyan]TWO-TIER MODEL:[/bold cyan]",
" [green]1.[/green] [bold]system_logs/[/bold] at repo root — system-wide aggregation ({branch}_{module}.log)",
" [green]2.[/green] [bold]logs/[/bold] at branch root — per-branch local logs",
"",
"[bold cyan]REQUIREMENTS:[/bold cyan]",
" [green]1.[/green] Every directory with .py files has a sibling [bold]logs/[/bold] directory",
" [green]1.[/green] [bold]logs/[/bold] directory exists at the branch root",
" [green]2.[/green] No hardcoded absolute paths to .log files",
" [green]3.[/green] No /home/ references in logging configuration",
"",
"[bold cyan]HIERARCHICAL DIRECTORY PATTERN:[/bold cyan]",
" [dim]src/aipass/{branch}/[/dim]",
" [dim] logs/ <-- branch root logs[/dim]",
" [dim] apps/[/dim]",
" [dim] logs/ <-- entry point level[/dim]",
" [dim] modules/[/dim]",
" [dim] logs/ <-- module level[/dim]",
" [dim] handlers/[/dim]",
" [dim] logs/ <-- handler root[/dim]",
" [dim] dispatch/[/dim]",
" [dim] logs/ <-- sub-handler level[/dim]",
" [dim] email/[/dim]",
" [dim] logs/ <-- sub-handler level[/dim]",
"[bold cyan]DIRECTORY LAYOUT:[/bold cyan]",
" [dim]repo_root/[/dim]",
" [dim] system_logs/ <-- system-wide logs[/dim]",
" [dim] src/aipass/{branch}/[/dim]",
" [dim] logs/ <-- branch-level logs (only here)[/dim]",
" [dim] apps/[/dim]",
" [dim] handlers/[/dim]",
" [dim] modules/[/dim]",
"",
"[bold cyan]LOG PATH PATTERN:[/bold cyan]",
" [green]CORRECT:[/green] Use prax's system_logger (auto-routes to correct location)",
" [green]CORRECT:[/green] Use prax's system_logger (auto-routes to correct tier)",
" [dim] from aipass.prax.apps.modules.logger import system_logger[/dim]",
" [dim] system_logger.info('message') # prax handles hierarchical placement[/dim]",
" [dim] system_logger.info('message') # prax handles tier routing[/dim]",
"",
" [green]ALSO OK:[/green] Manual relative path to sibling logs/",
" [dim] LOG_DIR = Path(__file__).resolve().parent / 'logs'[/dim]",
" [green]ALSO OK:[/green] Relative path to branch-root logs/",
" [dim] LOG_DIR = Path(__file__).resolve().parents[2] / 'logs'[/dim]",
" [dim] log_path = LOG_DIR / 'my_handler.log'[/dim]",
"",
" [red]WRONG:[/red] All logs dumped at branch root only",
" [dim] LOG_DIR = Path(__file__).resolve().parents[3] / 'logs'[/dim]",
" [dim] # All handlers write to branch/logs/ — no hierarchy[/dim]",
" [red]WRONG:[/red] logs/ at nested directories (old hierarchical pattern)",
" [dim] LOG_DIR = Path(__file__).resolve().parent / 'logs'[/dim]",
" [dim] # Creates logs/ inside handlers/ or modules/ — not two-tier[/dim]",
"",
" [red]WRONG:[/red] Hardcoded absolute paths",
" [dim] path = '/absolute/path/to/system_logs/module.log'[/dim]",
@@ -64,6 +59,5 @@ def get_log_structure_standards() -> str:
"",
"[bold cyan]REFERENCE:[/bold cyan]",
" [dim]Prax logger: src/aipass/prax/apps/modules/logger.py[/dim]",
" [dim]Hierarchical resolver: src/aipass/prax/apps/handlers/config/load.py[/dim]",
]
return "\n".join(lines)
@@ -1,9 +1,9 @@
# =================== AIPass ====================
# Name: meta_check.py
# Description: META Block Standards Checker Handler
# Version: 1.1.0
# Version: 1.2.0
# Created: 2026-03-05
# Modified: 2026-03-08
# Modified: 2026-03-16
# =============================================
"""
@@ -30,6 +30,7 @@ import re
from pathlib import Path
from typing import Dict, List
AUDIT_SCOPE = "all_files"
# Header/footer markers for library META
# Accept both AIPass (canonical) and META (legacy) header markers
@@ -1,21 +1,21 @@
# =================== AIPass ====================
# Name: json_handler.py
# Description: Json Handler
# Version: 1.0.0
# Description: Auto-Creating JSON Handler
# Version: 1.1.0
# Created: 2026-03-05
# Modified: 2026-03-05
# Modified: 2026-03-17
# =============================================
import json
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Any, Optional
import sys
from typing import Dict, Any, Optional
import inspect
PACK_ROOT = Path(__file__).resolve().parent.parent.parent # json/ -> handlers/ -> aipass/
SEEDGO_JSON_DIR = PACK_ROOT / "aipass_json"
JSON_TEMPLATES_DIR = PACK_ROOT / "json_templates"
_BRANCH_ROOT = Path(__file__).resolve().parents[3] # json/ -> handlers/ -> apps/ -> {branch}/
_BRANCH_NAME = _BRANCH_ROOT.name
JSON_DIR = _BRANCH_ROOT / f"{_BRANCH_NAME}_json"
JSON_TEMPLATES_DIR = _BRANCH_ROOT / "apps" / "json_templates"
def _get_caller_module_name() -> str:
@@ -82,12 +82,12 @@ def validate_json_structure(data: Any, json_type: str) -> bool:
def get_json_path(module_name: str, json_type: str) -> Path:
"""Get path for module JSON file"""
filename = f"{module_name}_{json_type}.json"
return SEEDGO_JSON_DIR / filename
return JSON_DIR / filename
def ensure_json_exists(module_name: str, json_type: str) -> bool:
"""Ensure JSON file exists, create from template if missing"""
SEEDGO_JSON_DIR.mkdir(parents=True, exist_ok=True)
JSON_DIR.mkdir(parents=True, exist_ok=True)
json_path = get_json_path(module_name, json_type)
@@ -238,16 +238,17 @@ if __name__ == "__main__":
border_style="bright_blue"
))
console.print()
console.print("[yellow]TESTING:[/yellow] Creating seedgo JSONs...")
console.print(f"[yellow]TESTING:[/yellow] Creating {_BRANCH_NAME} JSONs...")
console.print(f"[dim]JSON_DIR: {JSON_DIR}[/dim]")
# Test auto-creation
log_operation("test_operation", {"test": "data"}, "seedgo")
increment_counter("seedgo", "test_counter", 1)
update_data_metrics("seedgo", test_metric="working")
log_operation("test_operation", {"test": "data"}, _BRANCH_NAME)
increment_counter(_BRANCH_NAME, "test_counter", 1)
update_data_metrics(_BRANCH_NAME, test_metric="working")
console.print()
console.print("[green]Check aipass_json/ directory for created files:[/green]")
console.print(" [dim]•[/dim] seedgo_config.json")
console.print(" [dim]•[/dim] seedgo_data.json")
console.print(" [dim]•[/dim] seedgo_log.json")
console.print(f"[green]Check {JSON_DIR.relative_to(_BRANCH_ROOT)}/ for created files:[/green]")
console.print(f" [dim]•[/dim] {_BRANCH_NAME}_config.json")
console.print(f" [dim]•[/dim] {_BRANCH_NAME}_data.json")
console.print(f" [dim]•[/dim] {_BRANCH_NAME}_log.json")
console.print()