Skip to main content
Use @pack.migration to change an existing project’s company configuration. Harnest tracks the applied pack schema in harnest-packs.lock and runs only the migration steps needed to reach the installed pack’s target version.

Decorator contract

Rename a company property

The first pack release writes an owner property. Replace its definition with this second release to use team instead:
pack.py
The rename preserves the user’s current value and unrelated properties. An occupied team destination blocks the migration rather than overwriting it. If owner is absent, the rename makes no change; the final Settings validation still requires a valid team.
After a successful apply, the lock records version 2. A subsequent upgrade does not rerun this migration.

Keep the migration chain complete

For an installed pack at schema 3, a project at schema 1 needs both 1 → 2 and 2 → 3. Each callback sees the earlier step’s staged results. Configuration validation runs after all required steps for that pack, so intermediate schemas can differ from the final model. A missing step, a project version newer than the installed pack, or a pack recorded in the lock but absent from the CLI blocks upgrade. Retain older migrations while you support projects created by those releases. Upgrades do not automatically adopt new packs. An existing project without that pack’s version requires a separately designed adoption workflow; there is no built-in adoption decorator or command.

Read existing settings

During upgrades, context.options is None unless the caller supplied options for that pack. Read persisted choices through context.yaml.read("acme-agent.yaml") instead of requiring users to repeat init inputs. If upgrade options are supplied, the same options model validates them, including its required fields. For generated-file updates, use WritePolicy.MANAGED and handle local edits as blockers. See files and YAML changes and conflict recovery.