You could use DataObject::validate to enforce that there only ever be one though @Admonish - it's not quite the same thing and would perform a DB read before any write (should be low impact though).
From there you can return/throw (I forget which) a validation exception
Which would rely the message back to the user nicely
Perhaps then it would make sense to use a method instead
And in that method I would always get the first record (with ->first())
As for the interface, I would have to update the modelAdmin functionality to make it remove the Gridfield for any dataobject with the word "Settings" in it
But your right, for a robust solution I would have to add a onBeforeWrite() check
because even if you don't give the user a way to create multiple instances/records of the setting DataObject developers (read my future self) would be able to programically