@nbeuchat,
I found your idea interesting, at least from my point of view,
But function ST_Buffer() distorts the boundaries and so you don't mind my suggestion next,
run your script without ST_Buffer and see the result :-)...
SELECT (ST_MakePolygon(ST_ExteriorRing(ST_Union(
ST_Difference(ST_ConvexHull(ST_Union(geom)), ST_Collect(ST_Convexhull(geom))), ST_Collect(geom))))) AS geom FROM <name_table>;