Skip to main content
Lifecycle files | AEPThe format of an artifact lifecycle document — initial status, transitions, evidence-priced rungs, date-guarded rungs and descriptions — and how a kind finds its lifecycle.AEPreferenceaepreferenceadopterdevelopertry-spec-driven-developmentunderstand-safe-agentic-codingreference

Lifecycle files

A lifecycle document declares the statuses of one artifact kind and the moves between them. They live in the document tree under artifacts/lifecycles/, one file per kind. Any file name works, because the kind: inside decides.

kind: data-migration # the kind this governs; omit for the tree's fallback
initial: draft # where `new` starts an artifact (required)
transitions: # status -> the statuses that may follow it
draft: [rehearsed, abandoned]
rehearsed: [applied, abandoned]
applied: [] # terminal
abandoned: []
requires: # status -> what reaching it costs
rehearsed:
- evidence: test_result # an evidence kind the protocol declares
or: [ess_conformance] # further kinds, any one of which pays instead
applied:
- evidence: approval
at_least: 2 # default 1
when: # status -> a date the artifact itself records
abandoned:
before: decide_by # reachable only while now is before the artifact's `decide_by`
descriptions: # status -> one line, shown by `board --format markdown`
draft: Written down, not yet run anywhere.

Keys​

KeyRequiredShapeMeaning
kindnokebab-case kindthe kind governed; absent means this is the fallback for kinds with no nearer lifecycle (at most one per tree)
initialyesstatusthe status an artifact is created at
transitionsnomap of status → list of statusesthe legal moves; a status mapped to [] is terminal
requiresnomap of status → list of {evidence, or, at_least}evidence records of that kind, held for the artifact, needed to reach the status; or lists further kinds any one of which pays instead, each against at_least on its own
whennomap of status → {after, before}each names a front-matter key of the artifact holding a date; after: due means not until the instant is past this artifact's due
descriptionsnomap of status → stringwhat being at the status means

Unknown keys are refused. when compares against the instant move --at gives, which defaults to now. An empty guard constrains nothing.

requires is deliberately smaller than a principle's evidence requirement. It counts records of a kind and does not judge who produced them or whether they are independent. Those judgements belong to the engine. One judgement is made before the count: on an artifact that records a model_digest, an ESS conformance record (ess_conformance, ess_conformance_v2, ess_conformance_coverage_v1) counts only when it passed and its spec_digest is that digest, and a refused move names each record that did not count and why.

How a kind finds its lifecycle​

  1. the lifecycle whose kind is exactly the artifact's kind;
  2. a lifecycle for a kind it specialises, nearest first. A kind's parent is named by its last hyphen segment, so weekly-digest → digest and credential-blocker → blocker;
  3. the tree's fallback lifecycle (the document with no kind:).

Checking one​

aep govern validate --root <tree> # the whole tree, lifecycles included
aep plan artifact lifecycle <kind> # the ladder as the store will apply it

The JSON Schema is artifact-lifecycle.schema.json. The shipped lifecycles are in artifacts/lifecycles/.