ci: add weekly DRC end-to-end canary - #286
Conversation
Restores a routine end-to-end signal for the intake path. The Event Router drops any sender ending in "[bot]", so the nightly Daily Repository Summary issues never reach the council. Until today the only recurring event that traversed the full path was the PR Triage Pipeline's daily rewrite of issue #164, which re-ran the council on an unchanged premise every morning and has been filtered out. Without a replacement there is no routine proof the path works, and the existing Intake Canary only proves the n8n API is reachable. The assertion inspects the "Store to TIM Postgres" node output rather than the execution status, because that node masks its own errors and reports a green execution while dropping the audit row. Both branches were validated against real executions: the passing case against 7848, and the failing case against 7832, the run that exposed the bug in #284. Uses GH_PAT rather than GITHUB_TOKEN so the canary issue passes the router's bot-sender filter. Costs one council run per week. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017bKHKCuokjG8ZKcizbgRs1
📊 Code Complexity AnalysisSummary:
|
| File | Function | Complexity | Line |
|---|---|---|---|
core/risk_scorer.py |
score_pull_request |
35 | 141 |
autopilot/autopilot.py |
generate_summary |
24 | 195 |
autopilot/staleness_engine.py |
process_stale_prs |
16 | 281 |
autopilot/ai_optimization/performance_monitor.py |
get_benchmark_stats |
15 | 184 |
.github/scripts/weekly_digest.py |
build_blocks |
15 | 38 |
.github/scripts/batch_scan_dependabot.py |
main |
15 | 64 |
autopilot/recommendation_contract.py |
validate |
14 | 54 |
.github/scripts/prometheus_exporter.py |
collect_metrics |
14 | 99 |
.github/scripts/self_healing_system.py |
analyze_failure_patterns |
14 | 256 |
.github/scripts/setup_branch_protection.py |
main |
14 | 240 |
... and 19 more
Recommendations:
- Break down large functions into smaller, focused units
- Extract complex conditional logic into separate functions
- Use early returns to reduce nesting
🔧 Low Maintainability Files
These files have low maintainability scores and may need refactoring:
| File | Score | Status |
|---|---|---|
.github/scripts/health_dashboard_generator.py |
28.14 | 🔴 |
.github/scripts/workflow_monitor.py |
33.73 | 🔴 |
.github/scripts/ai_code_suggestor.py |
33.76 | 🔴 |
.github/scripts/ai_workflow_optimizer.py |
35.51 | 🔴 |
.github/scripts/performance_benchmark.py |
39.46 | 🔴 |
.github/scripts/self_healing_system.py |
40.27 | 🔴 |
.github/scripts/threshold_monitor.py |
41.13 | 🔴 |
.github/scripts/parallel_code_analyzer_optimized.py |
41.16 | 🔴 |
autopilot/tests/test_recommendation_contract.py |
42.05 | 🔴 |
autopilot/autopilot.py |
42.45 | 🔴 |
autopilot/ai_optimization/anomaly_detector.py |
42.56 | 🔴 |
.github/scripts/refactoring_assistant.py |
43.03 | 🔴 |
autopilot/ai_optimization/intelligent_cache.py |
43.28 | 🔴 |
autopilot/ai_optimization/commit_summarizer.py |
44.05 | 🔴 |
.github/scripts/async_parallel_analyzer.py |
44.47 | 🔴 |
autopilot/ai_optimization/performance_monitor.py |
44.69 | 🔴 |
.github/scripts/badge_generator.py |
45.28 | 🔴 |
.github/scripts/copilot_integration.py |
45.37 | 🔴 |
.github/scripts/distributed_monitoring.py |
45.53 | 🔴 |
autopilot/dependency_graph.py |
45.65 | 🔴 |
.github/scripts/elite_copilot.py |
45.69 | 🔴 |
.github/scripts/issue_auto_creator.py |
46.39 | 🔴 |
.github/scripts/cost_calculator.py |
46.4 | 🔴 |
.github/scripts/inline_pr_commenter.py |
46.63 | 🔴 |
.github/scripts/complexity_reporter.py |
46.78 | 🔴 |
.github/scripts/pr_triage.py |
47.13 | 🔴 |
core/risk_scorer.py |
48.15 | 🔴 |
autopilot/ai_optimization/nlp_relevance_filter.py |
48.43 | 🔴 |
.github/scripts/pr_inline_commenter.py |
48.47 | 🔴 |
.github/scripts/dependency_audit.py |
48.7 | 🔴 |
autopilot/staleness_engine.py |
48.73 | 🔴 |
.github/scripts/dependency_updater.py |
48.91 | 🔴 |
.github/scripts/metrics_collector.py |
48.91 | 🔴 |
autopilot/ai_optimization/ml_priority_scorer.py |
49.53 | 🔴 |
.github/scripts/parallel_code_analyzer.py |
49.96 | 🔴 |
autopilot/ai_optimization/api_optimizer.py |
50.46 | 🟡 |
.github/scripts/workflow_optimizer.py |
51.67 | 🟡 |
.github/scripts/cot_selector.py |
51.73 | 🟡 |
.github/scripts/release_manager.py |
51.92 | 🟡 |
.github/scripts/check_quality.py |
52.33 | 🟡 |
.github/scripts/auto_pr.py |
52.72 | 🟡 |
.github/scripts/changelog_generator.py |
53.13 | 🟡 |
.github/scripts/notification_manager.py |
53.58 | 🟡 |
.github/scripts/prometheus_exporter.py |
54.96 | 🟡 |
.github/scripts/weekly_digest.py |
55.02 | 🟡 |
.github/scripts/llm_router.py |
55.19 | 🟡 |
core/audit_logger.py |
55.6 | 🟡 |
.github/scripts/gather_context.py |
56.0 | 🟡 |
.github/scripts/batch_scan_dependabot.py |
56.3 | 🟡 |
core/llm_provider.py |
56.32 | 🟡 |
.github/scripts/streaming_results.py |
56.64 | 🟡 |
.github/scripts/setup_branch_protection.py |
57.0 | 🟡 |
.github/scripts/optimized_github_client.py |
58.27 | 🟡 |
agents/orchestrator_agent.py |
59.02 | 🟡 |
core/incident_freeze.py |
59.67 | 🟡 |
core/github_client.py |
61.96 | 🟡 |
core/message_queue.py |
63.22 | 🟡 |
core/agent_config.py |
63.82 | 🟡 |
autopilot/decisions/ledger.py |
63.92 | 🟡 |
core/idempotency.py |
64.45 | 🟡 |
Maintainability Index Guide:
- 🟢 85-100: Excellent maintainability
- 🟡 65-84: Good maintainability
- 🟠 50-64: Moderate maintainability (consider refactoring)
- 🔴 0-49: Poor maintainability (needs refactoring)
🟢 Risk Assessment: LOW (2.5/10)Analysed 3 files, 128+ / 24− lines. Security-sensitive paths detected. Test coverage unchanged or improved. Scoring breakdown
|
Code Quality Analysis ❌ FAILEDDuration: 0.01s Tool Results
View detailed results{
"timestamp": "2026-09-04 08:39:01",
"elapsed_seconds": 0.01,
"summary": {
"total_issues": 10,
"critical": 0,
"high": 0,
"medium": 0,
"low": 0
},
"tools": {
"pylint": {
"status": "failed",
"output": "",
"errors": "Pylint error: [Errno 2] No such file or directory: 'pylint'"
},
"flake8": {
"status": "failed",
"output": "",
"errors": "Flake8 error: [Errno 2] No such file or directory: 'flake8'"
},
"bandit": {
"status": "failed",
"output": "",
"errors": "Bandit error: [Errno 2] No such file or directory: 'bandit'"
},
"radon_cc": {
"status": "failed",
"output": "",
"errors": "Radon error: [Errno 2] No such file or directory: 'radon'"
},
"radon_mi": {
"status": "failed",
"output": "",
"errors": "Radon MI error: [Errno 2] No such file or directory: 'radon'"
}
},
"passed": false
} |
🔒 Security Scan Results🛡️ Bandit Security Scan
📦 Dependency Vulnerabilities
Vulnerable Dependencies:
Security scans run automatically on every PR. View detailed reports in the Actions tab. |
🔍 Pre-commit Checks✅ All pre-commit checks passed! Your code follows the project style guidelines. Pre-commit hooks help maintain code quality and consistency. |
🤖 Elite AI Copilot AnalysisElite AI Copilot Analysis ReportGenerated: 2026-09-04 08:39:27 🎯 Health Score: 100.0/100🚀 Top Recommendations
📊 Detailed InsightsCode Quality Baseline Established
Security Scan Initiated
Repository Structure Analyzed
Performance Baseline Captured
Documentation Structure Good
Powered by Elite AI Copilot v1.0 |
🤖 DRC Agent AnalysisRecommendation: 🟠 P1 IMPORTANT Summary: Minimal Synthetic Issue Canary (Dreamer Solution 1, Realist-validated as feasible with known workarounds) Next steps:
Strategic fit: Consulting: high · Product: high · Tech debt: reduces Analysed by GadgetLab DRC Agent (Dreamer → Realist → Critic) · Run |
There was a problem hiding this comment.
🟡 Changes recommended
The canary’s execution selection relies on lexicographic timestamp comparison (startedAt > since), which can misorder/filter n8n timestamps (notably with fractional seconds) and produce false results.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds a new scheduled GitHub Actions workflow intended to provide a low-cost, weekly end-to-end canary for the DRC intake pipeline (GitHub issue → n8n DRC execution → tim.agent_runs audit write), specifically asserting the Store to TIM Postgres node output rather than trusting overall execution “green”.
Changes:
- Introduces
.github/workflows/drc-e2e-canary.ymlto open a canary issue weekly usingGH_PAT, poll n8n for the resulting DRC execution, and validate the audit-write node output. - Closes the created canary issue on completion (success or failure) and optionally alerts Slack on workflow failure.
File summaries
| File | Description |
|---|---|
.github/workflows/drc-e2e-canary.yml |
New weekly workflow to exercise and assert the full DRC intake + audit-write path via a real GitHub issue and n8n execution inspection. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| N8N_API_KEY: ${{ secrets.N8N_API_KEY }} | ||
| SINCE: ${{ steps.t0.outputs.value }} | ||
| run: | | ||
| set -euo pipefail |
| | jq -r --arg since "$SINCE" \ | ||
| '[.data[] | select(.startedAt > $since) | select(.status != "running")] | ||
| | sort_by(.startedAt) | last | .id // ""') |
| node=$(curl -sS -H "X-N8N-API-KEY: $N8N_API_KEY" \ | ||
| "$N8N_BASE/api/v1/executions/$exec_id?includeData=true" \ | ||
| | jq -c '.data.resultData.runData["Store to TIM Postgres"][0].data.main[0][0].json // {}') |
Replaces the accidental daily end-to-end signal that was removed today, at a seventh of the cost.
Why
The Event Router drops any sender whose login ends in
[bot], so the nightly Daily Repository Summary issues never reach the council. That left the PR Triage Pipeline's daily rewrite of issue #164 as the only recurring event traversing the full path. That rewrite fired a three-minute council run every morning on an unchanged premise, so it was filtered out by droppingeditedfrom the router's actionable-action list.The Intake Canary that already runs every 30 minutes reads workflow metadata over the n8n API. It proves reachability, not that the path delivers. That is the same shape as the eight-day intake outage, where every probe stayed green.
What it asserts
It opens an issue, waits for a council execution, and then checks the
Store to TIM Postgresnode output rather than the execution status.That distinction is the point. The node masks its own errors, so a failed audit write still reports a green execution. Issue #284 is exactly that failure.
Both branches were validated against real executions before this was committed.
Notes
GH_PAT, notGITHUB_TOKEN, so the canary issue passes the bot-sender filter. WithGITHUB_TOKENit would be silently dropped and always fail.🤖 Generated with Claude Code
https://claude.ai/code/session_017bKHKCuokjG8ZKcizbgRs1