Engineering with AI · Engineering Process

Reading time · 7 min

Humans Steer, Agents Execute: Our Engineering Loop With AI

How StackLiberate uses AI coding agents as active engineering collaborators while keeping human ownership over architecture, scope, product intent, review, and final acceptance.

A Roman command structure showing human direction flowing into specialized agents that investigate, implement, test, and review software before returning results for acceptance.

There are two easy stories to tell about AI and software development.

In the first, AI is autocomplete with better marketing. Engineers still do essentially everything, while the model occasionally saves a few keystrokes.

In the second, a person describes a product, an autonomous agent builds it, the tests turn green, and software engineering mostly disappears.

Neither describes how we build StackLiberate.

AI participates deeply in the work.

Agents inspect the repository, trace behavior across layers, propose implementation plans, write production code, refactor systems, add tests, run browsers, investigate failures, challenge previous implementations, and review work produced by other agents.

Sometimes an agent does almost all of the mechanical implementation of a feature.

But that does not mean the engineering responsibility moved with the typing.

Our working principle is:

Humans steer. Agents execute. Responsibility stays attached to the system, not to whoever—or whatever—typed the code.

That distinction has become more important as the agents have become more capable.

The interesting question is no longer who typed the code

Counting human-written versus AI-written lines is becoming a poor way to describe modern software development.

An engineer can manually type ten thousand lines implementing a weak architecture.

An agent can generate a strong implementation from a carefully designed contract.

The reverse can also happen.

The important questions are higher level:

  • Who decided what the system should do?
  • Who chose the boundaries?
  • What is authoritative?
  • What risks are acceptable?
  • What behavior must remain invariant?
  • How is the implementation validated?
  • Who decides that the result is ready?

Those decisions determine much more about a system than whether the final syntax came from fingers or a model.

That is also where the professional conversation around coding agents is moving.

As agents become capable of completing longer tasks independently, engineers increasingly spend less time producing every implementation detail and more time specifying intent, designing environments, defining constraints, reviewing results, and deciding where human judgment matters.

We recognize that transition because it resembles our own experience.

Steering is not writing a giant prompt

“Human steering” can sound like someone sitting beside an agent and dictating every function.

That would waste much of the benefit.

We do not want to tell an capable coding agent:

Open this file.
Add this function.
Create this variable.
Now modify line 42.

At that point we are using an expensive keyboard.

The useful level of steering is different.

For substantial StackLiberate work, we care about establishing things like:

Product intent
      ↓
System boundaries
      ↓
Source of truth
      ↓
Required invariants
      ↓
Allowed scope
      ↓
Acceptance conditions

Within those boundaries, the agent can explore.

It can discover that the file we initially expected to change is not actually the correct ownership boundary.

It can propose a better implementation.

It can find an existing abstraction we forgot about.

It can tell us that the requested design conflicts with an existing invariant.

Steering defines the destination and the rules of the road.

It does not require manually choosing every turn.

Product intent remains human

Agents are excellent at turning explicit objectives into concrete work.

They are much less suited to deciding what the product should become.

A request like:

Let users move sections.

contains far more product policy than it initially appears to.

Can every section move?

Can the header move?

What happens to navigation?

Should the operation survive reload?

Does it participate in history?

Can it be exported?

What happens on mobile?

Do templates need to declare support?

What happens if an old project does not have the required identity?

An agent can help discover and analyze these questions.

But choosing the product behavior requires judgment about the system we are trying to create.

For StackLiberate, that ownership remains human.

We may ask an agent to challenge the decision.

We may change our minds because its analysis is better.

But the model is not implicitly authorized to turn an implementation convenience into product policy.

Architecture is a decision boundary

The same distinction applies to architecture.

Agents can reason extremely well about architecture when given the right repository context. They can trace writers and readers, inspect contracts, identify coupling, and propose surprisingly strong designs.

We use that capability extensively.

But an architecture proposal and an architectural decision are different things.

Suppose an agent finds two viable approaches.

One introduces a new abstraction that will make future features easier.

The other reuses the existing system and has a smaller blast radius.

Neither is inherently correct.

The choice depends on things the repository alone may not know:

  • What is actually on the roadmap?
  • Is this capability expected to expand?
  • Are we intentionally postponing a larger abstraction?
  • Is compatibility more important than elegance here?
  • Does the additional machinery earn its complexity?

Those are engineering decisions influenced by product strategy.

So our workflow allows agents to propose architecture without silently granting them ownership of architectural direction.

That is one reason we use Plan First for meaningful changes.

The architecture is easier to evaluate before hundreds of lines exist to defend it.

Execution is where agents become extraordinary

Once direction is established, the balance changes.

This is where agents can move very fast.

A bounded implementation task might require them to:

  • Inspect the relevant code paths.
  • Modify several layers.
  • Update types.
  • Extend validation.
  • Add tests.
  • Run existing suites.
  • Investigate failures.
  • Adjust the implementation.
  • Produce a final diff summary.

Doing this mechanically is no longer the scarce resource it once was.

The agent can remain focused on the implementation for far longer than a human would want to spend manually editing each file.

That creates leverage.

Instead of consuming human attention on every syntactic transformation, we can spend more of it deciding whether the resulting system is coherent.

This does not make implementation unimportant.

It makes implementation cheaper relative to judgment.

We do not assume execution is infallible

Delegation is useful only if the output can be trusted appropriately.

That does not mean trusting it blindly.

A coding agent can make an implementation that is:

  • Locally correct.
  • Well typed.
  • Thoroughly tested.
  • Visually convincing.

and still violate the intended architecture.

It can duplicate responsibility.

It can introduce a shortcut.

It can misunderstand an old compatibility constraint.

It can solve the current UI while forgetting another lifecycle path.

It can confidently clean up code that looked accidental but was protecting an important invariant.

This is why our loop does not end at:

Agent says done.

“Done” is a claim.

Acceptance is a separate stage.

Different stages deserve different kinds of intelligence

We do not think of AI as one agent doing one continuous job from idea to production.

Different stages benefit from different perspectives.

A discovery pass should be curious and broad.

A planner should question system boundaries.

An implementation agent should remain disciplined about scope.

A reviewer should be suspicious of the implementation rather than emotionally attached to it.

A validation pass should care about observable evidence.

Conceptually:

Human intent
      ↓
Agent discovery
      ↓
Agent plan
      ↓
Human architectural review
      ↓
Agent implementation
      ↓
Automated validation
      ↓
Independent engineering review
      ↓
Human acceptance

The same model can sometimes perform several of those roles.

Sometimes different agents or models are more useful.

The important part is the separation of responsibilities.

An implementation should not become correct merely because the agent that produced it says it is correct.

We want another perspective.

Agents are allowed to disagree

Human ownership does not mean human ideas are automatically right.

This is an important part of the relationship.

If we ask an agent to investigate a system and our proposed feature would violate an existing contract, we want it to say so.

If our preferred implementation requires unnecessary infrastructure, we want the plan to call that out.

If the requested blast radius is larger than we thought, we want evidence.

If the repository contradicts our mental model, the repository wins until we understand why.

That makes the relationship more useful than command-and-control automation.

The human provides direction.

The agent provides both execution and technical resistance.

A good agent should sometimes make the steering decision harder.

That usually means it discovered something worth considering.

Scope is a form of engineering control

One of the easiest things for a capable agent to do is solve more than we asked for.

It sees nearby cleanup.

An abstraction could be generalized.

A dependency could be modernized.

A test utility could be refactored.

A neighboring feature could use the same improvement.

Each idea may be reasonable.

Together they can turn a bounded change into an architectural migration nobody intended to start.

So scope remains an explicit human boundary.

We frequently care as much about what a task must not change as what it should change.

That gives agents freedom inside a known area without allowing every feature to become an excuse to redesign the repository.

The fastest agent is not particularly useful if every task expands the system unpredictably.

Acceptance belongs to humans

Tests can pass.

Review agents can approve.

Static checks can remain green.

The feature can look correct in the browser.

Those are all important pieces of evidence.

Someone still needs to decide whether the result is acceptable.

Acceptance asks a broader set of questions:

  • Does this actually solve the product problem?
  • Is the complexity justified?
  • Are the compromises acceptable?
  • Did we preserve the architecture we intended?
  • Does the interaction feel right?
  • Are we comfortable maintaining this?
  • Is this the feature we actually wanted?

Those questions combine technical evidence with product judgment.

AI can contribute to every one of them.

It cannot own the consequence of the answer.

That is the line we care about.

Human oversight should happen where it has leverage

There is also a bad version of human oversight.

If every agent action requires approval, the agent becomes slow and the human becomes an interrupt handler.

We are not trying to keep people constantly inside the loop.

We want them at the important points in the loop.

For us, those points tend to be:

Before implementation, when product scope and architecture are still cheap to change.

When assumptions break, because the approved plan may no longer describe reality.

During review, especially around state ownership, security, failure semantics, and architectural boundaries.

At acceptance, when we decide whether the resulting behavior belongs in the product.

Between those points, agents can execute substantial amounts of work independently.

That is a much more scalable relationship than either extreme:

Human writes everything

or:

Agent decides everything

Expertise does not disappear when agents improve

There is an appealing theory that sufficiently capable coding agents eventually make engineering expertise less relevant.

Our experience points in the opposite direction.

Better agents increase what good judgment can accomplish.

An engineer who understands the system can give a capable agent a much higher-level instruction because they know which details matter and which do not.

They can recognize when an agent's “simplification” actually damages an invariant.

They know which test failure is incidental and which reveals a broken design.

They can distinguish an abstraction that will pay for itself from one that merely looks elegant.

The emerging research on coding agents is finding something similar: people with greater domain expertise are often able to delegate more effectively, not less.

Expertise becomes leverage.

Instead of manually implementing every decision, the engineer can make consequential decisions and allow agents to amplify them.

This is not vibe coding

The distinction matters because all AI-assisted development can look similar from the outside.

Someone types natural language.

A model writes code.

But there is an enormous difference between:

Prompt
  ↓
Generated code
  ↓
Looks good
  ↓
Ship

and:

Intent
  ↓
Discovery
  ↓
Architecture
  ↓
Plan
  ↓
Implementation
  ↓
Tests
  ↓
Invariant review
  ↓
Product acceptance

Both use AI.

Only one makes the generated artifact subordinate to an engineering process.

We are comfortable saying that AI writes a substantial amount of StackLiberate.

There is nothing particularly prestigious about manually typing syntax that a capable agent can produce correctly.

What matters to us is that the resulting system remains deliberate.

The standard is not:

A human wrote this.

The standard is:

We understand why this exists, where it belongs, what it is allowed to do, and what evidence makes us willing to ship it.

The loop keeps changing

Our workflow today will not be our workflow forever.

Agents are getting better at planning.

They are getting better at long-horizon execution.

They are improving at repository-wide review, tool use, visual validation, and coordination with other agents.

That means some decisions that currently require explicit human intervention may eventually become routine enough to delegate.

Other decisions may become more important precisely because implementation capacity keeps increasing.

We do not think the right response is to freeze a permanent boundary between “human work” and “AI work.”

The better principle is:

Put human judgment where mistakes are expensive and intent matters. Put agent execution where speed, breadth, and iteration create leverage.

That boundary can move as the technology improves.

Responsibility does not.

We are building software, not generating it

The final product is not the transcript of the prompts that created it.

It is a system with architecture, state, history, constraints, users, and consequences.

AI gives us an extraordinary amount of implementation capacity.

We use it.

Aggressively.

But we do not confuse implementation capacity with ownership.

The agents investigate.

They propose.

They implement.

They test.

They review.

They sometimes prove us wrong.

Humans decide what StackLiberate is supposed to become, which architectural commitments we are willing to make, when a solution has expanded beyond its mandate, and whether the final result meets the standard we want to ship.

That is our engineering loop with AI.

Humans steer. Agents execute. The system remains our responsibility.