I don't see why it couples clients to the implementation.
Effectively, there's no difference between writing the code first and updating the OpenAPI spec, and updating the spec first and then doing some sort of code gen to update the implementation. The end state of the world is the same.
In either case, modifications to the spec will be scrutinized to make sure there are no breaking changes.
Yeah this is the way, I mean if the spec already exists it makes sense to go spec-first. I went spec-first last time I built an API because I find most generators to be imperfect or lacking features; going spec-first ensured that the spec was correct at least, and the implementations could do the workarounds (e.g. type conversions in Go) where necessary.
That is, generate spec from code and your spec is limited to what can be expressed by the code, its annotations, and the support that the generator has. Most generators (to or from openapi) are imperfect and have to compromise on some features, which can lead to miscommunication between clients/servers.
Effectively, there's no difference between writing the code first and updating the OpenAPI spec, and updating the spec first and then doing some sort of code gen to update the implementation. The end state of the world is the same.
In either case, modifications to the spec will be scrutinized to make sure there are no breaking changes.