# 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.