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

# fjall migrate

> Pin deployed AWS capacity identity into fjall-config.json with the Fjall CLI so re-synths reproduce your live resource names.

`fjall migrate` runs one-off migrations that bring deployed stacks onto current fjall contracts. It has one subcommand, `identity`.

<Note>
  This command does not run database or schema migrations. Application database migrations run as part of a deploy, and `fjall deploy --skip-migrations` controls them.
</Note>

`fjall migrate identity` pins the capacity identity of a deployed pre-6.0 application into `fjall-config.json`, so later synths reproduce the deployed resource names byte-for-byte and a rename-safe deploy stays rename-safe.

<Accordion title="Prerequisites">
  * The Fjall CLI installed and signed in. Run `fjall login` first, the command authenticates before it does any work.
  * A connected AWS account holding the deployed stacks. Connect one with `fjall connect`.
  * An application with an `infrastructure.ts`, created by `fjall create application`.
  * A shell in the fjall project root, so the CLI can detect application targets. Without `--app`, a single detected application is used, and several require you to name one.
  * An account and region that map to a configured deploy target. Check with `fjall target list`. Pins are keyed by target name, so a session that matches no target cannot write them.
</Accordion>

## Pin deployed capacity identity

```bash theme={null}
fjall migrate identity [options]
```

Pin the sole application detected in the current project:

```bash theme={null}
fjall migrate identity
```

Pin a named application:

```bash theme={null}
fjall migrate identity --app api
```

Resolve credentials through a specific deploy target, the same way `fjall deploy --target` does:

```bash theme={null}
fjall migrate identity --app web --target production-euw1
```

Override the region and show the full synth output:

```bash theme={null}
fjall migrate identity --app api --region eu-west-1 --verbose
```

Run it from an agent and get a structured result:

```bash theme={null}
fjall migrate identity --app api --agent
```

## What Happens

The command runs a gate-before-write ceremony. Nothing reaches disk until every candidate pin passes.

<Steps>
  <Step title="Resolve the application">
    `--app` must name a detected local application target. Without it, a single detected application is used. Several detected applications produce an error listing them.
  </Step>

  <Step title="Authenticate and resolve credentials">
    The command requires an authenticated session. `--target` resolves credentials exactly as `fjall deploy --target` does. `--region` overrides the region.
  </Step>

  <Step title="Synthesise with existing pins">
    The application is synthesised with any pins already in `fjall-config.json` applied, mirroring how a deploy threads capacity identity into the assembly.
  </Step>

  <Step title="Compute the plan against live templates">
    The synthesised assembly is diffed against the live CloudFormation templates. A synthesised stack with no live counterpart is recorded and skipped rather than failing the run.
  </Step>

  <Step title="Gate the candidate pins">
    Candidate pins are injected as CDK context, never written to disk first. The application is re-synthesised and the identity-surface gate runs over every pinned slot, both new candidates and pre-existing pins.
  </Step>

  <Step title="Write, all or nothing">
    Pins are written to `fjall-config.json` under `capacityIdentity[appName][targetName][slot]` only when every candidate passes. One failing slot means no pins are written at all.
  </Step>
</Steps>

Commit the resulting `fjall-config.json` change. Pins travel with the project, and deleting one renames every stateful resource in its slot.

### Dry runs

There is no dry-run flag. The gate-before-write ceremony gives you the equivalent safety: a run that refuses any candidate writes nothing, reports the failing slot and its gate failures, and exits with code 1.

### Nothing to pin

Three outcomes report no work rather than an error:

| Condition                                                   | What the report says                                                      |
| ----------------------------------------------------------- | ------------------------------------------------------------------------- |
| No live stack for the application in the account and region | Nothing to pin, no live stack found                                       |
| The application declares no EC2 capacity slots              | Nothing to pin, no capacity slots declared                                |
| No unpinned capacity renames detected                       | Nothing to pin, any existing pins already reproduce the deployed identity |

### Exit codes

| Code | Meaning                                                               |
| ---- | --------------------------------------------------------------------- |
| `0`  | The report is clean. Pins were written, or there was nothing to pin   |
| `1`  | A pin was refused by the identity-surface gate, or the command failed |

### Agent mode

With `--agent`, the command emits a structured result instead of the human report. The result name is one of:

| Result                  | Meaning                                                |
| ----------------------- | ------------------------------------------------------ |
| `identity-pins-applied` | Every candidate passed and pins were written           |
| `nothing-to-pin`        | No candidates and no existing pins to verify           |
| `identity-pin-refused`  | At least one slot failed the gate. Nothing was written |

The payload carries `app`, `accountId`, `region`, `targetName`, `clean`, `duration`, plus `outcomes` and `verified` arrays when the report has them. Dependency-gate warnings arrive as structured warning events rather than stderr diagnostics.

## Options

All options belong to the `identity` subcommand. The `fjall migrate` group itself accepts only `--non-interactive` and `-v, --verbose`.

| Flag                    | Description                                                                                  | Default                   |
| ----------------------- | -------------------------------------------------------------------------------------------- | ------------------------- |
| `--app <name>`          | Application whose deployed capacity identity to pin (defaults to the sole local application) | Sole detected application |
| `--target <name>`       | Deploy target for credential resolution (e.g. production-euw1)                               | None                      |
| `-r, --region <region>` | AWS region override                                                                          | None                      |
| `--non-interactive`     | Force plain CLI output (no UI)                                                               | Off                       |
| `-v, --verbose`         | Enable verbose output                                                                        | Off                       |
| `--agent`               | Enable agent output mode                                                                     | Off                       |
| `--budget <level>`      | Output budget: minimal, compact, or token count                                              | None                      |
| `--fields <fields>`     | Select exactly these output fields                                                           | All fields                |
| `--full`                | Disable content truncation                                                                   | Off                       |

Empty values are rejected at the boundary. `--app ""` and `--target ""` fail validation rather than falling back to auto-detection.

## Next Steps

<CardGroup cols={2}>
  <Card title="fjall deploy" icon="rocket" href="/cli/deploy">
    Deploy the application once its pins are committed.
  </Card>

  <Card title="Destructive Changes" icon="shield-halved" href="/deployment/destructive-changes">
    The rename and consent ceremony that pins protect against.
  </Card>

  <Card title="fjall drift" icon="wave-square" href="/cli/drift">
    Detect and repair resources changed outside CloudFormation.
  </Card>

  <Card title="fjall validate" icon="circle-check" href="/cli/validate">
    Check infrastructure.ts before the next deploy.
  </Card>
</CardGroup>
