The Illusion of Velocity: AI, Premature Instrumentation, and the Death of Design?

A software engineer riding a rocked powered car while coding.

In the contemporary software landscape, a dangerous inversion of the engineering process is taking root. We are watching the “how” (implementation details, libraries, syntax) precede (and often obliterate) the “what” and the “why”.

Let’s call this Premature Instrumentation: the impulse to construct a solution before we’ve done even minimal formal interrogation of the problem space (let alone research). Note: I’m not using “instrumentation” here in the observability sense (metrics/traces/logs). I mean building the machine before you’ve decided what the machine is for.

This tendency isn’t new. But generative AI has become a potent accelerant. By reducing the friction of code generation to near-zero, AI tools have validated a culture of vibing: iterating on implementation until it feels correct, rather than engineering a system that is correct.

The mechanism of Premature Instrumentation

Classically, software engineering requires separation between the problem domain and the solution domain. You define boundaries, constraints, requirements, risks, and success criteria (the problem) before you select patterns, technologies, or architectures (the solution).

Premature instrumentation collapses this distinction. Developers (often under pressure to demonstrate “progress”, or compensating for uncertainty in the domain) jump immediately to the IDE. They solve for the constraints they know (the tools) rather than the constraints that exist (the business reality).

This manifests as Stack-First Thinking and Resume-Driven Development, where the chosen technology dictates the architecture, rather than the architecture dictating the technology. That’s how teams end up with “foundations” that look impressive in a demo and metastasize into a nightmare: hard to explain, harder to maintain, and effectively a black box when it breaks.

The AI accelerant: vibing vs. engineering

Generative AI has altered the economics of trial-and-error. Previously, writing the wrong code carried a time penalty that was directly translated into budget. Today, you can generate a plausible prototype in seconds. The speed creates an illusion of competence and progress, and it makes code feel disposable.

Here’s the catch: LLMs optimize for plausibility, not necessity. They are excellent at producing code that looks right and often runs, but they do not guarantee correctness, completeness, security, or alignment with your system’s constraints.

So “vibing” becomes a workflow: prompt -> run ->prompt -> run, until you get the desired output. The code vibes (it works in the moment), but unless you deliberately demand structure and verify it, the result lacks intentionality.

The byproduct is a codebase that works more by accident than by design (where maintainability, security, edge cases, and long-term evolution were never first-class requirements). You don’t get engineering for free. You just get more output per unit time, and output is not the same thing as progress.

Reality check: the evidence doesn’t support a simple story

Don’t get me wrong, I’m an AI enthusiast and I know from experience that it can absolutely speed developers up in some contexts. But the “AI always increases productivity” narrative is already cracking under real-world measurement.

  • In a METR study widely reported in July 2025, experienced developers using an AI coding assistant (Cursor) were slower on familiar open-source codebases (despite believing they’d be faster). (Reuters)
  • Other controlled studies have shown substantial speedups on more bounded tasks and settings (e.g., GitHub Copilot experiments, and an enterprise RCT with Google engineers). (arXiv)

The point isn’t “AI is bad”. The point is: AI amplifies your process. If your process is sloppy, it helps you generate sloppiness faster. If your process is disciplined, it can accelerate disciplined execution.

The leadership vacuum

This deterioration of rigor is rarely only a developer failure. It is usually a leadership failure, one of two common patterns:

  1. The “Innovation” fallacy
    Managers confuse lack of structure with creative freedom. By refusing to enforce design gates (or even lightweight design notes), they believe they are “empowering” the team. In practice, they are abdicating their responsibility to provide constraints. Innovation requires constraints; without them, you get entropy.
  2. The relay race of ambiguity
    Requirements are passed down as “loose objectives”. Instead of refining them into testable specifications and trade-offs, middle management forwards them straight to developers. Developers then guess at requirements, and they anchor on what they can control: the code. AI makes that coping strategy faster, and more destructive.

I’ve already seen signs in the industry moving towards a “requirement formalization” process (making requirement engineering valuable again), but only on big enterprises that can “afford” the time or have more “mature” processes and templates (e.g. project document repositories) from where to start.

Recommendations for course correction

To combat the entropy of premature instrumentation, teams must reintroduce friction: not bureaucratic friction, but cognitive friction.

For engineering managers

  • Enforce a lightweight RFC process for significant work.
    No major feature should start as code. It should start as a one-to-two page design note: problem statement, constraints, proposed approach, risks, and rejected alternatives. (“We considered X and rejected it because…”) The goal is clarity, not ceremony. (Wikipedia)
  • Decouple research from delivery.
    Create explicit tickets for time-boxed investigation (“spikes”). The deliverables are documents, not pull requests. Treat thinking as billable work. These frequently mature into ADRs (Architectural Decision Records), which preserve rationale and prevent institutional amnesia. (Cognitect.com)
  • Define “ready” and “done” with teeth.
    Acceptance criteria must be precise and testable. If you cannot define the requirement, you cannot reasonably expect anyone (human or model) to build the solution. If the code base is not properly documented (e.g. comments) or has not been reviewed by a human, it will be contributing to make the black box larger.
  • Measure outcomes, not motion.
    “Lines of code shipped” and “tickets closed” are vanity metrics in the AI era. If you want velocity, measure: defect rates, incident rates, lead time to restore, change failure rate, and long-term maintainability indicators.

For developers

  • Write before you code (or prompt).
    Start with prose or pseudocode: invariants, failure modes, data contracts, and test cases. If you can’t explain the logic without code-syntax, you don’t understand the problem.
  • Treat AI like a junior developer with infinite confidence.
    Verify every non-trivial line. Assume the assistant is optimizing the wrong metric. You are the architect; the model is the bricklayer.
  • Use guardrails, not vibes, for safety.
    Avoid “permissive” agent settings that can modify large swaths of a repo or execute destructive commands. Use least-privilege, run in a sandbox, and require human review for filesystem operations, dependency changes, auth flows, and anything touching data. Versioning helps you recover (sometimes) but recovery is not the same as prevention.
  • Embrace the “why”.
    When given a loose requirement, don’t start coding. Start asking questions. Push back until ambiguity is reduced. Your job is to solve business problems, not just push code to close tickets.

Conclusion

The ease of generating code is not a substitute for the difficulty of designing systems. As our tools get faster, our thinking must get slower and more deliberate. Speed is irrelevant if you’re moving in the wrong direction, especially when the bill comes due as overtime, outages, and a codebase that nobody truly understands.