PtcRunner.Lisp.Prelude.Attach (PtcRunner v0.13.0)

Copy Markdown View Source

Attach-time validation for a compiled deployment prelude (Capability Prelude V1, plan §3 / §6A).

Prelude validation is split in two phases:

  • compile-time (PtcRunner.Lisp.Prelude.Compiler) checks source syntax, (ns ...) directives, reserved-namespace declarations, duplicate refs, visibility, and arity/signature metadata — facts that do NOT depend on a selected runtime. It also infers each export's requires backing ids from literal (tool/call {:server "x" :tool "y" ...}) patterns. Dynamic server/tool values yield :unknown effect and no requires.

  • attach-time (this module) checks each public export's requires against the SELECTED upstream runtime BEFORE user code is analyzed. If a public export requires an upstream operation that is not configured or not present on the selected runtime, attachment fails — naming the missing operation — so a run never starts against a prelude whose backing operations are unavailable.

This split lets a single compiled prelude artifact be reused across runs while still failing fast when the selected runtime cannot back it.

Where the attach hook lives

attach/2 is the seam P2 wires at the TOP of PtcRunner.Lisp.run (and the SubAgent / REPL surfaces), before parsing/analyzing user code. The prelude: option may be either a compiled %PtcRunner.Lisp.Prelude{} artifact or raw prelude source (a binary), which attach/2 compiles first. On success it yields the compiled artifact for the analyzer/evaluator path; on failure it yields a %PtcRunner.Lisp.Prelude.ValidationError{} that the call site maps to {:error, %PtcRunner.Step{fail: %{reason: :prelude_attach_failed}}}.

Genuine programmer misuse (passing a value that is neither a prelude artifact nor source) raises ArgumentError; a missing/ungranted upstream op is a recoverable {:error, ...}, never a raise.

Requires id format

Two backing id shapes are recognized:

  • "upstream:<server>/<tool>" — validated against the selected upstream runtime. <server> must be a configured upstream; <tool> must be present in that upstream's tool list (mirroring the upstream runtime's configured-tool checks). When an upstream's tool list is not yet materialized (lazy MCP transports report nil tools), the specific tool cannot be checked and the requirement passes on the configured server alone. When no upstream runtime is configured for the run, upstream requirements are skipped (there is no runtime to check; the granted (tool/call ...) closure plus check_undefined_tools still guard the actual surface) — preserving direct-Lisp.run-with-stub use.

  • "tool:<name>" — validated against the run's granted tools: map (a host-bound typed-tool capability). Fails closed when the host did not grant a tool of that name. This is checked regardless of whether an upstream runtime is configured.

Any other requires id shape fails attachment (fail-closed).

Summary

Types

A selected upstream runtime handle (a %PtcRunner.Upstream.Runtime{} struct, a pid, or a registered name), or nil when no upstream runtime is configured for the run. Mirrors the handle shapes PtcRunner.Upstream.Runtime.upstream/2 accepts.

Functions

Resolves prelude_or_source to a compiled artifact, then validates its requires against the attach context (%PtcRunner.Lisp.Prelude.AttachContext{}, bundling the upstream runtime and the granted tools: map).

Validates every public export's requires against the attach context.

Types

runtime()

@type runtime() :: struct() | pid() | atom() | nil

A selected upstream runtime handle (a %PtcRunner.Upstream.Runtime{} struct, a pid, or a registered name), or nil when no upstream runtime is configured for the run. Mirrors the handle shapes PtcRunner.Upstream.Runtime.upstream/2 accepts.

Functions

attach(prelude, context)

Resolves prelude_or_source to a compiled artifact, then validates its requires against the attach context (%PtcRunner.Lisp.Prelude.AttachContext{}, bundling the upstream runtime and the granted tools: map).

Returns {:ok, %PtcRunner.Lisp.Prelude{}} on success.

Returns {:error, %ValidationError{}} when:

  • the source fails compile-time validation (any compile reason), or
  • attach-time requires validation fails (:prelude_attach_failed).

Raises ArgumentError for genuine programmer misuse: a value that is neither a %PtcRunner.Lisp.Prelude{}, prelude source (binary), nor a list of source-bearing prelude selection maps.

validate_requires(prelude, context)

Validates every public export's requires against the attach context.

Returns :ok when all required backing operations are provided (or when there are no requires to check — e.g. dynamic-backed exports). Returns {:error, %ValidationError{reason: :prelude_attach_failed}} naming the first missing operation and the export that needs it.