Host-bound, read-only introspection over recorded turn-log sessions, packaged
as the log/ capability prelude (plan P3, D4).
This is the proving consumer for "preludes are the sole opt-in mechanism": the Elixir surface stays deliberately boring — plain data access over the turn log (list sessions, fetch a session's turns/programs/tool-calls). Higher-level analysis (dedup detection, cost aggregation, where-did-it-waste-turns) lives in the PTC-Lisp programs that call these exports, not here.
Wiring
source = sink_pid_or_jsonl_path_or_event_list
PtcRunner.Lisp.run(program,
prelude: PtcRunner.TraceLog.Introspection.prelude_source(),
tools: PtcRunner.TraceLog.Introspection.tools(source))The log/ prelude's exports invoke typed tools (tool/log_sessions, …), so
the compiler infers tool:log_sessions-style requires. Attach fails closed
unless the host grants those tools (the tools/0 map). Read-only by design
(the two-grant rule, D4): there is no live-session control here.
Memory model (P2 of docs/plans/sandbox-heap-rebaseline.md)
The granted closures are thin proxies: projections are computed host-side —
inside the MemorySink for pid sources, inside a
PtcRunner.TraceLog.Introspection.Holder started by tools/2 for path and
list sources — so only each call's RESULT enters the sandbox and a program's
heap cost tracks result size, never log size. Call tools/2 once per grant
(each path/list call starts a holder owned by the calling process; it stops
when that process goes down). A stopped sink/holder surfaces as a clear,
recoverable tool error, not a hang.
Trust
Recorded sessions are untrusted data — they may contain adversarial or junk programs. These tools return them as evidence to be analyzed, never as instructions to follow.
Summary
Types
A turn-log source: an in-memory sink pid, a JSONL trace path, or an already loaded list of event maps.
Types
Functions
@spec prelude_source() :: String.t()
The log/ introspection prelude source. Attach it with the tools/1 grant.
Builds the granted, host-bound tool closures over source.
Grant these as tools:; the keys ("log_sessions", "log_turns",
"log_programs", "log_tool_calls") match the tool:<name> requirements the
log/ prelude infers. All closures are read-only and return string-keyed data.
Path and list sources start a Holder owned by the calling process (see the
memory-model section above). Options: :max_bytes — the holder's
serialized-size load cap; raises ArgumentError for oversized logs.