# Migrate from 0.3 to 0.4

Keep the Linking manifest declarative, replace bare route arrays with the closed runtime artifact, and make every adapter consume the published package through its supported API.

## Before you change the pin {#before}

1. Commit the current manifest and deployment build inputs.
2. Capture a known-good 0.3 validation and integration-test result.
3. Locate any copied APIZIT Linking modules or calls to the old route-list API.
4. Plan to rebuild every generated artifact, ZIP, or container image.

## 1. Pin the published 0.4 package {#install}

requirements.txt or equivalent

```text
apizit-linking[preview]==0.4.0
```

Do not install from the private engine repository and do not copy its modules into an adapter. PyPI is the supported distribution boundary.

## 2. Make the manifest canonical {#manifest}

The canonical authoring contract still uses root `version: 1`. Explicitly declare it, use uppercase HTTP methods, dotted Python module paths, leading-slash route paths, and only documented fields.

apizit_linking.yaml

```yaml
version: 1
routes:
  - path: /hello
    method: GET
    function: hello:hello
```

The compiler may still accept selected historical forms to explain a migration, but that does not make those forms part of the [public JSON Schema](/apizit-linking-examples/schema/apizit-linking-v1.schema.json). New and migrated files should pass both schema validation and the CLI.

Terminal

```text
apizit-linking validate .
```

## 3. Replace the bare route list {#artifact}

Version 0.3 integrations could serialize individual route dictionaries and pass the unversioned list directly to the FastAPI adapter. Version 0.4 makes the complete artifact the supported handoff.

### Old migration-only shape

```text
runtime_routes = [
    route.to_runtime_dict()
    for route in compilation.routes
]
app = create_app_from_runtime_routes(
    runtime_routes,
    project_root=project_root,
)
```

### Supported 0.4 shape

```text
compilation = compile_linking_file(
    linking_file,
    project_root=project_root,
)
artifact = compilation.to_runtime_dict()
app = create_app_from_runtime_artifact(
    artifact,
    project_root=project_root,
)
```

Persist the complete artifact unchanged. Its closed envelope contains `format`, artifact `version`, `engine_version`, `manifest_version`, and `routes`. Treat it as opaque adapter input.

## 4. Expect strict signature checks {#signature}

Recompilation captures the complete callable contract: ordered parameters, their kinds, required/default state, annotations, `callable_kind`, and `return_annotation`. At startup, the adapter imports the callable and rejects any drift before serving requests. If customer Python changes, re-run compilation rather than editing metadata.

## 5. Remove generator routes {#generators}

Functions containing `yield` and asynchronous generators are not valid Linking targets in 0.4. Convert them to a normal synchronous or asynchronous function returning a supported value. Do not wrap a generator merely to hide its callable kind: streaming remains outside the V1 contract.

## 6. Rebuild APIZIT integration outputs {#apizit}

- Pin exactly `apizit-linking==0.4.0` in the build and runtime.
- Compile once during the controlled build step.
- Record artifact hash, package version, manifest version, and source revision.
- Package the untouched artifact with the exact 0.4.0 runtime dependency.
- Rebuild ZIP and container outputs; do not reuse 0.3 artifacts.
- Run scan, report, package, image, startup, and HTTP integration tests.

An artifact executes only under its exact `engine_version`. Changing the dependency without recompiling is expected to fail.

## 7. Verify the migration {#verify}

1. Run `apizit-linking validate` on every supported project.
2. Load each serialized artifact with the exact pinned engine.
3. Confirm drift tests fail when a fixture callable is deliberately changed.
4. Confirm generator fixtures fail during compilation.
5. Exercise successful requests and structured request errors over ASGI.

## Rollback safely {#rollback}

Restore the exact 0.3 package pin and rebuild its deployment output from the preserved 0.3 inputs. A 0.4 artifact is not a rollback artifact for a 0.3 runtime, and changing version fields by hand is not a rollback strategy.
