Every Effect program is built from a handful of tiny constructors, so start with the simplest one. When you already hold a plain value, Effect.succeed lifts it into an effect that always succeeds, a type whose error channel is simply never.
Its mirror image is how you signal trouble. Effect.fail lifts a value into the failure channel, and now the success type is never because this effect only ever fails. Notice the pattern from the last lesson, that a failure here is a value, never a thrown exception.
So far nothing has actually happened, because an effect is only a description of work. Effect.sync wraps a synchronous side effect so it fires later, when you run the effect, not the moment you write it.
Async work splits into two cases, and the difference is the whole point. Effect.promise is for a promise you trust never to reject, while tryPromise catches a rejection and surfaces it as an UnknownException in the E channel, finally visible to the type system.