Skip to content

fix false positive 'Ready to merge' with multi-layer CI detection (Issue #1480)#1481

Merged
konard merged 13 commits into
mainfrom
issue-1480-166d1fb39c80
Mar 28, 2026
Merged

fix false positive 'Ready to merge' with multi-layer CI detection (Issue #1480)#1481
konard merged 13 commits into
mainfrom
issue-1480-166d1fb39c80

Conversation

@konard

@konard konard commented Mar 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #1480

The auto-merge monitor posted a false positive "Ready to merge" comment on PR #1479 just 19 seconds after the last commit was pushed. CI workflows had not yet been registered in the GitHub Actions API, but the code incorrectly concluded "CI was definitively NOT triggered."

Root Cause

The fix for issue #1442 assumed that if getWorkflowRunsForSha() returns 0 workflow runs, CI was "definitively NOT triggered." But GitHub Actions workflow runs take 30-120 seconds to appear in the API after a push. The code only protected against check-runs not appearing yet, but not against workflow runs themselves not appearing yet.

Timeline of the false positive:

09:53:33Z — Commit 9ed29b7 pushed
09:53:50Z — getMergeBlockers() called (17 seconds after push)
09:53:50Z — getWorkflowRunsForSha() returns [] (not registered yet)
09:53:50Z — Code concludes: "CI definitively NOT triggered" ← FALSE POSITIVE
09:53:52Z — "Ready to merge" comment posted
09:55:18Z — CI actually starts running
09:56:11Z — CI finishes with FAILURES (lint, check-file-line-limits)

Fix: Multi-Layer CI Detection Defense

Four-layer defense against the race condition, collecting data from all available GitHub API endpoints:

  1. Layer 1 — Empty workflows folder detection: Parse .github/workflows/*.yml files via repository content API. If no workflow files exist, immediately conclude "no CI configured" — skip all other checks.

  2. Layer 2 — Grace period (120 seconds): When getWorkflowRunsForSha() returns 0 runs but commit is recent (< 120s), treat as potential race condition (ci_pending blocker). Also reports workflow PR triggers as context.

  3. Layer 3 — Previous commit CI history: After grace period, check if earlier commits in the same PR had workflow runs (checkPreviousPRCommitsHadCI()). If previous commits had CI AND workflow files have PR triggers, wait one more cycle as safety measure against GitHub API delays.

  4. Layer 4 — Definitive conclusion: Only conclude "CI not triggered" when grace period elapsed AND no previous commit CI evidence supports expecting CI.

GitHub API Data Sources Used

# API Endpoint Purpose
1 Check Runs API (commits/{sha}/check-runs) Check-runs from workflow jobs
2 Commit Statuses API (commits/{sha}/status) Legacy CI statuses (Jenkins, etc.)
3 Workflow Runs API (actions/runs?head_sha={sha}) Workflow runs for specific commit
4 Active Workflows API (actions/workflows) All configured repo workflows
5 Repository Content API (contents/.github/workflows) Parse workflow YAML for triggers
6 PR Commits API (pulls/{number}/commits) All PR commits for CI history
7 Commit API (commits/{sha}) Commit date for grace period

Changes

  • src/solve.auto-merge.lib.mjs: Multi-layer defense in getMergeBlockers() — empty workflows check, grace period, previous commit CI history
  • src/github-merge.lib.mjs: Added checkPreviousPRCommitsHadCI(), enhanced checkWorkflowsHavePRTriggers() with hasWorkflowFiles field
  • tests/test-false-positive-workflow-run-race-1480.mjs: 31 unit tests (10 test suites) covering all layers, priorities, edge cases
  • docs/case-studies/issue-1480/README.md: Full case study with timeline, all API data sources, multi-layer architecture
  • docs/case-studies/issue-1480/data/: Evidence data (PR add retry logic for transient GitHub API errors during PR creation (Issue #1478) #1479 details, comments, CI runs)
  • .changeset/fix-false-positive-ready-to-merge-1480.md: Changeset for patch release

Test plan

  • All 31 new tests pass (node tests/test-false-positive-workflow-run-race-1480.mjs)
  • All 12 existing issue We have Ready to merge as false positive #1363 tests still pass
  • All 14 existing issue Auto restart stuck at waiting for CI/CD #1466 tests still pass
  • Both modified source files pass syntax check (node -c)
  • Prettier formatting passes
  • File line limits check passes (all files under 1500 lines)
  • Backward compatible: repos with no CI, fork PRs with paths-ignore, action_required workflows all still handled correctly
  • Layer priority tested: no-files > grace-period > previous-CI > definitive-conclusion

🤖 Generated with Claude Code

Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: #1480
@konard konard self-assigned this Mar 25, 2026
konard and others added 3 commits March 25, 2026 12:12
…od (Issue #1480)

GitHub Actions workflow runs take 30-120s to appear in the API after a
push. The previous fix (issue #1442) assumed 0 workflow runs meant "CI
definitively NOT triggered", causing false positive "Ready to merge"
comments when checked within seconds of a push.

Adds a 120-second grace period: if a commit is recent and no workflow
runs are registered yet, treat it as a potential race condition instead
of concluding CI won't run. Also adds workflow file parsing to check
for PR triggers as an additional signal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
21 tests covering:
- Exact PR #1479 false positive scenario reproduction
- Grace period boundary conditions (0s, 119s, 120s, 300s)
- Null commit date edge case
- Workflow file PR trigger parsing patterns
- Backward compatibility with issue #1466 (action_required)
- End-to-end scenarios (fork PRs, paths-ignore, schedule-only)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@konard konard changed the title [WIP] Ready to merge was posted as false positive fix false positive 'Ready to merge' by adding workflow run grace period (Issue #1480) Mar 25, 2026
@konard
konard marked this pull request as ready for review March 25, 2026 12:15
konard and others added 2 commits March 25, 2026 12:17
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@konard

konard commented Mar 25, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $6.224289
  • Calculated by Anthropic: $3.966590 USD
  • Difference: $-2.257699 (-36.27%)

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Main model: Claude Opus 4.6 (claude-opus-4-6)
  • Additional models:
    • Claude Haiku 4.5 (claude-haiku-4-5-20251001)

📎 Log file uploaded as Gist (2539KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Mar 25, 2026

Copy link
Copy Markdown
Contributor Author

🔄 Auto-restart 1/3

Detected uncommitted changes from previous run. Starting new session to review and commit or discard them.

Uncommitted files:

?? ci-logs/gist-log-pr1479.txt

Auto-restart will stop after changes are committed or discarded, or after 2 more iterations. Please wait until working session will end and give your feedback.

@konard

konard commented Mar 25, 2026

Copy link
Copy Markdown
Contributor Author

🔄 Auto-restart 1/3 Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $1.500711
  • Calculated by Anthropic: $0.709610 USD
  • Difference: $-0.791102 (-52.72%)

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.6 (claude-opus-4-6)

📎 Log file uploaded as Gist (3068KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Mar 25, 2026

Copy link
Copy Markdown
Contributor Author

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@konard

konard commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

I think not all my requirements from the original issue are implemented.

We need to ensure all changes are correct, consistent, validated, tested, logged and fully meet all discussed requirements (check issue description and all comments in issue and in pull request). Ensure all CI/CD checks pass.

@konard
konard marked this pull request as draft March 26, 2026 10:31
@konard

konard commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

🤖 AI Work Session Started

Starting automated work session at 2026-03-26T10:31:25.028Z

The PR has been converted to draft mode while work is in progress.

This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback.

konard and others added 5 commits March 26, 2026 10:35
…flow parsing (Issue #1480)

Layer 3 defense: check if previous PR commits had CI workflow runs before
concluding "CI not triggered" when grace period elapses. If earlier commits
had CI and workflow files have PR triggers, wait one more cycle as safety
measure against GitHub API delays.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…#1480)

When .github/workflows folder doesn't exist or has no workflow files,
skip the grace period entirely and immediately conclude "CI not configured
at file level". This avoids unnecessary waiting for repos with no workflows.

Also adds hasWorkflowFiles field to checkWorkflowsHavePRTriggers return value
to distinguish "no workflow files" from "files exist but no PR triggers".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Downloaded PR #1479 details including statusCheckRollup (confirms lint and
check-file-line-limits failures at 09:56:11, CI started at 09:55:18),
PR comments showing the false positive "Ready to merge" timeline.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…es, and references (Issue #1480)

Enhanced documentation with:
- All 7 GitHub API endpoints used for CI/CD status detection
- Multi-layer defense architecture (4 layers)
- Updated code path diagram showing the full decision tree
- GitHub API documentation references
- Links to downloaded evidence data files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…t history (Issue #1480)

Extended test suite from 21 to 31 tests:
- Suite 8: Empty workflows folder detection (3 tests) — Layer 1 priority
- Suite 9: Previous commit CI history (4 tests) — Layer 3 safety measure
- Suite 10: Multi-layer defense interaction (3 tests) — layer priority ordering

Updated simulation function to match enhanced getMergeBlockers logic with
hasWorkflowFiles field and previousCI parameter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@konard konard changed the title fix false positive 'Ready to merge' by adding workflow run grace period (Issue #1480) fix false positive 'Ready to merge' with multi-layer CI detection (Issue #1480) Mar 26, 2026
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@konard
konard marked this pull request as ready for review March 26, 2026 10:48
@konard

konard commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $9.040130
  • Calculated by Anthropic: $6.175347 USD
  • Difference: $-2.864783 (-31.69%)

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Main model: Claude Opus 4.6 (claude-opus-4-6)
  • Additional models:
    • Claude Haiku 4.5 (claude-haiku-4-5-20251001)

📎 Log file uploaded as Gist (3210KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Mar 26, 2026

Copy link
Copy Markdown
Contributor Author

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@konard

konard commented Mar 28, 2026

Copy link
Copy Markdown
Contributor Author

Get latest changes from default branch, and double check everything.

We need to ensure all changes are correct, consistent, validated, tested, logged and fully meet all discussed requirements (check issue description and all comments in issue and in pull request). Ensure all CI/CD checks pass.

@konard
konard marked this pull request as draft March 28, 2026 19:23
@konard

konard commented Mar 28, 2026

Copy link
Copy Markdown
Contributor Author

🤖 AI Work Session Started

Starting automated work session at 2026-03-28T19:23:47.907Z

The PR has been converted to draft mode while work is in progress.

This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback.

@konard
konard marked this pull request as ready for review March 28, 2026 19:29
@konard

konard commented Mar 28, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Public pricing estimate: $1.276822
  • Calculated by Anthropic: $0.632066 USD
  • Difference: $-0.644756 (-50.50%)

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.6 (claude-opus-4-6)

📎 Log file uploaded as Gist (399KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Mar 28, 2026

Copy link
Copy Markdown
Contributor Author

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@konard
konard merged commit 50e5d47 into main Mar 28, 2026
21 checks passed
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.

Ready to merge was posted as false positive

1 participant