esmeralda
AGENTS.md25 starsChanged 8 days agoApache-2.0View on GitHub
Guidance for AI coding agents (and humans) working in this repository. Nested AGENTS.md files in infrastructure/, apps/agents/, apps/services/ and packages/esmeralda/ add local rules; the closest one to the file you edit wins. Full docs: <https://google.github.io/esmeralda/> (index for LLMs: <https://google.github.io/esmeralda/llms.txt>), sources in docs/src/. A reference blueprint for running AI agents (Google ADK, A2A) and MCP tool servers in production on Google Cloud. Agents run as bring-your-own-container images on Vertex AI Agent Engine (Agent Runtime) with a SPIFFE Agent Identity; all their…
- Reads credentials
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository6 other files it gives its agents.
- apps/agents/AGENTS.mdAGENTS.md
- apps/services/AGENTS.mdAGENTS.md
- infrastructure/AGENTS.mdAGENTS.md
- packages/esmeralda/AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- docs/src/llms.txtllms.txt
The file
We split this AGENTS.md into the rules it gives an agent
8 rules. About 0 are common, 1 is distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 36
Use layer (L0–L5), never "stage".
- Very specific: line 51
Gateway routes use agent engine IDs: after an agent engine is recreated, re-run make deploy-gateway ENV=<env> and make deploy-entrypoint …
- Very specific: line 54
Terragrunt env vars: read by every env.yaml: ESMERALDA_BILLING_ACCOUNT (required) and ESMERALDA_ORG_ID (optional).
- Very specific: line 60
Prefer the esmeralda CLI (uv run esmeralda --help) for day-to-day status, planning, verification, querying, logging, and repository guards.
- Very specific: line 83
Before an apply,: run uv run esmeralda plan <unit> --env <env> (or uv run esmeralda apply <unit> --env <env>, which plans first and …
- Very specific: line 89
Never destroy without explicit intent.
- Very specific: line 91
Never commit secrets, .env, *.tfvars, Terraform state or plans, certificates or keys (*.pem, *.crt), or load-test results.
- Distinctive: line 92
Use synthetic data only (the fictional applicants such as Julian Sterling).
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
Guidance for AI coding agents (and humans) working in this repository. Nested AGENTS.md files in
infrastructure/, apps/agents/, apps/services/ and packages/esmeralda/ add local rules; the
closest one to the file you edit wins. Full docs: https://google.github.io/esmeralda/ (index for
LLMs: https://google.github.io/esmeralda/llms.txt), sources in docs/src/.
What Esmeralda is
A reference blueprint for running AI agents (Google ADK, A2A) and MCP tool servers in production on
Google Cloud. Agents run as bring-your-own-container images on Vertex AI Agent Engine (Agent
Runtime) with a SPIFFE Agent Identity; all their egress goes through the Central Agent Gateway, which
only allows destinations registered in the Agent Registry. Private destinations live under
*.esmeralda.internal and reach an internal HTTPS load balancer (the entry point) that routes
each host to the built-in direct backend by default (or an optional gateway adapter such as
Envoy), which forwards to the agent or MCP server. The sample use case is a mortgage-underwriting
assistant: cx-mortgage-orchestrator (ADK, CX team project) calls ai-coe-mortgage-specialist
(A2A, AI CoE team project), which calls three MCP servers.
Repo map
| Path | What lives there |
apps/agents/<agent>/ | Agent packages: agent.yaml (framework, env, local_env, agent card), agent/, tests/, Dockerfile |
apps/services/<svc>/ | FastMCP servers (corporate-email, income-verification, legacy-dms) + tools.json; envoy/ is the digest-pinned Envoy adapter image |
packages/esmeralda/ | Runtime library shared by agents: esmeralda run/serve/query, auth, MCP/A2A clients, telemetry |
infrastructure/modules/ | Terraform modules, one folder per layer (0-cicd … 5-workloads) |
infrastructure/live/ | Terragrunt units: root.hcl, shared/layer-0-cicd, <env>/env.yaml + <env>/layer-* (envs: dev, prd) |
scripts/ | Helpers called by Make targets (lock, preflight, gateway probes, image checks, promotion) |
docs/ | MkDocs site: mkdocs.yml, src/ (pages), hooks/ (Make Targets page generated from the Makefile) |
tests/load_test/ | Locust load test (make load-test) |
.cloudbuild/, .github/, .githooks/ | Image build config, Docs + uv.lock workflows, pre-push lock check |
Layers and dependencies
Use layer (L0–L5), never "stage". Each layer reads the outputs of the layers below it through
Terragrunt dependency blocks; never reverse that direction.
- L0 CI/CD (
live/shared/layer-0-cicd, shared by all envs): CI/CD project, dev + release Artifact Registry repos, builder/promoter SAs. - L1 Projects → L2 Networking (Shared VPC, PSC, entry point IP +
esmeralda.internalDNS) → L3 Security (IAM, service accounts, internal Root CA, entry point certificate). - L4 Governance: Agent Gateway, Agent Registry, Model Armor, telemetry sinks, alerts, FinOps views.
- Images (
make build-images), then L5 Workloads in this order: MCP services → agents → gateways (gateways/direct+ any enabled adapter) → entry point (entrypoint) →iap-egress(+test-vm).
make deploy-workloads runs terragrunt run --all apply in layer-5-workloads, which derives that order from the dependency blocks.
Invariants and contracts
- Gateway adapter contract. A gateway module (
infrastructure/modules/5-workloads/gateways/<name>/) outputsbackend_service_id(a regionalINTERNAL_MANAGEDbackend service, ornullfordirect) androutes(host+probe=mcp|a2a|query|noneper host, plus per-routebackend_service_idand rewrite rules fordirect). It owns no load balancer, certificate or DNS. Any gateway change must passmake test-gateway ENV=<env>. Seedocs/src/2-workloads-and-catalog/01-ingress-gateways.md. catalogandgatewaysblocks ininfrastructure/live/<env>/env.yaml:catalogdeclares every MCP service and agent (kind,unit,token,probe,callers);gatewayssetsdefault("direct"or an enabled adapter),enabled(optional adapter units such as"envoy"), andhost_rules(host label or FQDN →"direct"or an enabled adapter). The entrypoint module validates these.- Hostnames. Agents reach MCP servers and other agents only via
https://<name>.esmeralda.internal(MCP at/mcp, A2A card at/v1/card). Never callrun.appor Reasoning Engine URLs directly from agent code. - Gateway routes use agent engine IDs: after an agent engine is recreated, re-run
make deploy-gateway ENV=<env>andmake deploy-entrypoint ENV=<env>. - Images are deployed by digest, never by tag.
make test-terraformfails onimage = var.…;make verify-imageschecks running digests. Images contain no certificates (injected at deploy time), so one digest is promoted from dev to prd (make promote TAG=vX.Y.Z). - Python is one uv workspace (root
pyproject.toml, singleuv.lock). The Makefile exportsUV_FROZEN=1: never runuv lockoruv addlocally. Editpyproject.toml, thenmake lock(runsuv lockin Cloud Build against public PyPI and writesuv.lockback) and commituv.lock.make lock-check(also the pre-push hook and a PR workflow) fails on a stale lock. - Terragrunt env vars read by every
env.yaml:ESMERALDA_BILLING_ACCOUNT(required) andESMERALDA_ORG_ID(optional). Export them in your shell; never write them into a file in the repo. - No hardcoded project IDs in code or docs: read them from layer outputs; write placeholders such as
esm-<env>-gateway-<sfx>. - Team ownership: CX orchestrators are
apps/agents/cx-*(CX project); reusable A2A agents areapps/agents/ai-coe-*(AI CoE project).
Commands that matter
Prefer the esmeralda CLI (uv run esmeralda --help) for day-to-day status, planning, verification, querying, logging, and repository guards; make targets wrap the CLI and multi-step image/Terragrunt workflows (make help, most take ENV=<env>, default dev).
| Command | Make equivalent | What it proves |
uv run esmeralda status --env <env> | make status ENV=<env> | Git branch/SHA, active worktrees, local state units, image tags/digests, and deployed environment outputs |
uv run esmeralda doctor --env <env> | make doctor ENV=<env> | Workstation preflight check: required tools, ESMERALDA_BILLING_ACCOUNT, ADC token, uv.lock, and local state readability |
uv run esmeralda units [--layer 0..5] --env <env> | make units ENV=<env> | Lists Terragrunt units, layer, dependencies, enabled/excluded status, and local state presence |
uv run esmeralda plan <unit|--all> --env <env> | make plan [UNIT=<unit>] ENV=<env> | Read-only terragrunt plan -lock=false summary (to add, to change, to destroy, to replace) |
uv run esmeralda apply <unit> --env <env> | make apply UNIT=<unit> ENV=<env> | Plans to a saved planfile, enforces the destroy guard (refuses destroy > 0 without --allow-destroy), and applies |
uv run esmeralda verify --env <env> | make verify ENV=<env> | Gateway conformance probes (scripts/test_gateway.sh) + remote specialist and orchestrator queries |
uv run esmeralda verify --partner --env <env> | make test-partner ENV=<env> | Apigee partner front-door conformance probes (scripts/test_partner.sh, offline or live) |
uv run esmeralda query --agent-dir apps/agents/<agent> "..." | make query AGENT=<agent> [TARGET=local|remote] | Queries an ADK or A2A agent in-process, over --url, or on Agent Runtime (--engine), with --user-token support |
uv run esmeralda logs <target> --env <env> | make logs TARGET_NAME=<target> ENV=<env> | Recent Cloud Logging entries for an agent or MCP service (tracebacks collapsed, deduplicated) |
uv run esmeralda contracts [--section ...] | — | Prints architectural contracts (entrypoint, gateway_adapter, agent_card, env_yaml) |
uv run esmeralda guard [--staged|--diff <range>|--all] | make guard | Public-repository sensitive-content and forbidden-path scanner |
| — | make bootstrap | Tools present (preflight), workspace synced with uv, .githooks installed |
| — | make lock-check | uv.lock matches every pyproject.toml (offline) |
| — | make test-all | lock-check + test + test-guards + test-terraform + test-gateway-unit + test-apigee: the offline gate before a PR |
| — | make docs-build | Docs site builds in strict mode (broken links, anchors, nav fail), same as CI |
Testing expectations
- Offline first:
make test-all(andmake docs-buildwhen docs change) anduv run esmeralda guard --stagedmust pass before any commit, plan, or PR. - Before an apply, run
uv run esmeralda plan <unit> --env <env>(oruv run esmeralda apply <unit> --env <env>, which plans first and enforces the destroy guard) and inspect the summary. - After an infra, gateway or agent change in a deployed env, prove it end to end with
uv run esmeralda verify --env <env>(which runs all gateway route probes plus realai-coe-mortgage-specialistandcx-mortgage-orchestratorqueries), anduv run esmeralda verify --partner --env <env>when partner front-door capabilities are modified. A routing or TLS-only check is not enough.
Safety
- The
make deploy-*targets apply with-auto-approve: review a plan first, and never apply toprdwithout explicit intent. - Never destroy without explicit intent.
make destroy-allrefusesprd, asks for confirmation and never touches L0. - With the default local state (
state_project/state_bucketempty inenv.yaml), state lives ininfrastructure/live/.local_states/;make cleandeletes*.tfstate*files, so don't run it on a machine that holds the only copy of a live env's state. - Never commit secrets,
.env,*.tfvars, Terraform state or plans, certificates or keys (*.pem,*.crt), or load-test results. They are gitignored; keep it that way. - Use synthetic data only (the fictional applicants such as Julian Sterling). No real customer data, names or project IDs in code, docs, tests, commits or PRs.
PR conventions
- Conventional commits:
feat(scope): …,fix(…),docs: …,refactor(…),chore: …,style: …; imperative, lower case. - One topic per PR; include doc updates (
docs/src/, and a new page indocs/mkdocs.ymlnav). Document new Make targets with their## ...help comment, not in the docs. - Stage explicit paths (no
git add -A); commituv.lockwith anypyproject.tomlchange. - See
docs/src/contributing.mdfor the CLA and the full contribution guide.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

