# `PtcRunner.Lisp.Prelude.Bundle`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/lisp/prelude/bundle.ex#L1)

Deterministic source-level composition for selected capability preludes.

This is the selection-only helper for live prelude evolution. It does not
introduce storage or version policy: callers pass source-bearing selection maps,
the helper validates each component, rejects duplicate namespaces, concatenates
the sources in selection order, and compiles the aggregate source once into the
normal `%PtcRunner.Lisp.Prelude{}` artifact accepted by `Lisp.run/2`.

# `component`

```elixir
@type component() :: %{
  id: String.t() | nil,
  version: pos_integer() | nil,
  checksum: String.t() | nil,
  source_hash: String.t(),
  namespaces: [String.t()],
  origin: String.t() | nil
}
```

# `origin`

```elixir
@type origin() :: String.t() | atom() | {:file, Path.t()} | {:memory, term()} | nil
```

# `selection`

```elixir
@type selection() ::
  %{
    :source =&gt; String.t(),
    optional(:id) =&gt; String.t(),
    optional(:version) =&gt; pos_integer(),
    optional(:checksum) =&gt; String.t(),
    optional(:origin) =&gt; origin()
  }
  | map()
```

# `compile`

```elixir
@spec compile([selection()]) ::
  {:ok, PtcRunner.Lisp.Prelude.t()}
  | {:error, PtcRunner.Lisp.Prelude.ValidationError.t()}
```

Compiles selected prelude sources into one frozen prelude artifact.

Source order is preserved. Duplicate namespace ids fail closed before the
aggregate compile. Component provenance is stored in `prelude.metadata` and
exposed by `PtcRunner.Lisp.Prelude.trace_summary/1`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
