Keep four identities separate
A reliable answer needs four related but distinct records:
- Source revision: the reviewed commit or equivalent source identifier.
- Artifact identity: the immutable image, package, or bundle produced from that revision, preferably identified by a digest.
- Deployment receipt: the artifact, environment, actor, outcome, and time recorded by the promotion workflow.
- Running identity: what the service currently reports from the deployed artifact.
main is not a running identity. A source tag is also insufficient when a
mutable build process can produce a different artifact later. The proof becomes
useful when a reviewer can follow the chain from source to artifact to receipt
to the service response.
Register an immutable artifact
Create an artifact once for the approved revision. Record both identifiers in the release system:
revision: a1b2c3d
artifactDigest: sha256:aaa...
Reject an attempt to associate the same revision with a different digest. That failure may reveal a mutable tag, a non-reproducible build, or a process that is silently rebuilding during promotion. It should not be overwritten for convenience.
The P61 fixture models this rule in memory. One of its tests registers a revision and then verifies that a second digest for the same revision is rejected. The result demonstrates the rule inside the fixture; it does not prove that a real registry or deployment system enforces it.
Issue a deployment receipt after the outcome is known
The receipt should identify:
- the immutable revision and artifact digest;
- the target environment;
- the human or workload identity that initiated promotion;
- whether promotion succeeded, failed, or was rejected; and
- an attributable time and receipt identifier.
Record failed attempts as well as successful ones. Deleting failed history makes it harder to explain why the old version remains live. GitHub's deployment model is one example of retaining environments and deployment activity; other delivery systems use different objects. The required behavior is an inspectable, environment-specific promotion record—not a dependency on one CI provider.
Do not accept a receipt merely because its text names the running digest. The P61 fixture rejects an unknown receipt and a recorded receipt whose fields have been altered. A real system also needs durable storage, access control, and stronger integrity protection than this local model provides.
Expose the identity from the running service
Add a small endpoint or equivalent diagnostic command that reads identity compiled or injected into the deployed artifact:
{
"revision": "a1b2c3d",
"artifactDigest": "sha256:aaa...",
"environment": "production"
}
The checked-in Node fixture exposes GET /__version, returns 503 before any
revision is running, and returns the promoted revision and digest with
Cache-Control: no-store. The endpoint stays on the prior identity after a
simulated promotion failure.
Treat the endpoint as diagnostic metadata, not a health check. It does not show that dependencies work, migrations completed, traffic reaches every instance, or the application is safe. Decide whether it should require operator access; avoid returning secrets, internal paths, build arguments, or unnecessary dependency details.
Verify the receipt against the live response
After promotion, an automated or human release check should:
- fetch the running identity from the intended environment;
- load the successful recorded receipt;
- require both the revision and digest to match;
- fail if the receipt is stale, altered, unknown, or unsuccessful; and
- retain the verification result with the release evidence.
Run the same check during incident triage. If instances disagree, stop treating the environment as one known release. Investigate partial rollout, stale traffic, cache behavior, or an untracked deployment before making another change.
The local P61 evidence suite ran on Node.js 22.18.0 with eleven passing tests and no failures. It covers an absent running version, a successful identity response, a failed promotion, immutable artifact registration, stale and altered receipts, an unrecorded receipt, and rollback. It does not call a real CI system, persist receipts, authenticate actors, sign artifacts, or query a separately deployed service.
Roll back by promoting a known artifact
Rollback should create a new promotion receipt for a previously known artifact. Do not change a mutable label and erase the history of what happened. The P61 fixture re-promotes its earlier artifact and records a new rollback actor and receipt.
A source revert is different. The Git project's
git revert documentation describes a
new commit that reverses earlier changes; that new commit would produce a new
artifact identity. Re-promoting an old artifact and building a new reverting
artifact are both possible release actions, but they are not the same event.
Neither restores application data. Before rollback, check schema and data compatibility, configuration changes, queues, caches, and external side effects. Use a separate recovery decision when state must be repaired or restored.
Verification checklist
- One revision maps to one retained artifact digest.
- The promotion system records successful and failed outcomes.
- The receipt identifies artifact, environment, actor, and time.
- The running service reports revision, digest, and environment.
- A post-promotion check compares the response with the recorded receipt.
- Unknown, altered, stale, and failed receipts are rejected.
- Rollback creates a new receipt for a known artifact.
- Data recovery remains a separate procedure and decision.
Frequently asked questions
Can the version endpoint just return a Git SHA?
A SHA is better than a release name alone, but it does not identify which build artifact is running. Include the immutable artifact digest when the build and registry support one.
Should the endpoint be public?
That depends on the threat model and operating environment. Expose only the minimum diagnostic identity, omit sensitive build detail, and apply the same access and logging review used for other operator endpoints.
Does a matching receipt prove the deployment is healthy?
No. It proves a bounded identity relationship. Health, critical workflows, dependencies, data compatibility, and recovery need separate evidence.