Well, you practically answered your question on that problem description! But yes, it's not obvious at first, and unfortunately the combination of buster and AMD is not so good at highlighting these problems clearly. I know I've lost my fair share of time debugging similar issues and every once in a while I still get a bit confused.
What you need to have on that file is basically a paths config that maps greeter to example/greeter, something like this:
This usually gets AMD newcomers by surprise, so make sure you read more about paths configs on AMD to understand better why this needs to be done.
You should specify it in a separate file and load it in the libs section, along with your loader library. You can probably even have different config files for testing and actual use on your application and build processes.
I personally like to keep just one file, so I use some additional tricks to sort of automatically prepare one file for testing based on the original file, but saves the trouble of having to specify those configs in more than one place.
Also, something which I have found out in the past couple of days is loading the modules to test in a bit of a different way (slightly more verbose) which I think helps me figure out better which modules have problems when you start to have big trees of dependencies. I've forked your example to demonstrate:
This is just something I think it's better and it's by no means a proven way of doing things better, and when you do have syntax errors on modules which are dependencies of what you are testing, you usually see similar script/syntax errors on loading files that you have no idea where they come from.
Let me know if any of that helps!