Python API; immutable Object
I've found a few solutions to this.
The nicest is the create the mesh in another .blend file, then link that in and attach to a local object.  This gives you a linked icon in the outliner (for the mesh) and prevents mesh changes - downsides are you need to work with multiple files.
@HikariTW's suggestion of Collection instancing works; though doesn't give quite the experience I was looking for.
The other solution is to just watch for mode changes and block them.  This seems to work pretty well; something like this works
import bpy

def restrict_edit_mode(object, data, unk=None):
    # XXX: check if bpy.context.object to see if it applies
    # remove the move into edit mode; so you can't undo into it
    bpy.ops.ed.undo()
    # make sure we're always in object mode, without this you can
    # end up in the wrong mode by undo/redo combos
    bpy.ops.object.mode_set(mode='OBJECT')
    # XXX: do something instead


# registering on a per oject basis seems unreliable
# but doing it for everything works pretty well
handle = object() 
subscribe_to = bpy.types.Object, &quot;mode&quot;


bpy.msgbus.subscribe_rna(
    key=subscribe_to,
    owner=handle,
    args=(None,),
    notify=restrict_edit_mode,
)
'''