---
name: updating-security
description: Resolve open GitHub Dependabot security alerts on a fleet repo. Fetches alerts via `gh api`, applies fixes (direct dep bump, pnpm override for transitives, or principled dismissal for unfixable), validates with `pnpm run check`, commits per-alert, and reports remaining advisories. Sibling of `updating-lockstep` under the `updating` umbrella.
user-invocable: true
allowed-tools: AskUserQuestion, Read, Edit, Grep, Glob, Bash(gh api:*), Bash(gh auth:*), Bash(pnpm:*), Bash(git:*), Bash(node:*), Bash(jq:*)
---

# updating-security

Walk open Dependabot security alerts on the current repo and fix
them via the cheapest principled mechanism. Invoked directly via
`/update-security` or as Phase 5 of the `updating` umbrella.

## When to use

- A `gh dependabot alerts` listing shows open advisories.
- The GitHub web UI security tab is non-empty after a push (`gh`
  warns "Dependabot found N vulnerabilities" on push completion).
- As part of weekly maintenance (the `updating` umbrella invokes
  this automatically when alerts are present).

## What it does NOT do

- **Disable alerts at the repo level.** Suppressing the security
  tab via repo settings is a separate (heavier) decision; this
  skill resolves the underlying CVEs.
- **Touch `dependabot.yml`.** The fleet ships a no-op
  `dependabot.yml` (`open-pull-requests-limit: 0`) so Dependabot
  doesn't open version-update PRs; security alerts are independent
  and surface regardless.
- **Auto-dismiss without evidence.** Dismissals require a reason
  matching one of GitHub's documented values
  (`fix_started` / `inaccurate` / `no_bandwidth` / `not_used` /
  `tolerable_risk`) and a one-line justification. The skill asks
  before dismissing.

## Phases

| #   | Phase                | Outcome                                                                                                                       |
| --- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| 1   | Discover             | `gh api repos/{owner}/{repo}/dependabot/alerts?state=open`. Group by package + relationship (direct / transitive).            |
| 2   | Classify             | Each alert → one of: `direct-fix` (bump `package.json`), `override-fix` (pnpm override for transitive), `dismiss-with-reason`. |
| 3   | Apply direct fixes   | For each direct dep: `pnpm update <pkg>@<first-patched-version>` (or higher); commit per alert.                               |
| 4   | Apply override fixes | For each transitive: add `pnpm.overrides[<pkg>]` to `package.json` pinning the patched range; `pnpm install`; commit per row. |
| 5   | Validate             | `pnpm run check --all` (interactive) or `pnpm run check --staged` (CI). Roll back any commit whose check fails.                |
| 6   | Push                 | Per CLAUDE.md push policy — `git push origin <branch>`, fall back to PR on rejection. NEVER force-push.                       |
| 7   | Verify resolution    | After push lands, `gh api .../dependabot/alerts` should show each fixed alert as `auto_dismissed` or `fixed`. Log remaining.   |
| 8   | Report               | Per-alert table: alert # / pkg / severity / action taken / state.                                                             |

## Hard requirements

- **Clean tree on entry** — same rule as `updating` umbrella.
- **One commit per alert** — `chore(security): bump <pkg> to <ver> (GHSA-XXXX)` or `chore(security): override <pkg> ~> <ver> (GHSA-XXXX)`.
- **No `--no-verify`** — the soak / cooldown guard (`minimum-release-age-guard`) MUST be honored. If a patched version is inside the 7-day soak, the skill notes the alert as `awaiting-soak` and returns without modification.
- **Conventional Commits** — `chore(security): <action>` (per CLAUDE.md _Commits & PRs_).
- **Default-branch fallback** — never hard-code `main` (per CLAUDE.md _Default branch fallback_).
- **GitHub auth** — assumes `gh auth status` returns OK. Token must have `security_events:read` + `repo` scopes. Personal `gh` login satisfies both.

## Success criteria

- Every alert that has a `first_patched_version` is either fixed,
  awaiting-soak, or has an explicit dismissal request.
- Working tree clean after the commit chain.
- `pnpm run check` passes against the fix set.

**Safety:** every commit is atomic and the skill can be interrupted at
any phase. Resume by re-running — already-applied fixes show up as
`auto_dismissed` and are skipped.

Full bash, alert-shape reference, dismissal-reason taxonomy, and
recovery procedures in [`reference.md`](reference.md).
