DEV Community

Cover image for What Is an AI Harness? A Practical Guide with a Laravel CMS Example
Yasser Elgammal
Yasser Elgammal

Posted on

What Is an AI Harness? A Practical Guide with a Laravel CMS Example

An AI harness is a structured set of files, rules, skills, workflows, and project context that surrounds an AI coding agent.

Instead of repeating the same instructions in every prompt, the harness gives the agent a consistent way of working across tasks and sessions.

And that's the key idea:

Prompting tells the agent what to do. A harness tells it how to work.


The Problem

If you've spent any time pairing with an AI coding agent, you've probably seen the same problems:

  • It forgets your project conventions.
  • It touches files it shouldn't.
  • It skips important validation.
  • It considers a task "done" too early.
  • You have to explain the same architecture repeatedly.
  • Every new session feels like starting from zero.

So you keep writing prompts like:

"Remember to use Policies for authorization."

"Run the tests before you're done."

"Don't modify unrelated files."

"Follow our existing service architecture."

These instructions are valuable.

But they shouldn't have to live in your prompt every time.

They should live in the environment around the agent.

That's where an AI harness comes in.


What Is an AI Harness?

An AI harness is the structured layer around an AI coding agent that defines:

  • Rules — what must always be true.
  • Skills — how specific engineering tasks should be handled.
  • Workflows — the order in which work should happen.
  • Context — facts about the current project.
  • Agents — roles and authority, when multiple specialized roles are useful.
  • Adapters — how different coding tools connect to the same harness.

The model provides the reasoning.

The harness provides the discipline.

Think about a simple task:

"Add an endpoint for publishing posts."

Without a harness, the process might look like:

Understand request
↓
Explore project
↓
Guess conventions
↓
Implement
↓
Run some tests
↓
"Done"
Enter fullscreen mode Exit fullscreen mode

With a harness:

Identify task
↓
Load relevant rules
↓
Load project context
↓
Select required skills
↓
Follow workflow
↓
Implement smallest change
↓
Validate
↓
Test
↓
Review
↓
Verify requirement
↓
Done
Enter fullscreen mode Exit fullscreen mode

The difference isn't necessarily a smarter model.

It's a more reliable operating environment.


Prompt vs. Harness

A prompt is ideal for task-specific intent.

A harness is ideal for persistent engineering knowledge.

Plain Prompt AI Harness
Instructions rewritten when needed Instructions persist in the project
Consistency depends on the prompt Same rules across sessions
Project knowledge gets repeated Project knowledge is stored
Rules and context are often mixed Responsibilities are separated
Human decides when it's "done" Definition of Done can be explicit
Safety depends heavily on instructions Approval gates can be defined
Harder to reuse Structure can be reused across projects

For example, instead of writing this every time:

"Use Form Requests for validation, Policies for authorization, feature tests for endpoints, don't touch unrelated files, and run php artisan test."

You can store those decisions once.

Then your actual prompt can remain simple:

"Add an instant-publish button to the post editor."

The harness supplies the engineering context.


The Architecture of an AI Harness

A practical harness can look like this:

ai-harness/
├── AGENTS.md        # Entry point / index
├── agents/          # WHO acts
├── skills/          # HOW to handle a concern
├── rules/           # WHAT must always be true
├── workflows/       # IN WHAT ORDER to work
├── context/         # WHAT is true about this project
└── adapters/        # Tool-specific integration
Enter fullscreen mode Exit fullscreen mode

These components have different responsibilities.

Agents — WHO

Defines roles and authority.

agents/
├── developer.md
├── reviewer.md
└── debugger.md
Enter fullscreen mode Exit fullscreen mode

For example, a Developer may implement changes while a Reviewer focuses on inspecting them.

Not every project needs multiple agents. Start with one if that's enough.


Skills — HOW

Reusable engineering knowledge.

skills/
├── testing-strategy.md
├── api-design.md
├── database-design.md
└── code-review.md
Enter fullscreen mode Exit fullscreen mode

A testing skill can explain how the project approaches tests, factories, edge cases, and assertions.


Rules — WHAT MUST ALWAYS BE TRUE

Rules are constraints.

rules/
├── core-rules.md
├── approval-gates.md
└── definition-of-done.md
Enter fullscreen mode Exit fullscreen mode

Examples:

Do not modify unrelated files.

Do not bypass authorization.

Do not introduce unnecessary dependencies.

Do not declare a task complete without validation.

Destructive operations require human approval.
Enter fullscreen mode Exit fullscreen mode

Workflows — IN WHAT ORDER

A workflow defines the sequence for a type of task.

For example:

workflows/
├── feature-development.md
├── bug-fix.md
└── release.md
Enter fullscreen mode Exit fullscreen mode

A feature workflow could be:

Understand
↓
Inspect
↓
Plan
↓
Implement
↓
Test
↓
Review
↓
Verify
Enter fullscreen mode Exit fullscreen mode

Context — WHAT IS TRUE ABOUT THIS PROJECT

Context contains project-specific facts.

context/
├── project.md
├── architecture.md
├── domain.md
└── conventions.md
Enter fullscreen mode Exit fullscreen mode

For example:

project.md
→ Laravel 11
→ PHP 8.3
→ MySQL
→ Redis

architecture.md
→ Form Requests
→ Policies
→ Services
→ Feature Tests
Enter fullscreen mode Exit fullscreen mode

This is the part that changes most from project to project.


Rule vs. Skill vs. Workflow vs. Context

One instruction can actually contain four different concepts.

Take:

"Always run tests before finishing."

It can become:

  • Rule: A change must be validated before completion.
  • Skill: How to write and run appropriate tests.
  • Workflow: Validation happens before the task is considered complete.
  • Context: The project's actual test command is php artisan test.

This separation is important.

It prevents one giant instruction file from becoming the place where everything lives.


A Laravel CMS Example

Imagine a Laravel CMS with:

  • Posts
  • Categories
  • Users
  • Roles
  • Publishing workflows

The repository could look like:

laravel-cms/
├── AGENTS.md
├── ai-harness/
│   ├── AGENTS.md
│   ├── agents/
│   ├── skills/
│   ├── rules/
│   │   ├── core-rules.md
│   │   ├── approval-gates.md
│   │   └── definition-of-done.md
│   ├── workflows/
│   ├── context/
│   │   ├── project.md
│   │   ├── architecture.md
│   │   ├── domain.md
│   │   └── conventions.md
│   └── adapters/
├── app/
├── database/
├── tests/
└── ...
Enter fullscreen mode Exit fullscreen mode

Now imagine the task is:

"Add an instant-publish button for a post from the admin panel."

The harness can guide the agent through:

Task arrives
↓
Identify task type
↓
Feature Development workflow
↓
Load core Rules
↓
Load relevant Context
↓
Select required Skills
↓
Check Approval Gates
↓
Implement smallest possible change
↓
Run validation
↓
Run tests
↓
Review changes
↓
Verify original requirement
↓
Done
Enter fullscreen mode Exit fullscreen mode

Notice that the agent doesn't necessarily need every project document.

A good harness can instruct it to load only the context relevant to the task.

For this feature, that might mean:

project.md       ✓
architecture.md  ✓
domain.md        ✓
conventions.md   ✓
payments.md      ✗
Enter fullscreen mode Exit fullscreen mode

The exact loading behavior depends on the coding tool, but the harness should make the intended boundaries explicit.


"Done" Must Be Checkable

One of the biggest benefits of a harness is defining what "done" actually means.

Creating the button isn't enough.

The agent should verify:

✓ Button exists
✓ Correct users can access it
✓ Authorization is enforced
✓ Post becomes published
✓ Invalid states are handled
✓ Relevant tests pass
✓ No unrelated files were changed
✓ Original requirement is satisfied
Enter fullscreen mode Exit fullscreen mode

That's what a:

rules/definition-of-done.md
Enter fullscreen mode Exit fullscreen mode

can establish.

The goal is simple:

"Code exists" ≠ "Task is complete."


Approval Gates

Some operations are routine.

Others are risky.

Imagine the agent receives:

"Delete this category and all its posts."

That's potentially destructive.

The harness can define an approval gate:

Potentially destructive operation
↓
Explain impact
↓
Stop
↓
Request human approval
↓
Continue only after approval
Enter fullscreen mode Exit fullscreen mode

This is an important distinction:

A good agent shouldn't only know how to continue. It should also know when to stop.

Whether a particular tool can technically enforce every gate depends on the tool, but the policy itself belongs in the harness.


Codex and Cursor

The harness should remain tool-agnostic.

Your engineering rules shouldn't need to change because you switched from Codex to Cursor.

Only the entry point changes.

Conceptually:

                 Shared AI Harness
                        │
             ┌──────────┴──────────┐
             │                     │
           Codex                 Cursor
             │                     │
        AGENTS.md            .cursor/rules/
Enter fullscreen mode Exit fullscreen mode

For Codex, keep the repository-level AGENTS.md thin:

## Laravel CMS — Agent Entry Point

Before performing engineering work in this repository,
read and follow `ai-harness/AGENTS.md`.

The harness defines the project's:
- Agents
- Skills
- Rules
- Workflows
- Context

Do not duplicate the harness content here.
Enter fullscreen mode Exit fullscreen mode

For Cursor, use its project rules under:

.cursor/
└── rules/
    └── harness.mdc
Enter fullscreen mode Exit fullscreen mode

That rule can simply point the agent toward the shared harness.

The principle is:

One source of truth. Thin tool adapters.

Don't copy your entire engineering system into both AGENTS.md and Cursor rules.


Where Should Each Thing Go?

When you're unsure where an instruction belongs, ask:

Question Put it in
"This must always be true." rules/
"This is how we do this." skills/
"These steps must happen in this order." workflows/
"This is true about this project." context/
"This role has specific authority." agents/
"This is how Cursor/Codex connects." adapters/ / entry point

This simple distinction prevents the harness from becoming another giant instruction dump.


Start Small

You don't need a huge framework on day one.

A useful starting point could be:

ai-harness/
├── AGENTS.md
├── rules/
│   ├── core-rules.md
│   └── definition-of-done.md
├── workflows/
│   ├── feature-development.md
│   └── bug-fix.md
├── skills/
│   └── testing-strategy.md
└── context/
    ├── project.md
    └── architecture.md
Enter fullscreen mode Exit fullscreen mode

Then grow it when you notice repetition.

If you keep explaining the same thing to the agent, that's a signal that the knowledge probably belongs in the harness.


Final Takeaways

An AI harness isn't just a bigger prompt.

It's a structured engineering environment that gives an AI coding agent:

  • Consistency
  • Project knowledge
  • Reusable engineering practices
  • Repeatable workflows
  • Clear completion criteria
  • Safety boundaries

The goal isn't to make the model smarter.

It's to make the model more predictable and reliable inside your project.

The strongest principle is:

Don't put more instructions in the prompt. Put persistent engineering knowledge in the environment around the agent.

Prompting tells the agent what you want.

Harness engineering tells it how to work.

And that's the real shift:

From prompting an AI to engineering the environment in which the AI works.

Top comments (0)