dev
← All ADRs

Lifecycle Tasks and Bootstrap Sequence

ACCEPTEDEngine2026-06-01

Context

Autograph projects go through a lifecycle: setup, dependency resolution, infrastructure startup, app installation, runtime, and teardown. The engine must define a clear, predictable sequence of tasks that:

  • Works on first clone (bootstrap)
  • Works on subsequent sessions (idempotent)
  • Allows packages to hook into the lifecycle (future)
  • Provides clear operator UX (discoverable, symmetric)
  • Each task can self-diagnose (preconditions, status checks)
  • Each constructive task has a symmetric destructive counterpart for safe testing

Additional constraint (discovered during implementation)

Project paths (AUGR_PATH_REPOS, AUGR_PATH_WORKSPACE, etc.) are resolved from ROOT_DIR (via git rev-parse --show-toplevel) and exported to process environment via the root Taskfile's env: section. This makes them available to compose files via ${VAR:?} without needing them in env/.env.

The env/.env file contains ONLY operator secrets (LLM tokens, etc.), not structural paths. Separation of concerns: paths are derived from the repo structure, secrets are provided by the operator.

The setup step creates env/.env and must run before augr:prepare because the dotenv loading provides secrets needed by some compose services (not west, but the agent later). This step lives at the admin: level - it is project instance configuration, not engine lifecycle.

Options considered

Option A - Single `augr:init` that does everything

One task that handles the entire bootstrap.

  • Advantage: Simple UX (one command)
  • Disadvantage: Opaque. Hard to debug when something fails. Cannot resume from a failure point. Mixes concerns. Cannot work due to dotenv chicken-and-egg problem.

Option B - Fine-grained lifecycle stages (chosen)

Separate tasks for each stage, with clear semantics and ordering.

  • Advantage: Debuggable, resumable, composable. Each stage can be run independently. Packages can hook into specific stages. Solves the dotenv loading problem (setup creates env, subsequent commands read it).
  • Disadvantage: More commands for the operator to learn. Must document the expected sequence.

Option C - Make-style dependency graph

Tasks declare their dependencies and the runner figures out the order.

  • Advantage: Declarative, no manual sequencing
  • Disadvantage: Taskfile supports deps: but it makes the execution order implicit. Harder to understand what will run. Debugging dependency chains is painful.

Decision

Option B - Fine-grained lifecycle stages with symmetric pairs.

Explicit is better than implicit. The operator should understand what each stage does and be able to run any stage independently for debugging or testing.

Consequences

Lifecycle levels

The lifecycle operates at four levels, from outermost (host) to innermost (app). Each level has its own namespace and vocabulary. Levels are nested: augr:up starts the autograph infrastructure, app:up starts the application services on top of it.

Level Namespace Scope What it manages
Host host: The developer's machine Docker daemon, system resources, global cleanup
Admin admin: Project instance configuration Secrets, profiles, env, backup, deploy - orchestrator-agnostic
Autograph augr: The engine + packages Dependencies (West), env aggregation, agent container
App app: The application code App containers, dev servers, dependencies, tests

The admin level manages the project as a deployed instance: configuring secrets, choosing profiles, managing backups. It is independent of the underlying orchestrator (Docker Compose today, potentially k3d or others tomorrow). setup/teardown live here - they instantiate the project into a working environment, not just clone it.

Each level can be operated independently. An operator can augr:down (stop autograph infra) without affecting app: containers, or app:stop (stop dev servers) without touching the containers.

Standard verbs

Verbs are consistent across levels. Not every level uses every verb, but when a verb is used, it always means the same thing.

Admin lifecycle (project instance management)

Verb Meaning Constructs/Destroys
setup First-time project bootstrap (submodules, env template) Constructs
teardown Revert to post-clone state Destroys
backup Snapshot current env configuration Read-only (copy)
restore Restore env from backup Constructs

These verbs manage the project as a deployed instance - secrets, profiles, env directories. They are independent of the orchestrator (Docker Compose, k3d, etc.).

Container lifecycle (Docker compose level)

Verb Meaning Constructs/Destroys
up Build images (if needed) + create + start containers Constructs
down Stop + remove containers + networks Destroys
rebuild Force build (no cache) + recreate containers Constructs
ps Show container status Read-only
logs Stream container logs Read-only

These verbs map directly to docker compose commands. They operate on containers, not on what runs inside them.

Application lifecycle (inside containers)

Verb Meaning Constructs/Destroys
init Install dependencies (npm install, cargo build, etc.) Constructs
serve Start development server(s) Constructs
stop Stop development server(s) without removing containers Destroys
build Produce production artifacts (bundle, compile) Constructs
test Run test suite Read-only
quality Run linters, typechecks, formatters Read-only
clean Remove build artifacts, node_modules, generated config Destroys

These verbs operate on processes and files inside containers. serve starts a dev server, stop kills it. The container stays running.

Autograph lifecycle (engine-specific)

Verb Meaning Constructs/Destroys
install Resolve dependencies (West) + collect env templates Constructs
uninstall Backup env.d/ + remove resolved deps Destroys
build Aggregate env config + validate Constructs
clean Remove aggregated env config + runtime artifacts Destroys
diagnos Check system health, report actionable issues Read-only

Note: augr:build is not Docker image build. It is env config aggregation. Docker image build happens inside augr:up. This is intentional - build at the autograph level means "prepare the configuration", not "compile containers".

Composite verbs (convenience shortcuts)

Verb Meaning Typical expansion
start Full startup sequence (up + init + serve) Containers + deps + dev servers
restart down + up Quick container reset
reinstall stop + clean + init + serve Fresh deps without rebuilding containers

Host-level verbs (destructive, exceptional)

Verb Meaning
host:clean Remove all project Docker containers, volumes, networks
host:purge Full reset: host:clean + remove images

These are emergency/maintenance operations, not part of the normal lifecycle.

Verb matrix by level

Verb host: admin: augr: augr:pkg:<name>: app: app:<name>:
setup - yes - - - -
teardown - yes - - - -
backup - yes - - - -
restore - yes - - - -
install - - yes - - -
uninstall - - yes - - -
build - - yes (env) - - yes (art)
clean yes - yes yes yes yes
up - - yes - yes -
down - - yes - yes -
rebuild - - yes - yes -
ps - - yes - yes -
logs - - yes yes yes yes
init - - - - yes yes
serve - - - - yes yes
stop - - - - yes yes
start - - - - yes -
restart - - yes - yes -
reinstall - - - - yes -
test - - - - yes yes
quality - - - - yes yes
shell - - - yes - yes
chat - - - yes - -
diagnos - - yes - - -
purge yes - - - - -

Package-level tasks

Packages expose tasks under augr:pkg:<name>:*. The verbs available depend on the package type:

Package Tasks exposed Notes
pkg.agent shell, chat, build, logs, clean Agent container management
pkg.metalab shell, chat, build, logs, clean, prepare Metalab mode (see meta-mode-architecture ADR)
pkg.delivery (skills only, no tasks) Delivery tracking via agent skills

Lifecycle stages (updated)

The lifecycle is designed around symmetric pairs: each constructive action has a destructive counterpart for safe revert.

Stage Up (construct) Down (deconstruct) Namespace
Admin setup admin:setup - submodules + env/ from env.template/ admin:teardown - remove env/, deinit submod admin:
Dependencies augr:install - west resolve + collect package env templates augr:uninstall - backup env.d/ + remove deps augr:
Configuration augr:build - aggregate env.d/ -> .env.project + validate augr:clean - remove .env.project + artifacts augr:
Infrastructure augr:up - build images + start containers augr:down - stop + remove containers augr:
App containers app:up - build + start app containers app:down - stop + remove app containers app:
App runtime app:init + app:serve - install deps + start dev servers app:stop - stop dev servers app:

Orthogonal (runs at any point):

Task Semantics Namespace
augr:diagnos Check full system health, report issues with corrective actions augr:

Safety operations:

Task Semantics Namespace
admin:backup Move env// to env/.backup/ admin:
admin:restore Restore env/.backup/ to env// admin:
admin:env:purge Permanently delete backups admin:

Destructive host operations (exceptional, not part of normal lifecycle):

Task Semantics Namespace
host:clean Remove all Docker containers, volumes, networks host:
host:purge Full reset to post-clone state (Docker + images) host:

Namespace conventions

Namespace Scope Examples
admin: Project instance management (orchestrator-agnostic) admin:setup, admin:teardown, admin:backup
augr: Engine lifecycle (portable across projects) augr:install, augr:build, augr:up
augr:pkg:<name>: Package-specific tasks augr:pkg:agent:shell, augr:pkg:agent:chat
augr:engine: Engine internal operations augr:engine:update, augr:engine:diagnos
app: Application umbrella app:up, app:start, app:test, app:quality
app:<name>: Per-service application tasks app:front:serve, app:back:test
host: Destructive host-level operations host:clean, host:purge

Bootstrap sequence (first time)

1. admin:setup
   |-- git submodule update --init (engine)
   |-- Copy workspace/env.template/ -> env/ (creates .env.augr, directory structure)
   '-- Display: "Edit env/.env.augr if needed, then run augr:install"

2. augr:install
   |-- Precondition: env/.env.augr exists
   |-- west init + update (engine deps -> core packages)
   |-- west init + update (project deps -> third-party packages)
   |-- Scan packages for env templates
   '-- Copy templates -> env/<ENV>/env.d/<package-name>.env

   --> MANUAL: operator fills env/<ENV>/env.d/*.env

3. augr:build
   |-- Aggregate env/<ENV>/env.d/*.env -> env/.env.project
   |-- Validate completeness (fail if empty required vars)
   '-- Display: "Build complete. Run task augr:up"

4. augr:up
   |-- Build Docker images (compose reads .env.project via dotenv)
   '-- Start containers (agent, phoenix, etc.)

5. app:up (if project has application services)
   '-- Build + start app containers (front, back, etc.)

6. app:start (convenience: app:up + app:init + app:serve)
   |-- app:init - install deps in containers
   '-- app:serve - start dev servers

Teardown sequence (reverse order)

1. app:stop           -> stop dev servers
2. app:down           -> stop + remove app containers
3. augr:down          -> stop + remove augr containers
4. augr:clean         -> remove .env.project + runtime artifacts
5. augr:uninstall     -> backup env.d/ + remove west modules
6. admin:teardown     -> remove env/ entirely + deinit submodules

Self-diagnosis rules

Each task must be able to determine its own state:

Task Preconditions (fail if not met) Status (skip if already done)
admin:setup - env/.env.augr exists
admin:teardown - env/.env.augr does not exist
augr:install env/.env.augr exists engine/deps/.west exists + modules + env.d/ present
augr:uninstall - engine/deps/.west does not exist
augr:build env/<ENV>/env.d/ has files .env.project newer than all sources
augr:clean - .env.project does not exist
augr:up .env.project exists containers running
augr:down - containers not running
augr:diagnos - (must work in any state) never skips
app:up augr containers running app containers running
app:down - app containers not running
app:init app containers running node_modules / target present
app:serve app:init done dev servers responding
app:stop - dev servers not responding

Idempotency

All constructive tasks are safe to run multiple times:

  • admin:setup - skips if env/.env.augr already exists
  • augr:install - skips if deps already resolved + env.d/ already populated
  • augr:build - skips if .env.project is fresher than all sources
  • augr:up - rebuilds only changed images, recreates only changed containers
  • app:up - same as augr:up
  • app:init - skips if lock file unchanged
  • app:serve - restarts if already running
  • augr:diagnos - pure read, no side effects

Future: package hooks

Each lifecycle stage will become a hook point where packages can register actions. The exact mechanism (Taskfile includes, convention-based task names) will be defined when we have concrete packages that need it.

Trade-offs

  • More commands to learn than a single augr:init
  • The symmetric pairs add surface area but make the mental model predictable and safe for testing
  • The admin:setup -> manual edit -> augr:install two-step is required by Task's dotenv mechanics (env file must exist before parsing)
  • The lifecycle model will grow with usage - current stages are the minimum viable set
  • augr:build meaning "env aggregation" (not Docker images) is non-obvious - but consistent within the autograph domain (build = prepare the configuration layer)