Cyclomatic (and cognitive complexity) are a good start.
Some other ideas
1) Enforce architecture decisions (see archunit). But somebody needs to write them down first.
2) Check that tests actually break if the code that accompanies them is removed (several LLMs/agents today create tests that don't actually test the code they "guard against)
3) Automated performance testing. An LLM/agent might create a change that is "correct" but increases latency for 3x (best case) and 20x (worst case)
The hardest part that I see no solution for today is to understand when a change breaks backwards compatibility. LLMs/agents are trigger-happy and will happily refactor/remove stuff without any care about who is using that.I don't have a proposal for that, but the problem is there and is not covered by 12-factor config.
Excellent set of criteria, thank you. Something like am archlint, or performance lint, and sanity check on tests "Actually testing a seam or function" of the actual code base sound like good research avenues.