What is the join logic when using API chaining with action = get?
Chaining will attempt to "guess" at the id of the chained entity. In your first example, the fetched participant record has an "event_id" and the api chaining controller passes that into the chained Event api call as the id.

The guessing is pretty basic though. For everything else, you should specify params explicitly. You do so by using the magic "$value" notation. E.g. 

CRM.api3('participant', 'get', {
  id: 12345,
  "api.ParticipantStatusType.get": {id: '$value.status_id'}
});


Note that you can also use joins for this type of thing, which is generally more efficient than chaining. Check out joins in the Api explorer.