Skip to content
Insights · Engineering

Name the commit they are running

Name the digest that is actually running, name the commit you shipped, and say whether they match. A branch name is not a release.

Scroll
EngineeringOct 20, 202610 min readBy Salman Naqvi, Founder & CEO
Name the commit they are running

The client says production is wrong. Tonight, in an account you or the client administer, three things. Name the digest of what is actually running: an image digest, or the commit the release was built from. Name the commit you believe you shipped. Say whether those two are the same. If you cannot name the one that is running, stop telling them the fix is live. If any of the three requires the person who pressed the button and then left, you have not identified the release. You have a branch name and a hope.

This is the identity of a release that is already in production. It is not the review you do before a change ships. Read their change before it ships is whether you opened the diff. A diff you approved is not a digest you can read off the running process. It is not the hour before a demo. Check the demo before the client does asks whether you can open the build you are about to project. A demo and a production process can disagree, which is the whole point of naming both. It is not the message you send when something is broken and you do not yet know why. Tell the client what still works is that message. It is not the license on a dependency the build added. Name the license the build added is the grant. A grant does not tell you which tree is running. And it is not a key. Revoke the key they minted is a credential. You can revoke every key and still not know which commit is serving traffic.

Most dependencies sit still for a long time, and that fact is not a count of deploys you failed to label. Sonatype's 10th annual State of the Software Supply Chain report, with a press date of 10 October 2024, describes dependency update patterns drawn from public and proprietary data, including more than 1.5 trillion requests to Maven Central, and an assessment it describes as hundreds of thousands of key enterprise applications. In the section on dependencies that had not been upgraded within a year, it says 80% were unmanaged and remained outdated. The same report's summary line is that 80% of application dependencies remain un-upgraded for over a year. A different 80% on the same document is a year-over-year increase associated with AI and cloud. That increase is not the share of dependencies. Do not slide one 80 under the other. 95% of the time, when vulnerable components are consumed, a fixed version already exists, a trend the report says has persisted for three years. 3.6% of dependencies are still vulnerable because they were updated to another insecure version. 0.5% of components had no fixed version available. A separate sentence says an analysis of over 20,000 enterprise applications shows that reliance on end-of-life components indicates increased vulnerabilities. The report does not print 20,000 as the denominator of the 80%, so do not treat it as one. A sample it describes as 84k components, 42k core and 42k peripheral, found peripheral components 25 times more likely to contain malware. Sonatype sells supply-chain security. None of these figures is a survey of agency repositories. None of them is the probability that this client's production process is the commit you named in Slack (Sonatype, State of the Software Supply Chain, 2024).

What the figures are for, here, is the reason a branch name is not an answer. If most dependencies are not the current fixed version, then "we are on main" does not tell the client which of those versions the running process loaded. The outdated dependency and the current one can share a name. The thing that distinguishes them is a digest, and the thing that distinguishes two builds of your own code is the same kind of object. An 80% about other people's dependencies is not a finding that your last release drifted. It is a reason not to accept a name where a digest was required.

The specification that separates the name from the digest is SLSA provenance v1.0. The build's external parameters are the values under the control of a user or a tenant. They must be complete at SLSA Build L3, meaning there is no additional mechanism for an external party to influence the build, and at lower levels that completeness may be best effort. The parameters should contain the values passed in, not the metadata about them. Digests of artifacts those parameters refer to go in resolved dependencies. The spec's own example puts a repository and a ref in the external parameters — `refs/heads/main` — and puts the resolved commit in the dependency's digest, under the key `gitCommit`, with the value `7fd1a60b01f91b314f59955a4e4d4e80d8edf11d` (SLSA, Provenance v1.0). Read that twice. The ref is a name that moves. The digest is the commit that name pointed at when the build resolved it. Shipping "main" and recording "main" has recorded the parameter. It has not recorded the release.

Resolved dependencies are an unordered collection of artifacts needed at build time, and the spec says completeness is best effort, at least through Build L3. If the build fetches a script, and the script fetches an archive, both should be listed. "Best effort" is the spec's own limit. A provenance file that names the commit of your repository and is silent on the base image is not a complete list, and the spec does not pretend it is. The outputs of the build are a different field. The model says the process outputs one or more artifacts, identified by the statement's subject. A subject you cannot read back from the running process is a document about a build. It is not yet a document about production. The builder id is what the spec treats as the claim about how much of this to trust. Two provenances with the same commit and different builder ids are not the same claim.

Do the three proofs against the process that is taking traffic, not against the repository you have open. First, the running digest. From a console you or the client administer, read the identifier the cluster, the host, or the function is actually executing. An image digest is one. A git commit the release artifact was built from is another, if that is what the platform prints and you can tie it to the artifact. A branch, a tag that moves, a "latest," and a deploy time without a digest are not this line. If the console shows a tag, resolve the tag to a digest before you write it down, and write both, with the date you resolved it. Second, the commit you believe you shipped. The commit your pipeline says it built, from the run that you intend the client to be on. Not the tip of the branch as of this evening, unless that tip is what the run built. Third, the comparison. Same, or not the same. If they are not the same, say which one is running and which one you thought was running. If you cannot read the first line, the third line is "not known," and you stop saying the fix is live. A revert you cannot see is not a revert.

The comparison fails in ordinary ways that look like success. The pipeline is green and the cluster is still on the previous digest, because the rollout did not finish, or finished onto a service that does not take this traffic. Two environments share a name, and you read the digest from the one the client is not using. A hotfix was applied in a console and never became a commit, so the running tree matches neither line. A provenance file in the repository describes the build you wanted, and the cluster was started from a laptop image that file does not mention. In each case the client-facing sentence "the fix is out" is false, and the falsehood is checkable in one screen. The handover you must receive lists an identifiable archive of what is in production as one of the ten things that have to arrive. This article is the evening you are asked to use it.

Three moves that feel like an identification and are a second problem. Asking a model to "look at the repo and tell us what is deployed," which reads a tree that may not be the process and then speaks as if it had been. Pasting production environment variables into a chat so the model can find the tag, which puts the client's secrets into a vendor. Restarting the service onto the commit you wish were running, in order to make the two lines match, before you have written down what was wrong. The first is a guess with a confident tone. The second is a new disclosure. The third destroys the evidence the client asked you for.

A deployment can exist, as a shape, without being a ledger of digests. Inflectiv Helios is a multi-assistant platform with a containerized deployment on AWS or GCP and observability beside it. The shape that matters here is that a release leaves the repository and becomes a process someone can point at. That case is not a record of the digest that was running on a given evening, and it is not a comparison against the commit a partner believed it had shipped. Nothing in the description is a headcount, a duration, or a result figure. If the only status page says "healthy" and will not print a digest, you do not have the first proof. You have a pulse.

There is a version of this call where hiring someone to build the path is the wrong purchase. You have not sold the work, so there is no client production to name. The client has asked to meet the people who will write the code, and a digest will not hide that. The thing in the room is a slide, with no process behind it. Or the buyer only wants a template of a provenance file, with no cluster to read. A white label software development partner is the wrong purchase for a blank. The criteria for choosing a firm, when you are still choosing, sit on the page for a top SaaS development company. That page is criteria. It does not rank anyone, including us.

When a client is already asking which release they are on, the missing object is specific. A running digest you can read without the person who deployed it, and a commit your pipeline will stand next to it. The price a customer of the product says they were shown is a different record, show the price they accepted, and it will not tell you which build served the page. Two sentences from one question are a different failure, when one question gets two answers. If the first slice is a fixed capability, an AI integration sprint is the shape where the acceptance sentence can include one production digest you can read yourself. If nothing has been deployed and the question is whether the pipeline could name a release at all, a two-week AI readiness assessment hands you the findings either way. The findings are yours. They are not a digest, and they are not an 80.

Before you tell the client the fix is live, write three lines and the time you read them. The digest of what you shipped is this page. The third-party action the workflow fetched while building it is name the action the workflow runs. The digest that is running. The commit you shipped. Whether they are the same. If the first line is a branch, you have not started. Do not ask a model what is deployed. Do not restart the process to improve the answer. The migration the database applied is a different name, name the migration the deploy applied. A digest is not a schema version. The file a workflow kept after the run is a different object from the digest that is running: which artifact did that run keep?. An expired zip is not a commit. The image the job ran, as opposed to the commit you shipped, is which image did that deploy run?. A tag is not the digest of the process. The screen that prints the digest is the page you can defend.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→