An agent's change adds a dependency that does not exist — what makes this a security problem?
answer
- The broken build is the easy half
- The risk is what you do about it
- An unclaimed name can be claimed by anyone
- A fetch that works proves only that
- New manifest lines are their own review
basics
~20 sThe broken build is not the risk; the reflex is. Fetching a name to make the build pass hands the decision to whoever claimed that name, and a plausible invented name is worth claiming in advance.
solid answer
~50 sA name nothing provides fails the moment something tries to resolve it, so this failure announces itself — that part is easy. The risk is what it invites: the fastest route to a green build is to fetch the name, and an unclaimed name can be claimed by anyone, which is a cheap way to get code onto the machines of everyone who takes that route. Invented names are plausible rather than random, which is what makes them look right and also what makes them predictable enough to be worth claiming. The quieter case is worse: a name that resolves to a real project nobody chose, where the build simply goes green. Read every line the run added to the dependency manifest as its own review item, and remember that a successful fetch proves a name was claimed, not that it is the library you wanted.
code
pseudocode · 11 lines# one file of the forty this run touched
import retry_policy # already used elsewhere in the project
import retry_policy_async # the run added this one
sender = retry_policy_async.withBackoff(attempts = 5, jitter = true)
# and one line appeared in the dependency manifest:
# retry_policy_async
# the code around the import is fine, the names follow the same
# convention, and nothing here tells you whether the second one existsgo deeper
Recall the rule and be able to say it plainly: do not make a missing-dependency error go away by fetching the name. Delete the import, or choose the dependency deliberately.
Explain both cases — the name that resolves to nothing and the name that resolves to the wrong project — and why a successful fetch is evidence about the name rather than about the library.
Show why this failure mode is unlike the rest: it reaches outward into everything built from the repository, and it survives the session, so it earns a review step of its own.
Own the position that adding a dependency is a decision a person makes on purpose, and say how you would make one visible as an event rather than as a line inside somebody else's change.
## Two ways a generated dependency line can be wrong A run that writes code also writes the lines that say what the code depends on. Those lines fail in two quite different ways. The **loud** way is a name that nothing provides. It fails as soon as anything tries to resolve it: the fetch fails, or the build does. It is hard to ship by accident. The **quiet** way is a name that resolves to something — but not to the thing the code was written against. A near-miss of a real name, a differently published project under a similar name, an abandoned project holding a generic word. It fetches, it builds, and the only visible thing wrong with it is that nobody chose it. ## The loud failure and the reflex it provokes The danger in the loud case is not the failure. It is the response to the failure, which is fast, obvious and wrong: *the build says this is missing, so fetch it.* If nothing currently holds that name, somebody can take it. Publishing under a name that tools keep suggesting is a cheap way to get code onto machines that never chose it, because in many ecosystems fetching a dependency can run code during installation — and either way, the code you fetched is code you are about to run. This is also why invented names are not a random hazard. A model produces names that fit the naming habits of their neighbourhood, which is exactly what makes them look right to you and predictable to somebody else. **The name is plausible to a third party for the same reason it was plausible to you.** ## Why this failure is unlike the other ways a session goes wrong | failure | what it costs | how far it reaches | |---|---|---| | a drifted premise | rework, and a change that has to be re-read | the change in front of you | | a change that widened | review time and unwinding | the change in front of you | | a dependency nobody chose | possibly running somebody else's code | everything built from the repository, from now on | The other failures in a bad session cost work. This one can hand execution to a third party, it fails outward into everything built from your repository, and unlike the rest of them it outlives the session that produced it. ## What to check before the line goes in 1. **Review the manifest separately from the code.** Lines added to it are a different kind of decision from lines added to a function, and reading them inside a large diff is how they get waved through. 2. **Identify the project behind each new name**: where it is published from, who publishes it, and whether what it provides is what your code calls. 3. **Treat a successful fetch as evidence about the name, not about the library.** It proves somebody has claimed that name. It says nothing about who, or when they claimed it. 4. **Do not repair a failing import by fetching the name it asks for.** Delete the import and have the work done with what the project already depends on, or decide the dependency yourself, deliberately, as its own change. 5. **Ask why a new dependency was needed at all.** A run reaching for a library to do something small is usually a question about the request, and what a run may add is something the opening instruction can settle — a separate subject, but a cheap sentence. ## The quiet case deserves the same treatment Everything above is about a name that fails. The name that resolves is the one that reaches production, because a green build removes the prompt that would otherwise have made somebody look. A review that reads new manifest lines on their own terms catches both; a review that waits for something to go wrong catches only the loud one. This is one reason pinning is not the protection people take it for. Pinning fixes which version of a name you get, and that is worth doing — but a pin on a name nobody verified pins the wrong thing precisely. ## What this is not This is not about a model being manipulated by hostile input; how a model can be steered by what it reads is a separate security subject with its own controls. Nothing attacked the run here: the name was produced because it was plausible. Whoever is waiting at the other end, if anyone is, claimed a name and left the ordinary way of making a red build green to do the rest. It is also not the same failure as a call to a function that a real dependency does not provide. That one is about a wrong call against a library you did choose, and its fix is in the code rather than in the manifest.
- The dependency does exist and looks maintained. Is that enough to keep it?It clears the invented-name question and leaves the ordinary one: do you want this dependency? That it arrived inside a change about something else is the part to resist, because it was never proposed as a decision. Judge it as you would a dependency a colleague added in passing — on its own, and separately from the change that carried it.
- Does locking the version protect you here?It protects against the content behind a name changing later, which is worth having. It does nothing about the name being wrong in the first place: a lock on an unverified name records precisely the artifact nobody chose. Verify what the name refers to first, then pin it.
- How would you catch this on a team rather than one review at a time?Make new dependencies visible as their own event rather than as lines inside a diff — anything that surfaces an added manifest entry for a decision will do. The mechanism matters less than the principle: adding a dependency should be something a person approves on purpose, not something a change can carry in.
saying these in an interview costs you the question
- The build fails, so an invented dependency is the harmless kind of mistake
- Fetch it and see — if it installs, the name was real
- A name the model produced must exist somewhere or it would not have produced it
- It fetches and the tests pass, so it is the library that was meant
- Pinning the version makes an unverified dependency safe
- Reviewing dependencies is the build system's job, not the reviewer's