Skip to content

fix(ci): harden repository reconciliation drift detection - #1788

Open
groupthinking with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-repository-drift-report
Open

fix(ci): harden repository reconciliation drift detection#1788
groupthinking with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-repository-drift-report

Conversation

Copilot AI commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Canonical issue

Outcome

Repository reconciliation stops flagging valid PRs as missing a canonical issue when they use repo-qualified closing refs or when the linked issue has already been closed. The drift report also refreshes on the repository events that actually change reconciliation state instead of waiting for the daily cron.

Scope

  • Included:
    • Trigger coverage
      • Run reconciliation on pull_request_target lifecycle changes, issues open/close changes, and branch create / delete.
    • Canonical issue parsing
      • Accept both Closes #123 and Closes owner/repo#123.
      • Treat validated issues as canonical regardless of open/closed state; still exclude PR references and missing issues.
    • Regression coverage
      • Add workflow contract tests for trigger wiring.
      • Add behavioral tests that execute the inline github-script against stubbed GitHub API responses for the two false-positive cases.
    • Example
      Closes #1669
      Closes groupthinking/EventRelay#900
  • Explicitly excluded:
    • branch cleanup or deletion policy
    • report formatting changes beyond corrected classification behavior
    • broader governance/remediation changes outside repository reconciliation

Risk

  • Risk level: low
  • Failure mode:
    • Over-broad trigger wiring could run the report more often than intended.
    • An overly permissive closing-ref regex could misclassify non-canonical text, though issue validation remains the backstop.
  • Rollback:
    • Revert .github/workflows/repository-reconciliation.yml and tests/unit/test_repository_reconciliation_workflow.py.

Verification

List exact automated and manual checks, tied to the current head SHA.

  • Automated:
    • python -m pytest tests/unit/test_repository_reconciliation_workflow.py -q --override-ini=addopts=''
    • behavioral workflow tests cover repo-qualified refs and closed canonical issues
    • parallel validation reported no review findings and no CodeQL alerts
  • Manual:
    • inspected the generated workflow diff to confirm the change is limited to trigger wiring and canonical-issue classification
  • Focused tests
  • Required CI
  • Review threads resolved

Production evidence

Not applicable. This change is limited to GitHub workflow automation and its regression tests; there is no runtime, Vercel, or production-surface change.

Agent handoff

  • One canonical issue is linked
  • No competing PR implements the same issue
  • Acceptance criteria are satisfied
  • Required checks pass on the current head
  • Human decision is requested only for product, security, irreversible infrastructure, or production approval

@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
v0-uvai Ready Ready Preview, v0 Sep 12, 2026 9:06am UTC

Co-authored-by: groupthinking <154503486+groupthinking@users.noreply.github.com>

@vercel vercel Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Additional Suggestion:

Broadened closing-reference regex accepts foreign owner/repo#N references and silently maps them onto local issue numbers, mis-binding PRs and fabricating duplicate groups.

Fix on Vercel

Copilot AI changed the title [WIP] Fix repository drift report issues fix(ci): harden repository reconciliation drift detection Sep 8, 2026
Copilot AI requested a review from groupthinking September 8, 2026 23:17
@groupthinking
groupthinking marked this pull request as ready for review September 12, 2026 08:03
@github-actions

Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 298f9d3.
Ensure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice.

Scanned Files

None

@coderabbitai

coderabbitai Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: d6edcba8-5ed0-4d0b-baa5-29c6fbf5d797

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

… references and silently maps them onto local issue numbers, mis-binding PRs and fabricating duplicate groups.

This commit fixes the issue reported at .github/workflows/repository-reconciliation.yml:40

## Bug

The closing-reference regex was broadened from `...#(\d+)` to:

```js
/(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+(?:[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)?#(\d+)/gi
```

The `(?:[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)?` prefix group is **non-capturing** and matches **any** `owner/repo`, but it is never compared against `repoFullName` (`${owner}/${repo}`). Only the trailing number is captured (`m[1]`), and downstream it is validated/classified against the **local** repo:

```js
const resp = await github.rest.issues.get({ owner, repo, issue_number: issueNum });
```

### Concrete trigger

A PR body containing `Closes otherorg/otherrepo#42` is parsed as issue `42`. It is then:

1. Validated via `issues.get({ owner, repo, issue_number: 42 })` against the **local** repo — if a local issue #42 exists, the PR is treated as canonically tracked by the wrong issue.
2. Added to `issueToPulls.get(42)`, so if another local PR legitimately references local #42, they are reported as a **false "competing PRs" duplicate group**, and the superseded-draft auto-close remediation could then act on them.

This silently binds a PR to the wrong (local) issue and can trigger destructive remediation (auto-closing draft PRs).

## Fix

- Made the repo prefix a **capturing** group so it can be inspected; the issue number is now `m[2]`.
- Added an `extractIssueNumbers(body)` helper that accepts a reference only when the prefix is **absent** (unqualified `#N`) or **equal to the current repo's full name** (`owner/repo#N`), discarding cross-repo references.
- Replaced both matchAll sites (issue-number collection and per-PR classification) with the helper.

Verified via a standalone Node script:

```
unqualified: [ 900 ]
local qualified: [ 900 ]
foreign: []
mixed: [ 5, 7 ]
```

Foreign references are dropped while the intended canonical repo-qualified form (`#900`) is still accepted.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: groupthinking <garveyht@gmail.com>
@cursor

cursor Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Backlog triage: leaving open. Drift-detection harden (#1584) is CONFLICTING vs rewritten main. Rebase required.

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

Labels

bug Something isn't working ci/cd python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[automation] Repository drift report

2 participants