# Project configuration and locking

> Committed desired state and generated template provenance.

---

LLMS index: [llms.txt](/ainfra/v0.1/llms.txt)

---

An ainfra project separates committed intent from local operational state:

```text
my-infrastructure/
├── ainfra.yaml
├── ainfra.lock
├── environments/
│   └── development.yaml
└── .ainfra/
```

`ainfra.yaml` names the project, selects one built-in template, and maps
environment names to `TemplateInput` files. Those files hold non-secret
provider, topology, network, access, and state intent. Credentials remain
external references such as `HCLOUD_TOKEN`.

`ainfra.lock` is generated by `ainfra init` and should normally be committed.
It pins the template source, name, manifest version, and SHA-256 digest of the
complete embedded template. Normal project validation never rewrites it.

`.ainfra/` is ignored operational state. Reviewed plans, retained workspaces,
outputs, and other run artifacts belong there, not in committed
configuration.

## Discovery and containment

Running `ainfra validate` without a target searches from the current directory
upward and selects the nearest `ainfra.yaml`. Project configuration, lockfiles,
and environment inputs must be regular files rather than symbolic links.
Environment paths must be relative and remain inside the canonical project
root.

Lifecycle commands select project mode explicitly with `--environment ENV`.
The reviewed plan uses `ainfra.plan/v1alpha2` and binds the canonical project
root, `ainfra.yaml`, `ainfra.lock`, selected input, embedded template, backend,
and OpenTofu plan bytes. Any committed-input change requires a new plan.

The explicit `TEMPLATE --input INPUT` compatibility mode remains available for
existing development runs. It uses the legacy `v1alpha1` record protocol.
Neither record version can authorize execution through the other mode.

Legacy explicit records may remain under the original repository's ignored
`.ainfra/` directory as audit and recovery evidence. They cannot be upgraded
in place, filled with project fields, or used by `up` or `down`. Inspect them
with `ainfra legacy inspect --root PATH`; normal project lifecycle requires a
new `v1alpha2` plan bound to the exact project, lockfile, input, template, and
backend configuration.
