The same report-renderer image runs in an integration environment and in production — what may legitimately differ between the two?
answer
- same bytes, different surroundings
- the artifact is the constant
- values arrive at start-up, not at build
- endpoints, scale and verbosity differ; code does not
- identical bytes are what makes test evidence transfer
basics
~20 sOnly the values supplied around the artifact may differ: endpoints, credentials, copy count, verbosity, feature switches. The image bytes stay identical, because identical bytes are what makes an earlier environment's test evidence mean anything in production.
solid answer
~50 sThe rule is that nothing inside the artifact differs and everything around it may. The image — application code, resolved dependencies, base layers, the defaults it ships with, the command it starts — is one set of bytes that moves forward untouched, and the deployment references that exact artifact rather than a name that could have been repointed. What differs is supplied at start-up or declared in the workload spec: which storage or database endpoint to write to, which account it authenticates as, how many copies run, queue and pool sizing, log verbosity, which feature switches are on. The surroundings differ too — data volume, traffic, network rules, quotas. The reason for the split is evidential: a test tells you about the thing that was tested, so if production runs different bytes, the test was about something you did not ship.
go deeper
Recall the split: one image, many value sets. The bytes are fixed; endpoints, credentials, copy count, verbosity and feature switches are supplied around them at start-up.
Explain why the split exists rather than restating it. Identical bytes are what carries a lower environment's test evidence forward; different bytes mean the evidence describes something that is not serving traffic.
Show the judgment call on the grey cases — a debug build, an extra module, a different base below production. Name the test: same artifact, values only, or you now own two artifacts and need evidence for both.
Frame it as an organisational guarantee, not a habit. Decide what your platform enforces — that deployments reference an identity that cannot move, and that a per-environment build is a reviewable exception rather than a default someone can pick.
## The claim being made When a team says "one artifact runs in every environment", they are making a narrow and checkable claim: the **bytes** of the packaged image that ran in the integration environment are the bytes now running in production, and every difference between the two runs was supplied *around* the artifact rather than built into it. The value of that claim is entirely evidential. A test run is evidence about the thing that was tested. If the thing running in production is a different thing — even a thing built from the same source, an hour later — then the evidence you collected is about something you did not ship. So the question "what may differ?" has a sharp answer: **the surroundings may differ, the artifact may not**. ## What must be identical - The application code and every dependency that was resolved into the image at build time. - The base layers underneath it, and any tooling baked in alongside the application. - The default values the artifact ships with, including the ones nobody overrides. - The command the artifact declares for itself and the arguments it defaults to. - The artifact's identity that the deployment references. "The same image" is only checkable if the reference cannot have been repointed since the test; a name that may move is a promise, not evidence. ## What legitimately differs | What differs | Example for the renderer | Where it comes from | |---|---|---| | Endpoints and addresses | the storage service it writes finished reports to | the value set supplied at start-up | | Identity and credentials | a per-environment account with narrower rights in the lower one | supplied per environment, never baked in | | Copy count | one copy in the integration environment, twelve in production | the workload spec | | Sizing | render queue depth, connection pool size, memory ceiling | the workload spec and the value set | | Verbosity and sampling | full debug logging below, sampled logging in production | the value set | | Feature switches | a half-finished export format enabled only in the lower environment | the value set | | Surroundings | data volume, real traffic, stricter network rules, quotas | the environment itself | Notice that none of those require touching the image. That is the test: **if a difference can only be expressed by producing different bytes, it is not configuration** — it is a second artifact wearing the first one's name. ## The grey zone, and how to judge it Some differences look like configuration and are really a different build: - A debug build for the lower environments with extra tooling and symbols in it. - An "enterprise" variant with an extra module compiled in for one environment only. - A different base image below production "because the lower environment needs a shell". - An environment name compiled into the artifact so the code can branch on it. Each of these means the tested unit and the shipped unit are not the same unit. The honest framing is that you now have two artifacts and need test evidence for both. A useful interview-grade check is: *could I take this exact artifact, put it in the other environment, change only the supplied values, and expect correct behaviour?* If the answer is no, the difference was not configuration. ## Values differ; the set of keys should not A second, less obvious part of the rule: while **values** differ between environments, the **set of keys** normally should not. Every environment should have an answer for every value the artifact needs — its own answer, or an explicit inherited default. A key that exists in one environment's set and nowhere else is drift, and drift is invisible until the code path that reads it runs somewhere it was never supplied. ## Why interviewers ask it It separates a candidate who has internalised the model from one who has memorised a slogan. "Build once, deploy many" is easy to recite; the follow-through is knowing which axis the rule constrains (the artifact) and which axis it deliberately leaves free (everything around it). It also surfaces a very common real-world habit — a per-environment build from the same commit — which feels rigorous, looks reproducible, and quietly destroys the connection between what was tested and what is serving traffic.
- If the artifact really is identical, why is the production run still riskier than the integration run?Because the surroundings are not identical and were never meant to be. Production meets real data volume and shape, real concurrency, real dependencies with their own limits, more copies, stricter network rules, different quotas and a different account. The code is the same; what it encounters is not, which is why a lower environment's pass narrows risk rather than eliminating it.
- Does one artifact everywhere mean the two deployments' configuration is the same object too?No. Only the artifact is the constant; each environment has its own value set, and that is the point. What should match across environments is the set of keys, not the values behind them. A key that only one environment's set contains is configuration drift, and it will surface as a failure the first time the code path that reads it runs where nobody supplied it.
saying these in an interview costs you the question
- Thinks each environment needs its own image built for it
- Treats an environment name compiled into the artifact as configuration
- Says nothing at all may differ, not even copy count or endpoints
- Thinks a key present in one environment only is a harmless difference
- Accepts different dependency versions across environments from one commit