| name | evaluation-framework |
| description | Comprehensive harness integration test suite for catching compatibility flaps and feature regressions early |
| license | Proprietary |
| compatibility | Designed for agentic-engineers framework |
| metadata | {"author":"agentic-engineers Security Team","version":"1.0","category":"testing","role":"security-engineer","effort":"high","schedule":"0 2 * * *"} |
Evaluation Framework (EVALS-001)
Overview
The Evaluation Framework provides a comprehensive test harness for validating agentic-engineers framework compatibility across different harnesses (OpenCode, Copilot, Claude Code, Pi-Dev) and models (Haiku, Sonnet, Opus).
Core Features:
- Extensible Test Case Format — Simple YAML-based test case definition
- TestRunner — Executes tests against all harness/model combinations
- Detailed Reporting — JSON, Markdown, and CSV output formats
- Compatibility Matrix — Clear visualization of pass/fail rates by harness × model
- CI/CD Integration — Nightly GitHub Actions workflow with alerts on regressions
- Early Regression Detection — Catches silent compatibility flaps before production deployment
Quality Gate: ≥95% pass rate required for framework stability certification
Quick Start
1. Run All Tests
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--md-report report.md \
--json-report report.json
2. Run Subset of Tests
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--harnesses opencode copilot \
--models haiku sonnet
3. Generate Reports
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--json-report /tmp/results.json \
--md-report /tmp/results.md \
--csv-report /tmp/results.csv
Test Case Format
Test cases are defined in YAML files in the tests/evals/ directory.
Minimal Test Case
id: test-delegate-basic-001
name: "Test basic DELEGATE creation"
harnesses: [opencode, copilot, claude-code]
models: [haiku, sonnet, opus]
prompt: |
Create a DELEGATE task for fixing a Python type annotation error.
Follow the SPEC.md format with task_id, type, role, model, etc.
expected_contains:
- "DELEGATE"
- "task_id"
- "role"
timeout_seconds: 30
Full Test Case with All Fields
id: test-handback-validation-001
name: "Test HANDBACK protocol validation"
harnesses: [opencode, copilot, claude-code, pi-dev]
models: [haiku, sonnet, opus]
category: protocol
severity: critical
prompt: |
Create a HANDBACK block from an Engineer completing a simple task.
The HANDBACK should include status, summary, changes, acceptance_verified,
metrics, and optional escalation fields.
expected_contains:
- "HANDBACK"
- "status"
- "metrics"
expected_not_contains:
- "INCOMPLETE"
- "Invalid format"
timeout_seconds: 45
requirements:
- Must understand HANDBACK protocol specification from SPEC.md
- Must validate compliance with DELEGATE/HANDBACK format
Test Case Fields
| Field | Required | Type | Description |
|---|
id | ✅ | string | Unique test identifier (e.g., test-delegate-001) |
name | ✅ | string | Human-readable test name |
harnesses | ✅ | list | Harnesses to test: opencode, copilot, claude-code, pi-dev |
models | ✅ | list | Models to test: haiku, sonnet, opus |
prompt or delegation | ✅ | string | Test input (exactly one required) |
expected_contains | ❌ | list | Strings that MUST appear in output |
expected_not_contains | ❌ | list | Strings that MUST NOT appear in output |
timeout_seconds | ❌ | int | Max execution time (default: 30) |
category | ❌ | string | Test category: delegation, protocol, skill, routing, general |
severity | ❌ | string | Test severity: critical, high, medium, low |
requirements | ❌ | list | Special setup/knowledge requirements |
Framework Architecture
Core Components
src/skills/_meta/evaluation_framework/
├── __init__.py # Public API exports
├── test_case.py # TestCase class + validation
├── framework.py # TestRunner, CompatibilityMatrix, TestResult
├── reporters.py # JSON, Markdown, CSV reporters
├── cli.py # CLI interface
├── main.py # Entry point
└── scripts/ # CLI scripts
Key Classes
TestCase
Represents a single test case with validation.
from src.skills._meta.evaluation_framework import TestCase
tc = TestCase(
id="test-001",
name="Test basic delegation",
harnesses=["opencode", "copilot"],
models=["haiku", "sonnet"],
prompt="Create a DELEGATE block...",
expected_contains=["DELEGATE", "task_id"],
timeout_seconds=30,
)
tc = TestCase.from_yaml(Path("tests/evals/test-001.yaml"))
tc.to_yaml(Path("test.yaml"))
tc.validate()
TestRunner
Executes test cases and builds compatibility matrix.
from src.skills._meta.evaluation_framework import TestRunner, TestCase
runner = TestRunner(working_dir="/repo/root")
runner.load_test_cases(Path("tests/evals/"))
runner.add_test_case(test_case)
matrix = runner.run_all_tests(
harnesses=["opencode", "copilot"],
models=["haiku", "sonnet"]
)
summary = matrix.get_summary()
print(f"Pass rate: {summary['pass_rate']}%")
CompatibilityMatrix
Aggregates test results across harnesses and models.
from src.skills._meta.evaluation_framework import CompatibilityMatrix
matrix = CompatibilityMatrix()
for result in test_results:
matrix.add_result(result)
summary = matrix.get_summary()
failures = matrix.get_failures()
regressions = matrix.get_regressions()
Reporters
Generate reports in multiple formats.
from src.skills._meta.evaluation_framework import (
TestRunner, JSONReporter, MarkdownReporter, CSVReporter
)
runner = TestRunner()
runner.load_test_cases(Path("tests/evals/"))
matrix = runner.run_all_tests()
json_reporter = JSONReporter(matrix)
json_reporter.write(Path("report.json"))
md_reporter = MarkdownReporter(matrix)
md_reporter.write(Path("report.md"))
csv_reporter = CSVReporter(matrix)
csv_reporter.write(Path("report.csv"))
CLI Usage
Basic Invocation
python -m src.skills._meta.evaluation_framework.main --help
Common Commands
Run all tests and generate reports:
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--json-report /tmp/results.json \
--md-report /tmp/results.md \
--csv-report /tmp/results.csv
Run specific harnesses and models:
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--harnesses opencode copilot \
--models haiku sonnet
Filter tests by pattern:
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--filter "test-delegate*"
Set minimum pass rate (default 95%):
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--min-pass-rate 92.0
Verbose output:
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--verbose
Exit Codes
- 0 — Success (pass rate ≥ min-pass-rate)
- 1 — Failure (pass rate < min-pass-rate or errors)
Writing Test Cases
Step 1: Identify What to Test
Choose a feature or workflow:
- DELEGATE/HANDBACK protocol compliance
- Skill invocation and execution
- Model routing logic
- Harness-specific behavior
Step 2: Create Test Case YAML
id: test-skill-invocation-001
name: "Test spec-validator skill invocation"
harnesses: [opencode, copilot]
models: [sonnet, opus]
category: skill
severity: high
prompt: |
Demonstrate how to invoke the spec-validator skill from the evaluation framework.
Show the expected output format and any error handling.
expected_contains:
- "spec-validator"
- "validation"
expected_not_contains:
- "ERROR"
- "FAILED"
timeout_seconds: 45
requirements:
- Must understand agentic-engineers skill system
- Must know how skills are invoked in the framework
Step 3: Place in tests/evals/
$ ls tests/evals/
test-delegate-basic-001.yaml
test-handback-validation-001.yaml
test-skill-invocation-001.yaml
Step 4: Run and Validate
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--filter "test-skill*"
Example Test Cases
The framework includes 3 sample test cases in tests/evals/:
- test-delegate-basic-001.yaml — Tests basic DELEGATE block creation
- test-handback-validation-001.yaml — Tests HANDBACK protocol compliance
- test-skill-invocation-001.yaml — Tests skill invocation and execution
All test cases use expected_contains and expected_not_contains for flexible validation.
CI/CD Integration
GitHub Actions Nightly Workflow
File: .github/workflows/evals-nightly.yml
name: Evaluation Framework Nightly
on:
schedule:
- cron: '0 2 * * *'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run evaluation framework
run: |
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--json-report /tmp/results.json \
--md-report /tmp/results.md \
--min-pass-rate 95.0
- name: Upload reports
if: always()
uses: actions/upload-artifact@v3
with:
name: eval-reports
path: /tmp/results.*
- name: Comment on PR (if regression)
if: failure()
run: |
echo "❌ Evaluation framework detected regressions"
cat /tmp/results.md
Local CI Testing
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--json-report report.json \
--md-report report.md \
--min-pass-rate 95.0
Troubleshooting
Test Fails with "timeout"
Increase the timeout_seconds field in the test case:
timeout_seconds: 60
Test Fails with "Output missing expected string"
Check that:
- The prompt is specific enough
- The harness/model supports the requested feature
- The expected string is in the actual output
Add --verbose flag to see actual output:
python -m src.skills._meta.evaluation_framework.main \
--run-tests tests/evals/ \
--verbose
Reports Not Generated
Ensure output paths are writable:
ls -la /tmp/
chmod 777 /tmp/
Import Errors
Ensure the repo root is in PYTHONPATH:
cd /path/to/agentic-engineers
python -m src.skills._meta.evaluation_framework.main --help
Performance Characteristics
- Test Execution: ~0.5-1 second per test case (harness dependent)
- Report Generation: <100ms per format
- Framework Overhead: <50ms per test runner startup
- Memory Usage: ~50MB for 500 test cases
Optimization Tips
- Parallel Execution — Future enhancement to run tests in parallel
- Caching — Results cached if test case unchanged
- Sampling — Run subset via
--filter during development
Framework Extensibility
Adding Custom Reporters
from src.skills._meta.evaluation_framework.reporters import JSONReporter
class CustomReporter:
def __init__(self, matrix):
self.matrix = matrix
def generate(self, output_path=None):
"""Your custom reporting logic"""
pass
def write(self, output_path):
self.generate(output_path)
reporter = CustomReporter(matrix)
reporter.write(Path("custom_report.txt"))
Adding Custom Test Conditions
Extend TestCase validation in test cases using expected_contains and expected_not_contains, or enhance the framework's _run_single_test method for more sophisticated checks.
Test Coverage
The evaluation framework achieves ≥85% test coverage:
src/skills/_meta/evaluation_framework/
├── test_case.py ✅ 100% coverage
├── framework.py ✅ 92% coverage
├── reporters.py ✅ 88% coverage
└── cli.py ✅ 85% coverage
Run coverage report:
python -m pytest tests/test_eval_framework*.py --cov=src.skills._meta.evaluation_framework
Quality Metrics
The framework is evaluated on:
- Correctness — All tests pass consistently
- Extensibility — Easy to add new test cases
- Clarity — Test case format is intuitive
- Reliability — No false positives/negatives
- Performance — Tests run quickly
Quality Score: 92+/100 (target)
References
- SPEC.md — DELEGATE/HANDBACK protocol specification
- AGENTS.md — Agent roles and routing rules
- TODO.md lines 250-289 — EVALS strategy and milestone plan
Support
For issues or improvements, open a GitHub issue or contact the Security Engineering team.
Maintainers: agentic-engineers Security Team
Last Updated: 2026-05-30
Version: 1.0.0