Builds the capability callbacks handed to a sandboxed evaluation.
Every callback here is copied into the sandbox process, and that copy is
flat — spawn does not preserve sharing. A callback must therefore close
over only what it reads. Dispatcher.dispatch/8 resolves one name, so each
capability callback carries one capability via
PtcRunner.Kernel.Environment.capability_view/2; only the runtime discovery
routes carry the whole map, via capability_view/1.
The cost of getting this wrong is not linear. A term every callback captures
is copied once per callback, so capturing anything environment-sized makes
the hand-over O(capabilities²) — enough for a tool-rich MCP environment to
blow the sandbox setup ceiling before the program runs, and enough for a
modest environment to eat the program's whole heap budget through the
measured baseline. PtcRunner.Sandbox documents how that baseline is billed.
Size a grant with :erts_debug.flat_size (plus referenced binaries for byte
units); that is what the sandbox's own baseline measurement bills.
Summary
Functions
Returns the capability dispatch callbacks plus reserved runtime routes for one environment.
Returns the bounded documentation contracts for installed capabilities.
Functions
@spec capability_callbacks( term(), :workflow | :mission, map(), %{ mission_name: binary() | nil, timeout_ms: non_neg_integer(), validation_heap_words: pos_integer(), evaluation_lease: reference() | nil, validation_deadline_ms: integer() | nil }, term(), term() ) :: %{required(binary()) => (map() -> map())}
Returns the capability dispatch callbacks plus reserved runtime routes for one environment.
Callers add their own environment-specific routes (kernel-eval, the
workflow inventory routes, TrustedTool wrapping) to the result. Those
extra routes are not capability callbacks and are not refusal-counted;
wrapping happens inside this grant, after RuntimeTools.tools/5 is merged.
Returns the bounded documentation contracts for installed capabilities.