# Semantics and Limits An image is not a sandboxed runtime or a different evaluator — it is the same code, compiled ahead of time. What changes is where the code comes from; what stays is how it runs. ## What Works Unchanged - The prelude still loads. Images run on top of the normal prelude, so mounts, `config.dft`, `lang.dft`, `keys.dft`, and project settings layer on exactly as they do for source apps. - `eval` still sees the app. Runtime `[eval ...]` resolves the image's globals and expands its macros, because the macro registry is installed from the image before any statement executes. - Imports resolve without the source tree. The loader pre-creates every module namespace and registers it by import name and by compile-time source path. Relative imports inside the image (`./lib/foo`, directory-index forms, dotted stems like `./colors.syntax`) find the embedded modules without touching disk. - `source` is captured. Top-level `source "file"` forms are resolved and inlined recursively at compile time, so sourced definitions are embedded like imports. - Errors behave the same. A statement that fails while the image loads is reported and skipped, then later statements still run — matching the source loader's policy. ## What Images Cannot Do - No source reads at runtime. `reload`/`load` of new files are unavailable. `source` forms reached only at runtime (for example inside a function body) are not captured; only top-level `source` is inlined. - No dynamic import targets unless embedded. Imports whose names are computed at runtime are invisible to the static walk. Pass `--embed <module>` for each target; the importer then resolves it from the pre-registered namespace. - `require` is compile-time only. Its macro effects are captured; the file itself is not loaded again at runtime. ## A Mixed World by Design The compiler stays linked in every host. That is deliberate: the same runtime executes a vendor image and locally compiled user code (config files, `eval`, plugin loading) side by side. A locked-down build that omits the compiler entirely is a separate build option, not something an image toggles. Images still need a compatible runtime: `DFTC` is versioned (v1 today), and a reader rejects unknown versions and non-zero header flags. The header reserves flags for encrypted/signed images — signing and per-license encryption are planned, not implemented. Rebuild images when moving to a kernel with a newer image format. ## Capabilities and Platforms - `requires` (from `--requires`, recorded in the image manifest) is enforced: a host refuses an image whose requirements its plugin set cannot satisfy. - `platforms` (from the package's `capabilities.platform`, recorded in both manifests) is advisory metadata naming the intended hosts — useful for installers and for `bundle.dft` consumers, but not a loader gate. ## Assets Are Files, Not Bytes The image embeds imported modules and their compiled bodies; it does not embed images, fonts, or data. Package assets are copied into the bundle's `assets/` directory and resolved beside the image through `[import/resolve]`. An app that hard-codes absolute asset paths, or only probes its original package root, needs those files placed to match. See Bundles and Manifests.