# Bundles and Manifests A compiled app carries its metadata in three places, each with a different job. They overlap by design — one is authoritative at run time, one is the distribution descriptor, one exists for discovery. | Artifact | Format | Written by | Read by | |---|---|---|---| | `*.dftc` image manifest | binary `DFTC` payload | `deft compile` | hosts/app loader (identity, capabilities) | | `bundle.dft` | Deft data (`%DeftApp{…}`) | `deft compile --app` | installers/launchers (today: nothing at runtime) | | `package.dft` | Deft data (`%Package{…}`) | copied from the package | launcher/app-selector package discovery | ## The Image Manifest The image is self-describing. Its `DFTC` header (magic, version, flags, payload length) is followed by the manifest — `entry`, `requires`, `created-by`, prelude policy, and, for `--app` images, the app identity: `app-owner`, `app-name`, `app-version`, `app-description`, `app-entry`, `app-platforms`. The rest of the payload carries the macro registry, the module table, and the compiled bodies. That manifest is what the runtime actually consults: `retro app` and friends can peek it before decoding, and the capability check reads `requires` from it. When in doubt, the image is the source of truth. ## `bundle.dft` Generated by `deft compile --app`, it is the distribution descriptor — everything an installer or launcher needs in human-readable form: ``` %DeftApp{ owner "deft" name "editor" version "0.1.0" description "Code editor" main "src/editor.dft" image "editor.dftc" sha256 "1c21ac2b…d896d2" platforms @{ "retro" "retra" } requires @{ } } ```` | Field | Meaning | |---|---| | `owner`, `name`, `version`, `description` | App identity, from the package manifest | | `main` | The package's original source entry (may not exist in the bundle) | | `image` | Image filename, relative to the bundle directory | | `sha256` | Lowercase hex SHA-256 of the image file's bytes | | `platforms` | Intended hosts, from the package's `capabilities.platform` (advisory) | | `requires` | Runtime capabilities recorded by `--requires` (enforced by hosts) | Every field is always written; absent values are empty strings/lists. Nothing in the runtime reads `bundle.dft` today — the image manifest carries the authoritative copy. Treat it as the hand-off format for your installer: verify `sha256`, copy `image` + `assets/` + `icon.svg`, and read `requires`/`platforms` for placement decisions. If you repack or replace the image, regenerate the file (recompile) or recompute the digest, or the two artifacts disagree. ## `package.dft` The original package manifest is copied into the bundle verbatim. The launcher and app selector identify a package by its `package.dft` (plus an entry), so the copy is what makes the bundle directory discoverable under a `:pkgs` root. It keeps the authoring fields the image does not need — `tags`, `author`, `license`, `deps`, `capabilities` — and its `main` still names the source path, which the discovery probes handle when only the `.dftc` exists. ## Verifying a Bundle `sha256` is a plain checksum over the image bytes: ```sh sha256sum /opt/vendor/packages/acme/pos/pos.dftc # compare with the sha256 field in bundle.dft grep sha256 /opt/vendor/packages/acme/pos/bundle.dft ```` `bundle.dft` parses as ordinary Deft data, so tooling can read it with `[fs/read]` + `[deft/parse]` rather than string matching.