Skip to content

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 10, 2026

Summary

Optimizes the PR lifecycle in the supervisor to reduce time from PR creation to deployment by implementing:

  1. Fast-path for clean PRs: When CI is green and zero review threads exist, skip the review_triage state entirely and go directly from pr_reviewmerging
  2. Multi-stage transitions: Already supported - tasks can progress through multiple states (pr_reviewmergingmergeddeployingdeployed) in a single pulse
  3. Timing metrics: Track time spent in each stage and log to proof-log.jsonl for pipeline latency analysis

Impact

  • Clean PRs (CI green + no review comments) now go from completedeployed in 1-2 pulses instead of 3+
  • Timing data enables data-driven optimization of bottlenecks
  • Fast-path marked in triage_result with fast_path:true flag for analytics

Implementation Details

Fast-Path Logic

When a PR reaches pr_review state with ready_to_merge status:

  1. Check if skip_review_triage is enabled (bypass)
  2. If not, query GitHub GraphQL API for unresolved review threads
  3. If thread count is 0, transition directly to merging (skip review_triage)
  4. If threads exist, go through normal triage flow

Timing Metrics

Each stage tracks:

  • pr_review: Time from entering pr_review to exiting (includes CI wait)
  • review_triage: Time spent triaging review feedback
  • merging: Time to merge PR
  • deploying: Time to run postflight + deploy + cleanup
  • total: Total lifecycle time

Logged to proof-log.jsonl as:

{
  "timestamp": "2026-02-10T05:30:00Z",
  "task_id": "t219",
  "event": "pr_lifecycle_timing",
  "stages": {
    "pr_review": "5s",
    "merging": "3s",
    "deploying": "12s",
    "total": "20s"
  }
}

Testing

  • Syntax validated with bash -n
  • Logic verified against existing cmd_pr_lifecycle flow
  • Fast-path only activates when CI is green (existing check_pr_status validation)
  • Timing metrics are best-effort (failures don't block lifecycle)

Related

  • t218: proof-log infrastructure
  • t148: review triage system
  • t210: orphaned PR scanner

Closes #914

Summary by CodeRabbit

  • Chores
    • Enhanced pipeline observability by introducing detailed timing metrics collection across PR lifecycle stages (review, merging, deployment)
    • Expanded telemetry to capture per-stage durations and overall pipeline latency for improved performance analysis
    • Integrated task tracking into pipeline provenance for comprehensive visibility into pipeline efficiency

…triage (t219)

Optimizations:
1. Fast-path for clean PRs: Skip review_triage state when CI is green and zero review threads exist
2. Multi-stage transitions: Already supported - pr_review → merging → merged → deploying → deployed in single pulse
3. Timing metrics: Track time spent in each stage (pr_review, review_triage, merging, deploying) and log to proof-log.jsonl for pipeline latency analysis

Impact:
- Clean PRs (CI green + no review comments) now go from complete → deployed in 1-2 pulses instead of 3+
- Timing data enables data-driven optimization of bottlenecks
- Fast-path marked in triage_result with fast_path:true flag

Related: t218 (proof-log), t148 (review triage)
@gemini-code-assist
Copy link

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 10, 2026

Walkthrough

Added lifecycle timing instrumentation to the PR pipeline supervisor script by introducing a record_lifecycle_timing() function that captures per-stage durations (pr_review, merging, deploying, etc.) and persists structured timing metrics to a proof-log for latency analysis.

Changes

Cohort / File(s) Summary
Lifecycle Timing Instrumentation
.agents/scripts/supervisor-helper.sh
New record_lifecycle_timing(task_id, stage_timings) function appends JSON-formatted timing entries to proof-log. Timing hooks integrated across PR lifecycle checkpoints: pr_review, review_triage, merging, deploying, and deployed stages. Task-tool usage metrics (task_tool_count) incorporated into telemetry. Minor comment clarifications on parallel task guidance (no runtime logic changes).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • PR #392: Adds lifecycle timing instrumentation with instrumentation calls to the same PR lifecycle functions (pr_review, merging, deploying paths in supervisor-helper.sh).
  • PR #429: Modifies PR lifecycle flow and cmd_pr_lifecycle behavior in supervisor-helper.sh, affecting the same stage transition mechanisms.

Poem

⏱️ Each stage now whispers secrets through,
As timing flows in JSON hue,
The proof-log blooms with measured grace,
Pipeline bottlenecks find their place,
From review's start to deploy's end,
Latency metrics blend and blend! 📊

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately reflects the main objective: optimizing the PR merge pipeline with parallel CI and review triage (t219), directly matching the changeset's core purpose.
Linked Issues check ✅ Passed The implementation comprehensively addresses all four coding objectives from #914: multi-stage transitions within single pulse, fast-path skipping review_triage when CI green, post-merge parallel execution (deploy/verify), and timing metrics logging to proof-log.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the PR lifecycle optimization: lifecycle timing instrumentation, fast-path logic, stage transitions, and telemetry integration per #914 requirements.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/t219

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 33 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Tue Feb 10 05:46:33 UTC 2026: Code review monitoring started
Tue Feb 10 05:46:33 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 33

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 33
  • VULNERABILITIES: 0

Generated on: Tue Feb 10 05:46:35 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

@marcusquinn marcusquinn merged commit fc35ae9 into main Feb 10, 2026
9 of 10 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.agents/scripts/supervisor-helper.sh (1)

6526-6578: ⚠️ Potential issue | 🟠 Major

Gate fast-path merge on successful review-thread verification.

The fast-path currently treats check_review_threads failures (API outage, auth issues) as zero threads, triggering immediate merge with potentially unresolved feedback. This creates an inconsistency with the regular triage path (line 6682), which does not suppress errors. Capture the return code and only merge if threads are successfully fetched and empty; otherwise fall back to review_triage.

Proposed fix
-                        threads_json_fastpath=$(check_review_threads "$repo_slug_fastpath" "$pr_number_fastpath" 2>/dev/null || echo "[]")
-                        local thread_count_fastpath
-                        thread_count_fastpath=$(echo "$threads_json_fastpath" | jq 'length' 2>/dev/null || echo "0")
-                        
-                        if [[ "$thread_count_fastpath" -eq 0 ]]; then
+                        threads_json_fastpath=$(check_review_threads "$repo_slug_fastpath" "$pr_number_fastpath" 2>/dev/null)
+                        local threads_rc=$?
+                        local thread_count_fastpath=0
+                        if [[ "$threads_rc" -eq 0 ]]; then
+                            thread_count_fastpath=$(echo "$threads_json_fastpath" | jq 'length' 2>/dev/null || echo "0")
+                        fi
+
+                        if [[ "$threads_rc" -eq 0 && "$thread_count_fastpath" -eq 0 ]]; then
                             log_info "Fast-path: CI green + zero review threads - skipping review_triage, going directly to merge"
                             if [[ "$dry_run" == "false" ]]; then
                                 db "$SUPERVISOR_DB" "UPDATE tasks SET triage_result = '{\"action\":\"merge\",\"threads\":0,\"fast_path\":true}' WHERE id = '$escaped_id';"
                                 cmd_transition "$task_id" "merging" 2>>"$SUPERVISOR_LOG" || true
                             fi
                             tstatus="merging"
                         else
-                            # Has review threads - go through normal triage
+                            # Has review threads OR verification failed — go through normal triage
                             if [[ "$dry_run" == "false" ]]; then
                                 cmd_transition "$task_id" "review_triage" 2>>"$SUPERVISOR_LOG" || true
                             fi
                             tstatus="review_triage"
                         fi
🤖 Fix all issues with AI agents
In @.agents/scripts/supervisor-helper.sh:
- Around line 4548-4554: Replace the basic-regex grep call that sets
task_tool_count with an extended-regex usage: update the grep invocation that
assigns task_tool_count (the line containing task_tool_count=$(grep -c
'mcp_task\|"tool_name":"task"\|"name":"task"' "$log_file" 2>/dev/null || echo
0)) to use grep -E and unescaped pipe characters (e.g. grep -c -E
'mcp_task|"tool_name":"task"|"name":"task"' ...) so it matches the codebase
convention and improves readability; apply the same change to the analogous
occurrence referenced (lines around 8986-8992).

Comment on lines +4548 to +4554
# Task tool parallelism tracking (t217): detect whether the worker used the
# Task tool (mcp_task) to spawn sub-agents for parallel work. This is a
# heuristic quality signal — workers that parallelise independent subtasks
# are more efficient. Logged for pattern tracking and supervisor dashboards.
local task_tool_count=0
task_tool_count=$(grep -c 'mcp_task\|"tool_name":"task"\|"name":"task"' "$log_file" 2>/dev/null || echo 0)
echo "task_tool_count=$task_tool_count"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and get its basic info
ls -la .agents/scripts/supervisor-helper.sh 2>&1 || echo "File not found"

Repository: marcusquinn/aidevops

Length of output: 151


🏁 Script executed:

# Check the actual content at the specified line ranges
echo "=== Lines 4548-4554 ===" && sed -n '4548,4554p' .agents/scripts/supervisor-helper.sh
echo "=== Lines 8986-8992 ===" && sed -n '8986,8992p' .agents/scripts/supervisor-helper.sh

Repository: marcusquinn/aidevops

Length of output: 1093


🏁 Script executed:

# Test grep behavior with basic regex (\|) vs extended regex (|)
# Create test data with mcp_task, "tool_name":"task", and "name":"task" patterns
test_data='log entry with mcp_task here
another line with "tool_name":"task"
more log with "name":"task" in it'

echo "=== Testing with basic regex (escaped pipes \|) ===" 
echo "$test_data" | grep -c 'mcp_task\|"tool_name":"task"\|"name":"task"' || echo "Count: 0 or grep found no matches"

echo "=== Testing with extended regex (-E, unescaped pipes) ==="
echo "$test_data" | grep -cE 'mcp_task|"tool_name":"task"|"name":"task"' || echo "Count: 0 or grep found no matches"

echo "=== Verify both return actual counts ===" 
echo "$test_data" | grep -c 'mcp_task\|"tool_name":"task"\|"name":"task"'
echo "$test_data" | grep -cE 'mcp_task|"tool_name":"task"|"name":"task"'

Repository: marcusquinn/aidevops

Length of output: 222


🏁 Script executed:

# Count total instances of this grep pattern in the file to ensure we have all of them
rg -n 'grep.*mcp_task' .agents/scripts/supervisor-helper.sh | head -20

Repository: marcusquinn/aidevops

Length of output: 299


🏁 Script executed:

# Verify the critical point: test literal | in basic regex (should NOT work)
test_data='log entry with mcp_task here
another line with "tool_name":"task"
more log with "name":"task" in it'

echo "=== Testing literal | in basic regex (should NOT match) ===" 
echo "$test_data" | grep -c 'mcp_task|"tool_name":"task"|"name":"task"' 2>&1

echo "=== Count using literal pipes ===" 
echo "$test_data" | grep 'mcp_task|"tool_name":"task"|"name":"task"'

echo "=== Confirm escaped pipes work in basic regex ===" 
echo "$test_data" | grep -c 'mcp_task\|"tool_name":"task"\|"name":"task"'

Repository: marcusquinn/aidevops

Length of output: 211


🏁 Script executed:

# Test ShellCheck on the grep patterns to see if there's a style warning
cat > /tmp/test_grep.sh << 'EOF'
#!/bin/bash
log_file="test.log"

# Original with escaped pipes (basic regex)
task_tool_count=$(grep -c 'mcp_task\|"tool_name":"task"\|"name":"task"' "$log_file" 2>/dev/null || echo 0)

# Suggested with -E and unescaped pipes (extended regex)
task_tool_count=$(grep -cE 'mcp_task|"tool_name":"task"|"name":"task"' "$log_file" 2>/dev/null || echo 0)
EOF

# Check if ShellCheck is available and run it
if command -v shellcheck &> /dev/null; then
    shellcheck /tmp/test_grep.sh
else
    echo "ShellCheck not available, but both patterns are syntactically valid."
fi

Repository: marcusquinn/aidevops

Length of output: 412


🏁 Script executed:

# Verify which grep variants are idiomatic/recommended in the codebase
echo "=== Check grep usage patterns in supervisor-helper.sh ===" 
rg 'grep\s+-' .agents/scripts/supervisor-helper.sh | head -15

Repository: marcusquinn/aidevops

Length of output: 1767


Align grep syntax with codebase conventions.

The current code uses basic regex with escaped pipes (\|), which works correctly. However, the codebase consistently uses grep -E for extended regex patterns (see grep usage throughout the file). Switch to -E with unescaped pipes for readability and consistency.

🔧 Suggested fix
-    task_tool_count=$(grep -c 'mcp_task\|"tool_name":"task"\|"name":"task"' "$log_file" 2>/dev/null || echo 0)
+    task_tool_count=$(grep -cE 'mcp_task|"tool_name":"task"|"name":"task"' "$log_file" 2>/dev/null || echo 0)
-        task_tool_count=$(grep -cE 'mcp_task\|"tool_name":"task"\|"name":"task"' "$log_file" 2>/dev/null || echo 0)
+        task_tool_count=$(grep -cE 'mcp_task|"tool_name":"task"|"name":"task"' "$log_file" 2>/dev/null || echo 0)

Also applies to: 8986-8992

🤖 Prompt for AI Agents
In @.agents/scripts/supervisor-helper.sh around lines 4548 - 4554, Replace the
basic-regex grep call that sets task_tool_count with an extended-regex usage:
update the grep invocation that assigns task_tool_count (the line containing
task_tool_count=$(grep -c 'mcp_task\|"tool_name":"task"\|"name":"task"'
"$log_file" 2>/dev/null || echo 0)) to use grep -E and unescaped pipe characters
(e.g. grep -c -E 'mcp_task|"tool_name":"task"|"name":"task"' ...) so it matches
the codebase convention and improves readability; apply the same change to the
analogous occurrence referenced (lines around 8986-8992).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

t219: PR lifecycle — faster merge pipeline with parallel CI + review triage

1 participant