Skip to content
Back to skills

Snyk Pr

ASecurity

Remediate a Snyk bot PR ([Snyk] Upgrade ..., author posit-snyk-bot, branch snyk-upgrade-*) so it goes green on CI and becomes mergeable. Use when the user asks to fix, unblock, or "make mergeable" a Snyk PR, mentions a red Snyk upgrade PR, or pastes a snyk-upgrade-* branch name. Invoke as /snyk-pr <PR#>; with no argument, list open posit-snyk-bot PRs and stop. Fixes the branch only — never weakens or skips the CI guard tests.

  • 265 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 3, 2026
testingrustgobashreactnodegit

Works with

  • cli

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 3 files and shows the line behind each finding

Scanned September 24, 2026

npx -y skills add quarto-dev/q2 --skill snyk-pr --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Snyk Pr?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Snyk Pr
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/quarto-dev-snyk-pr/badge)](https://www.skillsdirectory.com/skills/quarto-dev-snyk-pr)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: snyk-pr
description: Remediate a Snyk bot PR ([Snyk] Upgrade ..., author posit-snyk-bot, branch snyk-upgrade-*) so it goes green on CI and becomes mergeable. Use when the user asks to fix, unblock, or "make mergeable" a Snyk PR, mentions a red Snyk upgrade PR, or pastes a snyk-upgrade-* branch name. Invoke as /snyk-pr <PR#>; with no argument, list open posit-snyk-bot PRs and stop. Fixes the branch only — never weakens or skips the CI guard tests.
---

# snyk-pr: remediate a Snyk bot PR

Snyk integration is mandatory for this org, and its bot PRs recur. The bot
upgrades a dependency in exactly one `package.json` + lockfile pair, but this
repo deliberately couples dependency versions across multiple surfaces and
enforces the coupling with guard tests. The bot's PRs therefore arrive red
**by design** — the CI system is working. This skill fixes the *branch*, never
the checks.

## Invariants (read first)

- **Never weaken, skip, or `#[ignore]` a guard test.** If a guard fails, more
  copies of the version need bumping — find them.
- **Exact pins, no carets.** Guard tests require exact versions where the repo
  pins exactly; Snyk sometimes writes `^X.Y.Z` into lockfile mirrors — normalize
  it away (see the katex reference).
- **`npm install` only from the repo root** (npm workspaces), never from
  `hub-client/`. Sub-project installs (e.g. `quarto-hub-sandboxed-preview`) are
  driven by their own scripts (`npm run build:sandboxed`).
- **Push only with explicit user approval** (GIT PUSH POLICY in AGENTS.md).
  Merging the PR is always a human decision.
- **hub-client changes require the changelog two-commit workflow** (AGENTS.md,
  "hub-client Commit Instructions"). A regenerated committed bundle under
  `hub-client/` counts.

## Workflow

### 0. No argument? List and stop.

```bash
gh pr list --repo quarto-dev/q2 --author posit-snyk-bot --state open \
  --json number,title,headRefName
```

Report the list and stop — remediation needs a specific PR number.

### 1. Orient remotely — extract the *actual* failure

```bash
gh pr view <N> --repo quarto-dev/q2 --json title,headRefName,state,body
gh pr checks <N> --repo quarto-dev/q2
```

For each failing job, pull the log and find the real failing test — do not
assume it is the usual guard:

```bash
gh run view --repo quarto-dev/q2 --job <job-id> --log-failed 2>&1 | \
  sed 's/\x1b\[[0-9;]*m//g' | grep -B2 -A20 "FAIL \["
```

Known signatures:
- `katex_cdn_version_matches_npm_pin` (quarto-core) → the katex case; follow
  `references/katex.md`.
- Merge-conflict / "This branch has conflicts" on a paired package (react +
  react-dom) → follow `references/paired-packages.md`.
- Anything else → treat as a new package playbook: follow the generic steps
  below, and **add a new `references/<package>.md` before closing out** so the
  next occurrence is mechanical.

### 2. Fetch the bot branch and work on it directly

The bot pushes branches to quarto-dev/q2 itself (not a fork), so fix commits
go on the same branch. Use a worktree to avoid disturbing the main checkout:

```bash
git fetch origin <snyk-upgrade-...>
git worktree add .worktrees/snyk-pr-<N> <snyk-upgrade-...>
cd .worktrees/snyk-pr-<N>
```

(Plain `git switch` in the main checkout is acceptable if it is clean and the
user agrees.)

### 3. Merge `origin/main` first

Snyk branches are cut from stale mains — routinely weeks old. Merge before
touching anything else so you fix against current reality:

```bash
git fetch origin main
git merge origin/main
```

Resolve conflicts; for paired-package conflicts see
`references/paired-packages.md`. On a `.braid/snapshot.jsonl` conflict,
regenerate from the skein (`braid export > .braid/snapshot.jsonl`) — never
hand-merge.

### 4. Enumerate every copy of the version

The guard tests may lag reality (the committed sandbox bundle was invisible to
them — PR #571 missed it, PR #573 repaired it). Grep for *all* consumers of the
version, including committed build artifacts:

```bash
grep -rn '<pkg>@\|"<pkg>":' \
  --include='*.json' --include='*.rs' --include='*.ts' --include='*.tsx' \
  --include='*.html' . 2>/dev/null | \
  grep -v node_modules | grep -v target | grep -v '\.worktrees'
# then grep committed artifacts for the OLD version string itself:
grep -rn '<old-version>' hub-client/public/ resources/ 2>/dev/null | head
```

Every hit must end up naming the new version (or be justified as unrelated).

### 5. Apply the package playbook

- katex → `references/katex.md` (three coupled surfaces; the committed bundle
  was removed in `5684cfead`).
- react/react-dom → `references/paired-packages.md`.
- unknown package → bump all copies found in step 4; run a root `npm install`;
  rebuild any committed artifact that embeds the package.

### 6. Verify

Scale to what changed, per AGENTS.md:

```bash
# targeted guard first (fast signal)
cargo nextest run -p quarto-core -E 'test(katex_cdn_version_matches_npm_pin)'
# Rust files changed => workspace build + tests
cargo build --workspace && cargo nextest run --workspace
# hub-client touched => production build (stricter than tsc --noEmit)
cd hub-client && npm run build:all
# hub-client touched => CSS lint (a CI gate that neither test:ci nor
# cargo xtask verify runs — it red-flagged main for days unnoticed)
npm run lint:css
# dirty-tree trap: a fresh root install must not modify tracked files
npm install && git status --porcelain
```

`git status` must come back clean after the root install — if it dirties a
lockfile, a caret or pin mismatch survived (step 5 incomplete).

**Attribute failures before reacting to them.** After merging main, the branch
inherits any breakage main already has. When a verification leg fails, run the
same test file against `origin/main` (main checkout) and check main's recent
workflow runs (`gh run list --branch main`) before assuming your change caused
it. A failure that reproduces identically on main is pre-existing: file it as a
braid strand (`discovered-from` the current work), document it in the fix
commit's message, and proceed — the bar for the Snyk branch is "as green as
main", not "greener than main". (Seen 2026-09-01: 29 hub-client vitest
failures on the #637 branch were main's own mock drift, unrelated to katex.)

**Also run out-of-gate suites sensitive to the upgraded package.** Some test
tiers are not in the CI merge gate (see the ci-test-suite-unwired lint's known
gaps, e.g. `preview-renderer`'s `test:integration`). If the upgraded package
can affect one, run it from the remediation branch — it can confirm the
upgrade *fixes* known breakage (katex 0.18.4 fixed the `.katex-tag` strands)
or catch a regression CI would miss.

### 7. Commit (+ changelog if hub-client changed)

Commit the alignment with a message that records **which copies were bumped
and why** (see `ccaa8cc9` for the model). If any `hub-client/` file changed,
follow the two-commit changelog workflow: commit the change, then add the
`hub-client/changelog.md` entry referencing that commit's hash in a second
commit.

When a regenerated committed bundle is part of the diff, report its byte delta:
a pure version bump should change only version strings; a large delta means the
bundle was already stale — call that out explicitly.

### 8. Push with approval, watch CI, report

Ask the user for permission to push (GIT PUSH POLICY). Then:

```bash
git push origin HEAD:<snyk-upgrade-...>
gh pr checks <N> --repo quarto-dev/q2 --watch
```

Report the final check status. Do not merge; offer the green PR back to the
user. Clean up the worktree (`git worktree remove .worktrees/snyk-pr-<N>`).

### 9. Close the loop

If anything new was learned (a new package, a new failure signature, a new
committed artifact), fold it into this skill / a new reference file in the same
session, and file discovered work as braid strands linked
`discovered-from:<the strand you're working under>`.

## History (why each rule exists)

- #471, #571, #634 (katex): only-one-copy-bumped guard failures; #571's fix
  missed the committed sandbox bundle → follow-up PR #573. Playbook commit:
  `ccaa8cc9`.
- #511/#512 (react/react-dom): paired PRs conflicted with each other;
  resolution merged main and took both new versions (`91977474`).
- #637 (katex 0.18.2→0.18.4): validation target for this skill; same guard
  signature, branch predated the doc-branching merge.

Files in this skill

  • SKILL.md8.2 KB
  • references/katex.md2.9 KB
  • references/paired-packages.md1.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.