> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formae.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Apply modes

> What reconcile and patch modes each let formae do, and what they refuse to do.

Every `formae apply` requires a mode. The mode determines what formae is allowed to do, and more importantly, what it won't do.

## Reconcile

```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
formae apply --mode reconcile main.pkl
```

Reconcile is the [GitOps](/documentation/concepts/ways-to-work) mode: your codebase declares the desired state of your infrastructure, and reconcile makes reality match it. Resources in your forma are created or updated, and resources that exist in the cloud but **not** in your forma are destroyed. After a reconcile, your infrastructure is exactly what your code says it should be.

This is the everyday mode whenever your code is the source of truth and you want your infrastructure brought back in line with it, from a first deployment to routine changes.

## Patch

```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
formae apply --mode patch change.pkl
```

Patch is **append-only**. It only creates or updates the resources named in your forma, and never destroys anything. Resources you don't mention are left untouched, and within a resource, collection properties (tags, security groups, and the like) are only added to, never trimmed. Reconcile can destroy; patch cannot.

Patch exists for two situations:

* **Working without a declared codebase.** When you don't have code that describes the desired state of your infrastructure, or don't have it to hand, you work by extract-and-patch: extract the resource or two you want to change, edit them, and apply them back with patch.
* **Emergency fixes.** When you're firefighting an incident and want the smallest possible blast radius, patch one or two resources to resolve it rather than reconciling a whole stack.

### A patch is an out-of-band change

A patch changes your infrastructure without going through a full reconcile, so formae treats it exactly like a change made outside formae, the same way it treats an [out-of-band change](/documentation/concepts/synchronization) that sync pulls in. After a patch, your codebase no longer describes reality.

The next [soft reconcile](#hard-vs-soft-reconcile) on that stack detects the drift the patch introduced and **fails**, forcing you to deal with it: absorb the change back into your code, or undo it. This is deliberate. A 2am patch fixes the incident now; the drift it created surfaces the next morning, so someone reconciles the code back to reality instead of silently losing the change.

## Collection handling

When a resource has a collection property (tags, security groups, or any list of values), the apply mode determines how that collection is updated.

**Reconcile mode** treats your forma as the complete truth: the collection after apply matches exactly what you specified, and elements not in your forma are removed.

**Patch mode** is append-only: elements in your forma are guaranteed to exist after apply, but existing elements are never removed.

**Example:** a resource has tags `[A, B, C]` and your forma specifies `[B, D]`.

| Mode      | Result         | What happened                   |
| --------- | -------------- | ------------------------------- |
| Reconcile | `[B, D]`       | Tags A and C are removed        |
| Patch     | `[A, B, C, D]` | Tag D is added, nothing removed |

This makes patch mode safer for shared resources where multiple teams manage different parts of the same collection.

## Hard vs soft reconcile

When someone changes a resource outside of formae (through the cloud console, another tool, or a script), that's an out-of-band change. Reconcile mode handles them in two ways.

### Soft reconcile (default)

If formae detects out-of-band changes, it rejects the apply to protect you:

```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
formae apply --mode reconcile main.pkl
# Fails: external changes detected
```

This gives you a chance to review what changed: extract the current state, compare it with your code, and decide what to keep.

### Hard reconcile

If you've reviewed the changes and want to overwrite them, add `--force`:

```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
formae apply --mode reconcile --force main.pkl
```

Hard reconcile overwrites all out-of-band changes and brings the infrastructure exactly in line with your forma. Use it when your code is the authority and external changes should be discarded.

<Tip>
  Soft reconcile is a safety net. Reach for `--force` only when you know what you're overwriting.
</Tip>

## Resource replacement

Most property changes update a resource in place. Some properties are immutable, though: changing them triggers a destroy followed by a create.

```kotlin theme={"languages":{"custom":["/languages/pkl.json"]}}
myVpc = new vpc.Vpc {
  cidrBlock = "10.1.0.0/16"  // Immutable, triggers replacement
}
```

formae handles this automatically, but be aware: replacement means downtime for that resource and anything that depends on it. Simulation catches this before it happens:

```bash theme={"languages":{"custom":["/languages/pkl.json"]}}
formae apply --mode reconcile --simulate main.pkl
```

Check the simulation output for "replace" operations before applying.

## See also

* [Policy](/documentation/concepts/policy): auto-reconcile policies apply reconcile mode on a schedule.
* [Synchronization](/documentation/concepts/synchronization): how formae detects the out-of-band changes that soft reconcile protects against.
