We have established that code has become cheap raw material and that trusting AI blindly degrades system architecture through greedy local shortcuts.

This brings us to the question keeping thousands of software engineers awake at night:

“If AI writes code faster than I can, discovers libraries instantly, and completes routine tasks effortlessly—what is my actual value as an engineer?”

The answer is clear, even if uncomfortable for many: your value is no longer measured by your keystrokes per minute or your encyclopedic recall of standard library APIs.

Your job is to guarantee the conceptual integrity of the system. You are the safeguard preventing autonomous agents from turning a production codebase into a rotting junkyard of one-off scripts.

Here is the engineering framework developed from hundreds of hours managing autonomous coding agents in production environments.


The «Skeleton + Pluggable Modules» Architectural Pattern

The costliest mistake teams make is granting an AI agent unbounded freedom over an entire repository with a prompt like: “Build our new billing subsystem.”

Thirty minutes later, you receive a sprawling 20-file PR where domain logic is coupled with HTTP controllers, SQL queries are embedded in route handlers, and errors are swallowed by empty catch blocks.

To keep AI productive and safe, a system must be divided into an unyielding skeleton and disposable modules:

                       ┌────────────────────────────────────────┐
                       │           HUMAN ARCHITECT              │
                       │    Invariants, Data Schemas, Contracts │
                       └───────────────────┬────────────────────┘
                                           │ designs

                       ┌────────────────────────────────────────┐
                       │          SYSTEM SKELETON               │
                       │  Auth Context │ Event Bus │ DB Schemas │
                       └─────┬────────────────────────────┬─────┘
                             │                            │
               isolated      │                            │ isolated
               contract      ▼                            ▼ contract
       ┌───────────────────────────┐        ┌───────────────────────────┐
       │     PLUGGABLE MODULE A    │        │     PLUGGABLE MODULE B    │
       │     (Generated by AI)     │        │     (Generated by AI)     │
       │  Fast to build /          │        │  If degraded —            │
       │  Trivial to replace       │        │  regenerate from scratch  │
       └───────────────────────────┘        └───────────────────────────┘
  1. The Human Engineer Designs the Skeleton:

    • Centralized schema validation boundaries (e.g., Zod or Pydantic contracts).
    • Transactional scopes and tenant context propagation.
    • Event bus definitions and strict cross-boundary message protocols.
    • Standardized error handling, tracing, and audit logging.
  2. The AI Agent Fills the Pluggable Modules:

    • Each module is strictly confined within its contract boundaries. It cannot bypass interfaces or query neighboring database tables directly.
    • All module logic remains local.

Why is this pattern transformational?
If requirements change radically six months later or a module accumulates structural noise, you don’t spend weeks refactoring legacy code. You delete the module directory and instruct an agent to regenerate it from scratch against the unchanged contract. It takes 15 minutes.


The Death of Pull Requests and the Rise of DESIGN.md

Auditing a 3,000-line pull request generated by an AI is an exercise in cognitive exhaustion. Reviewers inevitably skim, rubber-stamping an empty “LGTM” and hoping automated tests will catch critical bugs.

In his essay, Salvatore Sanfilippo proposed a far more durable mechanism: the DESIGN.md artifact.

Before an agent writes a single line of implementation, you collaborate with the model to draft an architectural specification. This is not a bureaucratic 50-page specification; it is a concise 1–2 page markdown contract that captures:

  1. System Invariants (What can NEVER happen under any circumstances):
    Example: “A user balance cannot become negative under any concurrent retry; credit deduction and subscription activation must execute in the exact same atomic transaction.”
  2. Data Structures and State Lifecycles:
    Finite state machines: Draft → Pending → Paid → Fulfilled. No state transitions outside the defined state engine.
  3. Failure Modes & Resilience:
    What happens when an external payment gateway takes longer than 2,000ms? How are duplicate webhooks handled? (Idempotency keys).
  4. Acceptance Invariants:
    The exact boundary tests and chaos scenarios the implementation must pass to prove the invariants hold.

Once the DESIGN.md is approved by the human engineer, coding becomes a deterministic exercise. In reviews, you audit the implementation against the declared invariants—not syntax trivia.

Open-Source Tool:
Rather than re-inventing this architecture and specification structure from scratch on every project, I published a ready-to-use starter template: AVP-Dev / agent-starter-kit on GitHub. It includes foundational architectural rails, DESIGN.md specification blueprints, coding agent rules, and modular isolation patterns you can fork directly into your workflow.


The Delegation Matrix: What to Give to AI vs. What to Keep

To avoid both paranoid micromanagement and reckless “vibe coding,” I apply a strict tripartite division of responsibility:

Delegation TierAssigned ToEngineering Scope
1. Autonomous Delegation (100% AI)AI AgentsPure functions without side effects, DTO transformers, edge-case unit test generation, UI layout based on design tokens, parsers, and data migration scripts.
2. Contract Delegation (50 / 50)Human Architect designs → AI implementsCRUD API routes, external third-party integrations, background queue consumers, report aggregations. The engineer verifies only contracts and failure states.
3. Zero Delegation (Human Only)Human ArchitectData ownership topology, distributed transactions, authorization and permission models (RBAC/ABAC), consensus protocols, disaster recovery, and data security models.

If you delegate tier three to unguided generation, you are no longer the engineer of your platform. You are merely a passenger in a vehicle without brakes.


Key Takeaway: The Real Role of the Engineer

The software industry is undergoing a necessary and overdue maturation.

For four decades, we romanticized typing code. We engaged in flame wars over tabs versus spaces, memorized compiler flags, and celebrated spending late nights hunting down a missing semicolon.

That era has drawn to a close.

AI can be an extraordinary, lightning-fast programmer. But it will never be the owner of the outcome.

  • AI does not bear responsibility to the business when database connections saturate during Black Friday.
  • AI does not join midnight war rooms when user data leaks across multi-tenant boundaries.
  • AI does not hold the vision for where the platform needs to stand two years from now.

The human engineer owns the system.

And as code generation becomes instantaneous and free, the true value of an engineer is elevated: the ability to step above the syntax, preserve the architecture, and say with authority:
“We are deleting this code. We will design the system differently.”


Articles in this series:

  1. Code Became Cheap. Engineering Thinking Did Not
  2. AI Loves Straight Roads: Why Local Optimization Breaks Complex Systems
  3. The Architect of the Future: From Line Reviews to Design Reviews (this article)