Commands
layoutd gen
Generate the Migration<Old, New> scaffold with DANGER lines annotated.
Purpose
layoutd gen writes the migration. It produces a Migration<Old, New> implementation that carries every safe field across unchanged and annotates every dangerous decision so you can’t ship one by accident.
Invocation
layoutd gen v1.json v2.json --account UserStateThe scaffold
For the UserState example, the inserted is_active field is a DANGER, so gen emits a complete scaffold with that one decision left for you — every other field is wired up automatically.
// layoutd gen — account: UserState [borsh]// WARNING: dangerous changes present — resolve every DANGER line before shippingimpl Migration<OldUserState, UserState> { pub fn migrate(old: OldUserState) -> UserState { UserState { authority: old.authority, // DANGER: is_active inserted at index 1 — shifts following offsets; supply value // is_active: todo!("supply value"), balance: old.balance, bump: old.bump, } }}How DANGER lines are annotated
- Each dangerous field becomes a commented
// DANGER: …line explaining the consequence, paired with atodo!("supply value")placeholder. - The scaffold does not compile until you resolve every
todo!()— so a dangerous migration can never silently slip through. - Safe fields (
authority,balance,bump) are mapped directly from the old account, with shifted offsets computed for you.
Proof-hash pinning & realloc
gen pins a proof hash of the exact layouts it analysed, so a later check can confirm the migration still matches the inputs it was generated from. For variable-size accounts, the scaffold includes the realloc and rent-adjustment steps needed when the new layout changes the account’s size.
Verify against your binary
gen on your real account versions and confirm the output before committing — your installed binary is the source of truth.Once you’ve resolved the todo!() lines, acknowledge the deliberate danger and let layoutd check confirm the upgrade is safe to ship.