Skip to content

fix(container-security): one Backlog ticket per image instead of one Triage ticket per CVE [ENG-3962] - #9781

Open
xernobyl wants to merge 1 commit into
mainfrom
fix/ENG-3962_container-scan-per-image-tickets
Open

xernobyl wants to merge 1 commit into
mainfrom
fix/ENG-3962_container-scan-per-image-tickets

Conversation

@xernobyl

Copy link
Copy Markdown
Contributor

Ref ENG-3962

What & why

Was: the daily container scan opened one ENG Triage ticket per image and CVE, which came to about 2.4k tickets on the first run. Most were linux-libc-dev kernel headers that never apply inside a container.

Now: each image repository with critical/high findings gets one Backlog ticket labelled container-scan. It lists every CVE with tags, architectures and fix versions, and closes when none are left.

  • linux-libc-dev is ignored. Images from docker-compose.dev.yml stay in scope.
  • Old per-CVE tickets still in Triage are canceled once their repository scans cleanly. Assessed ones are left alone.
  • Priority tops out at High. Medium/low findings are only counted, and a ticket closes when nothing above them remains.

Where to look

Breaking changes

  • This PR contains breaking changes

None. This only changes an internal CI job and how it writes Linear tickets; nothing reaches self-hosters or API consumers.

Migrations & env

  • none. The container-scan label already exists on the Engineering team.

How this was tested

Rerun: node node_modules/vitest/vitest.mjs run --config vitest.root.config.mts scripts/container-security/

Coverage

Behaviour How Outcome
One ticket per image repository across tags and architectures unit (red on main) — groups every CVE… Fails on main's sync.mjs, passes here
linux-libc-dev and medium/low findings open no ticket unit (mutation) — ignores kernel headers…; drop the IGNORED_PACKAGES check Turns red
Ticket stays open while any critical/high is left, closes otherwise unit (red on main) — keeps an image ticket open… Fails on main, passes here
Only untouched legacy tickets are canceled, and only after a complete scan unit (mutation) — supersedes untouched legacy…; drop canClose or the triage check in sync.mjs Turns red
Real data: yesterday's scan artifacts (30 images) against a stubbed Linear API manual 22 creates (19 images, 3 scan failures), all Backlog + container-scan, High/Medium; Triage legacy tickets canceled

Open gaps

  • Not run against real Linear. A manual dry run with the key shows the plan before the first write.
  • Canceling about 2.4k tickets takes one sequential request each, with no rate-limit backoff. A rerun is idempotent, so a cut-short run finishes the next day.

Risks

  • The biggest description, for taxonomy, is about 31k characters. I haven't checked that against Linear's description limit.

Note

AI model used — claude-opus-5-5, reasoning effort unknown.

…Triage ticket per CVE

The daily container scan opened one ENG Triage ticket per (image, CVE),
about 2.4k on its first run, most of them linux-libc-dev kernel headers
that never apply in a container.

Group findings per image repository into a single ticket listing its
critical/high CVEs, ignore linux-libc-dev, and create tickets in Backlog
with the container-scan label instead of Triage + vulnerability, capped
at High priority. Legacy per-CVE tickets still in Triage are canceled
once their repository scans successfully; assessed ones are left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between dd4b6da and 92c9edd.

📒 Files selected for processing: 4
  • scripts/container-security/README.md
  • scripts/container-security/container-security.test.ts
  • scripts/container-security/sync.mjs
  • scripts/dependabot-to-linear.mjs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The container scan workflow groups critical and high findings into tickets by image repository. Ticket descriptions include scan details and counts for lower-severity findings. The workflow creates and reopens tickets in Backlog, closes resolved tickets, and cancels eligible legacy per-CVE tickets after complete scans. Issue creation now accepts optional state and label values, with existing defaults retained.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 92c9e

The ticket workflow is mergeable after normal checks; no confirmed issue requires a change before merge.

Pre-merge checks: Passed 6 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Coverage Accounts For The Whole Diff Warning The Coverage table has mutation rows without the required mutated file:line locations. The kernel-header row says only to drop IGNORED_PACKAGES, although the changed check is at `scripts/container… Add exact mutation locations to both mutation rows, such as scripts/container-security/sync.mjs:52 and scripts/container-security/sync.mjs:128-156. Add a Coverage row or an Open gaps entry for reopening completed/canceled current ticket…
Passed Passed checks: 6 passed
Check name Status Explanation
Title check Passed The title follows Conventional Commits format, uses a valid type and scope, describes the main ticket consolidation change, uses lower-case summary text, and appends a valid Linear reference.
Description check Passed The description follows the repository template and includes the ticket reference, change summary, review locations, breaking-change declaration, migration notes, test coverage, open gaps, risks, and …
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Breaking Changes Match The Diff Passed The PR marks “This PR contains breaking changes” as unticked. The diff changes internal container-security reconciliation and Linear ticket values, and adds optional parameters to the internal `create…
Only The Ticket Line Carries A Magic Word Passed The description contains one magic-word/ticket pair: "Ref ENG-3962" on the top ticket line. No other Fixes, Closes, Resolves, or Ref pair appears with an ENG-<number> or #<number> referenc…
Full details: Description check

Explanation

The description follows the repository template and includes the ticket reference, change summary, review locations, breaking-change declaration, migration notes, test coverage, open gaps, risks, and AI note. Test names are abbreviated, but the required information is otherwise substantially complete.

Full details: Breaking Changes Match The Diff

Explanation

The PR marks “This PR contains breaking changes” as unticked. The diff changes internal container-security reconciliation and Linear ticket values, and adds optional parameters to the internal createIssue helper. It does not rename or remove an external API field or route, change an environment/config key, add a migration, or change the public SDK surface in the specified packages.

Full details: Only The Ticket Line Carries A Magic Word

Explanation

The description contains one magic-word/ticket pair: "Ref ENG-3962" on the top ticket line. No other Fixes, Closes, Resolves, or Ref pair appears with an ENG-&lt;number&gt; or #&lt;number&gt; reference.

Full details: Coverage Accounts For The Whole Diff

Explanation

The Coverage table has mutation rows without the required mutated file:line locations. The kernel-header row says only to drop IGNORED_PACKAGES, although the changed check is at scripts/container-security/sync.mjs:52. The legacy-ticket row names canClose or the triage check, but gives no file:line for the changed logic at scripts/container-security/sync.mjs:128-156. The diff also changes completed/canceled current tickets to reopen in Backlog at scripts/container-security/sync.mjs:225; no Coverage row or Open gaps entry verifies that behavior.

Resolution

Add exact mutation locations to both mutation rows, such as scripts/container-security/sync.mjs:52 and scripts/container-security/sync.mjs:128-156. Add a Coverage row or an Open gaps entry for reopening completed/canceled current tickets in Backlog, with a verification method and observed outcome if covered.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@xernobyl
xernobyl marked this pull request as ready for review October 22, 2026 18:42
@sonarqubecloud

Copy link
Copy Markdown

@xernobyl
xernobyl requested a review from mattinannt October 22, 2026 18:42

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant