Project Setup and Manifest¶
The project manifest (aat-project.yaml) marks your project root and tells AAT where all its artifacts live, so most CLI flags become optional.
Overview¶
AAT separates what to test (graph, templates, domain knowledge) from where things live (file paths, directory layout). The manifest bridges these — it declares artifact locations once so every command can find them automatically. When a manifest is discoverable, you can run aat run batch or aat mcp serve without passing --graph, --templates, or --env-config flags.
Project Directory Layout¶
A typical project directory looks like this:
my-ecommerce-api/
aat-project.yaml # project manifest (discovery root)
graph.yaml # API graph
env.yaml # environment config (auth, endpoints)
domain.yaml # domain knowledge (optional)
templates/ # request/response templates
listProducts.yaml
createOrder.yaml
cancelOrder.yaml
getOrderStatus.yaml
workflows/ # reusable workflow templates (optional)
order-lifecycle.yaml
return-flow.yaml
plans/ # saved plan instances (optional)
smoke-test.yaml
full-checkout.yaml
runs/ # execution archives (auto-created)
traces/ # planning traces (auto-created)
These paths are convention, not enforced. You can name files and directories however you like — the manifest maps each artifact type to its actual location.
To share part of a project with your API's integrators while keeping your internal tests, add a second manifest for that part and package it in CI; see Share Your API with Integrators.
The Project Manifest¶
The manifest is a YAML file named aat-project.yaml that declares your project's artifacts:
name: ecommerce
description: E-commerce order management API tests
tags: [orders, inventory, payments]
graph: graph.yaml
templates: templates/
domain: domain.yaml
environment: env.yaml
workflows: workflows/
plans: plans/
archives: runs/
traces: traces/
All paths are resolved relative to the manifest file's directory. Absolute paths are also accepted and used as-is. Unknown keys are errors: a typo such as plan: fails with the file, the line, and a suggestion (did you mean "plans"?).
Required vs Optional Fields¶
Only two fields are required by the manifest loader:
| Field | Required | Description |
|---|---|---|
graph |
Yes | Path to the API graph YAML |
templates |
Yes | Path to the templates directory |
Everything else is optional. When omitted, commands that need those paths will either use sensible defaults or require explicit flags.
Schema Reference¶
| Field | YAML Key | Type | Description |
|---|---|---|---|
| Name | name |
string | Project name (for display and identification) |
| Description | description |
string | Brief project description |
| Tags | tags |
list | Freeform tags for categorization |
| Graph | graph |
string | Path to the API graph YAML file (required) |
| Templates | templates |
string | Path to the templates directory (required) |
| Domain | domain |
string | Path to the domain knowledge YAML file |
| Docs | docs |
string | Directory of per-node Markdown docs (<node>.md) for the MCP server; no default (see MCP Server: Per-Node Documentation) |
| Workflows | workflows |
string | Path to the workflows directory |
| Layers | layers |
string | Path to the graph layers directory |
| Plans | plans |
string or list | Path(s) to plan directories |
| OAS | oas |
string or list | OpenAPI spec file(s) the MCP server loads for its OpenAPI tools, in addition to the specs the graph references. Static and runtime validation use only the graph's oas references |
| Archives | archives |
string | Path to the run archive directory (default: _output/runs in the working directory) |
| Traces | traces |
string | Path to the planning trace directory (default: traces/ next to the manifest) |
| Visualizers | visualizers |
string | Path to the visualizer plugins directory |
| Environment | environment |
string | Path to the default environment YAML file |
| Default Environment | defaultEnvironment |
string | Default environment name for multi-env files |
The plans field accepts either a single path or a list of paths:
# Single directory
plans: plans/
# Multiple directories
plans:
- plans/
- /shared/plans/regression
Auto-Discovery¶
AAT automatically finds your manifest by walking up from the current working directory toward the filesystem root, looking for a file named aat-project.yaml. The first match wins.
/home/user/projects/ecommerce/plans/ # cwd — no manifest here
/home/user/projects/ecommerce/ # aat-project.yaml found here
Commands that use auto-discovery: aat run, aat prompt, aat validate, aat web, aat mcp serve, aat plan list, aat env list, aat import, and aat docs generate.
To override auto-discovery, pass the --manifest flag:
aat validate --manifest /path/to/other-project/aat-project.yaml
Resolution Priority¶
AAT looks for a manifest at four levels, from lowest to highest priority:
- User config — a persistent
default_projectsetting in your user-level config file AAT_PROJECTenvironment variable — a directory or manifest path- CWD walk-up — automatic discovery from the current working directory
--manifestflag — explicit manifest path (overrides discovery)
The highest-priority manifest found describes the whole project: lower levels do not fill in fields it leaves out, so a CWD manifest without domain: has no domain file even if the AAT_PROJECT project has one.
A discovered level whose manifest does not exist is skipped, so a stale default_project or AAT_PROJECT does not block a run. A --manifest path that does not exist is an error (manifest not found: ...). A manifest that exists but fails to load, such as one with an unknown key, is an error, unless a higher-priority level loads a manifest.
After manifest resolution, explicit CLI flags (--graph, --templates, --env-config, etc.) always take final precedence over the matching manifest-derived path.
User Config¶
The user config file lives at the platform-native config directory:
| Platform | Path |
|---|---|
| macOS | ~/Library/Application Support/aat/config.yaml |
| Linux | ~/.config/aat/config.yaml |
| Windows | %AppData%/aat/config.yaml |
The file sets a default project that applies when no other manifest is found:
default_project: /home/user/projects/ecommerce
The value can be a directory (AAT looks for aat-project.yaml inside) or a direct path to a manifest file.
AAT_PROJECT Environment Variable¶
Set AAT_PROJECT to point at a project directory or manifest file:
export AAT_PROJECT=/home/user/projects/ecommerce
aat validate # uses that project's manifest
This is useful in CI/CD environments that run AAT from outside the project directory. A manifest found by walking up from the working directory still takes priority over AAT_PROJECT.
Overriding Manifest Paths¶
CLI flags always override the corresponding manifest field. This lets you test against alternate configurations without modifying the manifest:
| CLI Flag | Manifest Field |
|---|---|
--graph |
graph |
--templates |
templates |
--env-config |
environment |
--domain |
domain |
--output |
archives |
--trace-dir |
traces |
# Use the project's graph and templates, but a different environment
aat run plan checkout.yaml --env-config staging-env.yaml
# Use the project's environment, but a different graph
aat validate graph --graph experimental-graph.yaml
Multiple Environments¶
A single project often targets multiple environments (development, staging, production). The recommended approach is to define all environments in a single multi-environment file:
my-ecommerce-api/
aat-project.yaml # environment: env.yaml, defaultEnvironment: dev
env.yaml # shared config + all environment definitions
env.secrets.yaml # auth credentials (gitignored)
graph.yaml
templates/
# Uses the manifest's defaultEnvironment
aat run batch
# Selects a specific environment
aat run batch --env staging
# List all available environments
aat env list
Set defaultEnvironment in the manifest to avoid passing --env every time. The AAT_ENV_NAME environment variable also works, which is useful for CI/CD.
You can also use the include directive in env.yaml to split secrets into a separate, gitignored file. See Environments: File Splitting for details.
See Environments for the full environment file reference.
Bootstrapping from OpenAPI¶
If you have an OpenAPI specification, aat generate --oas openapi.yaml scaffolds a graph and one template per operation. It writes nothing else: you add the manifest, the environment, ordering (requires/satisfies), cleanup pairings, and domain knowledge by hand. See Scaffolding from OpenAPI.
Schema Reference¶
# aat-project.yaml — complete annotated example
name: ecommerce # project name (for display)
description: Order management API # brief description (optional)
tags: [orders, inventory] # freeform tags (optional)
graph: graph.yaml # required — path to API graph
templates: templates/ # required — path to templates directory
domain: domain.yaml # optional — domain knowledge file
docs: docs/nodes/ # optional — per-node Markdown docs for the MCP server
environment: env.yaml # optional — default environment file
defaultEnvironment: dev # optional — default env name (multi-env files)
workflows: workflows/ # optional — workflow templates directory
layers: layers/ # optional — graph layers directory
plans: plans/ # optional — plan directory (string or list)
oas: openapi.yaml # optional — extra OpenAPI spec(s) for MCP tools (string or list)
archives: runs/ # optional — run archive output directory
traces: traces/ # optional — planning trace output directory
visualizers: visualizers/ # optional — visualizer plugins directory
Source: config/manifest.go, config/resolver.go, config/user_config.go.