Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
98fe151
refactor: reduce codebase complexity across events, observers, and go…
ElNiak Mar 13, 2026
c146cec
refactor: reduce complexity via integration wiring, dead code removal…
ElNiak Mar 16, 2026
4504238
feat(logging): add structured JSONL logging foundation
ElNiak Mar 16, 2026
34c15e5
feat(observability): add log context propagation and EventStreamRecorder
ElNiak Mar 16, 2026
9e22095
fix: remove unused imports in event_stream_recorder
ElNiak Mar 16, 2026
ebaf366
feat(cli): add log query engine and `panther logs` CLI commands
ElNiak Mar 16, 2026
5cfaa55
feat(outputs): add OutputIndexBuilder for experiment artifact manifest
ElNiak Mar 16, 2026
a67b0c0
feat(cli): add timeline renderer, artifact browser, and report subcom…
ElNiak Mar 16, 2026
7e32dc3
feat(reporting): add root cause analysis engine with failure pattern …
ElNiak Mar 16, 2026
2c15dff
feat(logging): add ConsoleFormatter with phase context and banners
ElNiak Mar 16, 2026
f4d6dca
feat(cli): add --verbose / --debug flags to set console log level
ElNiak Mar 16, 2026
1060283
test: add unit tests for test execution display helpers
ElNiak Mar 16, 2026
3ff8d97
feat: add experiment summary banner at end of test execution
ElNiak Mar 16, 2026
249a4c1
feat(docker): verbose-aware build output and progress messages
ElNiak Mar 16, 2026
3cc8658
feat(metrics): write metrics to structured.jsonl and add CLI query su…
ElNiak Mar 16, 2026
49099e0
refactor(logging,observers): improve log quality, fix observer event …
ElNiak Mar 17, 2026
e4294a0
fix(observer): fix dead event handlers and structured log level regre…
ElNiak Mar 17, 2026
20b4272
fix(observer): fix broken dedup, is_interested substring bug, add dis…
ElNiak Mar 17, 2026
cea44ec
fix(observer): wire up LoggerObserver typed handlers, fix success def…
ElNiak Mar 17, 2026
72bccde
fix(error-handling): replace bare except:pass with circuit-breaker lo…
ElNiak Mar 17, 2026
55f88c8
fix(reporting): fix O(n*m) dedup, log pattern errors, remove stale do…
ElNiak Mar 17, 2026
fd8c18a
docs: fix inaccurate docstrings in logger_factory and typed_observer
ElNiak Mar 17, 2026
e5c9a5b
fix(observer): address code review findings - set-based dedup in base…
ElNiak Mar 17, 2026
702bcf0
fix(tests): fix 17 pre-existing test failures across observer, logger…
ElNiak Mar 17, 2026
f13aa79
fix(tests): fix 62 webapp test failures from missing nicegui + rename…
ElNiak Mar 17, 2026
0f6814b
refactor(logging): clean up output channels and improve log quality
ElNiak Mar 17, 2026
fe3eb08
refactor(webapp): add __all__ to components __init__ for explicit pub…
ElNiak Mar 17, 2026
17278a9
fix(tests): exclude e2e directory from pytest collection
ElNiak Mar 17, 2026
57b9986
refactor(observer): simplify observer system, remove dead code, clean…
ElNiak Mar 17, 2026
6af75a8
fix(docs): correct inaccurate docstrings, comments, and dead code acr…
ElNiak Mar 17, 2026
3e9a38c
refactor(observer): extract _is_duplicate helper, fix test isolation,…
ElNiak Mar 17, 2026
dbcf5ca
refactor(observer): remove dead create_default_observers/create_defau…
ElNiak Mar 17, 2026
d563939
refactor: strip panther_builder.py to bootstrap-only (188→135 lines)
ElNiak Mar 17, 2026
bb13950
refactor(config): deduplicate ValidationResult/ValidationError across…
ElNiak Mar 17, 2026
1d61a3e
feat(cli): wire 8 orphaned CLI params to config system
ElNiak Mar 17, 2026
937ad5e
refactor(events): flatten ServiceManagerEventMixin (881→700 lines)
ElNiak Mar 17, 2026
9606892
refactor(events): extract _requires_emitter decorator from 14 notify …
ElNiak Mar 17, 2026
1f90c12
chore: add pytest temp dirs to .gitignore and basetemp config
ElNiak Mar 26, 2026
2888055
fix(cli): fix list.remove crash in panther check --format/--imports
ElNiak Mar 26, 2026
f107f18
fix(cli): remove invalid force_overwrite param from create plugin/sub…
ElNiak Mar 26, 2026
ac5b4d8
fix(cli): fix PluginMetadata iteration crashes in plugins params/scan
ElNiak Mar 26, 2026
d8137f1
fix(cli): convert str to Path in plugins validate command
ElNiak Mar 26, 2026
4929f33
fix(tests): fix FastFailHandler import, unsafe singleton reset, stale…
ElNiak Mar 26, 2026
3519b9f
fix: fix 6 output management bugs (report formatting, duplicate event…
ElNiak Mar 10, 2026
8aa3126
fix(tests): remove duplicate test classes from merge artifact
ElNiak Mar 26, 2026
f014fa6
fix(cli): remove dead --force, --template, --output-dir options from …
ElNiak Mar 26, 2026
06d7d5e
fix(cli): fix pytest.ini header and type annotations in plugins.py
ElNiak Mar 26, 2026
f70f6a3
fix(tests): fix fast-fail integration test failures
ElNiak Mar 27, 2026
24bfd0e
fix(tests): fix early termination test failures (thread timing, remov…
ElNiak Mar 27, 2026
31a44e7
fix(tests): fix early termination test failures (thread timing, remov…
ElNiak Mar 27, 2026
f06f7aa
fix: address PR review findings (thread safety, silent failures, dead…
ElNiak Mar 27, 2026
8f8d9f1
fix: address Copilot review comments and CI failure
ElNiak Mar 27, 2026
65a6f9e
fix(ci): guard webapp forms imports for missing nicegui
ElNiak Mar 27, 2026
00dda61
fix(perf): remove coverage from default pytest addopts to prevent 50G…
ElNiak Mar 30, 2026
4dc5545
fix: address 17 PR #116 review findings
ElNiak Mar 30, 2026
9a6f48c
fix: increase Docker error context and handle webapp client disconnec…
ElNiak Mar 30, 2026
19959d8
docs: reformat and add missing docstrings across codebase
ElNiak Mar 30, 2026
c85fbd6
refactor: centralize JSONL writes through single JsonlWriter
ElNiak Mar 30, 2026
f0768e4
fix: address remaining PR #116 review findings and add test coverage
ElNiak Mar 30, 2026
116a58f
fix: improve test_experiment_observer_mixin quality
ElNiak Mar 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 1 addition & 2 deletions .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
pip install pytest black isort flake8
pip install -e .[tests,lint,web]

- name: Get changed files
id: changed-files
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unittests_codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
pip3 install --upgrade pip
pip3 install --upgrade setuptools
pip3 install --upgrade wheel
pip3 install .[tests]
pip3 install .[tests,web]

- name: Generate coverage report
run: |
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ locks/
.coverage
copy.git/
.pytest_cache/
pytest-of-*/
.pytest_tmp/
*.egg-info
*.log
pyvenv.cfg
Expand Down
3 changes: 1 addition & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ repos:
args: ["--profile", "black"]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.6
rev: v0.8.6 # Keep in sync with pyproject.toml [project.optional-dependencies] lint
hooks:
- id: ruff
files: ^(tests|panther)/.*\.py$
exclude: ^tests/tests_ressources/
args: ["--select=D"]

- repo: https://github.com/pycqa/flake8
rev: 7.1.2
Expand Down
14 changes: 12 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ git submodule update --init panther/plugins/services/testers/panther_ivy
# Then re-run package-dev, or install manually:
pip install -e panther/plugins/services/testers/panther_ivy/

# Run tests
# Run tests (no coverage by default — fast, low memory)
pytest tests/ -n auto -m unit # Fast unit tests
pytest tests/ -n auto -m integration # Requires Docker

# Run with coverage (explicit — use -n 4 to cap memory)
pytest tests/ --cov=panther --cov-report= -n 4
coverage combine && coverage report --show-missing --fail-under=70

# Code quality
black panther/ # Format
isort panther/ # Sort imports
Expand Down Expand Up @@ -155,7 +159,13 @@ Dependencies defined in `pyproject.toml`
## Testing

```bash
pytest tests/ -n auto --cov=panther --cov-fail-under=70 # Coverage required: 70%
# Quick tests (no coverage, low memory)
pytest tests/ -n auto -m unit

# Full coverage (explicit, capped workers to limit memory)
pytest tests/ --cov=panther --cov-report= -n 4
coverage combine && coverage report --show-missing --fail-under=70
coverage html # optional: generate HTML report
```

**Test Markers**:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ logging:
level: DEBUG # Set to DEBUG for detailed logs, or INFO for less verbosity
format: "%(asctime)s [%(levelname)s] - %(module)s - %(message)s"
enable_colors: true
debug_file_logging: true # Set to true to enable debug file logging

# Feature-specific log levels - set all to INFO to match global level
feature_levels:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,31 @@
logging:
level: DEBUG # Set to DEBUG for detailed logs, or INFO for less verbosity
level: INFO # Set to DEBUG for detailed logs, or INFO for less verbosity
format: "%(asctime)s [%(levelname)s] - %(module)s - %(message)s"
enable_colors: true
debug_file_logging: true # Set to true to enable debug file logging

# Feature-specific log levels - set all to INFO to match global level
# Feature-specific log levels — names must match feature_registry canonical names
feature_levels:
# Core Components
command_generation: DEBUG
template_rendering: DEBUG
docker_builder: DEBUG
docker_operations: DEBUG # This was causing INFO logs to show
config_processing: DEBUG
command_generation: ERROR
template_rendering: ERROR
docker_operations: ERROR
config_processing: INFO
event_system: ERROR
file_operations: ERROR

# Service Management
# service_managers: INFO
service_managers: DEBUG
service_managers: INFO
ivy_operations: ERROR
quic_services: ERROR
plugin_loading: DEBUG
service_coordination: ERROR
plugin_loading: INFO
service_coordination: INFO

# Environment Management
network_environments: DEBUG
execution_environment: DEBUG
docker_compose: DEBUG
shadow_ns: DEBUG
localhost_container: DEBUG

# Event System
event_emission: ERROR
event_processing: ERROR
state_management: ERROR
observer_operations: ERROR
event_manager: ERROR
network_environments: ERROR
execution_environment: ERROR
docker_compose: ERROR
shadow_ns: ERROR
localhost_container: ERROR

# Protocol Operations
certificate_management: ERROR
Expand All @@ -51,9 +41,10 @@ logging:

# Development and Testing
test_execution: ERROR
experiment_workflow: ERROR
validation_checks: ERROR
error_handling: ERROR
state_management: ERROR
observer_operations: ERROR

progress:
enable_progress_bar: true
Expand Down Expand Up @@ -98,7 +89,7 @@ paths:

docker:
force_build_docker_image: false
no_docker_cache: true # Set to true to disable Docker build cache for all builds
no_docker_cache: false # Set to true to disable Docker build cache for all builds
log_docker_image_build: true # Enable Docker build log files
use_buildx: true # Set to true to use Docker Buildx for multi-platform builds

Expand Down Expand Up @@ -132,7 +123,7 @@ tests:
# timeout: 200
# docker:
# force_build_docker_image: true # Force build for this service's Docker image
# no_docker_cache: true # Disable Docker build cache for this service's image
# no_docker_cache: false # Disable Docker build cache for this service's image

# implementation:
# # build_mode: "rel-lto"
Expand Down Expand Up @@ -177,8 +168,7 @@ tests:
timeout: 200
docker:
force_build_docker_image: true # Force build for this service's Docker image
no_docker_cache: true # Disable Docker build cache for this service's image

no_docker_cache: false # Disable Docker build cache for this service's image
implementation:
# build_mode: "rel-lto"
# z3_source: "pip" # "local" (default, ~30min build) or "pip" (fast, pip z3-solver only)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ logging:
level: DEBUG
format: "%(asctime)s [%(levelname)s] - %(module)s - %(message)s"
enable_colors: true
debug_file_logging: true

feature_levels:
command_generation: DEBUG
Expand Down
7 changes: 2 additions & 5 deletions panther/banner.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
"""
This module contains a function to display an ASCII art banner with a message and author information.
"""
"""This module contains a function to display an ASCII art banner with a message and author information."""


def display_banner():
"""
Displays an ASCII art banner with a message and author information.
"""Displays an ASCII art banner with a message and author information.

The banner includes:
- An ASCII art design
Expand Down
18 changes: 11 additions & 7 deletions panther/builder_metrics/resource_sampler.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
"""Resource monitoring for CPU and memory usage."""

import logging
import threading
import time
from typing import Dict, List, Optional

import psutil

logger = logging.getLogger(__name__)

class ResourceSampler:
"""

from typing import Dict, List, Optional, OptionalSamples system resources (CPU, memory) during operation.
"""
class ResourceSampler:
"""from typing import Dict, List, Optional, OptionalSamples system resources (CPU, memory) during operation."""

def __init__(self, interval: float = 1.0):
"""Initialize the resource sampler.
Expand Down Expand Up @@ -91,9 +91,13 @@ def _sample_loop(self) -> None:
self._process = psutil.Process()
except psutil.NoSuchProcess:
break
except Exception:
# Ignore sampling errors and continue
pass
except Exception as exc:
if not getattr(self, "_sampling_error_warned", False):
self._sampling_error_warned = True
logger.warning(
"Resource sampling error (further errors suppressed): %s",
exc,
)

def get_current_stats(self) -> Dict[str, float]:
"""Get current resource usage without stopping sampling.
Expand Down
8 changes: 3 additions & 5 deletions panther/builder_metrics/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@


def get_directory_size_mb(directory: Path) -> float:
"""

from typing import Dict, List, Optional, Tuple, TupleGet the total size of a directory in megabytes.
"""From typing import Dict, List, Optional, Tuple, TupleGet the total size of a directory in megabytes.

Args:
Args:
directory: Path to the directory

Returns:
Returns:
Size in megabytes
"""
if not directory.exists() or not directory.is_dir():
Expand Down
6 changes: 6 additions & 0 deletions panther/cli/commands/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
success_message,
)

logger = logging.getLogger(__name__)


@featured_example("panther admin status")
@click.group()
Expand Down Expand Up @@ -119,6 +121,7 @@ def teardown(ctx, force):
click.echo(f" ⚠️ {step_name} completed with warnings")

except Exception as e:
logger.debug("CLI error in teardown: %s", e, exc_info=True)
click.echo(f" ⚠️ {step_name} failed: {e}")

bar.update(1)
Expand Down Expand Up @@ -385,6 +388,7 @@ def _clean_directories(dir_names):
total_removed += removed
click.echo(f" ✅ {operation_name}: {removed} items removed")
except Exception as e:
logger.debug("CLI error in clean: %s", e, exc_info=True)
click.echo(f" ⚠️ {operation_name}: {e}")

success_message(
Expand Down Expand Up @@ -754,6 +758,7 @@ def _system_cleanup_services():
f" ✅ {operation_name}: {processed} items processed"
)
except Exception as e:
logger.debug("CLI error in docker: %s", e, exc_info=True)
click.echo(f" ⚠️ {operation_name}: {e}")
else:
# For registry operations, no progress bar needed
Expand All @@ -766,6 +771,7 @@ def _system_cleanup_services():
f" ✅ {operation_name}: {processed} items processed"
)
except Exception as e:
logger.debug("CLI error in docker: %s", e, exc_info=True)
click.echo(f" ⚠️ {operation_name}: {e}")

success_message(
Expand Down
Loading
Loading