CI/CD Pipeline Excellence: Release Evidence and Recovery Design

Design a delivery pipeline around trusted artifacts, risk-based tests, progressive exposure, and data-aware recovery. Includes a release packet, failure drills, and...

Decision brief

A continuous integration and continuous delivery (CI/CD) pipeline decides whether a particular artifact may change a particular environment. Faster feedback helps, but a fast pipeline that cannot establish what it deployed or how to recover has not solved the delivery problem.

This paper proposes a reference release contract for engineering and platform leaders. It connects contribution trust, artifact identity, test evidence, deployment authorization, and recovery. The examples are illustrative design choices, not customer stories or measured Ampity outcomes. No delivery-frequency improvement, failure reduction, or recovery-time result is asserted.

The practical output is a release packet: a versioned record of the artifact, checks, exposure plan, and recovery limits. Use it for one service before standardizing it across a portfolio. Tool selection and pipeline syntax follow from that contract; this is not a catalog of products or a promise that every change should deploy automatically.

1. Define a service-level release contract

Start with the effects of a bad release. A stateless formatting change, an authorization change, and a database migration should not inherit identical acceptance criteria simply because they use the same repository.

Contract fieldDecision to makeAccountable role
Change scopeServices, configuration, schemas, consumers, and external effects affectedService owner
Artifact identityImmutable digest and source/build identity to promoteBuild-system owner
Required evidenceTests, security review, compatibility checks, and exceptionsService and security owners
Exposure planCohort, traffic limits, observation period, and stop conditionsRelease owner
Recovery envelopeConditions where traffic reversal is safe; alternatives where it is notService and data owners
Deployment authorityWho or what may promote the artifact into each environmentPlatform owner
CompletionBusiness invariants, runtime identity, and reconciliation evidenceRelease owner

An approval is meaningful only if it refers to a fixed artifact and a known evidence set. Rebuilding after approval can invalidate that relationship. If an environment-specific build is unavoidable, identify it as a new artifact and rerun the relevant checks instead of presenting it as the artifact already tested.

2. Separate contribution trust from release authority

Treat contributed code, pull-request metadata, dependencies, and generated artifacts as untrusted inputs. A job that evaluates them should not inherit deployment credentials merely because it runs inside the same automation product.

The diagram shows a proposed trust boundary, not a complete supply-chain security architecture. Artifact stores, identity providers, network policies, and administrator access still require their own threat review.

Release authority begins after contribution review

Untrusted contributions run in isolated checks. A reviewed source revision enters an authorized build. A deployment gate verifies the resulting digest and evidence before runtime promotion. Contribution checks cannot directly obtain release authority. Gate decisions and runtime receipts go to the evidence record.

One release, two trust zones

CONTRIBUTION ZONE

AUTHORIZED RELEASE ZONE

Contributed code

No release credentials

Isolated checks

Results are input

Direct promotion blocked

Review admits a revision

Authorized build

Reviewed revision

Digest + provenance

Verify + authorize

Identity, evidence,

target environment

Permit

Runtime rollout

Same artifact digest

Evidence record

Decision + receipts

Gate decision

Runtime receipt

  1. Run contributed code in isolated checks without release credentials.
  2. After review, admit an exact source revision into an authorized build. Checks cannot promote it directly.
  3. Produce an immutable artifact digest and provenance.
  4. Verify artifact identity, required evidence, and environment authorization at the deployment gate.
  5. Roll out the same digest and record both the gate decision and runtime receipt.

Proposed release trust boundary. Test success is evidence for a decision, not permission to deploy.

For GitHub Actions implementations, use the platform's security guidance to review workflow permissions, injection risks, action dependencies, and runner isolation. Pin third-party actions to reviewed full-length commit identifiers and maintain an update process. Do not execute untrusted contribution code in a privileged workflow that exposes secrets. Short-lived credentials reduce persistent-secret exposure only when their identity and resource permissions are restricted. See GitHub's secure-use reference.

Also isolate caches and artifacts across trust levels. A later trusted job should not blindly execute an executable restored from an untrusted job's cache. Review artifact paths, archive extraction, and metadata before consumption. Discarding a runner after a job helps limit persistence but does not make credentials exposed during that job safe.

3. Establish artifact identity, not just a successful build

Attach the source revision, build invocation, dependency locks, builder identity, and output digest to the release record. Promote the digest, not a mutable tag. Keep enough evidence to answer which workflow produced the bytes running in production.

Signing an artifact is not a guarantee that it is safe or that the signer was authorized. Verification needs an accepted identity or key, trusted issuer where applicable, artifact binding, and policy for the evidence. Sigstore documents identity and issuer checks as part of keyless verification. See Sigstore signature verification.

Provenance describes an artifact's origin and production process. It does not replace tests or establish that its inputs were benign. Use SLSA provenance as a reference for the evidence model, without claiming a SLSA level that has not been assessed.

Reproducible builds are a separately testable property. The same source commit can produce different outputs if toolchains, dependencies, timestamps, network inputs, or environment behavior change. Where reproducibility is required, control those inputs and compare independent rebuilds. Where it is not achieved, document the gap and preserve the original artifact.

4. Assign tests to risks and failure modes

A test suite should explain what it detects, what it does not detect, and why it runs at a particular stage. A pipeline duration target is a local engineering decision, not an excuse to remove the only check for a critical failure.

Evidence layerUseful questionImportant limitation
Static and dependency checksDoes the change violate known rules or introduce identified dependency issues?Rules and vulnerability databases are incomplete and time-dependent
Unit testsDoes a small unit preserve its expected behavior?Mocks may conceal integration differences
Contract testsCan producers and consumers agree on a versioned interface?They do not prove network, authorization, or full runtime behavior
Integration testsDo selected real components work together?The tested configuration may differ from production
End-to-end checksCan a critical user journey complete?A small set of journeys cannot cover all combinations
Performance and resilience testsDoes the service meet its workload and failure requirements?Results depend on test realism and environment constraints

Affected-only test selection can help feedback time when the dependency graph is reliable. Treat changes to shared configuration, code generation, toolchains, or the graph itself as possible invalidations. Run periodic full checks and compare what the selection mechanism would have skipped.

Quarantining a flaky test requires an owner, reason, expiry, tracked fix, and an alternative for the risk it covered. A test's unreliability does not prove the underlying risk is unimportant. Preserve failed evidence instead of repeatedly rerunning until the first green result erases the problem.

5. Protect credentials and enforce exception expiry

Give build, artifact-publish, and deployment jobs separate permissions. Restrict credential issuance to the intended repository, workflow, revision context, and environment where the identity platform permits it. Test that a job with similar names but a different trust context cannot obtain the same authority.

If a secrets service is unavailable, do not automatically fall back to an indefinitely cached credential. Any supported cache needs explicit expiry, revocation behavior, encryption at rest, restricted access, and an owner. When a required valid credential is unavailable, stop the affected release operation.

Security exceptions should name the artifact or bounded set of changes, the risk, compensating controls, approver, and expiration. An exception recorded only in a chat message is difficult to enforce at the release gate. A scanner finding marked accepted also needs reassessment when the affected component, exposure, or threat changes.

A GitOps controller is another privileged actor. Moving deployment authority from a pipeline into a controller can improve separation, but it does not automatically make deployment secure. Protect the configuration repository, controller credentials, reconciliation policy, and emergency overrides.

6. Choose progressive exposure based on observability

Canary, rolling, and blue-green releases expose different failure and capacity tradeoffs. Choose a strategy based on traffic routing, session behavior, data compatibility, dependency limits, and the ability to detect harm before expanding exposure.

Before a canary, define the cohort, comparison method, minimum useful observations, and stop conditions. Very low traffic or delayed business effects may make a short automated comparison inconclusive. A lack of errors is not a positive result if the risky path was never exercised.

Blue-green deployment keeps alternate application capacity available, but the required capacity depends on topology, workload, and shared dependencies. It is not universally a fixed multiple of production. Routing traffic back can recover some application failures, but shared database writes, messages, and external actions may persist.

Record the runtime artifact and configuration actually observed after promotion. A pipeline status of successful deployment is not sufficient if reconciliation failed, a mutable image reference changed, or part of the fleet still runs a different revision.

7. Define the data-aware recovery envelope

Use compatibility windows for changes that cross application and data boundaries. One proposed sequence is to add compatible storage or interface behavior, migrate consumers and data with reconciliation, then remove the old behavior only after the compatibility window closes. This is a design approach, not a guarantee of zero downtime.

Change statePossible recovery actionEvidence needed before relying on it
New application, compatible schema, no incompatible writesRoute back to the known compatible artifactRehearsed traffic switch and old-version read/write tests
New writes readable by both versionsRoute back only within the verified compatibility windowFixtures for both readers, writers, and mixed-version operation
Data semantics changed or external effects executedStop additional effects; reconcile or fix forwardEffect ledger, compensating procedure, accountable decision maker
Destructive schema change completedUse a rehearsed recovery or fix-forward plan, not an assumed application rollbackRestore timing, data-loss exposure, dependency coordination, and approvals

A down migration that recreates a deleted column does not restore its lost values. A database restore can also discard valid writes made after the recovery point. Recovery therefore needs both a technical procedure and an explicit decision about data reconciliation.

Test duplicate messages, partially completed backfills, and delayed consumers. A schema can be syntactically compatible while changing a field's meaning in a way an older consumer cannot handle. Stop the release if its recovery plan depends on untested assumptions about those consumers.

8. Capture one release packet

The packet should be generated from pipeline and runtime evidence where possible, with human decisions attached to exact versions. It is not a separate manually maintained success narrative.

Release identifier and service:
Source revision and workflow revision:
Artifact digest, builder identity, and provenance reference:
Dependency and configuration versions:
Required checks with result references:
Exceptions, owners, and expiration:
Data/interface compatibility window:
Target environment and deployment authorization:
Cohort, observation criteria, and stop conditions:
Runtime artifact/configuration receipt:
Recovery procedure and known limits:
Business invariant checks and reconciliation result:
Final disposition and accountable reviewer:

Store the packet under access and retention rules appropriate to its content. Avoid copying secrets, personal data, or unrestricted production logs into it. An evidence link should have a stable identifier and meaningful access controls, not depend on a developer's temporary workstation.

The release gate should reject mismatched artifacts, missing mandatory evidence, expired exceptions, or an unauthorized target. If the evidence service is unavailable, define whether promotion pauses. Do not silently skip verification because the mechanism that should prove safety has failed.

9. Rehearse failures before trusting automation

Use a non-production environment representative enough to test the specific boundary. These drills are proposed acceptance tests, not reports of tests already performed.

DrillExpected boundaryRetained evidence
Untrusted contribution requests a deployment credentialCredential issuance is deniedIdentity claims, denial, and absence of a deployment
Artifact changes after approvalDigest mismatch blocks promotionApproved digest and rejected candidate
Signature belongs to an unapproved identityCryptographic validity alone is insufficientPolicy decision and signer identity
Required evidence or exception expiresGate pauses or rejects according to policyExpiry calculation and gate output
Canary breaks a business invariantExpansion stops and recovery decision beginsCohort observation and stop receipt
New writes are incompatible with the old applicationTraffic reversal is not treated as a safe rollbackCompatibility test and selected reconciliation path
Secrets dependency is unavailableNo use of expired or unauthorized fallback credentialsJob outcome and credential-access audit

Include the operators who would make the recovery decision. A runbook that depends on a person who lacks access, a backup that has not been restored, or a feature flag that requires the failing service is not yet usable recovery evidence.

10. Measure delivery without turning metrics into quotas

DORA's current guidance describes five software delivery performance metrics. Use consistent service boundaries and definitions, and investigate trends with context rather than ranking unrelated teams. See DORA's software delivery performance metrics.

MetricMeasurement meaning
Change lead timeTime from a committed change to production deployment
Deployment frequencyDeployment cadence for the application or service
Failed deployment recovery timeTime to recover from a deployment failure requiring intervention
Change fail rateShare of deployments requiring immediate intervention, including fixes or reversal
Deployment rework rateShare of deployments that are unplanned responses to production incidents

Failed deployment recovery time is not a substitute for measuring every kind of incident. Keep broader incident metrics separately. Likewise, counting only rollbacks understates change failures when hotfixes or other interventions were required.

Define timestamps, denominators, service scope, and attribution rules before drawing conclusions. Separate queue time, execution time, and approval waiting to identify the constraint. Pair delivery measurements with customer-impact and reliability evidence so that a higher deployment count does not conceal repeated rework.

11. Introduce the contract incrementally

Select a service with an accountable owner and a change whose effects can be observed. Inventory its present release path, including manual steps and emergency access. Establish artifact identity and runtime readback before adding complex automated promotion rules.

Next, make one high-consequence failure test enforceable. For example, require evidence that an older application can read data written by the candidate during the proposed compatibility window. The exact test should come from the service's risk, not a generic maturity score.

After the first release, compare the packet with what actually happened. Missing evidence, unusable runbooks, and noisy gates are inputs to improve the contract. Expand only when the owning team can operate and maintain it. Central templates should provide maintained defaults with explicit exceptions, not obscure service-specific responsibilities.

12. Build a release packet for a stateful change

Consider an illustrative refund service that currently stores one refund result per request. A candidate release introduces a pending state because a payment provider can accept a request before returning its final result. This change affects the API, persistence, background processing, operator tools, and customer messaging. Testing only a successful refund would miss the recovery risk: the old application may interpret a pending record as failed and submit another refund.

The service owner starts with an invariant: one business refund request must not cause more than the authorized refund amount, even when responses are lost or jobs are repeated. The release packet records the idempotency identity, its scope, the authoritative provider status lookup, and the retention window. The example assumes the chosen provider exposes sufficient reconciliation information. If it does not, the design needs another recovery process and an explicit unresolved-case state; a pipeline cannot manufacture an external guarantee.

Expand the data contract before enabling the new workflow. Add a representation the existing reader can tolerate, or deploy an intermediate reader that understands pending records without creating another side effect. Test current and candidate versions against data written by each supported version. Include a record created immediately before deployment, a delayed provider response, and a retry after a worker restart. Record whether the old writer can still operate safely during the overlap, rather than treating read compatibility as the whole answer.

The release owner enables the candidate for a bounded set of eligible requests, with a stop condition tied to unresolved refund state, duplicate-intent detection, and reconciliation failures. Cohort assignment must stay stable for the business operation. Sending a retry through the old path because it landed on a different instance can defeat the intended boundary. A feature flag may disable new candidate work, but already accepted work still needs an owner and completion procedure.

Evidence in the illustrative packetWhat the reviewer should be able to establish
Exact artifact and configuration digestThe tested candidate is the candidate receiving refund work
Mixed-version fixturesSupported readers and writers preserve the pending-state semantics
Provider reconciliation recordAn ambiguous response can be resolved without issuing an unrelated new refund
Cohort and retry testsOne business operation does not switch incompatible execution paths
Stop and drain exerciseNew work stops while accepted work remains visible and recoverable
Recovery decisionThe prior artifact is compatible, or a named fix-forward process replaces traffic reversal

Contract tests can establish agreement about the pending response shape. They cannot establish that credentials, network policy, database transactions, provider behavior, and worker retries cooperate correctly. Retain selected integration tests for those boundaries. Use a provider test environment or controlled adapter where appropriate, and document which live behaviors it cannot reproduce. A green synthetic response is not evidence that the provider honors the same idempotency retention in production.

Close the release only when runtime identity, accepted operations, and reconciliation agree. If the candidate is disabled, the packet should show how outstanding pending records will finish. If a destructive contract change follows later, it gets a new decision after old consumers and queued work are accounted for. This separates a successful application rollout from completion of the business transition.

13. Shorten feedback time using the dependency path

Measure elapsed feedback time as queue delay, preparation, required execution, result publication, and any approval wait. Summing job durations is useful for resource accounting, but it is not the elapsed duration of a parallel pipeline. Conversely, reading only the fastest green job can conceal a slow prerequisite that still blocks a releasable artifact.

Use a constructed example with six required jobs: lint takes three minutes, the artifact build takes four, unit checks take six, contract checks take five, integration checks take fourteen, and final evidence verification takes two. Assume the three test jobs require the built artifact, lint can run independently, and verification waits for every check. Assume no queue delay, startup overhead, shared-resource contention, or retries.

Running every job serially takes thirty-four minutes. In parallel, lint finishes after three minutes. The build and longest test branch finish after four plus fourteen minutes. Verification then takes two more minutes, giving a twenty-minute critical path.

The release gate waits for every required dependency

Verification depends on lint and three test jobs; the test jobs each depend on the same built artifact, making the illustrative build, integration, and verification path twenty minutes long.

Verify evidence

2 minutes after all checks

Lint

Unit checks

Contract

Integration

Build artifact

Arrows mean “requires”; badges count dependents. Durations are hypothetical.

  1. Lint runs independently in three hypothetical minutes.
  2. The four-minute build produces the artifact required by all three test jobs.
  3. Unit, contract, and integration checks run in parallel for six, five, and fourteen minutes respectively.
  4. Evidence verification takes two minutes after all required checks succeed.
  5. The critical path is four plus fourteen plus two, or twenty minutes. Serial execution would take thirty-four.

Dependency view, not execution order from top to bottom. Reusing a built artifact preserves identity; parallelism does not remove any required check.

The difference is fourteen minutes in this hypothetical model, not a customer result. The total job work is still thirty-four job-minutes if resources and runtimes remain equal. Additional concurrent runners can change spending, cache contention, test-data collisions, and downstream capacity. Measure those effects before interpreting a shorter critical path as an economic improvement.

Use the model to choose the next experiment. Shortening a six-minute unit job to three minutes does not change the twenty-minute critical path while integration still takes fourteen. Reducing unnecessary integration setup, reusing an eligible environment, or dividing independent integration groups may help, but deleting the only integration evidence for a critical path changes the release contract. Evaluate the coverage and resource impact of each intervention, not only its elapsed time.

Retain timestamps for queued, started, completed, and published results. If waiting for a runner dominates, optimizing test execution will not address the observed delay. If an approval wait dominates, inspect whether the reviewer receives a complete, trustworthy packet at the right time. Report missing evidence and inconclusive runs separately from execution failure so the team can identify whether the bottleneck is infrastructure, tests, or the release decision itself.

14. Bind every approval to artifact, policy, and environment

An approved source revision can produce several artifacts, and a tested artifact can be deployed with several configurations. The gate should identify the artifact digest, configuration digest, workflow or builder identity, target environment, applicable policy version, and evidence references. A generic green status attached to a branch name leaves room for a later build or changed configuration to receive authority it was never assessed for.

Make evidence invalidation explicit. A changed dependency lock, compiler image, generated client, migration script, or test selection policy may invalidate earlier results even if the main application files appear unchanged. A new vulnerability finding may change an exception decision without changing any artifact bytes. Record which evidence is about immutable content and which is a time-sensitive assessment. Preserve the earlier decision for audit, then produce a new disposition rather than rewriting history to make it appear continuously valid.

For federated deployment credentials, review the identity claims accepted by the cloud role. GitHub's OpenID Connect documentation explains the token-based exchange for a cloud credential. The trust policy still needs to constrain the intended organization, repository, workflow context, audience, and environment using supported claims. A short-lived token granted to the wrong workflow is still the wrong authority. Include a negative test from a similar but unauthorized context.

Gate behavior should distinguish invalid evidence from an unavailable verifier. Invalid or mismatched evidence blocks promotion. A verifier outage may pause the release and require an approved recovery process, but it should not convert a missing result into a pass. If a break-glass release is permitted, define the bounded change, accountable approver, compensating checks, expiration, and required post-release reconciliation. Emergency access must not silently replace the standard release identity.

Keep runtime readback independent enough to catch a deployment tool's mistaken success. For Kubernetes, the Deployment documentation describes rollout status, progress conditions, and revision behavior. A progressing or available Deployment does not establish that the intended refund invariant passed or that an external provider completed its work. Check the actual artifact and configuration across the relevant instances, then run the service-specific acceptance observations.

15. Manage scarce test environments and unsafe cancellations

Parallel jobs can compete for a database, shared tenant, mock provider, deployment namespace, or quota. Record which resources are isolated per run and which are serialized. A test that passes only when neighboring jobs are idle is weak release evidence even if its assertions are correct. Prefer a unique run identity in test data, explicit cleanup ownership, and bounded environmental dependencies. Where isolation is expensive, reserve a shared environment with an enforceable lease and a recovery path for an abandoned run.

Cancellation is also a state transition. A superseded unit-test run can often stop without durable consequences. A migration, external deployment, or provider interaction may have already committed work. Do not assume that marking the automation run canceled reverses that work. Record the last durable step and reconcile the target environment before another run takes over. Concurrent release jobs need a service-level exclusion or coordination mechanism appropriate to their state changes.

Caches should accelerate repeatable computation, not become an undocumented source of release inputs. Key them by the dependencies and toolchain they represent, separate trust levels, and verify that a cache miss still produces a correct build. If a cache hit avoids a required verification step, explain why the reused evidence remains applicable. Test poisoned or malformed cache entries in an isolated environment, especially when downloaded executables or generated scripts are involved.

Operational and security review should cover the costs of keeping evidence. Test reports can contain credentials, customer-like fixtures, stack traces, and dependency information. Apply retention and access policies to artifacts, job logs, crash dumps, and temporary environments. Expiring logs too quickly can make a recovery investigation impossible; retaining unrestricted production samples indefinitely creates a different risk. Set retention according to the service's investigation and governance needs, with an owner for exceptions.

16. Review checklist and completion criteria

Before adopting the reference contract, ask the service owner to bring one candidate release and one deliberately failed release through it. The failed run should exercise a meaningful boundary such as an unapproved signer, incompatible data, or a missing reconciliation result. A demonstration containing only successful jobs cannot show that the release gate rejects unsafe transitions.

Review gateEvidence that closes it
Contribution isolationUntrusted code cannot obtain release credentials or poison trusted executable inputs
Artifact bindingApproval, required checks, and runtime receipt identify the same immutable bytes
Test sufficiencyCritical risks have owned checks, and skipped or quarantined coverage is explicit
Progressive exposureCohort, observation quality, stop conditions, and delayed effects are assessed
RecoveryMixed-version data and unfinished external effects have a rehearsed procedure
Operating ownershipMaintainers can update policy, repair evidence collection, and handle exceptions

Complete the adoption review when the team can explain both why a candidate was admitted and why another was rejected, using retained evidence. Record unsupported product behaviors and untested failure conditions as limitations. The next implementation step is to make the largest unresolved boundary testable for the selected service, then revise the contract from the results. A common template can follow once its owners can support the behavior it promises.

Limitations, provenance, and next step

This reference design has not established any customer's delivery performance. Its official sources support bounded security and measurement concepts, not a claim that this pipeline is complete, certified, or production-proven.

Before applying this design to a service, obtain review from its authorized technical owners, complete version-specific implementation checks, and retain evidence from the proposed failure drills. Any future customer example needs attributable delivery records and permission for the claims disclosed. Editorial label: Ampity Editorial Review. The linked references were checked on September 21, 2026; that source check is not technical approval of an implementation.

This paper owns the release-evidence and recovery contract. Related pipeline articles and playbooks should serve distinct implementation questions; consolidation still needs provenance and search-performance evidence.

For a scoped assessment of the release path, see CI/CD and observability. For broader runtime ownership and shared infrastructure, see cloud platform engineering.

Primary references

Related services