Rendered at 16:48:31 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
MichaelNolan 3 hours ago [-]
Maybe I missed it, but it look like this has just a single metric. Maybe instead of making a new project, you could try to get this metric added to a existing tool like https://dekobon.github.io/big-code-analysis/index.html which already has dozens of metrics.
sagenschneider 3 hours ago [-]
Yes, I'm doing my own research on AI augmented pipelines https://blog.officefloor.net . I actually found most code quality tools look for bugs and complexity, but nothing much about cohesive erosion. The nice thing about this metric, is that it determine the files where the erosion is occurring. I turned it into a GitHub action to make it easier to access to get wider feedback on the metric. The GitHub action triggers on your merge request and tells you the files where erosion is occurring to refactor. This stops erosion before it gets too expensive to change (big refactors or rewrite). Yes, happy to work with others to get the metric into other tools.
visarga 2 hours ago [-]
I just dump all user messages from all sessions in a project into a flat .md file and have agents synthesize the user's intent. Then, using that extracted intent, the agents review code and tests. I call this a retro/reflection pass. It checks whether the code matches the intent and whether the tests match the code.
Compactly formatted user messages are something an agent can ingest in a few minutes, even if they are thousands of lines long. And the quality of those messages is great: they don't track what the agent does well, only what changes and what breaks.
Having this top-down view helps a lot. Usually, within a session and deep into a task, the agent loses the global perspective and optimizes for local success. I find it weird there is no harness that treats user messages as high value signal (except my own, of course, I have it, https://github.com/horiacristescu/playbook-harness).
sagenschneider 14 minutes ago [-]
Keeping all the specifications and user discussion does create more context, which is useful for AI.
The problem with specification and user discussion is they still have errors that code has. But unlike code, there are no tests to confirm correctness.
So now we have a definition of the system in a non-exact language with no ability to test to confirm it's correctness. The code holds the essential complexity and now we are adding accidental complexity on top to manage.
Again agree the specifications and user discussion provides context for the AI. However, a well written test suite provides similar context that can actually confirm correctness of the system.
However, saying all the above. Focus of ImpactGate ( https://impactgate.officefloor.net ) is about erosion of the code, not correctness.
catlifeonmars 3 hours ago [-]
What exactly is “cohesive erosion”?
sagenschneider 2 hours ago [-]
Comes from the basic Computer Science principals of High Cohesion and Low Coupling.
High cohesion means the functionality of a component are closely related and focused on performing a single well defined task. Basically single classes for single purposes.
Erosion of this is when classes start doing to many things, in the case of God classes.
The Change Impact formula looks at a way of detecting when the cohesion is eroding and flagging it on a change (as the pull/merge request itself should generally be single focus cohesive change)
apercu 3 hours ago [-]
I've never encountered that term before (cohesive erosion) but I like it, if I'm interpreting it correctly.
Do you mean like the hyper focus an LLM puts on the task in front of it so you end up with drift (duplicated concepts/multiple ways of doing things, terminology drift (e.g., now we have "customer" and "client"). That sort of thing?
sagenschneider 2 hours ago [-]
When you think about a god class or god method, it occurs over time by adding more than a single responsibility.
Yes, there are generally complex algorithms but they usually are not things developers write (imported from libraries).
What is usually going on in the god class/method is that things keep getting added to it. These things should be separated out. So the cohesiveness of the class/method erodes into doing too many things.
The idea of the Change Impact formula is to catch this early so you start refactoring to separate out into classes with single cohesive purposes.
The problem with AI is it handles complexity really well and will happily keep piling changes into god classes/methods reaching ridiculous CC levels (have see over 200). Previously developers would get annoyed and do the refactor. But with AI these days, changes are happening faster. So Change Impact is to try to monitor the cohesive erosion.
stingraycharles 3 hours ago [-]
That project in itself looks very interesting. How are people using it, any examples of how people get this into an actual report / CI test / benchmark / whatever ?
MichaelNolan 3 hours ago [-]
Code metrics in general aren’t that widely used. I’ve only ever worked at one place (a bank) that tracked it, and that was only because sonarcube had it built in.
While a lot of metrics make intuitive sense, we don’t have that much hard evidence to prove or disprove their value. Part of it is the whole “if a metric becomes a target, it ceases to be a good metric” thing. Adding the checks to a large existing project probably has negative value. But I think it’s worth doing for greenfield projects.
For humans, these should just be advisory. But for LLMs I’m happy enough to make it a blocking check.
I keep thinking of doing an experiment where I give the same LLM the same problem, and only change which metric is enforced. And then see if any of them have a noticeable effect on correctness/maintainability.
> any examples of how people get this into an actual report / CI test / benchmark / whatever ?
Yeah they have examples of adding it to CI, or local checks, generate html reports, etc in their docs.
paimapi 2 hours ago [-]
I think the future of development will be a lot of automated quality checks like these on AI-drafted code that humans review and ensures that it doesn't muck up the business logic and actually fulfills the acceptance criteria. that said, I don't think existing toolsets are really great at actually measuring code quality
I've been in the process of reviewing and validating a lot of tools like this (qlty, Sonarqube, fallow, etc) and the false positive rate is anywhere from 20% to 80% for a lot of our sniff tests (zizmor produces an overwhelming majority of false positives here for what feels like arbitrary and very context-dependent GHA requirements)
the last thing I want to do is to annoy the hell out of our devs by requiring checks like these to pass especially since it's only a small percentage of them who vibe code everything and then also vibe response to code reviews. I feel like that's the anti-pattern that we'd push people towards by requiring checks like these to pass
another avenue of exploration has been requiring test coverage but also good test quality metrics (eg are there negative tests? mutation testing? empty asserts?) something that seems quite easy to spin up into a skill and pair with a deterministic harness. trash-tests is a neat little project that incorporates some of this: https://github.com/frangelbarrera/trash-tests (disclosure: I am not the repo owner or even a contributor, just a quality nerd who loves underdogs lol)
all in all, it really does feel like we'll need a revamp of the SDLC with our current expected velocities
sagenschneider 2 hours ago [-]
Yep, agree on annoying developers. So just to cover usability it can run in warn and block mode to address this.
Though to the bigger point of your comment, yes SDLC are becoming faster. We can churn out code at a ridiculous rate. However, doesn't mean it's good code. And hence, there are studies showing things actually slowing down because reviews pile up.
I guess I look at the Change Impact formula (and https://impactgate.officefloor.net implementation of it) as threshold tool. Small changes that aren't contributing to god classes, just let through. When things start to smell, the files involved get marked for review.
Ideally this then can cut down on review time and allow overall increased velocity.
But yes relies on trusting the AI to do "simple" things
sagenschneider 2 hours ago [-]
Yep, this all actually started because of experimenting with my own open source project https://officefloor.net (giving full disclosure)
I was testing the additive pipeline style of OfficeFloor against the mutative handler style of Spring. I was looking to see what factors could be used to allow AI to make long on going changes (experiment is 60 changes to an end point, where all add functionality and every 4th change is mutative on existing rules). Then I watch how AI manages to make the 60 changes in each architecture.
I've done many runs and you are quite right about Goodhart effect in giving it the metric. Never knew Spring code could be written so badly.
I've tried runs with better prompting also and I'm starting to find the key factor is actually the architecture itself.
From my initial findings, it's seeming that additive pipeline architectures hold up much better against AI slop than our typically single method web handler architectures.
appleappleapple 4 hours ago [-]
Nice idea. Our new CTO brought in a tool he made for analyzing cyclomatic complexity and it’s been useful since we’re a heavily AI-forward shop.
BTW, you can avoid your comments being flagged and killed by writing them yourself! I know it’s tempting to offshore it to AI (especially after you’ve vibe-coded a whole project) but some genuine human communication goes a long way.
crab_galaxy 3 hours ago [-]
I know cyclomatic complexity has been heavily debated for a long time, but I do think it’s valuable. It’s really good at highlighting common annoyances like overly clever code, nested ternaries, dense functions with too many branches…
The only thing is that these issues seem like human code problems and IME LLMs don’t really write code like this anymore. It’s almost the opposite in python, actually, where Claude leans on writing lots of 2-3 liner private utils which is a separate kind of complexity and organization problem.
I still find it useful specifically for React where it’s frustratingly normalized to write many branches in your JSX though.
sagenschneider 3 hours ago [-]
The difference to previous CC use, is the the change impact formula looks at the complexity already in the class/file. Typical CC just looks at the function it is change and not the context of the change. The Change Impact formula incorporates that to avoid god class and god method issues. Plus multiplying by number of files punishes for non-cohesive code bases. For me it puts the intuition of high cohesion and low coupling into a measurable metric.
crab_galaxy 56 minutes ago [-]
[dead]
j_bum 2 hours ago [-]
Is it public? Would love to try it!
ecshafer 2 hours ago [-]
Sonarqube has existed for like 20 years. There's doezens of cyclomatic complexity, linter, and cve scanner tools though.
Lerc 2 hours ago [-]
What score do we get for a group of fixes to single line bugs that are obvious once spotted?
There is an implication that all AI changes add complexity and reduce quality, but it is obvious that the quality and complexity is a property of the code not the writer, so all equivalent changes should be equal no matter what the shource.
How do clear improvements to make something simpler yet more functional score under this system?
sagenschneider 1 hours ago [-]
Yes, the formula does make some approximations.
The problem with cohesion is understanding what is "single purpose". Nothing can determine this without interpreting the code and making a judgement call on whether it needs to be refactored into two or more classes.
So I'm looking to approximate this. Instead of looking for cohesion, Change Impact formula approximates this by looking at existing complexity in the file.
If the change adds more complex functions to an already complex class, it scores high. Smell of it doing too many things.
If the change adds a complex function to an empty file, it's likely just a complex single problem.
If the change adds simple change to complex file, then if this happens too many times, we flag it for concern. Especially if it changes a lot of other files too.
So it's not mean to measure your code exactly. It's meant to highlight smell that needs investigation. And the formula points out the classes that need looking at.
Plus I'm not sure that all changes are equivalent. I'm not looking at single one off changes. I'm looking at 60 changes in a row. The first 20 might go through fine. However, after the changes pile on, there needs to be some refactoring to keep the code clean. This is trying to catch it before it becomes a mess.
eithed 60 minutes ago [-]
> If the change adds a complex function to an empty file, it's likely just a complex single problem.
How do you determine that this is correct = adding complexity to a single file vs adding less complexity to multiple files that this one file then orchestrates.
sagenschneider 50 minutes ago [-]
Yes, you are right that looking at one commit doesn't tell you much.
It's looking at the nature of on going changes.
A single complex file written once and never touched is likely a good cohesive file about a single problem solved.
However, if we start making many changes to that file increasing it's complexity, it's likely not the problem getting more complex. It's likely we're adding more purposes to the file, eroding it's cohesion. This is the signal I'm trying to catch to avoid a mess starting.
eithed 30 minutes ago [-]
Right, so really any fresh file is more or less fine (would still evaluate cyclomatic complexity). It's the quantity/frequency of changes that matters (or CRAP)
VladVladikoff 3 hours ago [-]
The overuse of “gate” in this post title makes me think the entire thing was vibe coded even the marketing.
appleappleapple 3 hours ago [-]
Personally I’m ok with vibe coded projects - certainly feels like the future of things, and I think the line between vibe coded and “professionally” coded is increasingly blurring - but I completely agree on the marketing/communications piece. Ideally your communication about a project conveys real expertise and ownership, signaling that you really understand the problem you’re trying to solve and the tradeoffs you made in your approach to do so. I am very hesitant to use a project where it feels like the eng couldn’t pass a pop quiz about how it works + why.
Uncanny how any coding model I use will employ the word "gate".
sagenschneider 3 hours ago [-]
Probably because I've had Quality Gates in my pipelines for so long :)
EliasWatson 2 hours ago [-]
What languages does this support? I'm guessing it's Python only, but it would be nice if that was mentioned somewhere.
sagenschneider 2 hours ago [-]
It uses lizard for parsing, so Python, Java, JavaScript, TypeScript, C, C#, Go, Scala, and more.
altcognito 2 hours ago [-]
Isn't this just static code analysis? We have tools for this.
sagenschneider 1 hours ago [-]
Most static code analysis looks for bugs or just too complex functions.
The novelty of Change Impact is it looks at the context of the complexity. Adding complexity to something already complex should be flagged for review.
I've not come across any static code analysis so far that has provided this.
And in my own research of architectures, I came to this formula.
Retr0id 2 hours ago [-]
What's the structural decay score of this HN title? Apparently not high enough to be gated.
WD-42 2 hours ago [-]
Kind of ironic that this thing purports to “gate” slop, yet the entire project is slop, including the README and even the authors comments here. I hate this timeline.
samayashar 2 hours ago [-]
Great way of detecting AI slop.
Claude is pretty good at adding focused changes and if a fix is already present, then it correctly points it out rather than adding unnecessary refactors.
sagenschneider 2 hours ago [-]
I'm not looking at building prototypes. Looking at ways to manage code bases after they've gone through hundreds if not thousands of changes.
philipwhiuk 3 hours ago [-]
Interesting idea even for non-AI code.
sagenschneider 3 hours ago [-]
Yes, I've run it against a bunch of open source projects with long histories (before AI) to see if it predicts bugs. Seems file size is still a better predictor. However, for the projects where good coding was strictly adhered to and others that were not, it showed the differences appropriately. So I've found it useful in general for Software erosion.
owebmaster 3 hours ago [-]
A sloppy project to find slop in projects. It sure works well
Compactly formatted user messages are something an agent can ingest in a few minutes, even if they are thousands of lines long. And the quality of those messages is great: they don't track what the agent does well, only what changes and what breaks.
Having this top-down view helps a lot. Usually, within a session and deep into a task, the agent loses the global perspective and optimizes for local success. I find it weird there is no harness that treats user messages as high value signal (except my own, of course, I have it, https://github.com/horiacristescu/playbook-harness).
However, I'd bring in Brooks discussion on essential and accidental complexity. In other words, there being No Silver Bullet https://www.cs.unc.edu/techreports/86-020.pdf
The problem with specification and user discussion is they still have errors that code has. But unlike code, there are no tests to confirm correctness.
So now we have a definition of the system in a non-exact language with no ability to test to confirm it's correctness. The code holds the essential complexity and now we are adding accidental complexity on top to manage.
Again agree the specifications and user discussion provides context for the AI. However, a well written test suite provides similar context that can actually confirm correctness of the system.
However, saying all the above. Focus of ImpactGate ( https://impactgate.officefloor.net ) is about erosion of the code, not correctness.
High cohesion means the functionality of a component are closely related and focused on performing a single well defined task. Basically single classes for single purposes.
Erosion of this is when classes start doing to many things, in the case of God classes.
The Change Impact formula looks at a way of detecting when the cohesion is eroding and flagging it on a change (as the pull/merge request itself should generally be single focus cohesive change)
Do you mean like the hyper focus an LLM puts on the task in front of it so you end up with drift (duplicated concepts/multiple ways of doing things, terminology drift (e.g., now we have "customer" and "client"). That sort of thing?
Yes, there are generally complex algorithms but they usually are not things developers write (imported from libraries).
What is usually going on in the god class/method is that things keep getting added to it. These things should be separated out. So the cohesiveness of the class/method erodes into doing too many things.
The idea of the Change Impact formula is to catch this early so you start refactoring to separate out into classes with single cohesive purposes.
The problem with AI is it handles complexity really well and will happily keep piling changes into god classes/methods reaching ridiculous CC levels (have see over 200). Previously developers would get annoyed and do the refactor. But with AI these days, changes are happening faster. So Change Impact is to try to monitor the cohesive erosion.
While a lot of metrics make intuitive sense, we don’t have that much hard evidence to prove or disprove their value. Part of it is the whole “if a metric becomes a target, it ceases to be a good metric” thing. Adding the checks to a large existing project probably has negative value. But I think it’s worth doing for greenfield projects.
For humans, these should just be advisory. But for LLMs I’m happy enough to make it a blocking check.
I keep thinking of doing an experiment where I give the same LLM the same problem, and only change which metric is enforced. And then see if any of them have a noticeable effect on correctness/maintainability.
> any examples of how people get this into an actual report / CI test / benchmark / whatever ?
Yeah they have examples of adding it to CI, or local checks, generate html reports, etc in their docs.
I've been in the process of reviewing and validating a lot of tools like this (qlty, Sonarqube, fallow, etc) and the false positive rate is anywhere from 20% to 80% for a lot of our sniff tests (zizmor produces an overwhelming majority of false positives here for what feels like arbitrary and very context-dependent GHA requirements)
the last thing I want to do is to annoy the hell out of our devs by requiring checks like these to pass especially since it's only a small percentage of them who vibe code everything and then also vibe response to code reviews. I feel like that's the anti-pattern that we'd push people towards by requiring checks like these to pass
another avenue of exploration has been requiring test coverage but also good test quality metrics (eg are there negative tests? mutation testing? empty asserts?) something that seems quite easy to spin up into a skill and pair with a deterministic harness. trash-tests is a neat little project that incorporates some of this: https://github.com/frangelbarrera/trash-tests (disclosure: I am not the repo owner or even a contributor, just a quality nerd who loves underdogs lol)
all in all, it really does feel like we'll need a revamp of the SDLC with our current expected velocities
Though to the bigger point of your comment, yes SDLC are becoming faster. We can churn out code at a ridiculous rate. However, doesn't mean it's good code. And hence, there are studies showing things actually slowing down because reviews pile up.
I guess I look at the Change Impact formula (and https://impactgate.officefloor.net implementation of it) as threshold tool. Small changes that aren't contributing to god classes, just let through. When things start to smell, the files involved get marked for review.
Ideally this then can cut down on review time and allow overall increased velocity.
But yes relies on trusting the AI to do "simple" things
I was testing the additive pipeline style of OfficeFloor against the mutative handler style of Spring. I was looking to see what factors could be used to allow AI to make long on going changes (experiment is 60 changes to an end point, where all add functionality and every 4th change is mutative on existing rules). Then I watch how AI manages to make the 60 changes in each architecture.
I've done many runs and you are quite right about Goodhart effect in giving it the metric. Never knew Spring code could be written so badly.
I've tried runs with better prompting also and I'm starting to find the key factor is actually the architecture itself.
From my initial findings, it's seeming that additive pipeline architectures hold up much better against AI slop than our typically single method web handler architectures.
BTW, you can avoid your comments being flagged and killed by writing them yourself! I know it’s tempting to offshore it to AI (especially after you’ve vibe-coded a whole project) but some genuine human communication goes a long way.
The only thing is that these issues seem like human code problems and IME LLMs don’t really write code like this anymore. It’s almost the opposite in python, actually, where Claude leans on writing lots of 2-3 liner private utils which is a separate kind of complexity and organization problem.
I still find it useful specifically for React where it’s frustratingly normalized to write many branches in your JSX though.
There is an implication that all AI changes add complexity and reduce quality, but it is obvious that the quality and complexity is a property of the code not the writer, so all equivalent changes should be equal no matter what the shource.
How do clear improvements to make something simpler yet more functional score under this system?
The problem with cohesion is understanding what is "single purpose". Nothing can determine this without interpreting the code and making a judgement call on whether it needs to be refactored into two or more classes.
So I'm looking to approximate this. Instead of looking for cohesion, Change Impact formula approximates this by looking at existing complexity in the file.
If the change adds more complex functions to an already complex class, it scores high. Smell of it doing too many things.
If the change adds a complex function to an empty file, it's likely just a complex single problem.
If the change adds simple change to complex file, then if this happens too many times, we flag it for concern. Especially if it changes a lot of other files too.
So it's not mean to measure your code exactly. It's meant to highlight smell that needs investigation. And the formula points out the classes that need looking at.
Plus I'm not sure that all changes are equivalent. I'm not looking at single one off changes. I'm looking at 60 changes in a row. The first 20 might go through fine. However, after the changes pile on, there needs to be some refactoring to keep the code clean. This is trying to catch it before it becomes a mess.
How do you determine that this is correct = adding complexity to a single file vs adding less complexity to multiple files that this one file then orchestrates.
It's looking at the nature of on going changes.
A single complex file written once and never touched is likely a good cohesive file about a single problem solved.
However, if we start making many changes to that file increasing it's complexity, it's likely not the problem getting more complex. It's likely we're adding more purposes to the file, eroding it's cohesion. This is the signal I'm trying to catch to avoid a mess starting.
The novelty of Change Impact is it looks at the context of the complexity. Adding complexity to something already complex should be flagged for review.
I've not come across any static code analysis so far that has provided this.
And in my own research of architectures, I came to this formula.
Claude is pretty good at adding focused changes and if a fix is already present, then it correctly points it out rather than adding unnecessary refactors.