# AGENTS.md — Taste Constraints for AI Agents

> **Status:** Draft 0.1 · **Grammar version:** 2.0.0 · **Last updated:** 2026-05-20
>
> A repo-level instruction file that tells AI coding agents (Claude Code, Cursor, Windsurf, Copilot, and any MCP-compatible client) which brand taste-DNA to follow when generating UI, components, copy, or design tokens.

## TL;DR

Drop a file called `AGENTS.md` at the root of any repository. It declares which tasteHQ brand grammar the repo follows, where the canonical taste vector lives, and the rules an agent must respect when generating output for this codebase. Agents read it the same way they read `CLAUDE.md`, `GEMINI.md`, or `.cursorrules` — it's instruction context, not configuration.

`AGENTS.md` is to taste what `.editorconfig` is to indentation, and what `package.json` is to dependencies: a thin, declarative, machine-readable contract that survives across tools.

---

## Why this file exists

Every AI coding agent today does the same thing when asked to build UI: it guesses. "Build a pricing page" can return Stripe-blue, Linear-black, Notion-serif, or Tailwind-default depending on the model, the temperature, and the moon phase.

The fix is not better prompts. The fix is a **declared target**. `AGENTS.md` is that declaration:

- Brands publish their taste-DNA at `brand.com/.well-known/taste/{slug}` (Taste Protocol)
- Repos point at a brand (or a composed hybrid) via `AGENTS.md`
- Agents fetch the grammar vector, apply it, and verify before finishing
- `tastehq judge` provides a deterministic scorecard against the declared target

The same file works for first-party brand repos (Anthropic's own site declares `anthropic`), for design system consumers (a customer using Stripe's design system declares `stripe`), and for hybrids (`compose_brands` output saved as a custom grammar).

---

## File location and discovery

| Layer | Path | Required |
|---|---|---|
| Repo root | `./AGENTS.md` | Yes — primary lookup path |
| Hidden | `.agents/AGENTS.md` | Optional — for repos that prefer dotfile layout |
| Per-package | `packages/*/AGENTS.md` | Optional — overrides repo-root for that package |

Agents MUST read repo-root `AGENTS.md` if present. Per-package files override the root within their tree.

## Format

`AGENTS.md` is Markdown with one required YAML frontmatter block. The frontmatter is the machine-readable layer; the Markdown body is human and agent guidance.

```markdown
---
agents_md_version: "0.1"
taste:
  brand: stripe                              # required — tasteHQ slug, or "custom"
  source: https://taste-hq.vercel.app/.well-known/taste/stripe  # required
  grammar_version: "2.0.0"                   # optional — pin a grammar version
  tier: reference                            # informational — published tier
  conformance: L2                            # required — see conformance levels
required_axes:                               # optional — override which axes are gating
  - palette.strategy
  - voice.archetype
  - whitespace.discipline
forbidden_axes: []                           # optional — axes the brand explicitly violates
verify:
  judge: https://taste-hq.vercel.app/api/score
  min_fidelity: 0.75
---

# Taste constraints for this repo

This repository ships UI in **Stripe's** brand grammar.
...
```

### Required fields

- **`agents_md_version`** — string, semver of the spec. Currently `"0.1"`.
- **`taste.brand`** — tasteHQ slug (`stripe`, `anthropic`, `linear`, …), or the literal `custom` for a composed/private grammar.
- **`taste.source`** — fully qualified URL pointing at a `.well-known/taste` endpoint. Agents fetch this to load the grammar vector.
- **`taste.conformance`** — one of `L1`, `L2`, `L3`. See below.

### Optional fields

- **`taste.grammar_version`** — pins the grammar schema; defaults to whatever the source returns.
- **`taste.tier`** — informational hint (`reference`, `verified`, `community`, `unrated`).
- **`required_axes`** — list of `category.axis` strings the agent MUST match. Defaults to the brand's gating axes from the grammar weights.
- **`forbidden_axes`** — list of `category.axis` strings the agent MUST NOT match.
- **`verify.judge`** — URL of a Taste Protocol L2 judge. Defaults to `https://taste-hq.vercel.app/api/score`.
- **`verify.min_fidelity`** — float in `[0, 1]`. Verdict band threshold the agent should treat as a hard fail. Default `0.75`.

---

## Conformance levels

Agent behavior is gated by the declared `taste.conformance`:

| Level | Name | Behavior |
|---|---|---|
| **L1** | Reader | Agent fetches the grammar vector and surfaces it as context. No automatic enforcement. |
| **L2** | Judge | Agent runs every UI artifact through `verify.judge` and refuses output below `min_fidelity`. |
| **L3** | Publisher | The repo *is* canonical for this brand. Build outputs publish `.well-known/taste/{slug}` and are cryptographically signed (Ed25519). |

Most repos want **L2**. Brand owners declaring their own site want **L3**.

---

## Agent behavior contract

When an agent encounters `AGENTS.md`, it MUST:

1. **Read the frontmatter before generating any UI, component, or design token.**
2. **Fetch `taste.source`** and cache the response for the session (300s TTL recommended).
3. **At L1+**: keep the brand's `signature_move`, `mood`, `anti_patterns`, and `grammar` block in working context for every generation.
4. **At L2+**: after generating UI that touches the rendered surface (HTML/CSS/JSX/SwiftUI/etc.), POST the artifact to `verify.judge` and refuse to declare the task complete if fidelity < `min_fidelity`.
5. **At L3**: maintain `/.well-known/taste/{slug}` in the build output and sign it.

When in doubt, an agent MUST surface the conflict to the user rather than silently overriding the declared taste.

---

## Worked example: Stripe consumer

A repo that builds a marketing site in Stripe's house style:

```markdown
---
agents_md_version: "0.1"
taste:
  brand: stripe
  source: https://taste-hq.vercel.app/.well-known/taste/stripe
  conformance: L2
verify:
  min_fidelity: 0.80
---

# This repo is taste-faithful to Stripe

When generating any page, component, or design token, follow Stripe's grammar:

- **Surface**: white ground, generous radius, layered shadows
- **Palette**: cobalt mono with single accent (mono+1), saturated cool
- **Type**: sans/sans pairing, balanced display scale, tight tracking
- **Voice**: engineer archetype, technical, intimate-not-corporate
- **Motion**: persistent gradient mesh aurora; signature move

Run `tastehq judge <url> --target stripe` before merging UI PRs.

See: https://taste-hq.vercel.app/api/styles/stripe/design.md
```

## Worked example: Hybrid brand (composed)

A custom product that wants Stripe's surface with Anthropic's voice:

```markdown
---
agents_md_version: "0.1"
taste:
  brand: custom
  source: https://taste-hq.vercel.app/api/compose?surface=stripe&voice=anthropic
  conformance: L1
required_axes:
  - surface.ground
  - voice.archetype
---

# Custom grammar: Stripe surface × Anthropic voice

This repo composes from two reference brands. The composed grammar lives in
`./design/grammar.json`. Treat the file as ground truth — re-run the compose
endpoint only when intentionally re-mixing.
```

## Worked example: Brand owner (L3)

The repo behind `anthropic.com` declaring itself canonical:

```markdown
---
agents_md_version: "0.1"
taste:
  brand: anthropic
  source: https://anthropic.com/.well-known/taste/anthropic
  grammar_version: "2.0.0"
  tier: reference
  conformance: L3
verify:
  judge: https://taste-hq.vercel.app/api/score
  min_fidelity: 0.90
---

# This is the canonical Anthropic taste source

Build outputs publish `.well-known/taste/anthropic` signed with our Ed25519
publisher key (fingerprint in `.well-known/taste.key`).
```

---

## Relationship to other files

`AGENTS.md` does **not** replace `CLAUDE.md`, `GEMINI.md`, or `.cursorrules`. It is taste-scoped instruction context that those broader files can link to:

```markdown
<!-- CLAUDE.md -->
# Project conventions

…all the usual rules…

## Taste

This repo follows the constraints in [AGENTS.md](./AGENTS.md). Read that file
before generating any UI, component, or design token.
```

This keeps taste guidance composable across tools without forcing a particular agent harness.

---

## Discovery via Taste Protocol

Every brand in tasteHQ now exposes a ready-to-drop-in `AGENTS.md` at:

```
GET /api/styles/{slug}/agents.md
GET /.well-known/taste/{slug}  →  payload.agents_md  ⇒  href to the above
```

To bootstrap a repo against any tasteHQ brand:

```bash
curl https://taste-hq.vercel.app/api/styles/stripe/agents.md > AGENTS.md
```

That file is generated from the brand's live grammar vector and stays in sync with the published version. Pin `grammar_version` in the frontmatter if you want stability.

---

## Open questions (Draft 0.1)

These are deliberately unresolved and will harden in 0.2:

- **Signing.** L3 publishers need a canonical key-rotation pattern. Likely `/.well-known/taste.key` with Ed25519 + JWKS-style rotation.
- **Per-package overrides.** Should monorepo packages inherit the root file or fully override? Current default: full override.
- **Composition syntax.** `taste.brand: custom` with a source URL works, but a richer `taste.compose` block (axes mapped to source brands inline) may be cleaner.
- **Negative declarations.** Should `forbidden_axes` also be expressible as anti-patterns inline (`forbidden_anti_patterns:`)?

Discussion: `https://github.com/MustBeSimo/tasteHQ/issues` with the `agents-md` label.

---

## Prior art

`AGENTS.md` borrows shamelessly from:

- **`CLAUDE.md` / `GEMINI.md`** — repo-root instruction files for AI coding agents
- **`.editorconfig`** — declarative, tool-agnostic project preferences
- **`/.well-known/` URI namespace** — RFC 8615 patterns for protocol discovery
- **Design Tokens Community Group (DTCG)** — schema for portable design data
- **OpenAPI** — the model of a machine-readable contract that survives vendor changes

The novel contribution is the *layer*: not how to format design tokens (DTCG handles that), not how to instruct an agent (`CLAUDE.md` handles that), but how to declare the **target taste** so the two systems can connect.

---

*Spec maintained at `https://taste-hq.vercel.app/docs/AGENTS-MD-SPEC.md`. CC BY 4.0.*
