Forbid steps from calling other steps' lifecycle methods
Ref: https://discord.com/channels/489127045289476126/496715299505307678/1171582582450831503

We should also hint how you should do things; e.g. if the optimize method of a step tries to call another step's optimize method, we should tell it instead to set its own `allowMultipleOptimizations` to true - e.g. in Vincent's "string concatenation" step it can optimize if all the dependencies are constants, but initially they won't be constants until they are themselves optimized, so its optimize must be ran a second time.