# Actions and fixes

> Every change opsen can make, the API call behind it, and how to undo it.

Actions are taken only when an owner or admin presses the button for them. Every one is recorded in **Activity** with who pressed it, what the platform returned and what it saves, and in the [audit log](/docs/audit-log). Viewers cannot take actions.

## Fix pull requests

**Open fix PR** appears next to a workflow in [superseded runs](/docs/actions-minutes#superseded-pull-request-runs) and [hung jobs](/docs/actions-minutes#jobs-that-hang).

### What changes

Patches are textual insertions. The file is not parsed and re-serialised, which would reorder keys, drop comments and turn a five-line change into a rewrite. After patching, the file is parsed again and must be identical to the original apart from the added keys; if it is not, no pull request opens.

```diff title=".github/workflows/ci.yml · concurrency"
@@ -4,4 +4,10 @@
   push:
     branches: [main]
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
+  # Cancels superseded pull request runs only. Pushes to a branch are
+  # never cancelled, so deploys and release builds run to completion.
+  cancel-in-progress: ${{ github.event_name == 'pull_request' }}
 
 # the jobs
```

```diff title=".github/workflows/build.yml · timeouts"
@@ -3,4 +3,5 @@
 jobs:
   build:
+    timeout-minutes: 40
     runs-on: ubuntu-latest
     steps:
```

The group is keyed on the pull request number, so two pull requests never cancel each other, and `cancel-in-progress` is true only for `pull_request` events. A push to `main` is never cancelled.

opsen does not patch a file that already sets top-level `concurrency`, or a job that calls a reusable workflow (`uses:`), which cannot take a timeout.

### Linting

Before the pull request opens, the patched file is run through [actionlint](https://github.com/rhysd/actionlint) in an isolated sandbox. A file that fails lint never becomes a pull request; the failure is recorded in **Activity**. If the sandbox is unreachable the pull request still opens and its description says it was not linted.

### The pull request

| | |
| --- | --- |
| Branch | `opsen/cancel-superseded-runs-<file>` or `opsen/job-timeouts-<file>` |
| Base | the repository's default branch |
| Body | why, the measured monthly saving, the lint result, a link to the report |

Pressing the button again before the next audit changes nothing. After it, while the pull request is still open, it links to the existing one and counts no new saving. Closing it changes nothing else.

## Reclaim Copilot seats

`DELETE /orgs/{org}/copilot/billing/selected_users`. Seats go to pending cancellation and keep working to the end of the cycle. See [Copilot seats](/docs/copilot#reclaiming).

## Cancel invitations

`DELETE /orgs/{org}/invitations/{id}`, one per selected invitation. Failures are listed individually.

## Disable a schedule

`PUT /repos/{org}/{repo}/actions/workflows/{id}/disable`. Re-enable it from the repository's Actions tab.

## Not offered

Removing members or collaborators, deleting repositories, deleting workflows, or changing billing settings. These are listed and exported; GitHub is where they are done.


## Changes on other platforms

Findings from connected platforms carry their own one-click change. Each person is listed with a checkbox; untick anyone who should keep access.

| Platform | Button | What happens | Undo |
| --- | --- | --- | --- |
| GitLab (gitlab.com) | Remove members | Removed from the top-level group and every subgroup and project | Invite again |
| GitLab (self-managed) | Deactivate users | The licence seat frees; they are reactivated on their next sign-in | Reactivate in the admin area |
| GitLab Duo | Unassign seats | The Duo seat is unassigned; GitLab access is unchanged | Assign the seat again |
| Azure DevOps | Move to Stakeholder | The Basic or Test Plans charge stops; account and work items stay | Give Basic again |
| Atlassian | Remove access | That product's access is removed; account and other products stay | Grant access in admin.atlassian.com |
| JetBrains | Revoke licences | The licence returns to your pool | Assign it again |

The key you connected needs write access for these; each platform's guide says which.

## Fix in your IDE

Findings that are fixed in code (superseded runs, hung jobs, dormant schedules, failing CircleCI workflows) have a **Fix in your IDE** menu on each row. It opens Cursor, Claude Code or Codex with a prompt that names the repository and file, the measured cost, the exact change and how to check it, for you to review before it runs. **Run in the cloud** starts the same fix with Devin, a Cursor cloud agent or GitHub Copilot's coding agent, which opens a pull request. Connect Devin and Cursor in **Settings → Coding agents**; Copilot uses your own GitHub sign-in. See [MCP, plugins and API](/docs/mcp).
