> ## Content Index
> Fetch the complete content index at: https://devinside.cloud/llms.txt
> Use this file to discover other available public pages before exploring further.

# The next command must earn its permission
- URL: https://devinside.cloud/a-recovery-runbook-should-refuse-the-wrong-next-step/
- Published: 2026-11-12T15:49:29.000Z
- Updated: 2026-11-13T00:58:23.000Z
- Description: The database opens. A connection succeeds. A command returns without error. The operator is ready to switch traffic, but the restored database belongs to another application and an external dependency still contains the wrong content.
- Author: Marcin Borecki
- Tags: Engineering, Data and production, #plat08, #devinside-review

Historical edition · Sources and examples scoped to 2026-01-15.

*Retrospective edition, scoped to 15 January 2026\. The recovery states are hypothetical and the browser performs no SQL, restore or traffic switch. Its purpose is to compute which next action the supplied evidence permits.*

The database opens. A connection succeeds. A command returns without error. The operator is ready to switch traffic, but the restored database belongs to another application and an external dependency still contains the wrong content.

A runbook that treats reachability as recovery can walk confidently into that state. Every individual command may be valid. The sequence's assumptions are not.

The useful question is therefore not only whether the happy path works. It is whether the procedure refuses a plausible wrong state before the next consequential action, and identifies the evidence needed to proceed.

Consider a small application whose recovery depends on a database, a current application epoch, a reconciled operation ledger and an external reference file. We will distinguish validating a backup, restoring an isolated target, reconciling history and releasing traffic. Those actions have different prerequisites. A runbook should not authorize all of them merely because an endpoint responds.

The reader's task is to design refusal gates that protect the next transition while preserving enough evidence for an operator to understand the stop.

## Name the application, not just the database server

A connection string identifies a route to a server and database. It does not by itself prove that the destination is the intended recovered application. A decoy database can answer the same trivial query and still be the wrong target.

Use an application-owned identity record or another independently verifiable marker. The expected value should come from the recovery contract, not from whatever database happened to answer the probe. Comparing a value with itself establishes nothing.

```sql
IF @ObservedApplicationId IS NULL
   OR @ExpectedApplicationId IS NULL
   OR @ObservedApplicationId <> @ExpectedApplicationId
    THROW 50001, 'Unexpected recovery target', 1;

```

The variables here represent an independently supplied expectation and an observed target value. Missing values must be refused explicitly: a comparison with SQL NULL yields UNKNOWN, which is not a true IF condition. This is an illustrative guard, not a complete recovery script. The selected SQL Server 2022 baseline was [generally available before this edition](https://www.microsoft.com/en-us/sql-server/blog/2022/11/16/sql-server-2022-is-now-generally-available/?ref=devinside.cloud). No later patched engine build or laboratory result is used as historical evidence.

![The endpoint can answer while the target is wrong](https://devinside.cloud/content/images/2026/11/devinside/v4/PLAT08/reachable-is-not-identified.svg)

[Inspect the full diagram ↗](https://devinside.cloud/content/images/2026/11/devinside/v4/PLAT08/reachable-is-not-identified.svg)Swipe the drawing to inspect it.

In the visual, keep the endpoint reachable but change the target identity. A request to release traffic should stop at the identity boundary. The model should not silently change the expected identity to match the available target, because that would repair the appearance of the check rather than the recovery condition.

## A source artifact has to exist before it can be trusted

The restore path begins with a declared backup artifact. A missing path should stop before restore. A mismatched identity or digest should also stop before the file is treated as the intended source.

Verifying an artifact is different from proving that the application can recover from it. A valid backup can restore into a database that lacks a required external file, uses stale application authority or does not satisfy the next transaction's postconditions. The runbook needs both source validation and target acceptance.

The model separates those fields. “Backup exists” and “backup identity matches” are prerequisites for the modeled restore action. “Target restored and reachable” is a later observation. A request to restore over an existing target is refused under the example's isolated-target policy rather than silently overwriting it.

Permitting the modeled restore does not execute it. Before evaluating a later action, the operator must supply the newly observed target facts; an absent target cannot also count as a responding restored application.

That isolation rule is a deliberate safeguard for this teaching procedure. A real recovery plan may have a different overwrite policy, but it should be explicit, authorized and independently checked. A convenient remembered database name is not enough to justify a destructive restore.

## Different next actions require different evidence

Validating a backup does not require the application to be fully recovered. Restoring a new isolated target does not require traffic to be ready for release. Reconciliation requires the correct target and the relevant history. Cutover requires the complete application acceptance boundary.

If one generic “ready” flag authorizes every action, the procedure loses those distinctions. It can become impossible to tell whether a stop means the artifact is missing, the target is wrong or the final application probe failed.

![Each next action requires a different proof](https://devinside.cloud/content/images/2026/11/devinside/v4/PLAT08/next-action-contract.svg)

[Inspect the full diagram ↗](https://devinside.cloud/content/images/2026/11/devinside/v4/PLAT08/next-action-contract.svg)Swipe the drawing to inspect it.

The interactive model computes the required gate sequence from the requested action. Changing the action changes which evidence is relevant. A backup-validation request can pass while cutover remains blocked. That is not inconsistency; it is the point of separating the contracts.

Each refusal should identify the unsupported next step and the missing or contradictory fact. The operator should not have to infer it from a long transcript of commands that succeeded earlier.

## Epoch and identity answer different questions

The correct application identity does not prove that the target has current authority. A restored database can contain an older application epoch, configuration version or fencing value. If another environment still owns the current epoch, accepting writes through the old one can create conflicting histories.

The example treats epoch equality as a required cutover condition. It does not claim that one integer field solves every distributed ownership problem. The actual mechanism must define who can advance the epoch, how writers validate it and what happens to already in-flight operations.

For the runbook, the important distinction is that a target can be correctly identified and still have stale authority. Testing only the application ID would miss that case. Testing only the epoch would not protect against a different application that happens to use the same number.

A useful acceptance record keeps both observations and their independent expected values. That makes a failed gate diagnosable without broadening the next action's authority to get the procedure moving.

## Reconciliation is not a blind retry

Suppose the source recorded an operation as attempted before the interruption, while the target contains an effect whose acknowledgement may not have been recorded. Replaying the operation under a new identity can create another effect. Ignoring it can leave the application inconsistent.

The runbook should reconcile stable operation identities and request bindings under the domain's chosen policy. A matching known effect can establish completion. A conflicting payload under the same identity should stop. Missing evidence can remain unresolved rather than being converted into a convenient failure.

![Do not release traffic across an unexplained history](https://devinside.cloud/content/images/2026/11/devinside/v4/PLAT08/reconciliation-before-release.svg)

[Inspect the full diagram ↗](https://devinside.cloud/content/images/2026/11/devinside/v4/PLAT08/reconciliation-before-release.svg)Swipe the drawing to inspect it.

In the model, the ledger-reconciled field is separate from reachability and epoch. Releasing traffic while it is false is refused. Selecting the reconciliation action asks for the evidence needed by that action; it does not pretend the boolean becomes true simply because the operator clicked a button.

This matters for automation. An executable runbook should observe the postcondition of reconciliation rather than mark a step complete because its command returned zero. The command may have processed the wrong scope, skipped a conflict or produced an unresolved result that requires another decision.

## An external file can be part of database consistency

Applications often depend on data outside the restored database: configuration, reference files, object storage, keys or another service's versioned contract. A database restore can succeed while those dependencies remain wrong.

For the worked example, the external reference file has an expected content identity. A file at the correct path with different bytes does not satisfy the condition. The visual keeps that mismatch visible even when the database opens and every other gate passes.

The strongest objection is that checking every external dependency can make recovery slow or brittle. The answer is to identify the dependencies that participate in the application's actual acceptance contract. Not every decorative asset needs to block recovery. A reference dataset that changes a transaction's meaning may.

This is a product and architecture decision that should be made before an incident, not improvised under pressure. The runbook then records the selected scope and makes unsupported assumptions visible.

## A final probe should test the promise you are about to make

An application-ready probe can be more than `SELECT 1`. It can verify a known read, a scoped authorization decision and, where appropriate, a safe transaction against an isolated fixture. The exact probe should be designed around the operation the recovered application must perform correctly.

The model represents that result with an explicit final-probe condition. It does not perform the transaction. Its value is showing that all the earlier gates can pass while the final application condition still fails. A successful restore command is not allowed to overwrite that outcome.

For a real procedure, preserve the raw response and the assertion that interpreted it. A reviewer should be able to distinguish observed evidence from a summary written after the fact. If a probe was not executed, say so; do not inherit a passing result from another environment or an earlier rehearsal.

## Negative cases belong in the runbook's acceptance criteria

![A useful refusal names the unsupported transition](https://devinside.cloud/content/images/2026/11/devinside/v4/PLAT08/separate-postconditions.svg)

[Inspect the full diagram ↗](https://devinside.cloud/content/images/2026/11/devinside/v4/PLAT08/separate-postconditions.svg)Swipe the drawing to inspect it.

A discriminating fixture can make the expected refusal unambiguous. Set the endpoint to reachable, the backup to valid, the epoch to current and the external file to the expected content, but give the target another application identity. Cutover must stop at identity. Restore the correct identity and make only the ledger unreconciled; the next refusal should name reconciliation instead. A test that reports the same generic failure for both cases may be correct at denying traffic but inadequate at guiding recovery.

Also test that an earlier safe action is not blocked by an irrelevant later condition. Validating a backup can succeed while the final target is still unreconciled. That result does not authorize cutover; it establishes the narrower artifact observation. A runbook that demands every final condition before it can collect any intermediate evidence can become impossible to use, while one that treats any intermediate pass as final readiness becomes unsafe.

This is why the procedure should attach observations to actions and postconditions rather than maintain one mutable ready flag. The operator can then tell what has been established, what remains unknown and which next step is permitted. The distinction is especially useful when several people hand the incident across shifts.

Test a missing artifact, a wrong digest, an existing target under an isolated-restore policy, a reachable decoy database, an old epoch, unreconciled history, a wrong external file and a failed application probe. Each should stop at the intended boundary with no later consequential action.

Keep all other conditions valid when testing a particular guard. If the wrong-target case also has a missing backup, the procedure may stop for the missing file and never demonstrate target-identity protection. A targeted refusal test needs a discriminating fixture.

The browser provides those independently selectable conditions so the reader can derive an expected route. It is not a substitute for rehearsing the real commands, actual storage and operator handoff. It makes the next implementation question sharper: which observation must the real script obtain before it can justify this transition?

## The useful runbook can say no precisely

A good recovery procedure does not maximize the number of commands it can execute without interruption. It preserves the relationship between evidence and the next action. A precise refusal can be the most valuable output when the reachable destination is not the recovered application the organization needs.

Before accepting a runbook, deliberately point its probe at a plausible wrong target and keep the endpoint healthy. Then make the target correct while leaving one external consistency dependency wrong. If both cases still reach cutover, the procedure has confused a successful command sequence with a justified recovery decision.

GO FURTHER

## Inspect the contemporary laboratory.

This is a newly reconstructed historical edition, not a claim of earlier authorship. Later executed experiments, their exact environments and original results are preserved in a separate notebook.

[Open the current laboratory notebook ↗](https://devinside.cloud/lab-notebooks/v4/PLAT08.html)

[Download the current reconstruction sources ↗](https://devinside.cloud/content/files/v4/PLAT08-reconstruction.zip)