The Series Concludes Here
A concrete reference implementation — greenfield and brownfield
harness-eng repository is no longer public.Over the past several months, we have published seven guides that build the theoretical foundation for agentic engineering: DDD, Event Storming, Flowcharts, Domain Context Engineering, BMAD, Attractor, and the Synthesis. Together, they define the four layers of agentic development, the dependency sequence between them, and the discipline that ties them together.
This article is the reference implementation of those theories — specifically Layer 3, the structured execution harness. It is not a new framework. It is a concrete way to apply what the earlier guides described. If the previous guides answered "why," this one answers "how."
This article described the original harness-eng reference implementation. That idea has since evolved into a product: Oystro, with its public protocol at oystro-oss. The core concepts are also distilled into a single, framework-free skill — harness-ref.
The problem is not that AI agents are incompetent. They are remarkably capable. The problem is structural: an agent that tends toward agreement, working from input that may be incomplete, in a conversation with no external correction mechanism, will produce confident wrong answers at speed.
The AI Manifesto names this precisely: "The greatest risk of AI is not that it will think for us. It is that it will agree with us — and we will not notice."
A harness addresses this by building the correction mechanism structurally. Not by asking the AI to argue against you — the manifesto already tells us that is simulation, not challenge. By stopping the conversation entirely and putting the work in front of a human who is genuinely outside the agreement spiral.
Every human gate — design review, task approval, verification sign-off — is a structured moment where the human steps outside the spiral and makes a decision. The ceremony is not overhead. It is the external accountability that prevents the Dilbert swing.
The harness is designed for projects that span weeks or months — multi-phase efforts where context drifts, requirements evolve, and the cost of building the wrong thing compounds over time. It is a reference implementation. Adapt it to your use case. Keep it minimal and simple. The goal is not to follow every step perfectly. The goal is to ship the right thing.
That depends on the team, not the harness. The harness provides structure — shared documents, consistent conventions, clear gates. But structure without discipline is just paperwork. Culture eats process for breakfast! A team that values quality will use the harness effectively. A team that doesn't will find ways around it. The harness makes the right thing easy. It cannot make the team care.
The design philosophy behind the harness is simple: the human is in control — making decisions, not just approving them.
During define and design, the agent is a collaborator. It asks clarifying questions, identifies gaps, suggests story breakdowns, challenges assumptions. It is thinking alongside you — not generating for you. The active phase folder accumulates detailed context: specs, designs, research, interfaces. You can see everything the agent has considered.
Then comes the approve gate. The agent stops. The work is in front of you. The design document, the interfaces, the file layout, the verification criteria. You review it. You make changes. You approve or send it back. This is not a formality — it is the single most important moment in the feature lifecycle. The design you approve is the contract the agent builds against.
After approval, the agent shifts. During build and verify, it is a junior programmer. It follows the tasks in order. It writes tests first. It commits after each task. It does not improvise. It does not add features. It executes the approved design with discipline. If something goes wrong after three attempts, it stops and escalates.
This shift is deliberate. A collaborator during design produces better design. A disciplined executor during build produces reliable code. The same agent playing both roles — but at different times, with different instructions — gives you the best of both without the risk of either bleeding into the other.
The human's responsibility is therefore clear. You own the what and the why. The agent owns the how — within the boundaries you approved. If the output is wrong, the first question is not "did the agent fail?" but "did I review the design carefully enough?" The harness makes accountability practical, not theoretical.
This is what separates harness engineering from vibe coding. In vibe coding, the human is not in control. The agent generates, the human accepts or rejects the output after the fact. The decisions happened upstream, in the prompt, invisible and unaudited. In the harness, every decision is captured in a document. Every document is reviewed. Every review is recorded. The human is in the driving seat — not because the harness constrains the agent, but because the harness makes the human's role explicit and unavoidable.
The harness is built around a deliberate artifact model: a small number of authoritative documents that agents write and humans review, and one derived view that agents read to resume context efficiently.
Authoritative artifacts — these are written by agents and reviewed or approved by humans. They are the source of truth for every decision made during a project:
project.yaml — compiled policy: locked technology choices, constitution rules, workflow default level. Written once at init; revised only when policy changes materially.plan.yaml — milestone-level project direction. Future slices are summaries; only the current slice is detailed. Prevents scope inflation before it is needed.spec.yaml — the unified slice contract for each feature or change. Combines requirements, design decisions, tasks, state classification, and evidence contract into a single document. One read instead of three.CHG-NNN.yaml — change record for each bug or CR. Captures baseline, delta, decisions, and evidence in one place.verify/<slice>.yaml — evidence record per slice. Includes config hash, environment hash, revision, and recorded-at timestamp. Enables evidence reuse when nothing has changed.Derived artifact — generated by the status script, never hand-authored, never duplicates full artifact contents:
handover.yaml — a compact continuation view that links to authoritative artifacts. Agents read this to resume from any session without replaying history. The status command reads and renders it; define, build, verify, and change regenerate it after each milestone.The architecture is deliberately simple: the workflow is the tool, the folder structure is the state machine, any agent that can read and write files will follow it. No runtime. No server. No API keys.
Gold boxes are human gates — the agent stops and waits for you. Purple boxes are internally spawned agent reviews — you never type these; the Manager triggers them automatically. This is the M/L-level diagram. In S-level projects, the purple nodes and the design/tasks steps are skipped entirely, and the pipeline collapses to define → build → verify.
Every slice in spec.yaml declares a workflow_level. This single field controls which gates fire, what evidence is required, and how much ceremony the agent applies. If absent, the harness defaults to M/L — full gates, fail-safe.
| Level | Intended for | Pipeline | Gates that apply |
|---|---|---|---|
| S — Small | Low-risk, self-contained changes. Internal scripts, config tweaks, documentation, prototypes. | define → build → verify → release |
Human release gate only. No review-pre-verify. No tasks.md / design approval required. |
| M — Medium | Feature development with moderate risk. Standard product work. | define → build → review-pre-verify (auto) → verify → release |
Agent review gate (Sr Tech Lead, fresh context) + Human release gate. Full evidence contract. |
| L — Large | High-risk, high-complexity work. Architectural changes, security boundaries, data migrations. | Same as M | Same gates as M, but with extended evidence requirements and broader regression coverage. |
The level isn't a label — it changes what the harness actually enforces at each step:
spec.yaml with requirements only. For M/L, the agent also produces architecture decisions and a full task list internally before writing spec.yaml.spec.yaml requirements without reading a separate tasks list. For M/L, it follows the approved task list one commit at a time and requires worktree.yaml to record ownership.workflow_level is missing from spec.yaml, the harness assumes M/L. This is deliberate: the safe default is full gates, not permissive gates.The harness has five user-facing commands. That is the entire surface a developer touches during day-to-day work. Everything else is either Manager-orchestrated or M/L-only internal.
| Command | What it does | Gate? |
|---|---|---|
/h:define | Create or update the slice contract (spec.yaml) from BRD. For M/L, design and tasks are produced internally — you review a single unified document. | — |
/h:build | Implement against the Evidence Contract in spec.yaml. One commit per task. | — |
/h:verify | Run the evidence contract, fill verify/<slice>.yaml, mark Release Ref: PENDING. | — |
/h:change | Unified workflow for bugs and CRs: classify → baseline → smallest delta → verify affected flow → archive. | — |
/h:status | Read-only project snapshot. Renders handover.yaml as terminal, JSON, or HTML — no tests, no network, no mutations. | — |
Two additional commands are triggered by the human but function as gates — the agent stops and waits for your decision:
| Command | What it does | Gate? |
|---|---|---|
/h:init | Scan docs or empty directory, derive project.yaml, plan.yaml, and constitution. | — |
/h:release | Disclose deferred items, wait for human approval, then merge, archive, version bump, regenerate handover. | ✋ Human |
This command is never typed by the human. The Manager spawns it as an isolated subagent after /h:build completes in M/L projects. It reads only what it needs, produces a structured report, and hands control back.
| Command | Persona | When triggered | Outcome |
|---|---|---|---|
review-pre-verify |
Sr Tech Lead | After /h:build completes, before /h:verify |
APPROVED → proceed to verify. BLOCKER → route back to build. |
Starting from an empty directory. You have an idea for a service that processes financial transactions. No existing code. No existing docs. You are not even sure which language to use yet.
Before any harness, before any tooling decisions, you need to understand the problem. Open your AI agent and have a conversation. No harness. No structure. Just exploration.
I want to build a service that processes financial transactions. Help me think through the problem — what are the main components, what are the hard parts, what should I consider before choosing a technology stack?
The agent explores with you. You discuss throughput requirements, compliance constraints, integration points, team size, deployment model. By the end of the conversation, you have a rough outline of the problem and a sense of which technology fits. Maybe Go for the performance and deployment model. Maybe Python for the ecosystem and speed of development. Maybe Node for the team's existing skills.
This is not wasted time. This is the thinking that prevents the Dilbert swing. The harness cannot fix a problem you have not thought through.
Now that you have direction, open your agent in the project directory and paste:
Read the harness reference at https://raw.githubusercontent.com/avonsiservices/avonsiservices.github.io/main/harness-ref/SKILL.md and initialise this project using the harness.
The agent scans your project (empty in this case), asks clarifying questions, and creates the .harness-eng/ scaffold with constitution, BRD, architecture, and technology decisions. Two minutes. The foundation is ready.
Say "define the features from the BRD". The agent reads your BRD, counts requirements, and creates feature specs with Given/When/Then stories. For large BRDs (5+ requirements), it automatically organizes into phases — Phase 1: Foundation, Phase 2: MVP, Phase 3: Enhancements.
You review the features. Approve the phase plan.
Say "define this feature". For M/L projects, the agent produces a single unified spec.yaml — requirements, architecture decisions, file layout, and the task list, all in one document. The agent stops. You review the spec — design looks right, but the agent missed the idempotency requirement. You add it. Say "approved". Design and tasks were produced internally during define; you never need to type separate commands for them.
Say "build it". The agent works through each task in the approved spec.yaml: code, commit, report. For deterministic invariants — accounting logic, no-lookahead boundaries — it writes focused tests. After three failed attempts on a task, it stops and escalates rather than thrashing.
Say "verify the feature". The agent runs the evidence contract (tests, integration checks, scenario fixtures), fills the verification report, and marks it Release Ref: PENDING. Say "release it". The agent presents the verification report and any deferred items, waits for your approval, marks the report Release Ref: APPROVED, merges, archives the feature folder, bumps the version, appends to the build narrative, and regenerates the handover snapshot. Pick the next feature. Repeat.
An existing Go service. 15,000 lines of code. No documentation. No tests. The original developer left. You need to add features without breaking what exists.
Open your agent in the project directory and paste:
Read the harness reference at https://raw.githubusercontent.com/avonsiservices/avonsiservices.github.io/main/harness-ref/SKILL.md and initialise this project using the harness.
The agent scans your existing code, reads any docs (README, ADRs), and reverse-engineers the constitution, BRD, and architecture from what exists. It derives naming conventions from the actual code, not an ideal. The architecture rules come from the actual module boundaries, not a diagram.
The agent flags gaps: "The Customer type in internal/billing/ is different from the Customer in internal/support/ — are these the same concept?" You answer: different bounded contexts. The agent updates the architecture. You review the derived documents. Some rules need updating — the agent found inconsistencies in the existing code. You decide which patterns to keep and which to fix. Approve.
Say "show status". The agent shows project status — version, active features, phase progress. No phases yet — just a snapshot of what exists. You use this to plan the first phase: what needs to be built, what needs to be fixed, what needs to be documented.
From here, the workflow is identical to greenfield. Define features, design, approve, tasks, build, verify, release. The difference is the constitution and architecture are grounded in reality, not aspiration. The agent does not guess about how the existing code works — it was reverse-engineered from the actual codebase.
The main feature loop handles new features. But once software ships, most work is not new features — it is change requests and bug fixes. The harness has a separate, extremely lightweight workflow for these.
Bugs and CRs are handled by a single user-facing command: /h:change. This command skips the full design, task planning, and pre-build approval gates, allowing the agent to implement the smallest complete code delta directly. It only promotes to a full define/design loop if the change affects a locked technology choice, a public interface, a persistent database schema/migration, or a security/architecture boundary.
The change workflow is optimized for speed and token economy. The agent creates a single CHG-NNN.yaml change record, characterizes the baseline revision and dirty worktree state, implements the fix or adjustment, and verifies only the directly affected flow. The human reviews and approves the change at the final release gate, avoiding pre-build ceremony for routine bug fixes and minor CRs.
Agents have no memory across sessions. The harness solves this with three layers:
The narrative log — last three entries of the build story. What was built, what was decided, what comes next. Fastest context recovery.
The compact snapshot — one file per feature with relevant rules, interfaces, acceptance criteria, current task, files modified. One file instead of six.
The task list — checklist of what is done and what is next.
Together, the agent resumes in under thirty seconds without re-reading the constitution, architecture, or full design documents.
In multi-phase projects, visibility is critical. You need to know where you are, what's done, what's next, and whether the agent is on track. The status command provides this without touching the working tree.
Say "show status". The agent reads the derived handover.yaml snapshot and shows:
In a six-phase project, this is your daily standup. One command, full picture. The status command is read-only — it never modifies your working tree, so it is safe to run at any point during a session.
The harness manages git branches automatically. Every feature, bug fix, and change request gets its own branch. Commits follow a convention that ties every change back to the spec.
Commit convention: type(ID): description. Every commit traces back to a spec or a change record. Six months later, git log --oneline tells the story of what was built and why.
spec(F001), feat(F001): task 1.1, verify(F001), change(CHG-001): description. The ID in the commit maps to the ID in the spec or the change record. Traceability from requirement to code, enforced by convention.No harness guarantees that a model will behave as expected. The agent may skip steps, forget to update logs, or deviate from the approved design. The harness makes the right path clear, but it cannot force the agent to follow it.
The human must steer. The status command shows where you are and what the agent should do next. But the human is still responsible for watching, correcting, and deciding. The harness is a guide rail, not an autopilot.
This is a reference implementation — not a production-tested tool. It works for the cases we have tested. It may need adaptation for your context. Use it as a starting point, not a finished product.
harness-eng is Layer 3 in the four-layer sequence. It assumes Layers 1 and 2 have been done — the domain is understood, the vocabulary is agreed, the boundaries are drawn. It provides the execution discipline that prevents the confident wrong answer.
Layer 4 — the dark factory — is the horizon. It becomes viable when the domain understanding from Layers 1 and 2, combined with the execution discipline from Layer 3, produces specifications precise enough for full autonomy. That is not where most teams are today. Layer 3 is.
The harness is the foundation. Two extensions are emerging that will complement it:
A context hub for enterprise applications. Andrew Ng's context-hub helps agents with latest API documentation. The same approach applies to ERP systems and enterprise applications — SAP, Oracle, Salesforce. During large projects, the implementation team builds a context repository: vanilla application behaviour plus organisation-specific extensions and customisations. The harness constitution reads this repository. The agent starts with accurate domain knowledge, not generic training data.
Vector search and code intelligence. MCP-based tools like Sourcegraph and Tree-sitter can help coding agents find what they need quickly — reducing token burn and increasing accuracy. The harness does not replace these tools. It complements them. The harness controls the workflow. The tools improve the agent's ability to execute within that workflow.
Neither is a harness problem. Both enrich the harness. The workflow stays the same. The agent gets better at following it.
harness-eng ships as files you copy into your project — no runtime, no server, no API keys. Clone the repo and you have:
define, build, verify, change, status. That is the entire surface a developer touches day-to-day. init and release are also human-invoked but infrequent. Internal, M/L-specific, and upgrade commands exist but are not part of the normal workflow surface.spec.yaml per slice. Absent defaults to M/L — full gates, fail-safe.spec.yaml) — one document per feature combining requirements, design decisions, task list, state classification, and evidence contract. Replaces the old spec.md + design.md + tasks.md triple. One read, one review, one approval.project.yaml (locked constraints, constitution rules, technology decisions) and plan.yaml (milestone plan, future slices as summaries). Agents read these compact files instead of re-reading raw BRD and CONSTITUTION on every command.handover.yaml) — generated by the status script after each milestone. Links to authoritative artifacts; never duplicates their content. The agent reads this to resume any session without conversation history.verify/<slice>.yaml records a config hash, environment hash, and revision. If nothing has changed, the evidence is reused without re-running. No redundant test runs.handover.yaml, renders terminal/JSON/HTML from a single snapshot), migration engine (consent-gated project reclassification), harness check (prerequisites and constraint validation).The harness works with any agent that can read and write files. We have tested it with:
AGENTS.md rule file that Antigravity reads automatically at session start, giving it the full workflow context without any prompt engineering.Other agents — Claude Code, Codex, Copilot, Cursor — have their own built-in conventions (CLAUDE.md, project rules, system prompts). These agents may partially follow the harness while defaulting to their own workflows, particularly at transition points between commands. We have not tested harness-eng with these agents and cannot claim compatibility. An agent with its own harness has a competing context; an agent without one adopts yours cleanly.
The harness is a protocol, not a plugin. It works because the files are the instructions. Any agent that can read files will follow it — the question is whether it follows your files or its own defaults when the two conflict.
The review gates and persona-switching described above only work if the agent can actually launch an isolated sub-conversation. Different agents implement this differently, but the contract is the same: the Manager sends a bounded context packet to a fresh agent instance and waits for the result.
Bounded context packet — each subagent receives only what it needs: objective, authorised read/write paths, prohibited changes, evidence expectations, and stop conditions. History defaults to none. The full project history, constitution, and session context are not sent by default. This is what keeps the Sr Tech Lead genuinely fresh-eyes.
Antigravity uses an explicit invoke_subagent tool call. The Manager selects a persona (e.g. sr-tech-lead), passes the context packet as a structured prompt, and the subagent runs in a separate conversation thread with its own isolated context window. When it completes, the result is returned to the Manager thread. The persona is defined in .harness-eng/agents/sr-tech-lead/agent.md — a file the harness ships, not a capability the agent provides.
OpenCode spawns a new opencode session with a targeted prompt containing the context packet. The bounded prompt is the isolation mechanism — the subagent starts from the prompt, not from the parent session history.
In both cases, the isolation is what matters. An agent that continues the same session for build and review is not implementing the harness correctly — it is simulating a review with full context, which defeats the purpose of the gate entirely.
This repository is shared openly for external validation. We have tested it with a handful of agents and projects. Positive feedback from early users is encouraging, but limited. The real test is broader use — by teams with different contexts, different agents, different problems.
If you try it, let us know what breaks. The harness improves through honest challenge — which is, appropriately, what the AI Manifesto asks of its readers.