PtcRunner.Kernel.ReplSession (PtcRunner v0.14.0)

Copy Markdown View Source

Direct bounded PTC-Lisp continuation used by the Kernel REPL frontend.

Successful forms commit definitions transactionally and retain up to three prior results for *1, *2, and *3. Failed forms preserve the previous memory. A session uses the workflow bundle, capabilities, limits, input, labels, and event policy from an optional PtcRunner.Kernel.RunConfig but does not execute the manifest entry function. REPL continuation and history require the native result projection, so a supplied configuration sealed for JSON command output is rejected before its recorder is claimed.

A session is process-affine: the process that calls new/1 is its owner and must perform every eval/2, close/1, and abort/2 call. Passing the struct to another process does not transfer ownership; those calls return {:error, :session_owner_mismatch} without touching continuation or lifecycle state. The public value contains only an opaque ID, one shared creator-private lookup table, and bounded attempt counters—not an owner PID or token. Closed lookup entries are removed. Continuation values and raw run-state, sink, provider, and configuration capabilities remain inside the internal owner process. Watchdogs couple compilation and evaluation sandboxes to the creator; all owned resources and in-flight work are stopped if it exits.

Call close/1 for an atomically frozen terminal batch or abort/2 when the frontend terminates early. Both paths use the recorder's reserved terminal capacity and persist an authorized trace inside the session owner before releasing its resources.

Summary

Functions

Closes a session with an error reason and returns retained events when available. When provider cleanup or trace persistence fails after terminal publication, the error tuple also returns those events.

Closes a session normally and returns its atomically frozen canonical events. When provider cleanup fails after terminal publication, the error tuple also returns the frozen events as evidence; the session owner has already attempted any authorized trace persistence without exposing that authority to the frontend.

Evaluates one bounded source form and returns the updated session.

Starts a session with optional :config and :trace_path options.

Types

t()

@type t() :: %PtcRunner.Kernel.ReplSession{
  access: :ets.tid(),
  attempts: non_neg_integer(),
  errors: non_neg_integer(),
  id: reference()
}

Functions

abort(session, reason)

@spec abort(t(), atom()) ::
  {:ok, [map()]}
  | :ok
  | {:error, :provider_cleanup_failed, [map()]}
  | {:error, :trace_persistence_failed, [map()]}
  | {:error, :provider_cleanup_failed | :session_owner_mismatch}

Closes a session with an error reason and returns retained events when available. When provider cleanup or trace persistence fails after terminal publication, the error tuple also returns those events.

Returns {:error, :session_owner_mismatch} without closing anything when called outside the process that created the session.

close(session)

@spec close(t()) ::
  {:ok, [map()]}
  | {:error, :provider_cleanup_failed, [map()]}
  | {:error, :trace_persistence_failed, [map()]}
  | {:error,
     :event_sink_error
     | :provider_cleanup_failed
     | :session_closed
     | :session_owner_mismatch}

Closes a session normally and returns its atomically frozen canonical events. When provider cleanup fails after terminal publication, the error tuple also returns the frozen events as evidence; the session owner has already attempted any authorized trace persistence without exposing that authority to the frontend.

Returns {:error, :session_owner_mismatch} without closing anything when called outside the process that created the session.

eval(session, source)

@spec eval(t(), binary()) ::
  {:ok, PtcRunner.Lisp.Result.t(), t()}
  | {:error, PtcRunner.Lisp.Result.t(), t()}
  | {:error, :session_owner_mismatch}

Evaluates one bounded source form and returns the updated session.

The returned result is an observation-only public projection. The exact native memory and history used by later forms remain inside the session owner; callers must not thread the result's memory back into the session.

Returns {:error, :session_owner_mismatch} without evaluating when called outside the process that created the session.

new(opts \\ [])

@spec new(keyword()) :: {:ok, t()} | {:error, term()}

Starts a session with optional :config and :trace_path options.

Without a config, the session creates empty environments, default limits, and a normal in-memory event sink. Exact native history has the fixed language depth of three and is owned by RunState with continuation memory.

A supplied config's event and optional inspection sink owners are frozen when the config is constructed and must match the calling process. A mismatch or inconclusive live-sink ownership probe returns {:error, :session_owner_mismatch} before the recorder is claimed or a run state is started and leaves the config untouched. A trace destination is validated against the session's data class before any run state is started. A dead owned sink closes the config's provider session before setup fails. The config must select the native result projection; a JSON-projection config returns {:error, :invalid_repl_session} untouched.