Commit graph inspector/scripts/dependabot-alerts.mjs
Author SHA1 Message Date
cliffhall
1e58d2fe8a
chore(deps): address Copilot review round 4 on #2243
- Narrow each group to the advisories the installed copies are actually
  in range of. Two advisories can share a package, manifest and patched
  version while having different vulnerable ranges, so a group-level
  "does any match?" left the marker, title, severity and table all
  claiming an advisory that does not apply on this branch.
- Escape every free-form Markdown cell, the vulnerable range included.
  A semver range may contain `||`, which is also the column separator.
- Paginate the open-issue lookup instead of capping it at 100. The
  marker lookup is what makes the sweep idempotent, so a truncated list
  would file a duplicate for every issue it could not see — at the same
  scale the alert fetch is built to handle. Pull requests, which the
  issues endpoint also returns, are dropped.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6Cew3KB3jVmQ5x4Dq1sq
Signed-off-by: cliffhall <cliff@futurescale.com>
2026-09-04 09:06:32 -04:00
cliffhall
5c65bd2bfa
chore(deps): address Copilot review round 3 on #2243
Derive the remediation from WHICH copies are vulnerable, not from
whether the package is declared. A manifest can declare a safe `pkg@4`
while a dependency drags a vulnerable `pkg@3` into a nested folder; the
old boolean called that "direct" and asked for a range bump that would
have changed nothing, omitting the override the nested copy needs.

- `lockfileEntries` keeps each copy's tree path and whether it is the
  hoisted one; `lockfileVersions` is now derived from it.
- `remediation(affected, declared)` returns both flags, so the issue can
  ask for a range bump, an overrides pin, or explicitly both. The body
  lists the vulnerable copies and their paths.
- An undeclared hoisted copy counts as transitive: it got there the same
  way any other transitive copy did, and no declared range reaches it.
  (Found by a test written for this change.)

The `vulnerability-alerts: read` finding is declined — verified against
a real runner, which reports `VulnerabilityAlerts: read` and reads the
alerts successfully. See the PR comment for the log.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6Cew3KB3jVmQ5x4Dq1sq
Signed-off-by: cliffhall <cliff@futurescale.com>
2026-09-04 09:06:32 -04:00
cliffhall
761bdd128d
chore(deps): address Copilot review round 2 on #2243
- Remove the literal NUL bytes that were separating the grouping key's
  fields; they classified the whole source file as binary, so repo
  searches skipped it. The key is a JSON array now, with no separator
  left to justify.
- De-duplicate advisory comments per GHSA rather than per whole set. A
  run that comments and then fails before the marker edit left the next
  run computing a different set, which matched nothing and announced the
  same advisory twice.
- Refresh the issue title on edit; it carries the advisory count, so it
  went stale as soon as an issue grew past what it was filed with.
- Correct the test file's header, which still claimed main() was left
  to workflow_dispatch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6Cew3KB3jVmQ5x4Dq1sq
Signed-off-by: cliffhall <cliff@futurescale.com>
2026-09-04 09:06:32 -04:00
cliffhall
b53266bc72
chore(deps): address Copilot review round 1 on #2243
- `--slurp` the paginated alert feed; a bare `--paginate` emits one JSON
  array per page and `JSON.parse` rejects it past 100 open alerts.
- Put `fixedIn` in the marker and in the existing-issue lookup, so a
  second bump of one package cannot merge into the first one's issue.
- Only an authorization-shaped failure of the `automated-security-fixes`
  read becomes UNVERIFIED; a rate limit or 5xx now throws.
- Distinguish "card never added" (benign, triage picks it up) from
  "card added, field not set" — the latter finishes every group, then
  fails the run.
- Don't board an unmilestoned issue at Todo; `Incoming` <=> no milestone.
- Comment before rewriting the marker, and give the comment its own
  marker, so a failed comment cannot be skipped forever.
- Ask a direct dependency's range to be raised, not widened to `>=`.
- Test `main()` through an injected spawn, as the sibling sweep does.
- Correct the docs that named the removed release-time `npm audit fix`,
  the ones promising an unconditional guard, and the sibling sweep's
  issue body claiming security updates remain enabled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6Cew3KB3jVmQ5x4Dq1sq
Signed-off-by: cliffhall <cliff@futurescale.com>
2026-09-04 09:06:32 -04:00
cliffhall
66a3332f1d
chore(deps): sweep Dependabot alerts into board-tracked issues
Closes #2233 — the alert-consuming half of #2229. #2235 removed
`.github/dependabot.yml`, ending Dependabot's version-update PRs; this
ends its security-update PRs and replaces them with a daily sweep that
turns the alerts into ordinary board items.

- `scripts/dependabot-alerts.mjs` groups alerts by
  `(package, manifest_path, first_patched_version)` — one issue per
  BUMP, not per advisory — re-checks each vulnerable range against
  `v2/main`'s own lockfile before filing, and keys idempotency on a
  marker comment naming every GHSA the issue covers.
- `.github/workflows/dependabot-alerts.yml` runs it daily and on
  `workflow_dispatch`, with `vulnerability-alerts: read`.
- `semver` is declared at the repo root, per Dependency placement:
  `scripts/` is root-owned code with no manifest of its own.
- The sibling `dependency-refresh` comments no longer claim security
  updates are unaffected, and AGENTS.md gains the flow both halves
  now follow.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013H6Cew3KB3jVmQ5x4Dq1sq
Signed-off-by: cliffhall <cliff@futurescale.com>
2026-09-04 09:06:32 -04:00