# list_prs_addressed_changes_ci_failing — Open PRs With Failing CI, No Approvals, and Addressed Changes-Requested Reviews

**Script name:** `list_prs_addressed_changes_ci_failing`

**Script location:** [`scripts/list_prs_addressed_changes_ci_failing.ts`](../../../scripts/list_prs_addressed_changes_ci_failing.ts)

**Invoke:**
```bash
npx --yes tsx .opencode/skills/auto-agents-system/scripts/list_prs_addressed_changes_ci_failing.ts \
  --url URL --pat TOKEN --owner OWNER --repo REPO

**CRITICAL:** Always invoke the script using bash and the format noted above. **Never** try to use the skill as a task, or invoke it through any other method than by directly calling bash with a command of the form listed above under "Invoke:".
```


## Synopsis

```
list_prs_addressed_changes_ci_failing.ts --url URL --pat TOKEN --owner OWNER --repo REPO
```

Returns all **open** pull requests that have **failing CI**, **zero active
approvals**, **at least one active `REQUEST_CHANGES` review**, and where
**all `REQUEST_CHANGES` reviews have been addressed** — meaning the author has
pushed at least one new commit since every `REQUEST_CHANGES` review was filed.

These PRs have addressed reviewer feedback but broken CI in the process. A
reviewer can evaluate whether review feedback was addressed and flag CI failures
so the author can fix both issues.

This script is a thin wrapper around [`list_prs`](../list_prs/). It
hard-codes the following filters and delegates all logic to that script:

```
state:                        'open'
ciStatus:                     ['failing']
maxApprovals:                 0
hasRequestChanges:            true
hasUnaddressedRequestChanges: false
```


## Arguments

All four arguments are **required**. No optional filter arguments exist — the
filters are baked in and cannot be changed.

| Flag | Type | Description |
|------|------|-------------|
| `--url URL` | string | Forgejo base URL, **no trailing slash** (e.g. `https://git.example.com`) |
| `--pat TOKEN` | string | Personal Access Token with read access to the repository |
| `--owner OWNER` | string | Repository owner or organisation name |
| `--repo REPO` | string | Repository name |
| `-h`, `--help` | — | Print usage to stderr and exit 0 |

Any flag other than these five is **rejected** with exit code 1 and an error
message: `ERROR: Unknown argument: <flag>`. Filter parameters are hard-coded
and cannot be overridden via CLI flags on this wrapper script.

### Invalid Argument Combinations

There are no valid filter-combination errors since no optional filters exist.
However, passing any filter-style flag (e.g. `--min-approvals`, `--stale`, etc.)
will cause an immediate exit 1 — those flags are not accepted by this wrapper.


## Hard-Coded Filters

| Filter | Value | Meaning |
|--------|-------|---------|
| `state` | `open` | Only open PRs are returned |
| `ciStatus` | `['failing']` | CI checks have failed (`ci_status == 'failing'`) |
| `maxApprovals` | `0` | No reviewer has an active non-dismissed `APPROVED` review |
| `hasRequestChanges` | `true` | At least one reviewer's latest non-dismissed review is `REQUEST_CHANGES` |
| `hasUnaddressedRequestChanges` | `false` | Every `REQUEST_CHANGES` review has been followed by at least one new commit |

**"CI failing"** means the Forgejo combined commit-status for the PR's head SHA
returned `state == 'failure'` or `state == 'error'`. PRs with `pending`,
`passing`, or `unknown` CI are excluded.

**"Zero approvals"** means no reviewer has an active (non-dismissed) `APPROVED`
review as their most recent submission. The per-reviewer deduplication rule
applies: only the reviewer's highest-ID non-dismissed review counts per user.

**"Has request changes"** means at least one reviewer's latest non-dismissed
review has state `REQUEST_CHANGES`.

**"Addressed"** means every `REQUEST_CHANGES` review was submitted against a
commit that is no longer the PR's current HEAD SHA — the author has pushed at
least one new commit since the review was filed. Contrast with
[`list_prs_changes_requested`](../list_prs_changes_requested/) which selects
PRs where the `REQUEST_CHANGES` is **unaddressed** (no commits since the review).


## Output

Written to **stdout** as a pretty-printed JSON array sorted by `priority_rank`
(highest priority first). Each element is the full Forgejo PR object augmented
with four fields:

| Field | Type | Description |
|-------|------|-------------|
| `approvals_count` | integer | Will always be `0` for results of this script |
| `stale_state` | string | Any value — **not filtered** by this script |
| `ci_status` | string | Will always be `failing` for results of this script |
| `priority_rank` | integer | 0 (highest) through 6 (unlabelled) |
| `priority_label` | string \| null | Matched `Priority/*` label name, or `null` |

An **empty array** `[]` means no open PR currently has failing CI, zero
approvals, active REQUEST_CHANGES, and addressed feedback.

See [`list_prs`](../list_prs/) for the full output schema documentation.


## Diagnostics / stderr

Progress messages are written to stderr and do not affect the JSON output:

```
Fetching PRs from https://git.example.com/org/repo (state=open)...
Fetched 42 PR(s).  Enriching and filtering...
Fetching HEAD SHAs for 3 unique base branch(es)...
Fetching reviews for 42 PR(s) concurrently (limit=20)...
Fetching CI status for 42 PR(s) concurrently (limit=20)...

Result: 5/42 PR(s) matched the filter criteria.
```


## Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Success — JSON array written to stdout (may be `[]`) |
| 1 | Fatal error — message written to stderr |


## Errors the Script May Throw

| Condition | Behaviour |
|-----------|-----------|
| Missing `--url`, `--pat`, `--owner`, or `--repo` | Exit 1: `ERROR: --<flag> is required` |
| Any unknown flag passed | Exit 1: `ERROR: Unknown argument: <flag>` |
| Forgejo API non-2xx on PR list | Exit 1 with HTTP status and body detail |
| Forgejo API failure for a single branch or review | Warning to stderr; processing continues |
| Network timeout (30 s per request) | Exit 1 with error message |


## When to Use This Script

Use `list_prs_addressed_changes_ci_failing` when you need to identify PRs where
**reviewer feedback was addressed but CI broke**. The author pushed commits to
address `REQUEST_CHANGES` reviews, but the CI pipeline is now failing — a
reviewer can evaluate whether the feedback was addressed and flag the CI
failures. Typical use cases:

- **`pr-review-supervisor`** uses this as its **third-priority** review
  bucket: these PRs need attention because the author responded to feedback
  but introduced CI failures in the process.
- A **review dispatcher** agent can assign these to reviewers who can both
  verify the addressed feedback and identify CI-related issues.
- A **monitoring agent** can track this bucket to detect PRs stuck in a
  feedback-fix-break cycle.

### Position in the Review Pipeline

```
The review pipeline defines five non-overlapping buckets for open PRs
with zero approvals (excluding unaddressed REQUEST_CHANGES and CI pending):

  Bucket 1 — list_prs_addressed_changes_ci_passing    (addressed + CI passing)
  Bucket 2 — list_prs_no_active_review_ci_passing      (no review + CI passing)
  Bucket 3 — list_prs_addressed_changes_ci_failing     (addressed + CI failing)     ← THIS SCRIPT
  Bucket 4 — list_prs_no_active_review_ci_failing      (no review + CI failing)
  Bucket 5 — list_prs_missing_ci_checks                (no CI checks reported)
```

Workflow for a PR in this bucket once re-review passes:
```
Reviewer re-reviews + flags CI  →  author fixes CI  →  moves to Bucket 1 (if re-approved) or Bucket 2
```


## Usage Examples

```bash
# Standard usage
npx --yes tsx /app/.opencode/skills/auto-agents-system/scripts/list_prs_addressed_changes_ci_failing.ts \
  --url https://git.example.com \
  --pat ghp_XXXX \
  --owner my-org \
  --repo my-repo

# Count how many PRs addressed feedback but have failing CI
npx --yes tsx /app/.opencode/skills/auto-agents-system/scripts/list_prs_addressed_changes_ci_failing.ts \
  --url https://git.example.com \
  --pat ghp_XXXX \
  --owner my-org \
  --repo my-repo \
  | jq 'length'

# Get just the PR numbers and titles
npx --yes tsx /app/.opencode/skills/auto-agents-system/scripts/list_prs_addressed_changes_ci_failing.ts \
  --url https://git.example.com \
  --pat ghp_XXXX \
  --owner my-org \
  --repo my-repo \
  | jq '[.[] | {number, title}]'
```


## Agent Usage Examples

### pr-review-supervisor

The supervisor calls this script as the fetch algorithm for its third-priority
work group (`addressed_changes_ci_failing`). Each result is dispatched to a
`pr-review-worker` for a re-review that also flags CI failures.

```bash
npx --yes tsx /app/.opencode/skills/auto-agents-system/scripts/list_prs_addressed_changes_ci_failing.ts \
  --url $FORGEJO_URL \
  --pat $FORGEJO_PAT \
  --owner $REPO_OWNER \
  --repo $REPO_NAME
```


## Dependencies

- Node.js >= 18 (native `fetch` API)
- `npx tsx` for TypeScript execution
- Zero external npm packages
