I would say LPython, Codon, Mojo and Taichi are structured similarly as compilers written in C++, see the links at the bottom of https://lpython.org/.
Internally they each parse the syntax to AST, then have some kind of an intermediate representation (IR), do some optimizations and generate code. The differences are in the details of the IR and how the compiler is internally structured.
Regarding the type inference, this is for a blog post on its own. See this issue for now: https://github.com/lcompilers/lpython/issues/2168, roughly speaking, there is implicit typing (inference), implicit declarations and implicit casting. Rust disallows implicit declarations and casting, but allows implicit typing. As shown in that issue they only meant to do single line implicit typing, but (by a mistake?) allowed multi-statements implicit typing (action at a distance). LPython currently does not allow any implicit typing (type inference). As documented at the issue, the main problem with implicit typing is that there is no good syntax in CPython that would allow explicit type declaration but implicit typing. Typically you get both implicit declaration and implicit typing, say in `x = 5`, this both declares `x` as a new variable as well as types it as integer. C++ and Rust does not allow implicit declarations (you have to use `auto` or `let` keywords) and I think we should not do either. We could do something like `x: var = 5`, but at that point you might as well just do `x: i32 = 5`, use the actual type instead of `var`.
icontract and pycontracts do runtime Preconditions and Postconditions with Design-by-Contract patterns similar to Eiffel DbC; they check the types and values of arguments passed while the program in running and not just at coding or compile time.
Yes, we have Shedskin in the list at the bottom of https://lpython.org/. Note that the Shedskin compiler is written in Python, so the speed of compilation might be lower than other Python compilers written in C++. Unless it compiles itself, that would be interesting. We thought about eventually writing LPython in LPython, but for now we are focusing on delivering, so we are sticking to C++.
edit: after trying quickly, it seems that lpython really requires type annotations everywhere, while codon is more permissive (or does type inference)