
Harness Engineering
- 241 installs
- 191 repo stars
- Updated July 24, 2026
- pproenca/dot-skills
harness-engineering: A skill for development. This provides functionality for development workflows.
Key points
- harness-engineering
Harness Engineering by the numbers
- 241 all-time installs (skills.sh)
- +7 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #1,564 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/pproenca/dot-skills --skill harness-engineeringAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 241 |
|---|---|
| repo stars | ★ 191 |
| Last updated | July 24, 2026 |
| Repository | pproenca/dot-skills ↗ |
How do I use harness-engineering for development tasks?
Use harness-engineering for development tasks
Who is it for?
Best when you're working on backend & apis and need structured help with harness-engineering.
Skip if: Teams with no backend & apis needs, or anyone wanting a generic chat assistant without this specific workflow.
When should I use this skill?
When you need to use harness-engineering for development tasks, or when harness-engineering: a skill for development. this provides functionality for development workflows.
What you get
Structured output aligned to harness-engineering: harness-engineering.
Files
Harness: Agent-First Engineering Scaffolding
The harness is the scaffolding that makes coding agents effective in a repository. It encodes the knowledge, boundaries, and rules that an agent needs to reason about the full business domain directly from the repo itself.
The philosophy: agents execute, humans steer. The engineer's job is not to write code but to design environments, specify intent, and build feedback loops. The harness is what makes this possible.
Why It Matters
From the agent's point of view, anything it can't access in-context while running effectively doesn't exist. Slack discussions, Google Docs, tacit team knowledge — all invisible. The harness makes this knowledge legible by encoding it as repository-local, versioned artifacts.
A well-harnessed repo gives agents:
- A map (AGENTS.md) — where to look, not what to memorize
- Boundaries (domain specs) — what can depend on what
- Rules (golden principles) — taste encoded as enforceable invariants
- Quality baselines (scoring) — where the gaps are
Without this scaffolding, agents replicate whatever patterns they find — including bad ones. The harness is what prevents entropy from compounding.
Harness Maturity Model
The harness is built incrementally. Each level builds on the previous — don't try to jump from Level 0 to Level 4 in one pass. Assess the current level and build toward the next.
| Level | Name | What it enables | Key artifacts |
|---|---|---|---|
| 0 | Unharnessed | Agents guess everything — no map, no rules | Nothing |
| 1 | Map | Agents know where to look and what the codebase does | AGENTS.md, ARCHITECTURE.md, docs/ |
| 2 | Rules | Agents know what's allowed and what isn't | .harness/principles.yml, enforcement.yml, domains.yml |
| 3 | Feedback | Agents self-correct via quality signals and process patterns | .harness/quality.yml, doc-gardening, GC sweeps |
| 4 | Autonomy | Agents operate independently with defined escalation boundaries | Worktree isolation, escalation rules, agent-to-agent review |
Each level compounds. A repo at Level 2 without Level 1 has rules nobody can find. A repo at Level 3 without Level 2 has quality grades but no way to enforce improvement. Build the foundation first.
During assessment (Phase 1), determine the current maturity level. During planning (Phase 2), target the next level — not all levels at once. Repeat the harness workflow to climb.
Critical exception: for repos where agents are actively writing code (agent-first or agent-assisted), architecture boundaries (domain definitions and the forward-only dependency rule) should be co-created alongside the knowledge layer, not deferred to a separate Level 2 pass. The article is explicit: strict architecture is a day-one prerequisite for agent-driven development, not a scaling concern. Without boundaries, agents produce code faster than entropy can be contained.
Multi-Turn Workflow
Building a harness is interactive. Work through the phases below, presenting results and waiting for user confirmation at each phase boundary. The user may want to skip, reorder, or expand phases — follow their lead.
Phase 1: Assess → Analyze the repo, report agent readiness
Phase 2: Plan → Propose a tailored harness, user confirms
Phase 3: Knowledge → AGENTS.md, docs/, ARCHITECTURE.md
Phase 4: Domains → Identify domains, map layers, generate .harness/domains.yml
Phase 5: Enforce → Golden principles, rules → .harness/principles.yml, enforcement.yml
Phase 6: Quality → Grade domains → .harness/quality.yml
Phase 7: Process → Doc-gardening, GC, review patterns
Phase 8: Verify → Cross-check everything, report completenessDepth-First Bootstrap
Build the harness depth-first, not breadth-first. Early harness work is slower than expected — not because the repo is broken, but because the environment is underspecified. Each phase unlocks the next:
- AGENTS.md unlocks docs/ (agents know where to put deeper content)
- docs/ unlocks architecture awareness (agents can read domain context)
- Architecture specs unlock correct domain identification
- Domain specs unlock meaningful enforcement rules
- Enforcement rules unlock quality scoring (you can't grade what you can't check)
When something fails, the fix is almost never "try harder." Ask: what capability or context is missing? Then build that piece first.
For updates to an existing harness, the same phases apply but the assessment diffs against current .harness/ specs and only what has drifted gets updated.
Phase 1: Assess
Examine the repository across every harness layer. The goal is understanding what exists, what's missing, and what's misaligned — not immediately fixing things.
What to examine:
| Area | What to look for |
|---|---|
| Structure | Directories, languages, package manifests, monorepo vs single-package |
| Tech stack | Frameworks, build systems, deployment targets, dependency managers |
| Agent config | AGENTS.md, CLAUDE.md, .cursor/, .github/copilot/, any existing agent instructions |
| Documentation | README, docs/, architecture docs, ADRs, inline doc comments |
| Code organization | Domain structure, module boundaries, import patterns, dependency graph |
| Tests | Frameworks, coverage, CI gates, test organization |
| Observability | Logging patterns (structured?), metrics, error handling, tracing |
| Process | PR templates, review workflow, CI/CD configuration |
| Team config | Agent-first (agents write 90%+ code), agent-assisted (mixed), or agent-ready (preparing for future agent use) |
| Dependencies | Are external libraries agent-legible? Stable APIs, good docs, training data representation? |
Read references/assessment.md for the detailed checklist and scoring rubric.
Team configuration shapes the harness: an agent-first repo needs strong enforcement and GC from day one. An agent-assisted repo needs clear boundaries but can rely more on human review. An agent-ready repo mostly needs the knowledge layer.
Output: An Agent Readiness Report — a structured summary of current state per layer, key findings, and recommended harness components (prioritized).
Present the report and wait for the user to confirm or adjust before planning.
Phase 2: Plan
Propose a harness plan tailored to this specific repo. Not every repo needs every component — right-size based on the assessment.
Sizing by maturity level:
| Current level | Target | What to build |
|---|---|---|
| 0 → 1 | Map | AGENTS.md, ARCHITECTURE.md, core docs/ structure |
| 1 → 2 | Rules | .harness/domains.yml, principles.yml, enforcement.yml |
| 2 → 3 | Feedback | .harness/quality.yml, doc-gardening, GC patterns |
| 3 → 4 | Autonomy | Worktree isolation, escalation boundaries, agent review |
Also consider repo size — a small repo (< 5k LOC) may only need Level 1–2, while a large codebase (50k+ LOC) benefits from all four levels.
The plan should list every artifact to be created or updated, grouped by phase, with a brief note on what each one does. Present it as a checklist the user can approve, modify, or trim.
Wait for confirmation before implementing.
Phase 3: Knowledge Layer
Build the artifacts that give agents a map of the codebase.
AGENTS.md (~100 lines)
The single most important file. It is a routing table, not an encyclopedia.
It should contain:
- 3–5 non-negotiable rules (the ones that cause the most damage when violated)
- Pointers to deeper docs:
ARCHITECTURE.md,docs/, active plans - How to verify work (build/test commands)
- What the repo is and how it's structured (2–3 sentences)
Everything else belongs in docs/. If AGENTS.md exceeds ~100 lines, it's too long and should be refactored into docs/ with pointers.
docs/ Directory
docs/
├── design-docs/
│ ├── index.md # Catalogue with verification status
│ └── core-beliefs.md # Agent-first operating principles
├── exec-plans/
│ ├── active/ # In-flight work
│ ├── completed/ # Done work (context for future agents)
│ └── tech-debt-tracker.md # Known debt with priority
├── generated/ # Auto-generated (DB schema, API specs)
├── product-specs/
│ ├── index.md # Feature catalogue
│ └── <feature>.md
├── references/ # External docs in agent-friendly format
├── PRODUCT_SENSE.md # Product principles, personas, domain sensitivity
└── <DOMAIN>.md # Domain guides (only those relevant to the repo)Every file in docs/ should follow progressive disclosure structure: 1. Summary (2–3 sentences) — enough for an agent to decide if this file is relevant 2. Key decisions — the 3–5 most important things, up front 3. Details — full content for agents that need to go deeper 4. Pointers — links to related docs for further context
This prevents the "one big AGENTS.md" problem from recurring at the file level. Agents should be able to read just the summary of each doc and navigate to the right one, rather than loading every file into context.
Only create what the repo actually needs. Each file should contain real content derived from the assessment — not boilerplate.
ARCHITECTURE.md
Top-level domain map answering: what are the domains, how do they relate, what are the dependency rules, where does new code go.
Read references/knowledge-layer.md for templates and writing guidance. Read references/core-beliefs.md for the core beliefs template and content guide.
Phase 4: Architecture Layer
Define domain boundaries and dependency rules as machine-readable specs.
Domain Identification
A domain is a vertical slice — a tracer bullet that cuts through all integration layers end-to-end, from data shapes to user-facing output. It is NOT a horizontal technical layer.
The litmus test: can you trace a user action from UI through runtime, service, repo, and types — and does that path stay within one coherent business concept? If yes, that's a domain.
CORRECT (vertical slices): WRONG (horizontal layers):
┌─────────┐ ┌──────────┐ ┌──────────────────────────┐
│ Billing │ │ Onboard │ │ controllers/ │ ← NOT a domain
│ ┌─────┐ │ │ ┌─────┐ │ │ models/ │ ← NOT a domain
│ │Types│ │ │ │Types│ │ │ services/ │ ← NOT a domain
│ │Confg│ │ │ │Confg│ │ │ utils/ │ ← NOT a domain
│ │Repo │ │ │ │Svc │ │ └──────────────────────────┘
│ │Svc │ │ │ │UI │ │
│ │UI │ │ │ └─────┘ │
│ └─────┘ │ └──────────┘
└─────────┘Look for business concepts, not technical functions:
- "billing", "onboarding", "search" = domains (vertical, own their full stack)
- "controllers", "utils", "testing", "tooling" = layers or concerns (horizontal)
Read references/architecture-layer.md for detailed identification heuristics and the tracer-bullet test.
Layer Structure
Within each domain, code is organized into layers:
Types → Config → Repo → Service → Runtime → UIThe key rule: dependencies flow forward only. A types module never imports from service. Cross-cutting concerns (auth, telemetry, feature flags) enter through a single explicit interface called Providers.
Not every domain has every layer. A CLI tool might only have Types → Config → Service → Runtime. A library might only have Types → Service. Map what exists.
Generate .harness/domains.yml
Create the domain specification. Read references/yml-schemas.md for the schema and references/architecture-layer.md for identification heuristics.
Phase 5: Enforcement Layer
Encode architectural taste as machine-readable rules. The goal: enforce boundaries centrally, allow autonomy locally.
Golden Principles (.harness/principles.yml)
Identify 5–10 opinionated rules specific to this repo. Each principle needs:
- What: The rule itself
- Why: Why it matters (what goes wrong without it)
- How to check: lint, structural test, review, or manual inspection
- Examples: Concrete good/bad code snippets from this codebase
Start with principles from the assessment — patterns that are already causing problems, or invariants that are currently maintained manually but should be enforced.
Mechanical Rules (.harness/enforcement.yml)
Concrete rules that tooling can check:
- Naming conventions for files, types, functions
- File size limits
- Structured logging requirements
- Import boundary checks
- Test coverage expectations
Agent-Legible Error Messages
This is one of the highest-leverage patterns in the entire harness. Every enforcement rule MUST include a violation_message template with four parts: 1. What's wrong — the specific violation 2. Why it matters — rationale linked to a principle 3. How to fix it — concrete remediation steps 4. Where to look — file paths or doc pointers
Lint error messages are a delivery mechanism for injecting remediation instructions into an agent's context at the exact moment it needs them. Generic messages ("boundary violation in X") are nearly useless. Rich messages ("X imports from Y, violating forward-only rule. Fix: inject via Providers. See: ARCHITECTURE.md#cross-cutting") let agents self-correct immediately.
Generate Enforcement Code
The .harness/*.yml specs describe rules. But specs that nothing checks are documentation that rots — the same problem the harness is designed to prevent.
For every enforcement rule, also generate at minimum one concrete artifact:
- Lint configuration: ESLint/Ruff/Clippy config that enforces naming,
imports, or structural rules — with agent-legible error messages
- CI workflow: GitHub Actions / CI job that validates AGENTS.md links,
docs/ cross-references, or knowledge freshness
- Structural test: A test file that validates architectural invariants
(e.g., import direction, domain boundary compliance)
- Script: A validation script that checks file size limits, banned
patterns, or naming conventions
Even stub implementations are better than nothing. A lint rule with a TODO body is more valuable than a perfectly documented YAML spec that nothing reads.
Read references/enforcement-layer.md for the principles catalog and patterns. Read references/yml-schemas.md for schemas.
Phase 6: Quality Scoring
Grade each domain across standardized dimensions.
Dimensions: code quality, test coverage, documentation, observability, reliability, security.
Scale: A (exemplary) through F (missing/broken).
The initial scoring is a baseline. Future harness updates compare current state against these grades to track improvement or detect drift.
Generate .harness/quality.yml with scores, gap notes, and review dates. Read references/quality-scoring.md for the rubric.
Phase 6.5: Operational Legibility (if applicable)
For repos with a running application (web app, API, service), assess whether agents can observe the app, not just the code. The article's team made the running application directly legible to agents — this is what enabled 6+ hour autonomous agent sessions.
Assess and recommend:
- Worktree-bootable: Can the app boot per git worktree so each agent run
gets an isolated instance? If not, flag this as a high-priority gap.
- Browser automation: For UI apps — can agents drive the app via Chrome
DevTools Protocol (screenshots, DOM snapshots, navigation)?
- Observability: Can agents query logs (LogQL), metrics (PromQL), and
traces (TraceQL) from their own instance?
- Ephemeral state: Are logs, metrics, and app state torn down when the
agent's task completes?
This phase is only relevant for repos with runnable applications. Libraries, CLI tools, and infrastructure repos can skip it.
Phase 7: Process Patterns
Document the patterns that keep a harness-driven codebase healthy over time. These go into the appropriate docs/ guide files.
- Doc-gardening: Recurring scans for stale or incorrect documentation
- Garbage collection: Identifying and cleaning up pattern drift, duplicated
helpers, or accumulated "AI slop" — this is urgent, not optional. Without automated GC, agent-generated codebases degrade fast enough to consume 20% of engineering time in manual cleanup
- Agent review: At Level 3+ maturity, agent-to-agent review should be the
primary quality gate, not a supplement to human review. Humans review for judgment calls only (business logic, product decisions, architectural direction). The progression: L1-2 humans review everything → L3 agents pre-review, humans spot-check → L4 agent-to-agent review, humans only for escalations.
- Merge philosophy: Short-lived PRs, follow-up fixes over indefinite blocking.
Prerequisite: this is only appropriate when automated enforcement is in place (Level 2+ maturity), test coverage catches regressions, and agents can generate follow-up fixes. Without these, relaxed merge gates are reckless.
- Feedback encoding: How review comments and bugs become doc updates or rules
- Escalation boundaries: Define what decisions require human judgment vs.
what agents can resolve autonomously — prevents both over-asking (slow) and under-asking (dangerous)
Read references/process-patterns.md for templates.
Phase 8: Verify
After implementation, verify the harness is coherent:
- [ ] Every path referenced in AGENTS.md exists
- [ ] All cross-links in docs/ resolve
- [ ] .harness/*.yml files have valid structure
- [ ] domains.yml domains correspond to actual code directories
- [ ] ARCHITECTURE.md reflects the real module structure
- [ ] Quality scores have been populated for all identified domains
- [ ] Knowledge base structure matches knowledge.yml config
Report findings. Fix issues before marking the harness complete.
Update Flow
When updating an existing harness:
1. Detect drift: Compare .harness/ specs against the actual codebase
- New directories/modules not in domains.yml
- Docs referencing deleted or moved files
- Quality scores older than the configured review cadence
- Principles being violated in recently added code
2. Propose targeted updates: Don't rebuild — update only what drifted 3. Implement changes: Same phase structure, but scoped to the drift 4. Re-verify: Run the full verification checklist
.harness/ Directory
All machine-readable harness configuration lives in .harness/ at the repo root.
.harness/
├── config.yml # Harness metadata, version, tech stack summary
├── domains.yml # Business domain definitions + layer rules
├── principles.yml # Golden principles with rationale + examples
├── enforcement.yml # Mechanical rules (naming, limits, logging, imports)
├── quality.yml # Per-domain quality grades + gap tracking
└── knowledge.yml # Knowledge base structure configurationSee references/yml-schemas.md for complete schemas with examples.
Adaptation by Tech Stack
The harness is tech-agnostic but the implementation adapts:
- Naming conventions: camelCase for JS/TS, snake_case for Python/Rust
- Layer names: May differ — "repo" might be "repository" or "data-access"
- Build commands: Vary per stack — capture in AGENTS.md
- Dependency enforcement: Import style differs between module systems
- Logging: Different structured logging libraries per ecosystem
Identify the stack during assessment and adapt all templates accordingly. Don't force conventions from one ecosystem onto another.
{
"version": "1.0.5",
"organization": "OpenAI / Harness Engineering",
"technology": "Agent-First Engineering",
"date": "March 2026",
"abstract": "Implements the agent-first engineering harness described in 'Harness Engineering: Leveraging Codex in an Agent-First World.' Sets up or updates the complete scaffolding that makes AI coding agents effective in any repository: knowledge maps (AGENTS.md as a concise TOC), structured documentation, vertical domain architecture with enforced layer boundaries, golden principles with agent-legible error messages, quality scoring, enforcement code generation, and process patterns for agent-driven development. Multi-turn skill that assesses a repo's agent readiness (Level 0-4 maturity model), proposes a tailored harness plan, and implements it incrementally.",
"references": [
"https://openai.com/index/harness-engineering/",
"https://cookbook.openai.com/articles/codex_exec_plans",
"https://matklad.github.io/2021/02/06/ARCHITECTURE.md.html",
"https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/",
"https://ghuntley.com/loop/"
]
}
Architecture Layer: Domains, Layers, and Boundaries
This reference covers domain identification, layer mapping, and dependency rules.
The Tracer-Bullet Principle
A domain is a vertical slice that cuts through ALL integration layers end-to-end. Think of it as a tracer bullet: it starts at the data shapes (Types) and travels through configuration, data access, business logic, orchestration, all the way to the user-facing output (UI or CLI). That complete vertical path, serving one coherent business purpose, is a domain.
This is the most important concept in the architecture layer, and the most commonly confused. Agents default to slicing by technical function — grouping all controllers together, all models together, all utilities together. That produces horizontal layers, not domains. The harness architecture requires vertical slices.
The Litmus Test
Ask: "Can I trace a user-visible action from the UI, through business logic, through data access, down to the data types — and does that entire path belong to one coherent business concept?"
If yes → that's a domain. If the path crosses multiple business concepts → those are separate domains. If the grouping is by technical function (all controllers, all models) → that's a layer, not a domain.
Visual: Vertical vs Horizontal
CORRECT — Vertical domains: WRONG — Horizontal layers:
Billing Auth Onboarding ┌─ controllers/ ─────────────┐
┌──────┐ ┌──────┐ ┌──────────┐ │ billing_ctrl, auth_ctrl │
│Types │ │Types │ │Types │ ├─ services/ ────────────────┤
│Config│ │Config│ │Config │ │ billing_svc, auth_svc │
│Repo │ │Repo │ │Service │ ├─ models/ ─────────────────┤
│Svc │ │Svc │ │UI │ │ billing_model, auth_model │
│Rntme │ │Rntme │ └──────────┘ ├─ utils/ ──────────────────┤
│UI │ │UI │ │ helpers, formatters │
└──────┘ └──────┘ └────────────────────────────┘
Each domain owns its full Technical grouping scatters
stack. Layers are INSIDE each business concept across
each domain. multiple directories.Domain Identification Heuristics
Step 1: Start From Business Concepts, Not Code
Before looking at the code, ask: what does this product DO for users? Each distinct capability is a domain candidate:
- "Users can subscribe and pay" → Billing domain
- "Users can sign up and configure their account" → Onboarding domain
- "Users can search for content" → Search domain
- "The system sends notifications" → Notifications domain
Step 2: Validate Against the Codebase
Now look at the code to see how these concepts are implemented:
1. Directory structure — Top-level directories under src/, lib/, app/, or packages/ often map to domains if the repo is well-organized. 2. Package manifests — In monorepos, each package/workspace may be a domain. 3. Import graphs — Code that imports each other heavily but has few external imports is likely one domain. 4. Data models — Clusters of related types/schemas that serve one business concept indicate a domain. 5. Team ownership — If different teams own different parts, those boundaries are often domain boundaries.
Step 3: Apply the Vertical Test
For each candidate domain, check: does it own (or could it own) its own vertical stack? A domain should contain or be able to contain its own:
- Data types and contracts
- Business logic
- Data access (if applicable)
- User-facing interface (if applicable)
If a candidate "domain" is actually a technical concern shared across multiple business concepts (logging, auth middleware, test utilities), it's a cross-cutting concern, not a domain. It enters through Providers.
What Makes a Good Domain Boundary
- Vertical ownership: The domain owns its stack from types to UI
- Business alignment: The name maps to a business concept users would recognize
- Cohesion: Code inside the domain is tightly related to one purpose
- Loose coupling: Domains interact through defined interfaces, not deep imports
Common Anti-Patterns
- Horizontal slicing as domains: "controllers", "models", "services", "utils",
"tooling", "testing" are layers or concerns, NEVER domains. This is the single most common mistake. If your domain name describes a technical function rather than a business capability, it's wrong.
- Too granular: Every directory becomes a "domain" — usually means the code
should just be a module within a larger domain.
- Too coarse: Everything is one domain — look for natural seams where distinct
user-facing capabilities emerge.
- Infrastructure as domains: "database", "api-gateway", "message-queue" are
infrastructure, not domains. They serve domains through the Repo or Runtime layers.
Worked Example: A Skills Repository
Consider a repo that contains AI agent skills:
Wrong (horizontal slicing):
- "skills-content" (the skill files) ← technical grouping
- "skills-tooling" (validation scripts) ← technical grouping
- "skills-testing" (test fixtures) ← technical grouping
Right (vertical slicing by business concept):
- "skill-authoring" domain: types for skill format → validation service →
CLI tooling for creating/editing skills → template generation
- "skill-distribution" domain: packaging types → registry service →
install/publish commands
- "skill-evaluation" domain: eval types → scoring service → test runner →
report output
Each domain owns a complete user-facing capability with its own vertical stack. The "tooling" and "testing" that were incorrectly labeled as domains are actually layers within the real domains.
Layer Structure
Within each domain, code is organized into layers with strict dependency direction.
Canonical Layers
Types → Config → Repo → Service → Runtime → UI| Layer | Purpose | Typical contents |
|---|---|---|
| Types | Data shapes and contracts | Interfaces, schemas, enums, constants |
| Config | Configuration and dependency interfaces | Env vars, feature flags, @DependencyClient protocols |
| Repo | Data access | Database queries, API clients, cache, live implementations |
| Service | Pure business logic | Domain operations, validation, transformations — NO framework dependencies |
| Runtime | Orchestration and wiring | Framework integration (@Reducer in TCA, route handlers in Vapor, controllers in Express), dependency wiring, effect execution |
| UI | User-facing interface | Components, pages, views — imports Runtime to get wired features |
The Forward-Only Rule
Dependencies must flow forward in the layer order. A types module never imports from service. A repo module never imports from ui. This is the single most important architectural rule — it prevents circular dependencies and keeps each layer independently testable.
Not Every Domain Has Every Layer
A CLI tool might have: Types → Config → Service → Runtime (no Repo, no UI). A shared library might have: Types → Service (nothing else). A frontend-only module might have: Types → Service → UI.
Map what actually exists. Don't force empty layers into existence.
Cross-Cutting Concerns
Auth, telemetry, feature flags, connectors — these cut across all domains. They enter through a single explicit interface: Providers.
Cross-cutting concern → App Wiring → Providers → Service layerProviders are injected at the application wiring level and consumed by the service layer. This keeps cross-cutting logic out of domain internals while making it available everywhere.
Mapping for Different Tech Stacks
TypeScript/Node.js:
domain/
├── types.ts (or types/)
├── config.ts
├── repo.ts (or repo/)
├── service.ts (or service/)
├── runtime.ts (middleware, routes)
└── ui/ (React components)Python:
domain/
├── types.py (or models.py, schemas.py)
├── config.py
├── repo.py (or repository.py)
├── service.py
├── runtime.py (FastAPI routes, CLI commands)
└── ui/ (templates, if applicable)Swift (TCA):
Domain/
├── Types/ Data models, enums, constants
├── Config/ @DependencyClient protocols, settings
├── Repo/ Live implementations, SwiftData, network
├── Service/ Pure business logic (NO @Reducer, NO ComposableArchitecture)
├── Runtime/ @Reducer structs — orchestrate Config, Repo, Service into state
└── UI/ SwiftUI Views — consume StoreOf<Feature> from RuntimeKey insight for TCA apps: @Reducer lives in Runtime, NOT Service. A reducer wires dependencies (Config), calls data access (Repo via Config interfaces), and produces state for UI. That's orchestration. Service is for pure domain logic testable without TCA.
Go:
domain/
├── types.go
├── config.go
├── repo.go
├── service.go
├── handler.go (runtime/HTTP handlers)
└── (no UI layer typically)Adapt layer names to the ecosystem's conventions. The structure matters more than the exact names.
Generating domains.yml
When writing .harness/domains.yml, map only what actually exists in the codebase.
Pre-check before writing any domain entry: Does this domain pass the tracer-bullet test? Ask: 1. Does the name describe a business capability (not a technical function)? 2. Can I trace a user-visible action through this domain's layers end-to-end? 3. Does it own its own types, logic, and at least one integration layer?
If the answer to #1 is no — it's probably a cross-cutting concern (put it in cross_cutting:) or a layer within a real domain.
Each domain entry should:
1. Have a clear name and description tied to a business concept 2. Specify the path where the domain lives 3. List only the layers that actually exist in the code 4. Declare which cross-cutting providers the domain consumes
If a domain's internal structure doesn't follow clean layers yet, note this in the domain description and flag it in quality.yml. The spec captures the target state and the current reality.
When the Codebase Is Horizontally Organized
Many repos are organized by technical layer (controllers/, models/, services/). This doesn't mean there are no domains — it means the domain boundaries are implicit in the code rather than explicit in the directory structure.
In this case: 1. Identify the business concepts that the code serves 2. Map which files across the horizontal directories belong to each concept 3. Document these as the domains in domains.yml, noting that the current directory structure is horizontal 4. Flag this as a quality gap — the harness spec describes the target vertical organization even if the code hasn't been restructured yet
Assessment Checklist & Scoring
Use this checklist during Phase 1 to evaluate a repository's agent readiness. Score each layer, then summarize findings in the Agent Readiness Report.
Checklist
1. Knowledge Layer
- [ ] AGENTS.md or equivalent exists
- Is it concise (~100 lines) or bloated?
- Does it function as a TOC or as a monolithic instruction manual?
- Does it point to deeper docs or try to contain everything?
- [ ] docs/ directory exists with organized content
- Design docs with index and verification status?
- Execution plans (active and completed)?
- Product/feature specs?
- External references in agent-friendly format?
- [ ] ARCHITECTURE.md or equivalent exists
- Does it describe domain boundaries?
- Does it map dependencies?
- Is it current or stale?
- [ ] README provides orientation
- Quick start, what the project does, how to contribute
2. Architecture Layer
- [ ] Clear domain/module boundaries visible in directory structure
- [ ] Dependency patterns are intentional (not spaghetti imports)
- [ ] Cross-cutting concerns have defined entry points
- [ ] No circular dependencies between major modules
- [ ] Layer separation exists (even if informal)
3. Enforcement Layer
- [ ] Linting configured (ESLint, Ruff, clippy, etc.)
- [ ] Formatting enforced (Prettier, Black, rustfmt)
- [ ] CI runs checks automatically
- [ ] Import restrictions or boundary checks exist
- [ ] Naming conventions are followed (even if not enforced)
- [ ] File size is reasonable (no 2000+ line files)
- [ ] Structured logging is used (not ad-hoc console.log/print)
3.5 Operational Isolation
- [ ] App is bootable per git worktree (isolated instances per change)
- [ ] Each worktree gets its own logs, metrics, and state
- [ ] State is torn down when the task completes
- [ ] Multiple agent runs can work in parallel without stepping on each other
- [ ] Long-running agent sessions (multi-hour) are supported without resource leaks
4. Quality Layer
- [ ] Tests exist and run in CI
- [ ] Coverage is tracked
- [ ] Error handling is consistent
- [ ] Observability exists (logging, metrics, tracing)
- [ ] Security boundaries are defined
- [ ] Known tech debt is tracked somewhere
5. Process Layer
- [ ] PR/review workflow is defined
- [ ] CI/CD pipeline exists
- [ ] Documentation is maintained alongside code
- [ ] Tech debt is addressed periodically (not just accumulated)
- [ ] Escalation boundaries are defined (what requires human judgment)
- [ ] Agent autonomy levels are documented (what agents can merge/deploy/decide)
Scoring Rubric
Score each layer on a 1–5 scale:
| Score | Meaning |
|---|---|
| 5 | Fully harnessed — comprehensive, enforced, current |
| 4 | Well structured — most components present, minor gaps |
| 3 | Partially structured — some components, inconsistent coverage |
| 2 | Minimal — basic structure but largely unenforced or stale |
| 1 | Absent — no meaningful harness in this layer |
Overall agent readiness = average of layer scores:
- 4.0+ = Well harnessed, focus on updates and refinement
- 3.0–3.9 = Partially harnessed, targeted improvements needed
- 2.0–2.9 = Under-harnessed, significant scaffolding needed
- < 2.0 = Unharnessed, full build-out required
Maturity Level Assessment
In addition to per-layer scores, determine the overall harness maturity level:
| Level | Name | Criteria |
|---|---|---|
| 0 | Unharnessed | No agent config, no structured docs, no architectural documentation |
| 1 | Map | AGENTS.md exists and functions as a TOC, ARCHITECTURE.md present, basic docs/ |
| 2 | Rules | .harness/ specs exist with domain definitions, golden principles, enforcement rules |
| 3 | Feedback | Quality scoring active, doc-gardening and GC processes running, feedback encoding |
| 4 | Autonomy | Worktree isolation, escalation boundaries defined, agent-to-agent review operational |
A repo's maturity level is the highest level where ALL criteria are met. Partial completion of a level means you're "in progress" toward that level.
Report the maturity level in the Agent Readiness Report alongside the layer scores.
Agent Readiness Report Template
# Agent Readiness Report: [repo-name]
## Summary
- **Tech stack**: [languages, frameworks, build tools]
- **Repo size**: [approximate LOC, file count]
- **Overall readiness**: [score] / 5
## Layer Scores
| Layer | Score | Notes |
|-------|-------|-------|
| Knowledge | X/5 | [brief finding] |
| Architecture | X/5 | [brief finding] |
| Enforcement | X/5 | [brief finding] |
| Quality | X/5 | [brief finding] |
| Process | X/5 | [brief finding] |
## Maturity Level
**Current**: Level [X] — [Name]
**Target**: Level [X+1] — [Name]
**Gaps to next level**: [what's missing]
## Key Findings
- [What's working well]
- [What's missing]
- [What's misaligned or stale]
## Recommended Harness Components (prioritized)
1. [Highest impact item]
2. [Next priority]
3. ...
## Domains Identified
- [domain-1]: [brief description, path]
- [domain-2]: [brief description, path]
- ...Update Assessment Additions
When assessing an existing harness, also check:
- Drift: domains.yml domains vs actual directory structure
- Staleness: last_reviewed dates in quality.yml vs current date
- Coverage: new code directories not covered by any domain spec
- Violations: recently added code that breaks principles.yml rules
- Link rot: AGENTS.md and docs/ references that point to moved/deleted files
Report drift as a diff: what the spec says vs what the code shows.
Core Beliefs: Agent-First Operating Principles
This reference provides the template and content guidance for the docs/design-docs/core-beliefs.md file that the harness creates in each repo.
Core beliefs are the design principles that shape how agents make decisions in this specific codebase. They are not generic software principles — they are beliefs about how to build effectively when agents are the primary authors.
The Beliefs
1. Prefer Boring Technology
Technologies described as "boring" tend to be easier for agents to model. Composability, API stability, and broad representation in training data all make a technology more agent-legible. When choosing between a cutting-edge library and a well-established one that does 80% of what you need, prefer the established one.
Why this matters for agents: Agents reason about APIs by pattern-matching against their training data. A library with thousands of Stack Overflow answers and GitHub examples is one the agent can use correctly. A library released last month is one the agent will hallucinate APIs for.
Decision framework:
- Is this technology well-documented and widely used?
- Are its APIs stable across versions?
- Can the agent find correct usage examples in its training data?
- Does it have predictable, composable behavior?
If the answer to most of these is "no," the technology is a legibility risk.
2. Build vs. Buy: The Agent Calculus
In traditional engineering, the calculus is simple: buy (use a library) unless the library doesn't do what you need. With agents, the calculus shifts.
Sometimes it's cheaper to have the agent reimplement a subset of functionality than to work around opaque upstream behavior. The reimplemented version is:
- Tightly integrated with your codebase's patterns (observability, error handling)
- 100% inspectable and modifiable by agents
- Tested exactly the way your codebase expects
- Free of unnecessary complexity from features you don't use
When to reimplement:
- The library is a thin wrapper around simple logic (concurrency helpers,
retry utilities, data transformers)
- You need deep integration with your observability or error handling
- The library's API is unstable or poorly documented
- You only use 10–20% of the library's surface area
When to use the library:
- The library implements complex, well-tested logic (crypto, parsing, protocols)
- Reimplementing would take more than a day of agent time
- The library has a stable, well-documented API
- Multiple domains depend on it (standardization value)
3. Repository-Local Is the Only Real
From the agent's point of view, anything it can't access in-context while running doesn't exist. Knowledge that lives in Google Docs, Slack threads, or people's heads is invisible to the system.
This means:
- Decisions made in meetings must be encoded in docs/ or design-docs/
- Architecture discussions from Slack must become ARCHITECTURE.md updates
- Team conventions must become golden principles or enforcement rules
- External API docs must be copied into docs/references/ in agent-friendly format
The test: if a new agent run starts with zero context beyond the repository, can it make correct decisions? If not, the missing context needs to be encoded.
4. Onboard the Agent Like a New Hire
Giving the agent context means organizing and exposing the right information so it can reason over it, rather than overwhelming it with ad-hoc instructions.
Think about how you'd onboard a new teammate:
- Product principles (what are we building and why)
- Engineering norms (how we write code here)
- Team culture (what we care about, what we tolerate)
- Domain knowledge (how the business works)
All of this should be in the repo. The agent should absorb it the same way a new hire would — by reading the docs, not by asking in Slack.
5. Constraints Enable Speed
In a human-first workflow, strict architectural rules feel pedantic. With agents, they become multipliers. Once encoded, constraints apply everywhere at once. An agent working within well-defined boundaries ships faster than one guessing at boundaries that don't exist.
The right posture: enforce boundaries centrally, allow autonomy locally. Care deeply about what can depend on what, how errors propagate, and where data is validated. Within those boundaries, allow agents significant freedom in how solutions are expressed.
The resulting code may not match human stylistic preferences, and that's okay. As long as the output is correct, maintainable, and legible to future agent runs, it meets the bar.
6. Failure Means Missing Capability, Not Missing Effort
When an agent produces bad output, the fix is almost never "try harder" or "prompt better." It's a signal that something is missing from the environment: a tool, a guardrail, a document, an abstraction.
The diagnostic question: "What capability is missing, and how do we make it both legible and enforceable for the agent?"
Then build that capability — by having the agent write the fix.
Writing Core Beliefs for a Specific Repo
When creating docs/design-docs/core-beliefs.md for a repo:
1. Start with the universal beliefs above, but adapt them to the repo's context 2. Add repo-specific beliefs discovered during assessment (e.g., "We use Zod for all runtime validation" or "We prefer server components over client components") 3. Include concrete examples from the actual codebase 4. Keep to 6–10 beliefs — more than that and they stop being memorable 5. Review and update beliefs when the team's understanding evolves
Each belief should answer: "If an agent is making a decision and could go either way, which way should it go and why?"
Enforcement Layer: Principles, Rules, and Taste
This reference covers golden principles, mechanical enforcement rules, and patterns for encoding taste into the codebase.
Golden Principles
Golden principles are opinionated rules that keep a codebase coherent for agents. They are specific to each repo — not generic best practices. The key insight: agents replicate patterns they see. If the codebase has drift, agents amplify it. Principles arrest this entropy.
Principle Catalogue
These are starting points. Adapt to the specific repo's needs and challenges.
Parse, Don't Validate
Rule: Transform data at system boundaries into typed structures immediately. Don't pass raw data through and validate later.
Why: When raw data flows through multiple layers, agents add ad-hoc validation everywhere. Parsing at boundaries centralizes this — agents downstream can trust the types.
Enforcement: lint / structural test Severity: error
Shared Utilities Over Hand-Rolled Helpers
Rule: Use shared utility packages for common operations. Don't write one-off helpers that duplicate logic.
Why: Agents copy patterns they find. Scattered helpers breed more scattered helpers. Centralized utilities mean agents use the right pattern by default.
Enforcement: review / structural test Severity: warning
No YOLO Data
Rule: Don't probe data shapes speculatively. Validate at boundaries or use typed SDKs so code never builds on guessed shapes.
Why: Agents are confident about code they generate, even when it's based on incorrect assumptions about data shapes. Typed boundaries catch this.
Enforcement: lint Severity: error
Explicit Error Boundaries
Rule: Define where errors are caught and how they're reported. Don't let exceptions propagate implicitly through multiple layers.
Why: Agents add try/catch blocks wherever they see potential errors. Without clear boundaries, error handling becomes inconsistent and redundant.
Enforcement: review Severity: warning
Single Source of Truth for Configuration
Rule: Each configuration value has exactly one canonical source. No duplicated env vars, no hardcoded values that should be in config.
Why: Agents pull configuration from wherever they find it first. If the same value exists in three places, agents will read from the wrong one.
Enforcement: lint / structural test Severity: error
Structured Logging Everywhere
Rule: Use the project's structured logger. No ad-hoc console.log, print, or fmt.Println for operational output.
Why: Structured logs are queryable. Agents that emit unstructured logs create blind spots in observability. When agents can query their own logs, they can self-diagnose issues.
Enforcement: lint Severity: error
Writing Principles for a Specific Repo
When creating principles for a repo:
1. Start from the assessment — What patterns are already causing problems? What invariants are maintained manually but should be enforced? 2. Be specific — "Write clean code" is useless. "All API responses must use ResponseEnvelope<T> from src/shared/types/response.ts" is actionable. 3. Explain the agent angle — Why does this principle matter specifically in an agent-driven codebase? What goes wrong when agents ignore it? 4. Include examples from the actual codebase — Real code > hypothetical code. 5. Keep to 5–10 — Too many principles become non-guidance. Prioritize the ones that would cause the most damage if violated.
Mechanical Enforcement Rules
These are concrete rules that tooling can check automatically.
Naming Conventions
Define patterns per entity type. Adapt to the language ecosystem:
| Entity | TypeScript | Python | Swift | Go |
|---|---|---|---|---|
| Files | kebab-case | snake_case | PascalCase | snake_case |
| Types/Classes | PascalCase | PascalCase | PascalCase | PascalCase |
| Functions | camelCase | snake_case | camelCase | PascalCase (exported) |
| Constants | SCREAMING_SNAKE | SCREAMING_SNAKE | camelCase | PascalCase |
| Schemas | PascalCase + Schema suffix | PascalCase + Schema suffix | — | — |
Include exceptions for conventional files: README.md, AGENTS.md, Makefile, etc.
File Limits
- Max lines per file: 300–500 depending on language (smaller for scripts,
larger for generated code)
- Max functions per file: 10–15
- Max cyclomatic complexity: Per-function threshold (e.g., 10)
These limits prevent the accumulation of god-files that agents can't reason about in context.
Import Rules
- Boundary checking: Enforce the forward-only dependency rule from domains.yml
- External dependency limits: Cap how many external packages a single module
can import (prevents kitchen-sink dependencies)
- Banned imports: Explicitly list patterns that should never be used
(e.g., importing internals from another domain)
Test Requirements
- Boundary tests required: System boundaries (API endpoints, database access,
external service calls) must have test coverage
- Coverage targets for new code: Typically 80%+ for new code, tracking overall
trends rather than enforcing a global minimum
- Test naming conventions: Consistent naming helps agents find and understand
existing tests
Agent-Legible Error Messages
This is one of the most impactful and least obvious patterns in the article. When enforcement rules fire, the error messages should be written for agents to read and act on — not just for humans to squint at.
A human sees a lint error and knows from experience what to do. An agent sees a lint error and needs the error message itself to contain enough context to fix the issue without consulting any other document.
Pattern: Remediation-Rich Error Messages
Every custom lint or structural check should include: 1. What's wrong — the specific violation 2. Why it matters — brief rationale (link to principle if applicable) 3. How to fix it — concrete remediation steps 4. Where to look — file paths or documentation pointers
Example
Bad error message:
Error: Boundary violation in billing/service.tsGood error message:
Error: Boundary violation — billing/service.ts imports from auth/repo.ts
The forward-only dependency rule prohibits Service from importing Repo of
another domain. Cross-cutting concerns must enter through Providers.
To fix: inject the auth dependency via the billing Providers interface.
See: ARCHITECTURE.md#cross-cutting-concerns, .harness/domains.ymlIn .harness/enforcement.yml
When defining enforcement rules, include a message_template field that the tooling can use to generate agent-legible error messages:
imports:
boundary_check: true
violation_message: |
Boundary violation — {{source_file}} imports from {{target_file}}.
The {{rule_name}} rule prohibits {{source_layer}} from importing
{{target_layer}} of another domain.
To fix: {{remediation}}
See: ARCHITECTURE.md#cross-cutting-concerns, .harness/domains.ymlThis pattern extends to all enforcement: naming violations should suggest the correct name, file size violations should suggest how to split, logging violations should show the correct structured logging call.
CI Integration Patterns
The harness specs become most valuable when CI enforces them:
1. Knowledge freshness check: CI job validates that AGENTS.md references point to real files, docs/ cross-links resolve, and generated docs are current 2. Architecture boundary check: Validate import patterns against domains.yml layer rules 3. Principle compliance: Run linters/checks for each enforceable principle 4. Quality review reminder: Flag domains whose quality.yml scores haven't been reviewed within the configured cadence
These CI jobs can be implemented incrementally. Start with knowledge freshness (cheapest to implement, high impact) and add architectural checks as the tooling matures.
Knowledge Layer: AGENTS.md, docs/, ARCHITECTURE.md
This reference provides templates and writing guidance for the knowledge artifacts that give agents a map of the codebase.
AGENTS.md Writing Guide
Philosophy
AGENTS.md is a table of contents, not an encyclopedia. When everything is "important," nothing is. A giant instruction file crowds out the task, the code, and the relevant docs — agents end up pattern-matching locally instead of navigating intentionally.
A good AGENTS.md:
- Fits in ~100 lines
- States the 3–5 rules that cause the most damage when violated
- Points to deeper sources of truth (never duplicates them)
- Tells agents where to look, not what to know
- Includes verification commands (build, test, lint)
AGENTS.md Template
# [Project Name] — Agent Guide
[1–2 sentences: what this project is and its primary purpose.]
## Non-Negotiable Rules
[3–5 rules. These are the ones that, if violated, cause real damage.
Be specific. Don't list general best practices — list THIS repo's critical
invariants.]
1. [Rule 1 — specific to this repo]
2. [Rule 2]
3. [Rule 3]
## Repository Map
- `ARCHITECTURE.md` — Domain boundaries, dependency rules, module map
- `docs/design-docs/` — Design history and decisions (see `docs/design-docs/index.md`)
- `docs/exec-plans/active/` — Work in progress
- `docs/product-specs/` — Feature specifications (see `docs/product-specs/index.md`)
- `docs/references/` — External documentation in agent-friendly format
- `.harness/` — Machine-readable harness configuration (domains, principles, rules)
## Tech Stack
[Brief: languages, frameworks, build system, key dependencies]
## Verification
Run these before marking work complete:
[Exact commands with working directory context]
## Code Organization
[Brief description of how the codebase is organized — domain structure,
key directories, where new code goes. 5–10 lines max.]Common Mistakes
- Too long: If AGENTS.md exceeds 120 lines, refactor into docs/ with pointers
- Duplicating docs/: AGENTS.md points to docs, it doesn't repeat them
- Generic rules: "Write clean code" is useless. "All API responses must use the
ResponseEnvelope type from src/shared/types" is actionable
- Stale references: Every path in AGENTS.md must point to a real file
- Missing verification: Agents need to know how to check their own work
Progressive Disclosure: The Structural Principle
Progressive disclosure isn't just a property of AGENTS.md — it's the design principle for every document in the harness. Agents start with a small, stable entry point and are taught where to look next, rather than being overwhelmed.
Without this, the harness recreates the "one big AGENTS.md" problem at the file level — each doc becomes a wall of text that agents load entirely into context.
Structure Every Doc in Three Tiers
Tier 1 — Summary (2–3 sentences at the top) Enough for an agent to decide: "Is this file relevant to my current task?" If not, the agent stops reading here and moves on.
Tier 2 — Key Decisions (the 3–5 most important things) The rules, patterns, or facts that agents need most often. These should be scannable — tables, short lists, or bold callouts.
Tier 3 — Full Detail Complete explanations, examples, edge cases, historical context. Agents read this only when working deeply in this area.
Example: A Domain Guide
# Billing Domain Guide
Billing handles subscription management and payment processing via Stripe.
All payment operations go through the BillingService — never call Stripe
directly from other domains.
## Key Rules
- All money amounts use `Money` type from `src/billing/types` (never raw numbers)
- Webhook handlers must be idempotent (Stripe retries on failure)
- Payment state transitions must be persisted before acknowledging the webhook
## Architecture
[Detailed layer breakdown...]
## Stripe Integration
[API patterns, error handling, testing with test clocks...]How This Applies Across the Harness
| Artifact | Tier 1 | Tier 2 | Tier 3 |
|---|---|---|---|
| AGENTS.md | What the repo is | Non-negotiable rules | Pointers to docs/ |
| ARCHITECTURE.md | Architectural philosophy | Domain map + dependency rules | Per-domain detail |
| docs/\<DOMAIN\>.md | What the domain does | Key rules and patterns | Full implementation guide |
| design-docs/index.md | Purpose of design docs | Status table of all docs | Verification notes |
| exec-plans/active/*.md | Purpose of the plan | Progress + next steps | Full milestones + history |
docs/ Structure Guide
design-docs/
index.md — Catalogue of all design documents with:
- Title and one-line description
- Status: draft, accepted, superseded, deprecated
- Verification status: verified against current code, unverified, stale
- Date and author
core-beliefs.md — Agent-first operating principles for this specific repo. Not generic software principles — beliefs that shape how agents should make decisions in THIS codebase. Examples:
- "We prefer boring, well-documented technologies over cutting-edge ones because
agents reason better about APIs with extensive training data."
- "We reimplement small utilities rather than pulling in large opaque dependencies
because agents need to inspect and modify the full dependency surface."
exec-plans/
Follow the ExecPlan format defined in PLANS.md (if the repo has one) or use this minimal structure:
active/ — Plans for in-flight work. Each plan is a living document with progress tracking, decision logs, and acceptance criteria.
completed/ — Finished plans kept for context. Future agents use these to understand why the codebase looks the way it does.
tech-debt-tracker.md — Known technical debt with priority, impact, and estimated effort. Updated as debt is discovered or resolved.
product-specs/
index.md — Feature catalogue mapping user-facing features to:
- The spec document
- The primary code path / domain
- Current status (planned, in-progress, shipped)
\<feature\>.md — Each spec describes what the user can do (acceptance criteria), not how the code works. Implementation details belong in the code and design docs.
references/
External documentation converted to agent-friendly format. When the repo depends on a library or service whose docs are not in the training data (or are newer than the training cutoff), include the relevant portions here.
Name files descriptively: nextjs-app-router.md, stripe-webhooks.md, internal-auth-api.md.
Domain guides (docs/\<DOMAIN\>.md)
Create these only when a domain needs guidance beyond what ARCHITECTURE.md and the domain's code structure convey. Common examples:
FRONTEND.md— Component patterns, state management, design system usageDESIGN.md— Design system reference, tokens, component APIRELIABILITY.md— SLOs, retry patterns, circuit breaker configurationSECURITY.md— Threat model, auth boundaries, data classificationPLANS.md— ExecPlan template and maintenance rules
Each guide should be self-contained enough that an agent reading it can make correct decisions in that domain without additional context.
ARCHITECTURE.md Template
# Architecture
[2–3 sentences: architectural philosophy and primary constraints.]
## Domain Map
[Table or diagram showing the major domains and their relationships.]
| Domain | Path | Description | Key dependencies |
|--------|------|-------------|-----------------|
| [name] | [path] | [what it does] | [what it depends on] |
## Dependency Rules
[Explain the dependency direction rules. Which layers exist, what can
import what, where cross-cutting concerns enter.]
## Cross-Cutting Concerns
| Concern | Entry point | Used by |
|---------|------------|---------|
| [auth] | [providers/auth] | [all domains] |
| [telemetry] | [providers/telemetry] | [all domains] |
## Where New Code Goes
[Decision guide: given a new feature or change, how to determine which
domain it belongs to and which layer to put it in.]
## Key Interfaces
[List the 3–5 most important interfaces/types that bridge domains.
Name them by full path so agents can find them.]Process Patterns
Patterns that keep a harness-driven codebase healthy over time. These go into the appropriate docs/ guide files during Phase 7.
Doc-Gardening
Documentation rots. In an agent-driven codebase, stale docs are worse than no docs — agents follow incorrect instructions with confidence.
Pattern: Recurring Doc Scan
Set up a background task (agent or CI job) that periodically: 1. Checks every file path referenced in AGENTS.md and docs/ — flags broken links 2. Compares generated/ docs against the current schema/API — flags drift 3. Reviews exec-plans/active/ for plans that haven't been updated recently 4. Scans for TODO/FIXME comments older than a threshold 5. Opens targeted fix-up PRs for issues it can resolve
Guidelines
- Fix stale docs immediately when discovered during other work
- Treat docs as code: review them in PRs, test links in CI
- Prefer deleting wrong docs over leaving them — no docs is better than misleading docs
- When a doc is updated, check its cross-links and update them too
Garbage Collection
Agent-generated code accumulates entropy. Agents replicate patterns — including uneven or suboptimal ones. Without active cleanup, quality degrades.
Pattern: Golden-Principle Sweep
On a regular cadence (daily or weekly): 1. Scan the codebase for deviations from .harness/principles.yml 2. Grade domains against .harness/quality.yml and compare to last scores 3. Identify duplicated utility code that should be consolidated 4. Open targeted refactoring PRs (small, reviewable, automerge-able)
The "AI Slop" Problem
The source article describes spending 20% of engineering time cleaning up agent output. The solution: encode cleanup rules as principles and automate the sweep.
Signals to watch for:
- Hand-rolled helpers that duplicate shared utilities
- Inconsistent error handling patterns across domains
- Test files that test implementation details rather than behavior
- Overly defensive code (try/catch everywhere, redundant null checks)
- Dead code or unused imports accumulating
Guidelines
- Treat tech debt like a high-interest loan: pay continuously, not in bursts
- Small, frequent cleanup PRs > large periodic refactors
- Capture each new anti-pattern as a principle when first identified
- Track cleanup progress in quality.yml scores
Agent-to-Agent Review
As throughput increases, human review capacity becomes the bottleneck. Agent review offloads mechanical checks while preserving human judgment for decisions.
Pattern: Layered Review
1. Self-review: Agent reviews its own changes locally before opening a PR (check against principles, run tests, validate boundaries) 2. Agent review: A separate agent run reviews the PR against the harness specs (architecture, naming, principles, quality) 3. Human review: Humans review for judgment calls — business logic correctness, product sense, architectural direction 4. Iterate: Agent responds to all feedback and re-runs validation until clean
Guidelines
- Agent review checks mechanical things: boundary violations, naming, principles
- Human review focuses on: correctness, product alignment, taste
- Over time, push more mechanical review to agents, reserve humans for judgment
- Capture review feedback as principle updates or doc improvements
Merge Philosophy
In a high-throughput agent environment, conventional merge gates become counterproductive.
Principles
- Short-lived PRs: Changes should be small and merge quickly
- Follow-up fixes over blocking: If a non-critical issue is found post-merge,
a follow-up PR is often cheaper than blocking the original
- Test flake tolerance: Address flakes with follow-up runs rather than blocking
progress indefinitely
- Corrections are cheap, waiting is expensive: In a system where agent
throughput exceeds human attention, fast iteration with fast correction outperforms slow, perfect merges
When to Block
- Security-sensitive changes
- Breaking changes to public API contracts
- Changes that cross multiple domain boundaries
- Anything that affects data persistence or migration
Feedback Encoding
Every bug, review comment, and user complaint is a signal. The harness should capture these signals so they compound.
Pattern: Signal → Rule Pipeline
1. Bug discovered or review feedback given 2. Determine: is this a one-off or a systemic pattern? 3. If systemic: add a principle to principles.yml, add a check to enforcement.yml, or update the relevant docs/ guide 4. If one-off: fix it and move on
Guidelines
- When documentation falls short, promote the rule into code (lint, test, CI check)
- Capture the "why" alongside the "what" — principles without rationale get ignored
- Review feedback that keeps recurring = missing or unclear principle
The "Promote to Code" Escalation Ladder
Knowledge in a harness-driven codebase has a natural escalation path. Each level is more expensive to create but more reliable at preventing violations. When a rule at one level keeps failing, promote it to the next.
Level 1: Tacit knowledge → Lives in people's heads. Invisible to agents.
Level 2: Documentation → Written in docs/. Agents can read it but may ignore it.
Level 3: Golden principle → In principles.yml. Agents are told it matters, with rationale.
Level 4: Mechanical lint → In enforcement.yml. Tooling flags violations automatically.
Level 5: Structural test → Tests that verify architectural invariants at build time.
Level 6: CI gate → Blocks merge until the rule is satisfied. Cannot be bypassed.When to Promote
- Level 1 → 2: When the same question gets asked twice. If two different
agent runs make the same mistake because the knowledge was tacit, write it down.
- Level 2 → 3: When documentation exists but agents still violate it. The
principle format (rule + rationale + examples) is more legible than prose.
- Level 3 → 4: When a principle is violated regularly despite being documented.
Mechanical checking catches violations before they reach review.
- Level 4 → 5: When lint rules alone aren't sufficient — the violation is
structural (e.g., dependency direction) rather than syntactic.
- Level 5 → 6: When a structural test exists but violations still slip through
because the test isn't run before merge. Make it a blocking gate.
When NOT to Promote
- Don't promote taste to a lint. "This code doesn't feel right" is a review
comment, not an enforceable rule.
- Don't promote to a CI gate unless the rule is unambiguous and the check is
reliable. Flaky gates erode trust faster than they prevent violations.
- Don't skip levels. A rule that jumps from tacit to CI gate is brittle because
nobody documented the rationale, so nobody knows when to change it.
Escalation Boundaries
Define what decisions require human judgment vs. what agents can resolve autonomously. Without clear boundaries, agents either ask too much (blocking throughput) or too little (making dangerous decisions silently).
Pattern: Decision Classification
Classify decisions into three categories and document them in the process guide:
Agent-autonomous (proceed without asking):
- Code changes within a single domain that pass all tests
- Documentation updates that correct factual errors
- Dependency version bumps that pass CI
- Refactoring that doesn't change behavior
- Responding to review feedback with code changes
Agent-with-notification (proceed but tell a human):
- Changes that touch multiple domains
- New external dependencies
- Performance-sensitive code changes
- Changes to .harness/ configuration
- Quality score changes (upgrades or downgrades)
Human-required (stop and ask):
- Changes to public API contracts or persisted formats
- Security-sensitive changes (auth, encryption, access control)
- Architectural changes that affect domain boundaries
- Deleting or deprecating features
- Changes to escalation boundaries themselves
How to Document
Add an escalation section to .harness/config.yml:
escalation:
autonomous:
- single_domain_changes
- doc_corrections
- dependency_bumps
- refactoring
- review_response
notify:
- cross_domain_changes
- new_dependencies
- performance_sensitive
- harness_config_changes
human_required:
- public_api_changes
- security_changes
- architectural_changes
- feature_deprecation
- escalation_boundary_changesRevisit these boundaries as the harness matures. What starts as human-required at Level 2 maturity may become agent-autonomous at Level 4.
Quality Scoring
Quality scoring gives agents and humans a shared understanding of where each domain stands and where investment is needed. Scores are a baseline for tracking improvement, not a judgment.
Dimensions
Grade each domain across these six dimensions:
| Dimension | What it measures |
|---|---|
| Code quality | Clarity, consistency, adherence to principles, absence of code smells |
| Test coverage | Meaningful test coverage (not just line coverage — boundary and behavior tests) |
| Documentation | Accuracy and completeness of domain-specific docs, inline comments where needed |
| Observability | Structured logging, metrics, tracing, error reporting |
| Reliability | Error handling, retry logic, graceful degradation, edge case coverage |
| Security | Input validation, auth boundaries, data classification, secret handling |
Grading Scale
| Grade | Meaning | Description |
|---|---|---|
| A | Exemplary | Fully harnessed. Principles followed, tests comprehensive, docs current, observable. |
| B | Good | Solid foundation. Minor gaps that don't affect agent effectiveness. |
| C | Adequate | Functional but with notable gaps. Agents can work here but may stumble. |
| D | Weak | Significant gaps. Agents will likely produce inconsistent results in this domain. |
| F | Missing/broken | No meaningful coverage in this dimension. Agents are flying blind. |
How to Score
During assessment, evaluate each dimension for each domain by examining:
1. Code quality: Read 2–3 representative files. Check principle adherence, naming consistency, file organization. Look for god-files, duplicated logic, or inconsistent patterns.
2. Test coverage: Check test files exist, tests are meaningful (not just snapshot tests of implementation details), boundary tests are present. If coverage metrics are available, note them.
3. Documentation: Does the domain have relevant docs/ entries? Are they current? Would an agent understand the domain by reading ARCHITECTURE.md + the domain's docs?
4. Observability: Is logging structured? Are there metrics for key operations? Can an agent query logs to understand what happened? Are errors reported with enough context to diagnose?
5. Reliability: Are error paths handled? Are retries configured for external calls? Are timeouts set? Does the domain degrade gracefully?
6. Security: Are inputs validated at boundaries? Are auth checks present? Is sensitive data classified and handled appropriately? Are secrets managed through config, not hardcoded?
Gap Tracking
For each grade below B, note the specific gaps:
- What's missing or broken
- Impact on agent effectiveness
- Suggested remediation (if obvious)
Gaps feed directly into the garbage collection and doc-gardening patterns. They also inform which follow-up exec-plans to create.
Review Cadence
Quality scores go stale. Set a review cadence based on the repo's change velocity:
| Change velocity | Suggested cadence |
|---|---|
| High (daily deploys) | Monthly review |
| Medium (weekly deploys) | Quarterly review |
| Low (occasional releases) | Semi-annual review |
Track last_reviewed per domain in quality.yml. The harness update flow uses this to flag domains that are overdue for review.
Scoring New Domains
When a new domain is identified (either during initial assessment or during an update), score all dimensions immediately — even if the scores are low. Having explicit D or F grades is better than having no entry, because it makes the gap visible and trackable.
.harness/ YAML Schemas
All machine-readable harness configuration lives in .harness/ at the repo root. This reference defines the schema for each file with examples.
config.yml
Top-level harness metadata.
version: "1.0"
name: "my-project"
created: "2026-03-17"
updated: "2026-03-17"
tech_stack:
languages:
- typescript
- python
frameworks:
- next.js
- fastapi
build:
- turborepo
- poetry
test:
- vitest
- pytest
harness_components:
- knowledge
- architecture
- enforcement
- quality
- processFields:
version: Schema version (currently "1.0")name: Repository/project namecreated/updated: ISO datestech_stack: Detected or declared technology stackharness_components: Which harness layers are active
domains.yml
Business domain definitions with layer rules. Each domain is a vertical slice — a tracer bullet that owns a complete path from data types to user-facing output. Domains are NEVER horizontal technical layers (controllers, utils, tooling). See references/architecture-layer.md for the full identification guide.
version: "1.0"
layer_order:
- types
- config
- repo
- service
- runtime
- ui
dependency_rule: forward_only
cross_cutting:
- name: auth
description: Authentication and authorization
entry_point: providers
- name: telemetry
description: Logging, metrics, and tracing
entry_point: providers
- name: feature-flags
description: Feature flag evaluation
entry_point: providers
domains:
- name: billing
description: Subscription management and payment processing
path: src/billing
layers:
types: src/billing/types
config: src/billing/config
repo: src/billing/repo
service: src/billing/service
runtime: src/billing/runtime
ui: src/billing/ui
providers:
- auth
- telemetry
- name: onboarding
description: New user registration and setup flow
path: src/onboarding
layers:
types: src/onboarding/types
service: src/onboarding/service
ui: src/onboarding/ui
providers:
- auth
- telemetry
- feature-flagsFields:
layer_order: The canonical layer sequence for this repodependency_rule:forward_onlymeans imports go left-to-right onlycross_cutting: Shared concerns with their domain entry pointdomains[]: Each domain with its path, active layers, and consumed providersdomains[].layers: Only list layers that actually exist in the codebase
harness-spec.yml (v2 — domain-oriented)
For repos with a harness tool that enforces architecture via graph analysis, the v2 spec format replaces the flat layer list with a layer_model × domain expansion. Declare the layer model once; each domain is 3-4 lines.
version: 2
layer_model:
order: [Types, Config, Repo, Service, Runtime, UI]
Types:
contains: [DataType, Extension] # What node kinds belong here
extra_imports: [Foundation] # Always-allowed imports
Config:
contains: [DependencyClient, DataType, Extension]
extra_imports: [Foundation, Providers, ComposableArchitecture, Dependencies]
forbidden_imports: [SwiftUI] # Never allowed in this layer
Service:
contains: [Extension]
extra_imports: [Foundation]
skip_layers: [Repo] # Service skips Repo in the import chain
forbidden_imports: [SwiftUI, ComposableArchitecture]
forbidden_attributes: ["@State", "@Reducer"]
Runtime:
contains: [Reducer]
extra_imports: [Foundation, Providers, ComposableArchitecture, Dependencies, IssueReporting]
forbidden_imports: [SwiftUI]
UI:
contains: [View, ViewModifier, Preview]
extra_imports: [Foundation, SwiftUI, ComposableArchitecture]
skip_layers: [Repo, Service] # UI only imports Runtime
forbidden_attributes: ["@Reducer"]
cross_domain:
public_layers: [Types, Config] # Other domains can only reach these
app_visible: [UI] # App targets can only import these + foundation
domains:
billing:
path: Domains/Billing
prefix: Billing # Module names: BillingTypes, BillingConfig, etc.
auth:
path: Domains/Auth
prefix: Auth
extra_imports: # Per-layer domain-specific imports
Repo: [AuthenticationServices]
UI: [AuthenticationServices]
onboarding:
path: Domains/Onboarding
prefix: Onboarding
layers: [Types, Config, Service, UI] # No Repo, no Runtime
foundation:
packages:
providers:
classification: cross_cutting # cross_cutting | shared | app | backend
path: "Providers/Sources/Providers/"
allowed_imports: [Foundation, Utils]
forbidden_imports: [SwiftUI]
types:
classification: shared
path: "Types/"
bridges: [Infra, Utils, DomainModels] # Legacy modules being eliminated
allows: # Cross-domain exceptions with expiry
- from: Calendar
to: Appointments
layers: [Types, Config]
reason: "Calendar needs appointment time slots"
ticket: "PROJ-42"
expires: "2027-01-01"
naming:
forbidden_prefixes:
Types: [Clinic]
directory_suggestions:
"Live": "Repo"Key fields:
layer_model.order: Canonical layer sequence. The tool computes allowed_imports per domain.layer_model.<Layer>.skip_layers: Layers this layer does NOT import (e.g., UI skips Repo+Service)domains.<key>.prefix: Module naming prefix.BillingTypes,BillingConfig, etc.domains.<key>.layers: Subset oforder; omit for all layersdomains.<key>.extra_imports: Per-layer imports beyond the template (e.g., AuthenticationServices)domains.<key>.source_dir_style:"prefixed"forSources/PrefixTypes/instead ofSources/Types/cross_domain.public_layers: Which layers of a domain are visible to other domainscross_domain.app_visible: Which domain layers app targets can importfoundation.packages.<key>.classification: Determines how the module is classified in the graphallows[]: Time-bounded cross-domain exceptions with reason, ticket, and expiry
Expansion: The tool computes allowed_imports and forbidden_imports for each domain layer from the template. Adding a new domain = adding 3-4 lines of YAML.
principles.yml
Golden principles with rationale and enforcement guidance.
version: "1.0"
principles:
- id: parse-at-boundaries
name: Parse data shapes at system boundaries
description: >
Transform raw data into typed structures at the point of entry.
Don't pass untyped data through and validate later.
rationale: >
Without boundary parsing, agents add ad-hoc validation everywhere.
Typed structures from the boundary forward let agents trust the types.
enforcement: lint
severity: error
examples:
good: |
// API route handler
const order = OrderSchema.parse(req.body);
await processOrder(order); // order is typed
bad: |
// API route handler
const data = req.body;
if (data.items && Array.isArray(data.items)) {
await processOrder(data); // data is untyped
}
- id: shared-utils
name: Shared utilities over hand-rolled helpers
description: >
Common operations belong in shared utility packages, not scattered
across domains as one-off helpers.
rationale: >
Agents replicate patterns they find. Scattered helpers breed more
scattered helpers. Centralized utilities are used by default.
enforcement: review
severity: warning
examples:
good: |
import { mapWithConcurrency } from '@/shared/async';
const results = await mapWithConcurrency(items, processItem, { limit: 5 });
bad: |
// billing/utils.ts
async function processBatch(items, fn, concurrency) {
// hand-rolled concurrency logic duplicating shared/async
}Fields:
id: Kebab-case identifiername: Human-readable namedescription: What the rule isrationale: Why it matters in an agent-driven codebaseenforcement: How it's checked —lint,test,review,ci, ormanualseverity:error(must fix),warning(should fix),info(advisory)examples: Concrete good/bad code from the actual codebase when possible
enforcement.yml
Mechanical rules that tooling can check automatically.
version: "1.0"
naming:
files:
pattern: kebab-case
exceptions:
- AGENTS.md
- ARCHITECTURE.md
- README.md
- PLANS.md
- Makefile
- Dockerfile
types:
pattern: PascalCase
functions:
pattern: camelCase
constants:
pattern: SCREAMING_SNAKE_CASE
schemas:
pattern: PascalCase
suffix: Schema
file_limits:
max_lines: 500
max_functions_per_file: 15
max_complexity_per_function: 10
logging:
style: structured
required_fields:
- level
- message
- timestamp
prohibited_patterns:
- console.log
- console.warn
- console.error
imports:
boundary_check: true
max_external_deps_per_module: 10
banned_patterns:
- "../../**/internal"
- "../../../"
testing:
boundary_testing_required: true
min_coverage_new_code: 80
naming_pattern: "*.test.ts"
co_located: trueFields:
naming: Conventions per entity type with exceptionsfile_limits: Size and complexity limitslogging: Structured logging requirementsimports: Dependency rules and banned patternstesting: Coverage and test organization rules
quality.yml
Per-domain quality grades.
version: "1.0"
scale:
- A
- B
- C
- D
- F
dimensions:
- code_quality
- test_coverage
- documentation
- observability
- reliability
- security
review_cadence: monthly
domains:
billing:
scores:
code_quality: B
test_coverage: C
documentation: D
observability: F
reliability: B
security: B
gaps:
- "No structured logging in payment webhook handlers"
- "Missing retry logic for payment provider timeouts"
- "Domain docs not yet written"
notes: "Payment v2 migration in progress — scores will shift after completion"
last_reviewed: "2026-03-17"
onboarding:
scores:
code_quality: A
test_coverage: B
documentation: B
observability: C
reliability: C
security: A
gaps:
- "Metrics not wired for funnel drop-off tracking"
- "No circuit breaker on email service calls"
notes: "Recently refactored — quality is high"
last_reviewed: "2026-03-17"Fields:
scale: The grading scale (A–F)dimensions: What to gradereview_cadence: How often to re-evaluate (daily, weekly, monthly, quarterly)domains[]: Each domain with scores, gaps, notes, and review date
knowledge.yml
Configuration for the knowledge base structure.
version: "1.0"
agents_md:
style: toc
max_lines: 100
docs_structure:
design_docs:
enabled: true
index: true
core_beliefs: true
exec_plans:
enabled: true
sections:
- active
- completed
- tech_debt
template_path: PLANS.md
product_specs:
enabled: true
index: true
references:
enabled: true
generated:
enabled: false
guides:
- name: FRONTEND
path: docs/FRONTEND.md
description: Frontend architecture and component patterns
- name: RELIABILITY
path: docs/RELIABILITY.md
description: Reliability engineering and SLOs
- name: SECURITY
path: docs/SECURITY.md
description: Security model and threat boundariesFields:
agents_md: AGENTS.md configuration (style and size constraint)docs_structure: Which docs/ sections are enabledguides[]: Domain-specific guide files to create/maintain
Related skills
FAQ
What does harness-engineering do?
harness-engineering: A skill for development. This provides functionality for development workflows.
When should I use harness-engineering?
When you need to use harness-engineering for development tasks, or when harness-engineering: a skill for development. this provides functionality for development workflows.
What are the main capabilities?
harness-engineering.