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

The capability context a prelude's `requires` are validated against at attach
time (plan P3).

V1 attach validation saw only the upstream runtime. The introspection prelude
(and any future host-bound capability) declares `tool:<name>` requirements
that are satisfied by the run's granted `tools:` map, not the upstream
runtime — so attach needs both. This struct bundles them (with room for
future grant kinds) so the grant surface grows as a single context value
rather than a widening positional argument list.

Fields:

  * `:runtime` — the selected upstream runtime handle (a
    `%PtcRunner.Upstream.Runtime{}`, a pid, a registered name), or `nil` when
    no upstream runtime is configured. Validates `upstream:<server>/<tool>`
    requirements.
  * `:tools` — the granted `tools:` map (`%{name => closure | Tool}`) whose
    keys name the typed-tool capabilities the host has granted. Validates
    `tool:<name>` requirements.

Tool names are **strings**, matching `PtcRunner.Lisp.run/2`'s execution
contract (a `(tool/foo ...)` call resolves the tool by the string `"foo"`).
`tool:<name>` grant checks compare against string keys, so atom-keyed tools
are treated as ungranted — consistent with execution, where they would also be
unresolved. This is intentionally not papered over here: stringifying keys at
attach while execution stays string-keyed would let attach pass and the call
then fail at runtime.

# `t`

```elixir
@type t() :: %PtcRunner.Lisp.Prelude.AttachContext{
  runtime: PtcRunner.Lisp.Prelude.Attach.runtime(),
  tools: %{optional(String.t()) =&gt; term()}
}
```

# `grants_tool?`

```elixir
@spec grants_tool?(t(), String.t()) :: boolean()
```

True when the granted tools map contains a typed tool named `name`.

# `new`

```elixir
@spec new(keyword()) :: t()
```

Builds an attach context from options.

## Options

  * `:runtime` - upstream runtime handle (default: `nil`)
  * `:tools` - granted tools, in any shape `PtcRunner.Lisp.run/2` accepts (a
    `%{name => tool}` map OR a `[{name, tool}, ...]` tuple/keyword list);
    canonicalized to a map so grant checks are shape-agnostic (default: `%{}`)

---

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