# Moving from akm 0.8 to the current 0.9 line

The current 0.9 runtime does not contain a second 0.8 config/storage/runtime
architecture. Upgrading the package is supported; loading an old installation
in place is not.

## What the upgrade preserves

- authored assets that you copy into a current bundle;
- task-v2 source files that the explicit task migrator can translate — through
  task-v3 and on to task source v4 — without guessing;
- package-manager or standalone-binary updates through `akm upgrade`.

## What it does not preserve

- 0.8 config shapes;
- old `index.db`, `workflow.db`, task-history JSONL, or legacy lock/cache
  layouts;
- old ref grammar or old workflow/task execution paths;
- in-flight workflow plans older than `irVersion: 5`.

Those formats are not compatibility inputs to the current runtime. Keep an
archive if you need historical inspection; do not place it in the live 0.9
config/data directories.

## Upgrade procedure

### 1. Archive the old installation

Stop scheduled tasks and running AKM processes. Copy the old config, data,
state, cache, and authored bundle directories to an archive outside the live
AKM paths. Verify the copy before continuing.

Do not delete the authored bundle: it is the input you will selectively bring
forward.

### 2. Update the package or binary

Use the installation method that owns AKM:

```sh
akm upgrade --check
akm upgrade
akm --version
```

Alternatively install `akm-cli@0.9.2` directly with npm, Bun, or pnpm, or
replace the standalone binary after verifying its published checksum.

`akm upgrade` updates executable code. It does not rewrite old config or
storage.

### 3. Start from current config and state

Move the archived 0.8 config/data/state/cache paths out of the live locations,
then run current setup:

```sh
akm setup
akm health
```

Configure current `bundles`, `defaultBundle`, engines, and credentials. Copy
only authored assets you intend to retain into a current bundle. Regenerable
indexes and caches should be rebuilt, not imported.

Current additive `state.db` schema changes run automatically when the managed
database opens. That mechanism upgrades current ledgers; it is not an importer
for 0.8 databases.

### 4. Convert task-v2 sources explicitly

Normal task execution accepts task source v4 only. Preview every translation:

```sh
akm migrate status
akm migrate apply --dry-run
```

Review each `changed`, `skipped`, and `blocked` entry. The migrator runs both
generations in one pass — task-v2 to task-v3, then task-v3 to task source
v4 — against the resulting files. It blocks ambiguous argv arrays or any
conversion whose execution meaning is not provable. Rewrite blocked files
manually as task source v4.

Apply only after the preview is correct:

```sh
akm migrate apply
```

Each changed file is validated, backed up immediately before replacement, and
atomically replaced. `akm migrate` does not alter config or databases.

### 5. Rebuild and reactivate

```sh
akm index
akm task doctor
akm task sync
akm health
```

Review the scheduler plan before activation. Use `task sync --rebind` only when
you intentionally want the current installation to take ownership of an
existing scheduler entry.

## Workflow boundary

Current Markdown and GitHub-shaped YAML workflows compile to the same source
IR and freeze the durable plan v4 family's executable `irVersion: 5` format.
That is the only executable stored plan. Do not copy an old workflow database
expecting old runs to resume; start new runs from current authored sources.

## Storage relocations within the 0.9.x line

0.9.11 (itlackey/akm#890) moves five machine-local `akm improve` writers out
of `$STASH/.akm` — where they never belonged, per the "must travel with the
content" rule in [Storage locations](https://github.com/itlackey/akm/blob/main/docs/architecture/internals/storage-locations.md)
— into `$STATE`/`$CACHE`, namespaced per stash so two stashes on one machine
never collide:

| Old path | New path |
|---|---|
| `$STASH/.akm/distill-rejected/` | `$STATE/improve/distill-rejected/<stash>/` |
| `$STASH/.akm/eval-cases/` | `$STATE/improve/eval-cases/<stash>/` |
| `$STASH/.akm/measurement/verdicts/` | `$STATE/improve/measurement/verdicts/<stash>/` |
| `$STASH/.akm/unresolved-sources/` | `$CACHE/index/unresolved-sources/<stash>/` |
| `$STASH/.akm/improve.lock` (+ `.improve.lock.operations.sensitive`) | `$STATE/locks/<stash>/improve.lock` (+ `.improve.lock.operations.sensitive`) |

Any script that reads the old paths directly — `scripts/akm-eval/src/proactive-verdict.ts`
(verdicts), `scripts/akm-eval/README.md`'s eval-cases note, or a custom
snapshot/backup tool — must read the new ones instead; the pilot treatment
file at `$STASH/.akm/measurement/` (sibling to `verdicts/`) is unaffected, it
was never a writer output. `akm migrate status`/`apply [--dry-run]` covers
every configured LOCAL bundle (the default stash first, then every other
filesystem-backed bundle — a `git`/`website`/`npm` bundle is cache-backed,
never touched), and reports and relocates any files still sitting at the old
paths (same-filesystem rename, or copy-then-delete across filesystems). A
lock file is only ever deleted once the same staleness check `akm improve`
itself uses says its holder is dead; a lock a live run still holds (or one
this process cannot read) is left in place and reported instead. The whole
step is idempotent — a second run reports nothing pending.
`$STASH/.akm/memory-cleanup/` did not move; it is the one confirmed exception
to the rule (see Storage locations, above).

## Recovery

If the new setup is wrong, stop AKM, move the new current directories aside,
and restore the archived 0.8 installation with its matching 0.8 executable.
Do not mix old executable code with current state or current executable code
with old state.

For the task source v4 format and the narrower 0.9.1-to-0.9.2 transition, see
[Tasks](../reference/tasks.md) and
[Migrating from 0.9.1 to 0.9.2](v0.9.1-to-v0.9.2.md).
