Put new findings in pull requests, where the developer who introduced them can fix them cheaply, and keep the dashboard for backlog, trends, and reporting. Most teams need both. The mistake is sending everything to one place: a pull request is the wrong home for a two year old backlog, and a dashboard is the wrong place to catch a new risky dependency.
What each surface is good at
| Surface | Strength | Weakness |
|---|---|---|
| Pull request check or comment | Immediate, in context, tied to the change | Only sees what the change touches |
| Dashboard | Whole estate, trends, ownership | Easy to ignore |
| Ticket in a tracker | Fits existing sprint work | Can duplicate and go stale |
| Scheduled report | Good for managers and auditors | Not actionable on its own |
Route by type of finding
- New dependency or version introduced in this pull request. Show it in the pull request. If it breaks your rule, block the merge.
- Old finding in code the pull request does not touch. Do not block. Send it to the backlog.
- New advisory against a package already in production. This arrives with no pull request. Send it to the owner by ticket or alert, and show it on the dashboard.
- Accepted risk with an expiry. Keep it on the dashboard with its reason and review date.
The split keeps pull requests quick. Developers lose patience with a check that fails for reasons they did not cause.
Decide what blocks a merge
Blocking rules should be narrow and explainable. Examples: a new dependency with a known exploited vulnerability, a license your policy forbids, or a package flagged as malicious. Write the rule where developers can read it, and make the failure message say which rule fired and how to fix it.
Start in report-only mode for a few weeks. Review what would have blocked, tune the rule, then turn on enforcement for one team before everyone.
Dashboard hygiene
A dashboard earns attention only if someone owns it. Assign each finding an owner by repository or service, show age, and review the top items in a regular meeting. Without an owner, a dashboard becomes decoration.
Avoid duplicate work
If the same finding appears as a pull request comment, a ticket, and a dashboard row, developers will stop trusting any of them. Choose one system of record for status, and let the others link to it.
A worked example: one week of findings
A team of eight ships a web service. During one week, four things happen.
Monday: a developer adds a new HTTP client library in a pull request. The SCA check flags a known exploited vulnerability in that version. The rule blocks the merge. The developer picks the fixed version, pushes again, and the check passes. Cost: ten minutes.
Wednesday: a new advisory is published against a logging library already in production. There is no pull request. The tool rechecks stored inventories, finds the service, and opens a ticket for the owning team, and the dashboard shows it as new.
Thursday: a pull request changes unrelated code. The check runs, finds an older medium severity issue in an untouched dependency, and does not block. It appears in the backlog.
Friday: the lead reviews the dashboard, sees one item approaching its deadline, and asks about it in standup.
Each surface did a distinct job, and none of them duplicated another.
Step by step: set up the split
- Define blocking rules in plain language: for example, new dependency with a known exploited flaw, forbidden license, or flagged malicious package.
- Configure the pull request check in report-only mode for two to four weeks.
- Review what would have blocked, tune, and then enforce for one team.
- Configure ticket creation for new advisories on deployed services, routed to code owners.
- Choose the system of record for status, and make other places link to it.
- Build a dashboard view by team with age, severity, and owner.
- Add a weekly review of the top aging items.
- Review the rules each quarter.
Writing a good pull request message
A failing check should say which rule failed, which package and version caused it, what the fixed version is, and how to request an exception. If the message lacks any of these, developers will search for them, and some will go around the check.
Handling exceptions
Provide a quick, visible path for exceptions: a reason, an approver, and an expiry date. Without a path, people disable the check. With one, you get a record of decisions and a prompt to revisit them.
Metrics worth watching
| Metric | What it tells you |
|---|---|
| Share of pull requests blocked | Whether rules are too tight or too loose |
| Time from advisory to ticket | How quickly the system routes work |
| Age of open findings by owner | Where backlog is building |
| Exception count and expiry | How much risk is accepted and for how long |
Keep metrics separate for pull request scans and scheduled scans, since mixing them hides the trends in each.
Mind alert fatigue
If people see too many messages, they stop reading. Send only actionable items to chat channels, and keep low severity items on the dashboard. Review the volume monthly and prune.
Try it yourself
Click through it at your own pace, or open it full screen.
Watch what appears on the pull request and when a merge is blocked. Then picture what would remain for the dashboard.
Quick check
Should every finding block a pull request?
No. Block only on new risk that meets a clear rule. Everything else belongs in the backlog with an owner.
Do we still need a dashboard if we have pull request checks?
Yes. New advisories hit code that is already deployed, and managers and auditors need a whole estate view.
What goes wrong when all findings are sent to tickets?
The tracker fills with items nobody owns, duplicates multiply, and developers learn to ignore it. Route by type, deduplicate, and keep one system of record.
Last reviewed: 19 October 2026.