PostGIS 3.1.1, in PostgreSQL 13 (what I had handy), is able to report the issue --
WITH bad_data AS (
SELECT ST_GeomFromText('POLYGON((-122.148755985 37.42723718100007,-122.148462038 37.42697222300006,-122.1476020649999 37.42622237100005,-122.14681093 37.42551726300007,-122.146799162 37.42550704500007,-122.1467579119999 37.42547357700005,-122.146714522 37.42544187700003,-122.146669111 37.42541203100006,-122.1466218039999 37.42538412200003,-122.146554117 37.42534915200002,-122.145898905 37.42500666200004,-122.146606488 37.42414940300006,-122.14718414 37.42346177100006,-122.147744212 37.42278424400007,-122.147784198 37.42273583200006,-122.1480067479999 37.42246395100005,-122.148371184 37.42202471400003,-122.148569196 37.42178912700007,-122.14798232 37.42249379400005,-122.1480067479999 37.42246395100005,-122.14949105 37.42068471600004,-122.149804428 37.42030734400004,-122.150144279 37.41989809300003,-122.150733848 37.41919052400004,-122.151078419 37.41877586800007,-122.151717718 37.41800663700008,-122.151912941 37.41777175300007,-122.152503005 37.41706315200003,-122.1531540729999 37.41628313600006,-122.153061958 37.41623509800007,-122.153290778 37.41595996300003,-122.153292466 37.41596085600003,-122.153309575 37.41594035100007,-122.157366324 37.41810165800007,-122.1496241789999 37.42741009900004,-122.149316868 37.42775509600006,-122.149258069 37.42770423800005,-122.149162514 37.42761216700006,-122.148755985 37.42723718100007))',4326) as geom
)
SELECT ST_IsValidReason(geom)
FROM bad_data;
Returns:
st_isvalidreason
Self-intersection[-122.148261898889 37.4221581012526]
Indeed, if you convert the feature to LINESTRING (by replacing the "POLYGON(" with "LINESTRING" and removing the trailing parenpattern), then to points (I used ArcGIS Pro and Feature Vertices to Points, but other solutions exist), label the points, and visually inspect them, the problem stands out:
Your coordinates double back upon themselves.
The general solution for detecting this is calculating the angle at B across ABC for each triplet of sequential vertices, and looking for a very small (~0) value. Fixing it comes in two schools, dropping the later vertex, or the earlier one. You could also fold the removed vertices back into the line in an order that doesn't corrupt the shape. Evaluating which is most appropriate to your use case is left as an exercise.