PtcRunner.Kernel.ToolGrant (PtcRunner v0.15.0)

Copy Markdown View Source

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

capability_callbacks(state, kind, environment, dispatch_context, event_sink, inspection_sink)

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

capability_contracts(map)

@spec capability_contracts(map()) :: %{required(binary()) => map()}

Returns the bounded documentation contracts for installed capabilities.