I must be not getting something. I'm loading City_01_01.bin, one of the refs is grp_GC_Shutdown_Atmo (I assume for Refs I DO search the geobin rather than defnames), the first group of this def is grp_Media_Intvw, which is not present in defnames
;tldr - If a def name is a model, defnames tells you what .GEO contains the model. If the def does not have an entry in defnames, it's not geometry. It's something else.
You're not finding it in defnames because grp_Media_Intvw is not a model. It's an object in the object library that is a group of "atmosphere" NPC's. It's a group of models; though, the models in question are the dev-view-only spawn point models rather than the NPC's themselves. The NPC's are entities, which is something else entirely.
Maybe Codewalker's advice needs to be qualified to say that anytime you need to find the .GEO that holds a model, you look it up in defnames rather than futz around with parsing the path leading to the def. That's what defnames is: a mapping of def names to model file names. You go to defnames when you've reached a leaf node (or, I suppose, when you have a tray, given what we've recently learned about those from Codewalker) and that's how you find the .GEO for that model.
Typically, this would be indicated by an "object" def but as we've seen this isn't always necessarily the case. So, when you get a path, the first thing you do is look for it in the object library. If there's an object library bin for that path, you add it to the scene graph and follow that new patch to its conclusion, adding whatever other pieces are indicated. Eventually, you'll reach one or more leaves with no children; at that point, you've got a model name (assuming that it's not some other kind of def, like a sound file) and you use defnames to find the .GEO for the model.
Then the real fun starts when you try to figure out how to load the model and its texture.
What I've taken from Codewalker's explanations in the past is that in an ideal world, the object library would be completely loaded into memory and every piece of it would always be available permanently. In the real world, that would use an unrealistic amount of RAM and instead we demand-load the pieces that are going to be used by the current scene as they're encountered in the scene graph. Presumably, we also mark the loaded models so that when the scene changes, we can do a final pass on everything in memory and unload whatever is still in RAM that isn't currently being rendered. I've assumed that's why models get two defs - an object def and an apparently "null" def. My guess was that the "null" def is used to indicate what should be treated as cache and what should be unloaded after the scene is completely loaded but not yet rendered.
From the standpoint of loading the scene graph, you load the map bin, and when you encounter a path, you load that object from the object library, then examine the nodes in that new bin you just loaded. If there are more object library defs (say, it's a building composed of many parts that are all separate object library bits), you load them as well and process them recursively. If you encounter a leaf node and/or an "object" def, you treat it as a model (unless there's a reason to treat it as something else, because one of the other values of the def indicates that it's a sound file or LOD values or whatever).