How do you run dependency-adoption vetting across hundreds of services without it becoming a rubber stamp?
answer
- uniform gates decay into rubber stamps
- tier the review by blast radius
- record assumptions, owner and expiry
- price the exit while you still can
- measure refusals, not reviews completed
basics
~20 sTier the review by blast radius: most dependencies clear on automated signals alone, a smaller set needs a written human review, and the highest-impact set needs a reviewer outside the adopting team plus a recorded decision with an owner and an expiry.
solid answer
~50 sA gate applied uniformly to every dependency is approved by reflex within a month, so I tier it. Everything gets automated signals and a license check in the pull request, with no human involved. Anything that runs in production, or in the build with credentials, gets a short written review attached to the change: maintainer count, patch cadence, disclosure path, how much of it we use. The small set that touches money, keys, customer data or the build itself gets a named reviewer outside the adopting team and a decision record. Two things stop it turning into ceremony. Every approval records what it assumed and what would invalidate it, so it can be revisited rather than re-argued. And every reviewed adoption records the exit — what removing this package would cost in a year, and whether it sits behind our own interface at all. Then I measure the gate: approval rate, time to decision, and adoptions that later became incidents.
go deeper
Understand why a team reviews new dependencies at all, and that the depth of that review should depend on what the library will be allowed to touch rather than on who is asking.
Be able to describe what a lightweight written review contains — maintainer count, patch cadence, disclosure path, how much of the library is used — and why it belongs in the change itself.
Show how you keep the process proportional: automation for the common case, a real review only where blast radius justifies it, and decisions recorded with the assumptions they rest on.
Own the tradeoff between assurance and delivery speed: how you tier, how you avoid the gate being routed around, what you measure to prove it is not decorative, and when you retire a tier that buys nothing.
## The failure mode you are being asked about Every organisation that grows past a few dozen services eventually installs a dependency-approval step, and most of them decay the same way: uniform scope, no risk tiering, one queue, one overloaded reviewer. Within a quarter the approval rate is effectively one hundred percent, the median review takes minutes, and nobody can name a dependency it ever stopped. At that point the gate is worse than nothing — it consumes delivery time and manufactures a paper record of diligence that did not happen. ## Tier by blast radius, not by novelty The fix is to stop pretending all dependencies are alike. **Tier one — everything.** Automated signals in the pull request: license compatibility, known-vulnerability status, whether the package resolves from where you expect, basic project-health signals. No human. This is the vast majority of adoptions and it should cost the engineer nothing. **Tier two — runs in production, or in the build with credentials.** A short written review attached to the change, done by the adopting team: how many people maintain it, whether patch fixes ship, is there a private disclosure path, how much of the library we actually use, what it can reach. Ten minutes, in the change itself, reviewable by the code owner. **Tier three — money, keys, customer data, or the build system itself.** A named reviewer from outside the adopting team, and a written decision record. This tier should be small enough that you can list it from memory. If it is not small, your tiering is wrong. Tiering makes the expensive review affordable precisely because it is rare. It also gives an honest answer to "this slows us down": for most changes it does not, and where it does, you can name the risk being bought down. ## Make the approval carry its assumptions An approval that records only *yes* is worthless a year later. Record: what was assessed, what was assumed, which compensating controls the decision depends on, and what would invalidate it — a change of maintainer, a transfer of the project, the library growing well beyond the job it was adopted for, a control it relied on being removed. Attach an owner and a revisit date. This is the difference between a decision you can re-evaluate and one you can only re-litigate. ## Decide the exit at the moment of adoption The most under-used practice here: at adoption, estimate what removing this package would cost in a year. Not to discourage adoption — to make lock-in visible while you still have leverage. Two useful outputs. First, a rough number: how many call sites, is the abstraction leaky, is there a plausible alternative. Second, a design decision: for tier-three dependencies, is it worth putting our own narrow interface in front of it so that replacement is a contained change rather than an estate-wide refactor? That second point is where an adoption review earns its cost. Wrapping every dependency is architectural over-engineering; wrapping the handful that hold keys, parse hostile input, or would take a quarter to remove is cheap insurance. The review is the only moment anyone will ever ask the question. ## Provide the alternative, not just the refusal A gate that only says no gets routed around — vendored copies, an inlined file, a transitive pull that nobody declared. Publish a pre-approved set for common needs so the fast path is also the safe path, and make the reviewer's job include naming a substitute. Adoption security is largely a paved-road problem. ## Measure the gate, or it will drift The metrics that matter are uncomfortable ones: - **Approval rate.** Near one hundred percent, with short review times, means the gate is decorative. Some genuine refusals should exist. - **Time to decision.** If tier two takes days, teams will pick the dependency that avoids review, and you have optimised for evasion. - **Coverage.** What fraction of dependencies actually entered the estate through the gate versus arriving transitively or by vendoring. - **Outcomes.** Dependencies that passed review and later caused an incident, and dependencies removed as a result of a review. Both numbers inform tiering. Counting reviews completed is not a measure of anything except how much time the process consumed. ## What a strong answer sounds like An interviewer at this level is checking whether you can build a control that survives contact with delivery pressure: proportional scope, cheap common path, expensive path reserved for real blast radius, decisions that carry assumptions and expiry, an exit recorded while it is still cheap, and honest metrics — including the willingness to remove the gate for a tier where it demonstrably buys nothing.
- What exactly do you record about the exit at the moment of adoption?A rough removal cost — how many call sites, how leaky the abstraction is, whether a credible alternative exists — and a design decision for the high-impact tier: do we put our own narrow interface in front of this so replacement stays contained? The point is to make lock-in visible while you still have the leverage to avoid it, not to discourage adopting anything.
- Engineering says the gate is slowing delivery. How do you respond?With the numbers. If tier-two reviews take days, that is my defect to fix, not theirs to absorb. I move the common case fully into automation, publish a pre-approved set so the fast path is the safe path, and keep the expensive review only for the tier where I can name the risk being bought down. If a tier cannot state which risk it removes, it should be deleted.
- Which measurements tell you the gate is working rather than merely running?The refusal rate, and whether refusals came with a named alternative. Time to decision per tier. Coverage — how many dependencies entered the estate through the gate versus arriving transitively or by a vendored copy. And outcomes: adoptions that later caused an incident, and packages removed because a review asked the question. Reviews completed measures cost, not value.
saying these in an interview costs you the question
- Applies one identical review to every dependency regardless of impact
- Measures the process by number of reviews completed
- Treats an approval as permanent with no owner or expiry
- Blocks a dependency without offering a vetted alternative
- Assumes an automated score can replace judgment for high-impact code
- Ignores dependencies that arrive transitively or by vendored copy