# Recipe: edit a step

<!-- funnelsgrove:generated:start contract-v3/recipe/edit-step -->
Step contract version: `3`

Contract hash: `d761e91d5ac6ff9e72c6d49c5bcd014270912473a66f99c49d726c65998085cf`

| Capability | Allowed types | Allowed identities | Required owner |
| --- | --- | --- | --- |
| `browser-registration-completed` | _None_ | _None_ | `trusted-subscription-claim-server` |
| `checkout` | `paywall_offer`, `upsell_offer`, `checkout` | `any` | `named-payment-helpers` |
| `choice-write` | `single_step_choice`, `single_step_choice_emoji`, `multi_select_choice` | `any` | `useStepChoices` |
| `email-capture` | `form_input` | `email-capture` | `submitEmailCapture` |
| `hardcoded-navigation` | _None_ | _None_ | `manifest-flow-controller` |
| `provider-direct-analytics` | _None_ | _None_ | `analytics-adapter-outbox` |
| `subscription-handoff` | `subscription_handoff`, `purchase_completed` | `any` | `runtime-handoff-helper` |
| `subscription-management` | `subscription_management`, `cancellation_offer` | `any` | `runtime-subscription-helpers` |
<!-- funnelsgrove:generated:end contract-v3/recipe/edit-step -->

## Procedure

1. Read the current type page from the [step-type index](../steps/INDEX.md).
2. Decide whether the requested behavior still matches the existing type.
3. Preserve stable IDs, names, paths, answer keys, option IDs, and reserved identities unless the request is an explicit migration.
4. Update component, content/editor, registry, manifest, and tests only where the change requires.
5. Keep component and manifest metadata in parity.
6. Run focused tests, then `fgrove validate`.

## Manual QA

Re-run the complete current interaction, not just the changed visual state. Confirm existing analytics keys, answer shapes, lifecycle outcome, and routes remain intact.
