TradingAgents/.claude/hooks/verify_agent_pipeline.py

192 lines
6.3 KiB
Python
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Pipeline Verification Hook - Verify Agent Execution
This PreCommit hook verifies that the expected agents ran for feature implementations.
Hook Type: PreCommit (OPTIONAL - can be enabled for stricter enforcement)
Trigger: Before git commit completes
Purpose:
- Detect if full SDLC pipeline was skipped
- Warn about missing agents (researcher, test-master, etc.)
- Ensure autonomous workflow was used for feature work
Behavior:
- If today's pipeline file doesn't exist → PASS (not a feature commit)
- If file exists but agents missing → WARN (shows what's missing)
- If all expected agents ran → PASS (full pipeline executed)
Expected agents for feature implementations:
- researcher (always)
- planner (architecture/medium+ features)
- test-master (TDD required)
- implementer (always)
- reviewer (quality gate)
- security-auditor (security-sensitive features)
- doc-master (always)
Configuration (add to .claude/settings.local.json):
{
"hooks": {
"PreCommit": [{
"hooks": [{
"type": "command",
"command": "python .claude/hooks/verify_agent_pipeline.py || exit 1"
}]
}]
}
}
Exit codes:
0 - All checks passed
1 - Missing agents detected (if strict mode enabled)
Note: By default, this hook WARNS but doesn't block. Set STRICT_PIPELINE=1
environment variable to block commits when agents are missing.
"""
import json
import os
import sys
from datetime import date
from pathlib import Path
def get_today_pipeline():
"""Get today's pipeline JSON file if it exists"""
session_dir = Path("docs/sessions")
if not session_dir.exists():
return None
today = date.today().strftime("%Y%m%d")
pipeline_files = list(session_dir.glob(f"{today}-*-pipeline.json"))
if not pipeline_files:
return None
# Return most recent file
latest = sorted(pipeline_files)[-1]
return json.loads(latest.read_text())
def has_feature_commits():
"""
Check if current commit includes feature work.
Heuristic: If code files (src/, *.py, *.js, *.ts, etc.) changed,
likely a feature commit.
"""
try:
import subprocess
result = subprocess.run(
["git", "diff", "--cached", "--name-only"],
capture_output=True,
text=True,
check=True
)
changed_files = result.stdout.strip().split("\n")
# Check for code files
code_extensions = {".py", ".js", ".ts", ".tsx", ".jsx", ".go", ".rs", ".java", ".c", ".cpp"}
code_dirs = {"src/", "lib/", "app/"}
for file in changed_files:
# Check extension
if any(file.endswith(ext) for ext in code_extensions):
return True
# Check directory
if any(file.startswith(dir_path) for dir_path in code_dirs):
return True
return False
except Exception:
# If git command fails, assume feature commit (safe default)
return True
def verify_pipeline():
"""Verify that expected agents ran"""
# Get strict mode setting
strict_mode = os.environ.get("STRICT_PIPELINE", "0") == "1"
# Check if this is a feature commit
if not has_feature_commits():
print(" No feature code changes detected, skipping pipeline verification")
return 0
# Get today's pipeline
pipeline = get_today_pipeline()
if not pipeline:
print("⚠️ Warning: No agent pipeline file found for today")
print(" Expected: docs/sessions/{date}-{time}-pipeline.json")
print(" This usually means agents weren't invoked (manual implementation?)")
print("\n Recommendation: Use /auto-implement for feature work to ensure")
print(" full SDLC pipeline (research → plan → test → implement → review → security → docs)")
if strict_mode:
print("\n❌ STRICT_PIPELINE=1: Blocking commit (no pipeline evidence)")
return 1
else:
print("\n✅ Allowing commit (strict mode not enabled)")
print(" Set STRICT_PIPELINE=1 to enforce pipeline verification")
return 0
# Check which agents ran
completed_agents = {
entry["agent"]
for entry in pipeline["agents"]
if entry["status"] == "completed"
}
# Expected agents (minimum for feature work)
expected_minimum = {"researcher", "implementer", "doc-master"}
expected_full = {"researcher", "planner", "test-master", "implementer",
"reviewer", "security-auditor", "doc-master"}
# Check minimum requirements
if expected_minimum.issubset(completed_agents):
print(f"✅ Agent pipeline verification passed")
print(f" Agents ran: {', '.join(sorted(completed_agents))}")
# Warn if full pipeline not run (but don't block)
missing_from_full = expected_full - completed_agents
if missing_from_full:
print(f"\n Note: Full pipeline not run (optional agents: {', '.join(missing_from_full)})")
print(f" This is OK for simple features, but consider using full pipeline for complex work")
return 0
# Missing minimum requirements
missing = expected_minimum - completed_agents
print(f"⚠️ Warning: Minimum agent pipeline not complete")
print(f" Missing: {', '.join(missing)}")
print(f" Ran: {', '.join(sorted(completed_agents)) if completed_agents else 'none'}")
print("\n Expected minimum agents:")
print(" - researcher (find patterns & best practices)")
print(" - implementer (write code)")
print(" - doc-master (update documentation)")
print("\n Recommendation: Use /auto-implement to ensure full SDLC pipeline")
if strict_mode:
print("\n❌ STRICT_PIPELINE=1: Blocking commit (agents missing)")
return 1
else:
print("\n✅ Allowing commit (strict mode not enabled)")
print(" Set STRICT_PIPELINE=1 to enforce pipeline verification")
return 0
def main():
try:
return verify_pipeline()
except Exception as e:
print(f"⚠️ Pipeline verification error: {e}", file=sys.stderr)
print(" Allowing commit to proceed (verification hook failed gracefully)")
return 0 # Don't block on errors
if __name__ == "__main__":
sys.exit(main())