We use trunk based development. In short, changes should only be merged to dev when it is considered production ready. In most cases this will mean:
However, each piece of work should be assessed on a case-by-case basis so it is the responsibility of to the developer to determine what is considered production ready.
In trunk based development, releases happen from any point on the "trunk" (dev) and there is an assumption that any code existing on there is safe for release. If a hotfix is necessary, then it should be fixed forward by a revert commit or a rollback using the appropriate vendor.
There will be times where a portion of code is complete but the rest of the feature needs to be finished before releasing to the public. In this case, we should use feature flags via ConfigCat.
A feature flag allows developers to hide production code until it is ready to be released to production. All flags should be checked in a falsey and truthy state on staging before releasing to production.
If you want to read more about the change from git-flow to trunk-based, here is a great link: https://www.linkedin.com/pulse/trunk-based-development-vs-gitflow-tim-mutton