The reaction was overwhelmingly skeptical. The core complaint was familiar to anyone who lived through
Spring-era AOP. It makes the easy case look elegant, then turns the hard case into a swamp because behavior stops being visible where the code runs. Transactions, logging, and other cross-cutting concerns are manageable when they stay simple. Real systems do not stay simple. Once you need batching, partial rollback, ordering guarantees, or interactions between multiple concerns, the separation stops feeling clean and starts feeling like ghost code. Several people said the local reasoning loss is the real cost. You read a method and still do not know what it does without hunting through aspect definitions, proxies, or framework rules.
That made the LLM angle land even worse. People were not objecting to code generation in general. They were objecting to putting a nondeterministic system in charge of hidden program behavior. A compiler can transform code aggressively because it is deterministic and expected to preserve meaning. An LLM cannot offer that guarantee. So the proposal reads less like safer AOP and more like invisible monkey patching with weaker tooling. A few commenters did carve out narrower cases where AOP has always been useful, especially logging, middleware-style interception, and framework-provided transaction handling. Others noted that compile-time variants such as
Micronaut’s AOP are less painful than runtime matching, and that many “AOP” ideas survived by being absorbed into more explicit language features like interceptors, context managers, getters and setters, or effect tracking.
The most useful reframing was that the post is really about spec organization, not a comeback for
AspectJ-style magic. Organizing requirements by concern may help agent workflows. Tooling that can hide or highlight one concern at a time could also help humans and models. But commenters drew a bright line between better views over code and systems that silently rewrite semantics. The consensus landed on a practical rule. If a cross-cutting concern is truly stable, mechanically defined, and easy to inspect, specialized compile-time tooling or language support can work. If it depends on hidden joins, ambient state, or an LLM guessing where to weave behavior, you are rebuilding one of the least loved parts of old enterprise software.