skip to content

Under the S2C2F's Fix Upstream practice, how do you justify paying an engineer to patch a dependency?

level: principalimportance: nice to knowfreq 26%

answer

  1. who pays, and when do they pay
  2. a fork's cost is deferred, not avoided
  3. the version string stops meaning anything
  4. bounded once versus recurring forever
  5. count carried patches and their median age

basics

~20 s

By costing the alternative. A private fork is a recurring tax that grows with every upstream release and quietly detaches you from the project's own later fixes. Landing the patch upstream is a bounded cost that ends.

solid answer

~50 s

The framework puts Fix + Upstream at its highest maturity tier because carrying a private patch is an unbounded liability. A fork costs you a rebase on every upstream release you want, it drifts away from the project's own subsequent security fixes, and its version no longer means what advisory data thinks it means - so matching goes wrong in both directions. An upstream fix costs review latency and the work of contributing once, then nothing. The judgement inputs are how often you upgrade this dependency, how large and how generally useful the patch is, and whether the project is alive. The organisational half matters more: if the cost falls on the team that hit the bug, the locally rational choice is always the fork, because its cost is deferred onto whoever is here in two years. The practice only becomes real when a platform or open-source-programme function funds it.

go deeper

for a junior

Know that patching a dependency yourself creates a version that is not the public one, and that somebody has to keep re-applying that patch every time the project releases.

for a middle

Be ready to explain the concrete costs of a fork: rebasing on each upgrade, drifting away from later upstream fixes, and a version string that no longer lines up with advisory data.

for a senior

Expect to make the call for a specific dependency and defend it with the inputs - upgrade cadence, how general the change is, patch surface, project health - and to say what you would do if the maintainers went quiet.

for a principal

Own the funding and policy design: where the budget for contributions sits, the contributor-agreement and IP path that must exist first, the written default, and the metric that stops carried forks from being relabelled as upstream fixes.

## Where this practice sits The S2C2F's top maturity tier is about reducing **future** risk rather than reacting to today's findings, and two practices live there: rebuilding dependencies from source on infrastructure you trust, and fixing defects upstream instead of carrying them. Both are standing engineering commitments rather than configuration, which is why they are last. Rebuild buys independence from the published binary matching the published source, at the cost of owning a build recipe you did not write, forever. Fix + Upstream has the same shape: a one-time control with a permanent line item behind it if you get the choice wrong. ## The two options, costed **Carry a private fork.** You patch the code, build it, and consume your own version. The immediate cost is small and visible, which is exactly why it wins by default. The real costs are deferred: - A rebase on every upstream release you want to take. That cost recurs at your *upgrade cadence* - a dependency you refresh quarterly makes a fork expensive within a year, while one you pin for three years barely notices. - Drift from the project's own later fixes. Your fork keeps the bug you fixed fixed, and quietly does not receive anything the maintainers do afterwards unless a human goes and looks. - Broken identity. Advisory data keys on upstream coordinates and version ranges. A fork published under your own version can drop out of matching entirely - a false clean - or keep matching the version it was branched from, alarming you about a flaw you already patched while saying nothing about later ones you never took. - Institutional memory. The person who wrote the patch leaves, and the next reader finds a component whose version string is a lie with no note saying why. **Land the fix upstream.** The cost is review latency, the work of writing the change in a form a maintainer will accept, tests, and possibly a discussion you would rather not have. It is bounded: once merged, the cost is zero and it stays zero. And the fix propagates to everyone else consuming that project, which is why a *consumption* framework counts contributing as maturity - an ecosystem where consumers only take is an ecosystem where the code you depend on gets worse. ## The inputs to the decision - **Upgrade cadence.** The single strongest predictor of what a fork will cost you. - **Generality.** A change that only makes sense for your deployment will not land, and pretending otherwise is how organisations end up with a fork anyway, six months later, having spent the contribution effort as well. - **Patch surface.** A change touching a core abstraction will conflict on every release; a self-contained one may rebase cleanly for years. - **Project health.** Responsive maintainers make the upstream path cheap. An unresponsive project changes the question entirely: when upstream cannot or will not take the patch, you are no longer choosing between these two options at all, and that situation belongs to a different playbook. ## The organisational half This is what makes it a leadership question rather than an engineering one. Contributing upstream produces a benefit that accrues to the whole estate - and to every other consumer of that project - while the cost lands on one team's sprint. If that cost is charged to the team that happened to hit the bug, the fork wins every single time, and the practice will never appear no matter how it is scored. Making it real needs three things: 1. **A funded owner.** A platform team, an open-source programme office, or an explicit allocation. Somewhere the time is not stolen from a product commitment. 2. **A cleared legal path.** A contributor agreement and an employer intellectual-property sign-off must exist *before* an engineer can contribute anything. Building that path once is most of the adoption work, and organisations routinely discover it at the worst moment. 3. **A default that is written down.** "Attempt upstream first, fork only with an owner and a review date" turns a case-by-case argument into a policy. ## Measure it, or it is a slogan Track the number of patches you carry and their **median age**, per dependency if you can. Landing fixes upstream shows up as that median falling, because carried patches retire when the upstream release containing them arrives. A rising median means you are accumulating forks and describing them as fix-upstream. Every carried patch should also have a named owner and a review date, so that a fork is a decision with an expiry rather than a permanent artifact nobody remembers agreeing to.

  • Why does carrying a private fork weaken vulnerability matching?
    Advisory data keys on upstream package coordinates and version ranges. A fork published under your own version can fall out of matching entirely, which reads as clean, or keep matching the version it was branched from, which alarms you about a flaw you already fixed while staying silent about later upstream fixes you never took. Both failures are quiet.
  • What metric tells you this practice is actually working?
    The count of patches you carry and their median age. Landing fixes upstream retires carried patches when the release containing them lands, so the median falls. A rising median means forks are accumulating under the label of fixing upstream, which is the failure mode the metric exists to catch.
  • Who should hold the budget for upstream contributions?
    A shared function - a platform team or an open-source programme office - not the product team that hit the bug. The benefit is estate-wide and permanent while the cost is one sprint, so local accounting always chooses the fork. A named allocation is what converts the practice from aspiration into something that happens.
  • What has to exist before an engineer can contribute a fix at all?
    A cleared legal path: a contributor licence agreement signed where required, and an employer intellectual-property approval for the individual to contribute work done on company time. Establishing that once is most of the adoption effort, and discovering it is missing during an urgent fix is the common failure.

A fork is a loan taken out against a future team's time, at an interest rate set by your upgrade cadence. Landing the patch upstream pays cash once and closes the account.

saying these in an interview costs you the question

  • Treats a private fork as a free permanent fix
  • Assumes upstream will accept any patch offered
  • Ignores the rebase cost on every upstream release
  • Charges the contribution to the team that found the bug
  • Calls a long-lived private fork fixing upstream

context