Living Lisp guide

Marginalia for the image you are observing: facts are marked observed; explanations are models.

Values in memory

Observed: /proc/self/maps reports virtual regions and permissions. It does not identify Lisp objects.

Model: SBCL commonly represents small integers and simple values immediately, while conses, strings, vectors, closures, symbols, and larger numbers occupy heap objects with headers and pointers. Exact layout depends on SBCL, architecture, GC state, and object type.

Therefore: a large anonymous mapping is evidence of address-space reservation or heap/stack/runtime storage, not proof that one source form owns it.

Function calls

Observed: a request thread enters handle-client, parses a path, calls dispatch, writes a response, and emits completion.

Model: compiled Lisp functions pass arguments in registers and/or stack slots according to compiler decisions. Closures may carry environment objects. Exact frames are not shown here; /stack is the available backtrace.

Asynchrony

This server has threads and blocking waits, not server-side promises: listener -> request thread -> dispatch -> response; worker -> sleep -> state update -> event; SSE client -> condition-wait -> send event; browser fetch() -> JavaScript Promise -> render.

Marginal note: condition-wait is synchronization, not magic parallel evaluation. Events expose order; request IDs expose causal boundaries.

Evaluation path

HTTP request -> parse body -> select model -> assemble context -> validate -> provider request -> normalize -> redacted completion

Generated Lisp follows: read with *read-eval* = NIL -> inspect capabilities -> refuse live-image evaluation -> optionally run a narrow pure expression in a separate subprocess.

Inspect next

Use memory for address-space geography, source for definitions, events for behavior, stack for backtraces, and state for the raw snapshot.