Skip to main content

project.yaml | AEP

project.yaml | AEPproject.yaml in the source-owned AEP documentation.AEPreferenceaepreferenceadopterdevelopertry-spec-driven-developmentunderstand-safe-agentic-codingreference

a value that is not a non-negative integer, or a target not below its baseline is refused, naming the kind, the figure and the values; spend or a kind written with no value (empty, ~, null, {}) is refused naming it --- title: project.yaml sidebar_position: 2 description: Every field of .engineering/project.yaml, the file that makes a repository an AEP project.​

project.yaml

.engineering/project.yaml makes a directory an AEP project. Every command looks for it from the working directory upwards, up to twelve levels. AEP_PROJECT_DIR renames .engineering. Unknown keys are refused.

version: aep.project/5 # the store format; see below
protocol: adp/1 # the protocol the project runs under
profile: development.standard # the profile whose rules apply
protocols: git+https://github.com/beyond10x/aep#81d80288038e85dd30a1c54ce9c7f25e38b42ae0
planning_scope: shop # required by aep.project/5
store:
git: {} # the Git-native store, the default
summary: The web shop. # optional, for people
providers: # optional: link patterns for external references
jira: https://tracker.example/browse/{key}

Fields​

FieldRequiredDefaultMeaning
versionyesaep.project/5. aep.project/1 (also what a file with no version is) and aep.project/2–/4 are refused with the migration path.
protocolyesthe protocol reference, such as adp/1
profileyesthe profile, such as development.standard
protocolsno..where the governing documents come from: a path relative to .engineering/, or a git+ssh://, git+https:// or git+file:// URL pinned to a 40-hex commit after #
planning_scopewith /5the store's name, 1–255 UTF-8 bytes including a non-whitespace character; reverse init and migrate git set it to --planning-scope, else the origin remote's repository name, else the primary checkout's directory name, else (outside Git) the directory holding .engineering/
storenogit: {}where the plan is kept; see below
summarynoone line for people; nothing reads it
providersnoa URL pattern per external system, each containing {key}; a pattern without {key} is refused
findings_required_sincenoa calendar date, YYYY-MM-DD, read as starting at midnight UTC. Once it is set, whatever the date, new refuses a review-result without a findings block unless --prose-only <reason> says why; validate reads the date and counts such a review as a problem unless it predates the date, is superseded by a review carrying a block, or was recorded prose-only. A review the store cannot date (a shallow clone, a store outside Git) is undated, never before the date. See Reviews. A value that is not a calendar date, or no value at all (empty, ~, null), is refused naming the key
spendnoa baseline and a target per task kind and figure, spend.<kind>.<figure>: { baseline: <n>, target: <n> }, that aep plan artifact spend reports each median against. A figure is model_calls, total_tokens, cost_micro_usd, wall_time_ms or llm_steps_run; both values are required non-negative integers and the target is strictly below the baseline. Any other figure, a missing value or a target not below its baseline is refused, naming the kind, the figure and the values
artifactsnoartifacts.yamlthe artifact manifest for governed tasks
tasknotask.yamlthe task document govern and drive use when --task is absent
statenostate.yamlwhere execution state is kept
principlesnoprinciplesproject-local principles, merged over the tree's
profilesnoprofilesproject-local profiles, merged over the tree's
schemasnoschemasproject-owned JSON Schema contracts

Paths other than protocols are relative to .engineering/, and absolute paths are refused, so the repository can be cloned anywhere.

protocols​

FormExampleNotes
a path.., ../governancea tree in the repository, or beside it; use this to add your own lifecycles
a pinned Git URLgit+https://github.com/beyond10x/aep#<40-hex>fetched once into ~/.cache/aep/protocol-sources/ (or AEP_CACHE_DIR), verified against the commit, and read from there

A machine or pod with no route to the source needs the snapshot in its cache first: fill a cache where the network is reachable and point AEP_CACHE_DIR at it. A fetch that cannot finish is stopped after AEP_FETCH_TIMEOUT_SECS (60 s) and refused, naming the pin and the cache. A cache on a Kubernetes volume with fsGroup is group-writable; set AEP_CACHE_GROUP_WRITABLE=1 to admit it (see the environment).

An unpinned Git URL is refused. A governing tree that can move without a commit in your repository would be a gate whose meaning changes silently.

store​

storePlan lives in
git: {} (or absent).engineering/planning/ and .engineering/evidence/, see the planning store
sqlite: { path: <file> }one SQLite database, the path relative to .engineering/
postgres: { url: <url> }a PostgreSQL database; the password is never printed

Any other form — a bare word such as markdown, a misspelt key — is refused naming it. The SQLite and PostgreSQL stores keep no files: their history is the database's own event log.

An aep.project/1 file (store: markdown, sqlite: <file>, postgres: <url> or hybrid:) is refused by every command. A Markdown /1 store migrates with aep plan store migrate git --verify; a SQLite or PostgreSQL one is rewritten by hand as /5 with a planning_scope and the nested form above.

planning_tenant and planning_identity named event-log identities. Both are refused today.

Planning stores lists every supported and removed backend, generated from the code, with each removed store's migration path.

Written by​

  • aep plan reverse init --protocols … --profile … [--protocol adp/1] [--summary …] writes a new /5 file.
  • aep plan store migrate git rewrites a /1 file as /5 and keeps every other key.

.engineering/workspace.yaml (version: aep.workspace/1) lists the repositories that workspace commands answer across. The JSON Schemas for both files are published in schemas/generated/ as project.schema.json and workspace.schema.json.