Freezing a Flight Plan
Freeze is the author-time step that seals an installed Aileron skill into a Flight Plan (ADR-0027). A skill before freeze names its execution environment by a movable tag. A Flight Plan after freeze pins every image to a content-addressed digest, records a lockfile, content-addresses the whole unit, and carries a detached signature. The frozen version is written immutably into the canonical skill store. This guide walks through running freeze and explains the guarantees it produces.
What freeze does
Freeze runs a fixed sequence over one SKILL.md document.
- It parses and lints the manifest. The lint rejects any step that could reach an LLM outside the marked
llm-seam(see the manifest spec). - It resolves the declared environment to exactly one image digest. Declared
environment.toolsare resolved to their catalog devcontainer Features and composed onto the Aileron-provided runner base, and the built image is pinned by itssha256:digest. A customenvironment.imageis resolved to itssha256:digest; whentoolsare declared alongside it, they compose onto that custom base. The plan runs in one container, so this resolves to a single pin. A plan that declares no environment pins nothing. - It builds the lockfile. The lockfile records the single resolved image pin, the resolved capability set, the step-keyed sealed trust reach for each tool step that declared a trust contract, the content hash, and the semver label.
- It content-addresses the unit. The content hash is a
sha256over the canonical frozen manifest bytes plus the lockfile bytes. - It signs the content with a detached ed25519 signature.
- It writes the frozen version into the store as an immutable directory.
Freeze pins by digest, never by tag. A resolver that returns a tag rather than a digest is a hard error.
Running freeze
Freeze takes the name of an installed skill or a path to a SKILL.md.
aileron skill freeze weekly-metrics-digest \
--signing-key ~/.aileron/keys/author.pem \
--version 1.0.0The signing key is a PEM-encoded ed25519 private key. Pass it with --signing-key or set AILERON_SIGNING_KEY to the key path. The key is read for signing only. It is never copied into the frozen artifact or the store.
The --version flag records a human-facing semver label in the lock. It is optional.
Freeze prints the skill name, the version label, the content hash, and the on-disk location of the frozen version.
The frozen version
A frozen version lives under the skill in the store at ~/.aileron/skills/<name>/versions/<id>/. The version id is a short content-derived slug of the content hash. Each version directory holds four files.
| File | Contents |
|---|---|
SKILL.md | The frozen manifest with the populated lock block injected. |
aileron.lock | The standalone lockfile, the durable pin record. |
signature.sig | The detached ed25519 signature over the content bytes. |
signing-key.pub | The author public key the signature verifies against. |
The pre-freeze installed SKILL.md at the skill name root is never touched. Freeze adds versions beside it.
Guarantees
Freeze is reproducible. Running freeze twice over byte-identical input with the same key produces the same content hash, the same frozen bytes, and the same signature. ed25519 is deterministic for a fixed key and message.
Frozen versions are immutable. Re-freezing changed content writes a new version directory and leaves every prior version byte-identical. Re-freezing identical content to an existing version id is a verified no-op. Writing different content to an existing version id is rejected.
The signature is verifiable at launch. A verifier needs only the signature and the public key, both stored beside the version. The launch-time runtime (#1511 ↗) verifies the signature before it runs a Flight Plan.
The signing private key never enters the store. Only the public key and the detached signature are persisted.
A frozen version is multi-identity. The seal carries no credential binding and no identity. The identical frozen version launches under different vault-bound identities with different authorizations, and the audit trail records who ran it. The credential binding lives on the launching operator’s machine, so the same signed bytes serve many operators without carrying any one operator’s identity.