Study Notes / 2026 ・ No.06

Vibe Coding Field Notes

What goes beyond AGENTS.md on a larger system

Published

Questions for this issue

Q1Besides AGENTS.md, what do you need? Q2Where do specs and rule sets live, and how do you run them? Q3What is today's best practice for a mid-sized web system?

The short answer: split specs, rules and verification, and give each its own files and tooling

Last time covered AGENTS.md, the house rules you hand to an agent.
But building a business system with dozens of screens alongside AI takes more than that.
Using an order-management system as the example, here is what goes where, and how to proceed.

1

Where vibe coding stands

CORE

Andrej Karpathy coined “vibe coding” in February 2025. The original definition was to “fully give in to the vibes… and forget that the code even exists”, and he pitched it for throwaway projects and demos.

A year later, in February 2026, Karpathy gave the professional version a different name: agentic engineering. You write the code yourself perhaps 1% of the time, orchestrating agents who do the rest and acting as oversight; “engineering” because there is art, science and expertise to it. In practice, “vibe coding” increasingly means this, and that is the sense used here.

The data shows why the oversight matters.

StudyFinding
METR
(Jul 2025)
In a randomised trial with 16 experienced open-source developers, AI tools made tasks take 19% longer, while the developers felt faster
Veracode
(Mar 2026)
Across 150+ models, only 55% of generated code passed security tests. Syntax correctness is above 95%, yet security has barely moved since 2025. XSS defences passed just 15% of the time

AI now writes code that runs remarkably well. But whether it matches the right spec, whether it is safe, and whether it contradicts earlier decisions is not guaranteed unless you make it so. The bigger the system, the more that gap costs.

2

What you need beyond AGENTS.md — Q1

WHAT

AGENTS.md holds the rules read every session. Since it has to stay short, everything else lives somewhere else. Three things are missing: what to build (specs), how to work in each area (area rules and playbooks), and tooling that checks the work is done.

WhatContentsExample
SpecPer feature: purpose, out of scope, acceptance criteriaspecs/012-order-approval/spec.md
Plan, tasksHow to build it, and in what orderplan.md, tasks.md
ADRDecisions and the reasons for themdocs/adr/0007-approval-state.md
Product notesWhy the system exists, glossary, overall architecturedocs/product.md, architecture.md
Area rulesRules that apply only to the API, UI, database….claude/rules/api.md
Skills (playbooks)Steps for recurring workStarting a new feature, releasing
VerificationTests, types, lint, E2E, CI, hooksLint on every save, CI on every PR
ConnectionsLetting the AI reach the database, tickets, a browserMCP servers

The point is that each is read at a different moment. Cram it all into AGENTS.md and the agent reads everything every time, which, as last issue's research showed, makes results worse.

When each thing is read

Every session AGENTS.md When files match Rule: API Rule: DB When needed Spec, plan, ADR Skills Always runs Hooks CI, tests Context (a request) Tooling (enforced)

The top three rows are requests and can be ignored. Only the bottom row is guaranteed

3

Spec-driven development

SDD

The prevailing approach is spec-driven development. Before any code is written, you document what to build (spec) → how to build it (plan) → the work breakdown (tasks), and a person checks each before implementation begins.

The tooling has matured. Two representative examples:

GitHub Spec KitKiro (AWS)
FormOpen-source CLI plus commands for each agent; works with 30+ agents (v1.0 in 2026)An IDE with specs built in
Documentsconstitution.md (principles), spec.md, plan.md, tasks.md, plus research.md, data-model.md, contracts/ as neededrequirements.md (or bugfix.md), design.md, tasks.md
Locationspecs/NNN-feature/.kiro/specs/feature/
Flowconstitution → specify → clarify → plan → tasks → analyze → implementStart from requirements or from design

The names differ; the substance is almost identical: three documents, spec, plan and tasks, in a folder per feature, with a person checking each stage. Two points matter most.

  • Include a stage where the AI asks questions — like Spec Kit's clarify, have the AI read the draft spec and list what is still undecided. A hole in the spec costs more the later it turns up
  • One spec per feature — Kiro's own guidance is to split by feature (authentication, product catalogue, cart…) rather than write one monolith. The smaller each one, the more likely both AI and humans actually read all of it

You don't need the tools: the same folders and Markdown files made by hand work with any agent. The layout in the next chapter is tool-agnostic.

4

Where the files go — Q2

Take an internal order-management system: around 30 screens, a front end, an API and a database, used by purchasing, sales and finance. The repository is laid out like this:

order-system/ ├─ AGENTS.md ← house rules (under 100 lines) ├─ CLAUDE.md ← just "@AGENTS.md" ├─ docs/ │ ├─ product.md ← what it's for, glossary │ ├─ architecture.md ← structure and layer boundaries │ └─ adr/ │ ├─ 0001-use-postgresql.md │ └─ 0007-approval-state.md ├─ specs/ │ ├─ 012-order-approval/ │ │ ├─ spec.md ← what and why (acceptance) │ │ ├─ plan.md ← how │ │ └─ tasks.md ← breakdown and progress │ └─ 013-invoice-export/ ├─ .claude/ │ ├─ rules/ │ │ ├─ api.md ← only when touching apps/api/ │ │ ├─ web.md ← only when touching apps/web/ │ │ └─ db.md ← only when touching db/ │ ├─ skills/new-feature/ ← how to start a feature from a spec │ └─ settings.json ← hooks (lint, block risky actions) ├─ apps/web/ apps/api/ ├─ db/migrations/ └─ tests/e2e/

Five principles behind the layout:

  • Keep what is always read thin; let on-demand material be thick — AGENTS.md is the entrance and the rules. Details live in docs/ and specs/, and AGENTS.md points to them
  • A numbered folder per feature — numbering 012, 013 records order and history, and maps neatly onto branch names and PRs
  • Decisions go in ADRs, with reasons — “why PostgreSQL”, “why approval is a state machine”. When an agent starts redesigning on its own, this is what you point to
  • Scope area rules by path — API rules load only when the API is touched, not every session
  • Never write the same thing twice — rules link to docs. Copies drift, and one of them goes stale

The entrance, AGENTS.md, might look like this. Unlike last issue's example, it makes the process itself a rule: no spec, no build.

# AGENTS.md — order-system Internal order-management system. Use the terms in the glossary in docs/product.md. ## How we work - Build a feature only if it has a folder in specs/. If not, stop and ask - Work through specs/<number>/tasks.md in order, one task per commit - To change a design decision, add an ADR in docs/adr/ first ## Commands - Tests: pnpm test / E2E: pnpm e2e / Types: pnpm typecheck - Done means: all three pass ## Rules - Never touch the production database or production environment variables - Never edit an applied migration. Add a new file instead

Where each tool keeps these:

RoleClaude CodeCursorKiro
Always-read rulesAGENTS.md (or CLAUDE.md)AGENTS.md, Always rules.kiro/steering/
Area rules.claude/rules/ (scoped by paths).cursor/rules/ (scoped by globs)Steering inclusion settings
Specsspecs/ (free form)specs/ (free form).kiro/specs/feature/
5

One feature, end to end — the Q3 example

Let's add an order-approval flow to the system and follow it from spec to verification: six stages, with a human signing off at three of them.

How one feature moves

STEP 1 Write the spec spec.md You write, AI asks ✓ STEP 2 Plan it plan.md, ADR AI drafts; you pick ✓ STEP 3 Break into tasks tasks.md AI splits the work STEP 4 Implement 1 task = 1 commit AI, with tests STEP 5 Verify CI, E2E, review Tooling plus a human ✓ STEP 6 Close the spec update spec.md Write back any drift Next feature ✓ A human signs off here (don't skip it)

The urge to skip a stage usually comes when you are in a hurry, which is when rework hurts most

STEP 1 Write the spec (spec.md)

A person writes the purpose and acceptance criteria, because only people know the business context. Then have the AI read it and ask: “what is still undecided?”

# 012 Order approval flow ## Purpose Orders created by buyers must be approved by a manager, depending on the amount, before they can be confirmed. Today this runs on Excel and email, and a few orders a month slip through unapproved. ## Out of scope - Sending to suppliers (keep the existing EDI integration) - Budget management ## Acceptance criteria 1. For an order totalling ¥500,000 or more, "Request approval" sets the status to "Awaiting approval" and notifies the department manager 2. Orders under ¥500,000 can be confirmed without approval 3. A manager who rejects must give a reason; the status returns to "Draft" 4. While awaiting approval, nobody, including the creator, can edit the lines 5. Every status change records who, when, and from what to what ## Open questions - [ ] Do we need a deputy approver when the manager is away? (asking operations)

Write acceptance criteria so they can become tests as they stand. Not “easy to use” but “¥500,000 or more goes to awaiting approval”. When each condition maps to one outcome, both the AI and a person can judge it in step 5.

STEP 2 Plan it (plan.md and an ADR)

The AI drafts the plan; a person decides. Check that it doesn't break the existing structure or contradict earlier decisions. Decisions that are hard to reverse, such as how state is held, go in an ADR.

# 012 Plan - States: Draft → Awaiting approval → Approved → Confirmed; rejection returns to Draft All transitions live in OrderStatus in the orders domain (ADR-0007) - DB: add status, approved_by, approved_at to orders; new order_status_logs table (one migration) - API: POST /orders/{id}/request-approval, /approve, /reject - UI: buttons on the order page, a new "Awaiting approval" list - Notifications: reuse NotificationService (email) - Tests: state-transition unit tests first; E2E for criteria 1–4

STEP 3 Break it into tasks (tasks.md)

Make each task small enough to finish in one exchange and check once done. The trick is to put the test-writing task before the implementation.

# 012 Tasks - [x] T1 Unit tests for the OrderStatus transition table (criteria 1–4) - [x] T2 Implement OrderStatus so T1 passes - [ ] T3 Migration (status column, history table) - [ ] T4 Three API endpoints with permission checks (managers only approve) - [ ] T5 UI: buttons on the order page, the awaiting-approval list - [ ] T6 E2E: approve, reject, confirm under ¥500,000 - [ ] T7 Fold the open questions into spec.md; update docs/architecture.md

STEPS 4–6 Implement, verify, close the spec

  • Implement — work down tasks.md one item at a time. One task per commit means you always know where to roll back to. Hand broad investigation (mapping the blast radius, say) to a subagent so the main conversation stays clean
  • Verify — “tests, types and E2E pass” is the definition of done, enforced in CI. Human review compares against the acceptance criteria before reading the diff. Check security explicitly, missing permission checks and XSS above all; as chapter 1 showed, left alone nearly half slips through
  • Close the spec — write back what was decided along the way (no deputy approver, say) so spec and code agree. A spec that has drifted will steer the AI wrong on the next feature
6

Rules and hooks

RULES

Area rules should load only when that area is touched. In Claude Code, add paths to the top of a file in .claude/rules/ and it loads only when a matching file is read. Cursor's .cursor/rules/ does the same with globs.

# .claude/rules/api.md --- paths: - "apps/api/**" --- # API rules - Validate every input against a schema (apps/api/src/schemas/) - Return errors in the shared shape: { code, message } (see docs/architecture.md) - Check permissions in the use-case layer, not in controllers - Handle money as integers (yen). No floating point - Never build and return HTML. The UI escapes output; don't break that

Rules are requests. Anything that must always hold belongs in hooks or CI. As Claude Code's documentation puts it, writing “never edit .env” is a request, not a guarantee; if a rule must hold every time, make it a hook. Here is a hook that runs lint after every file edit:

// .claude/settings.json { "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "pnpm lint --silent" } ] } ] } }
When this happensAdd
The same mistake twiceA line in AGENTS.md, or an area rule
The same steps explained three timesA skill (playbook)
It must happen every timeA hook
It must never happenPermissions, branch protection, CI
Research floods the conversationA subagent

This table follows Claude Code's own advice to build your setup gradually. You don't need all of it on day one.

7

Today's best practice — Q3

BEST

Here are ten practices for building a mid-sized web system with AI, as of September 2026. They share one division of labour: people own what to build and whether it is done; the AI owns how it is written.

Practice
01Start every feature with a spec, with acceptance criteria that can become tests
02Three human gates: spec, plan, verification. Never skip them
03Let the AI ask questions before planning. Plug spec holes before they become code
04Small tasks, each with a way to check it. One task per commit
05Tests first, or at least alongside. Passing tests is the definition of done
06Keep always-read files thin. AGENTS.md is the entrance and the rules; area rules are scoped by path
07Recurring procedures become skills; must-hold rules become hooks, CI and permissions
08Record decisions in ADRs, with reasons
09Check security explicitly: write security rules, add static analysis to CI, review permissions and inputs and outputs
10Leave no drift between spec and code. Update the spec when you close a feature

And three things to avoid:

  • Having the AI write one giant spec in one go — a spec nobody can read through is a spec nobody has checked
  • Committing AI-written documents unread — as last issue's research found, auto-generated instructions left as they are make results worse
  • Calling it done because it works on screen — “works”, “correct” and “safe” are three different things

Tools and names will keep changing. What is here is the common ground of the official guidance from Spec Kit, Kiro, Claude Code and Cursor, restated so it doesn't depend on any one tool.

§ — On one page

  1. At work, vibe coding has become AI writing while people supervise (what Karpathy calls agentic engineering). AI code runs, but correctness and security aren't guaranteed unless you make them so.
  2. Beyond AGENTS.md you need specs (spec, plan, tasks), ADRs, product notes, area rules, skills and verification, placed according to when each is read.
  3. Specs go per feature in specs/number-feature/, decisions in docs/adr/, and area rules are scoped by path.
  4. Each feature goes spec → plan → tasks → implement → verify → close the spec, with human sign-off at spec, plan and verification.
  5. Don't just write down what must always hold: enforce it with hooks, CI and permissions, and check security explicitly.

References

Vibe Coding Field Notes — seven chapters / 2026.09

← Back to all posts