Most engineering teams find out about a critical CVE in one of two ways: either the security scanner fires in CI and a developer stops mid-sprint to deal with it, or a security team member sends a Slack message at 9 PM asking why a known-vulnerable version of cryptography or log4j is still in production. Neither path is comfortable, and both treat dependency patching as an interruption rather than a routine task.
Pylon-Patch exists to make dependency CVE remediation part of the background noise of a healthy codebase, not a fire drill. Here is exactly how the workflow runs end to end.
Reading the scanner output
We do not run our own vulnerability scanner. We read yours. The first step Pylon-Patch takes when a job is triggered is ingest whatever scanner output your CI already produces: Snyk JSON, Dependabot alerts via the GitHub API, Grype SARIF, or a plain requirements audit from pip-audit. We normalize these into a unified advisory list that captures the CVE identifier, the affected package, the installed version, and the minimum fixed version.
Critically, we keep the CVSS score and the affected-function list if the scanner provides one. Whether a function listed as vulnerable is actually reachable in your codebase is a question most teams never answer, because answering it requires reading both the advisory and the code. Pylon-Patch does both.
For each advisory, we cross-reference the dependency against the repository context graph we maintain for your codebase. We look at which modules import the affected package, how deeply it is used, and whether those import sites call any of the vulnerable code paths. An advisory rated CVSS 9.1 where the vulnerable function is never called is a different kind of work item than one where it is called in three different service entry points. That distinction changes how urgently we open a PR and how we word the PR body.
Selecting the minimal patch
The naive approach to a CVE is to bump the package to the latest available release. That approach creates its own problems: major version bumps often introduce breaking API changes, and upgrading a deep transitive dependency can have cascading effects on a dozen other packages that pin to a specific minor version. For a team in the middle of shipping a feature, a "just upgrade it" PR that touches requirements.txt in 14 places is not a patch, it is a project.
Pylon-Patch picks the smallest version jump that resolves the CVE. That means we parse the advisory's fixed-version constraint and select the minimum satisfying release, then run a simulated dependency resolution against your current lockfile to check for conflicts. If the minimum fix introduces a conflict with another pinned package, we explore whether there is a slightly higher version of the conflicting package that is also compatible with your other constraints. We surface the resolution tree in the PR body so your team can see what we changed and why.
We do not always succeed at this. Sometimes the minimal fix version requires a major-version bump of another package, and at that point the PR scope grows beyond what we are comfortable automating silently. In those cases we open a PR that documents the conflict and suggests two paths, one conservative and one more aggressive, and we leave the choice to the team. We are not saying "just upgrade everything"; we are saying "here is the tradeoff you are making, and here is the least disruptive path we found."
Updating tests that cover affected code
A dependency patch with no test changes is a patch we cannot trust. If your codebase had tests exercising the import sites for the patched package, those tests may now need to account for changed behavior in the new version. More commonly, the version bump is behavioral-neutral and the existing tests will still pass. But "will pass" is not the same as "have been verified to pass by the agent."
Before opening any PR, Pylon-Patch runs the test suite in a sandboxed environment with the proposed version bump applied. If tests pass cleanly, that result is reported in the PR body alongside the suite name and a run timestamp. If tests fail, we do not open the PR at all. Instead, we open an issue (or a draft PR, depending on your configuration) that shows the failing tests, the diff we attempted, and our analysis of whether the failure is likely caused by the version change or is a pre-existing flakiness problem.
When the version change is the cause of the test failure, we attempt a fix. For shallow failures where the test is asserting on a specific error message string that changed between versions, we update the assertion. For failures that indicate a real behavioral change, we stop and report it. We do not write new tests that paper over a broken integration. That would hide the problem rather than resolve it.
The PR body as a security memo
One thing we learned early in building Pylon-Patch: the PR body is the most important part of the workflow. A PR that says "bump cryptography from 41.0.3 to 41.0.7" gives a reviewer nothing to evaluate. They either approve it on faith or they go read the CVE themselves, duplicating the work the agent already did.
Our PR body template for security patches includes: the CVE identifier with a link to the NVD entry, a plain-English description of the vulnerability and attack vector, a statement of whether the vulnerable code path is reachable in this codebase, the version resolution tree showing what changed and why, the test run result, and a review checklist for the human approver. The checklist is not perfunctory. It includes things like "verify the new version's changelog for breaking changes in X" and "check that no other service in this monorepo pins to the old version." We write it specific to the advisory and the codebase, not as a generic template.
The goal is that an engineer who has never looked at this CVE before can review the PR in under ten minutes and make an informed decision. We do not expect blind trust in the agent's work.
Scheduling and backlog management
Not every CVE warrants a same-day PR. Pylon-Patch respects a priority configuration that maps CVSS score ranges and exploitability flags to response time targets. CVSS 9.0 or above with a known public exploit: we open a PR within the hour the advisory is ingested. CVSS 7.0-8.9 with no known exploit: we queue a PR for the next scheduled maintenance window, which defaults to Tuesday and Thursday mornings. Below 7.0: weekly batch PR that groups multiple low-severity advisory patches together to reduce review noise.
This is configurable. Some teams want to review every CVE individually regardless of severity, which is a valid preference for regulated industries. Some teams want all patches batched weekly. We support both modes. The default is the tiered schedule described above, which is what we found works well for engineering teams that want security handled but cannot afford a reviewer interrupt every time Snyk fires.
One thing we do not do is open a PR for the same advisory twice. If a CVE-targeted patch PR is open and waiting for review, Pylon-Patch will not open a duplicate. It will post a reminder comment on the original PR if it has been sitting unreviewed for more than the configured SLA window. The backlog stays clean.
What this workflow is not
Pylon-Patch is a dependency patch tool, not a security audit tool. It remediates known advisories in your direct and transitive dependencies. It does not find custom code vulnerabilities, does not scan for secrets in your repository, and does not replace a dedicated application security program. If your threat model requires SAST analysis or manual penetration testing, Pylon-Patch is complementary to that work, not a substitute.
It also does not handle zero-day advisories that appear before any version fix is available. When there is no fixed version, there is nothing to patch. In those cases we open an issue that documents the advisory status and checks back daily until a fixed version is released, then opens a patch PR automatically.
The workflow works best when your CI already has a dependency scanner configured and you have a test suite with reasonable coverage of the code that uses external packages. If tests are sparse, we can still run the patch and report "no tests cover this import site," but we will note that in the PR body rather than quietly bypassing the verification step.