Lisp Machine knowledge base
Bundle OKF 0.1 · 116 conceitos · htayj/lisp-machine-container-museum
Open source Repository Open in the app JSON README (API)
About
# Lisp Machine knowledge base
This is the durable research and interpretation layer of the repository. It records
what the preserved systems are, how their artifacts work, and what we learn while
running and studying them.
The root [README](../README.md) remains the practical guide to launching the museum.
These pages are written as portable Markdown so they can become the source of a future
public static site without moving the canonical content elsewhere.
The `docs/` directory is an Open Knowledge Format 0.1 bundle. OKF adds a small,
machine-readable metadata layer while retaining ordinary Markdown as the source.
## Collections
- [Guided tour](tour/index.md) - Linear beginner stories for learning the UI
language while moving through CADR and Genera applications, with reviewed runtime
views, many short interaction animations, and separate exhaustive atlases.
- [Symbolics Genera and Open Genera](genera/index.md) - The later Symbolics system,
its Virtual Lisp Machine, and preserved
Details
- Kind
- OKF bundles
- Topic
- AI, RAG & memory
- Publisher
- htayj
- Origin
- okf_github
- Category
- dados
- Version
- 0.1
- Stars
- 1
- Last push
- 2026-08-11T15:49:00Z
- Repository state
- ativo
- Language
- JavaScript
- Added
- 2026-09-09 19:04:11
- Updated
- 2026-09-09 19:04:11
- Origin id
htayj/lisp-machine-container-museum:docs/index.md
README
# lisp-machine-container-museum This repo launches two Lisp Machine environments in Guix containers: - `CADR / LM-3`: fully public, based on the LM-3 upstream Fossil repos - `Open Genera`: requires your own purchased `opengenera2.tar.bz2` If you only want one system to start exploring, use the CADR path first. Historical, architectural, and artifact research lives in the [museum knowledge base](docs/index.md). It includes the current analysis of [Open Genera VLOD world files](docs/genera/world-loads-and-vlod.md). The same canonical Markdown is published as a Genera-profile GitHub Pages site: <https://htayj.github.io/lisp-machine-container-museum/> Build the site locally with Pandoc and the pinned public Genera Fonts release: ```bash curl -L --fail \ https://github.com/htayj/genera-fonts/releases/download/v0.1.1/Genera-fonts-latin-v0.1.1.tar.gz \ -o /tmp/Genera-fonts-latin-v0.1.1.tar.gz echo "a72cfaa9ed6c418ba751d4a32d3cf715b1b3e6edd44acdc144f297d0c915b3cf /tmp/Genera-fonts-latin-v0.1.1.tar.gz" \ | sha256sum --check python3 scripts/build-docs-site.py \ --font-archive /tmp/Genera-fonts-latin-v0.1.1.tar.gz python3 -m http.server 8000 --directory _site ``` The generated `_site/` tree is ignored. The Pages workflow builds it from `docs/` and does not commit generated HTML or Genera font data to this repository. See [Publishing the museum documentation site](docs/site-publication.md) for the interface behavior, font provenance, build boundary, and validation procedure. ## What you need - Guix installed and working on the host - X11 available on the host - for Open Genera only: a local `opengenera2.tar.bz2` If X11 authentication fails, allow your user explicitly: ```bash xhost +SI:localuser:$USER ``` ## Which emulator to use Use `CADR / LM-3` if you want: - a fully public system - the simplest first boot - the MIT LM-3 environment from `tumbleweed.nu` Use `Open Genera` if you want: - Symbolics Genera - your own commercial Open Genera world - a closer approximation of a later Symbolics workstation environment ## CADR / LM-3 ### Launch ```bash ./scripts/cadr-guix-container.sh --mode run ``` The first run will: 1. start a Guix container with the build/runtime dependencies for `usim` 2. create a local Fossil checkout in `./l` 3. cache the supporting upstream Fossil repositories in the repo root 4. build and launch the emulator ### What a successful boot looks like A successful cold boot normally lands in a Lisp Listener. That is not a blank system; it is the expected usable prompt. On the first run, the bootstrap and build can take a while. Later runs should be much faster. ### Keyboard notes The default CADR key mapping in `usim` includes: - `F1` = System - `F2` = Network - `F3` = Status - `F4` = Terminal - `F5` = Help - `F6` = Clear Input If you are unsure what to do next after boot, `F5` is the first key to try. ### Headless computer-use harness The computer-use harness runs `usim` on a private, authenticated Xvfb display and drives its real X11 window through keyboard and mouse events. It is intended for repeatable behavioral checks and evidence screenshots without taking over the host desktop. Check the harness dependencies and prepared CADR artifacts: ```bash ./scripts/cadr-computer-use.sh doctor ``` Start a named session and inspect its status: ```bash ./scripts/cadr-computer-use.sh start --session research ./scripts/cadr-computer-use.sh status --session research ``` The first start creates private copies of the System 303 disk and source trees. A later plain `start` cold-boots that existing private runtime. Use `--fresh` to discard and recreate the private runtime from the current public base before cold booting a stopped session: ```bash ./scripts/cadr-computer-use.sh stop --session research ./scripts/cadr-computer-use.sh start --session research --fresh ``` Fresh preparation builds and validates a staged runtime before installing it. The state root, each session, and each completed private runtime carry harness ownership markers; the tool refuses to adopt similarly named existing directories without them. A pre-hardening session directory therefore cannot be reused automatically: preserve it as evidence or remove it manually after review, then choose a new session name. Wait for an elapsed interval or a stable screen, then send keyboard input: ```bash ./scripts/cadr-computer-use.sh wait --session research --seconds 10 ./scripts/cadr-computer-use.sh wait --session research --stable-for 3 --timeout 180 ./scripts/cadr-computer-use.sh key --session research help ./scripts/cadr-computer-use.sh type --session research --enter '(+ 2 3)' ``` `help` is the portable key alias for `F5`; the other aliases are listed by the script's `key --help` output. Mouse coordinates address the 768 by 963 CADR client window. Host button 3 is the CADR head/rightmost button: ```bash ./scripts/cadr-computer-use.sh mouse --session research move 400 500 ./scripts/cadr-computer-use.sh mouse --session research click 400 500 --button 3 ``` Capture the exact client window and stop the session cleanly: ```bash ./scripts/cadr-computer-use.sh screenshot --session research --label listener ./scripts/cadr-computer-use.sh stop --session research ``` Screenshots, JSON provenance sidecars, private disks and source trees, saved emulator state, credentials, and logs stay in the ignored `build/cadr-computer-use/<session>/` directory. `stop --discard` deletes that named session instead of retaining it. Current sidecars distinguish revisions in the public checkouts at start from the private sources' copy-time revisions; they also hash the private source trees, `usim` executable, and private microcode and symbol files used by the run. Toolchain provenance records the Guix channel, manifest hash, Python version, and resolved commands as well. Immediately before launching the shared `usim` executable, the supervisor reacquires the preparation lock, hashes it again, compares that value with `usim_sha256_at_start`, and performs the launch while still holding the lock. A mismatch fails the start. The execution-time hash is kept in session state; screenshot sidecars retain only the start-time hash. A normal stop reports `forced_stop: false` and `state_may_be_incomplete: false`. If a process exceeds its shutdown timeout and must be killed, the session is labeled `forced-stopped` with both flags true; do not treat that saved emulator state as a known-complete warm-resume artifact. Warm `start --resume` is experimental. In the 2026-07-17 smoke run, restoring the state written by a clean stop halted immediately at microcode `ILLOP`; a subsequent `--fresh` cold boot worked. Do not currently rely on `--resume` for session persistence. See the [harness architecture and observation record](docs/mit-cadr/cadr-computer-use-harness.md) for provenance and the exact evidence boundary. Raw screenshots remain in the ignored session tree. A small number may be copied into the museum only after an image- and use-specific copyright review under the [runtime screenshot publication policy](docs/screenshot-publication-rights-review.md). Curated screenshot files are outside any blanket project license. ### Useful CADR commands Validate the container toolchain without starting the GUI: ```bash ./scripts/cadr-guix-container.sh --mode run --verify ``` Only create the upstream checkout: ```bash ./scripts/cadr-guix-container.sh --mode run --bootstrap-only ``` Prepare the repositories and build `usim` without launching the GUI: ```bash ./scripts/cadr-guix-container.sh --mode run --prepare-only ``` Open a shell inside the prepared environment: ```bash ./scripts/cadr-guix-container.sh --mode shell ``` Update the upstream LM-3 checkout: ```bash ./scripts/cadr-guix-container.sh --mode update ``` ### LOD helpers The repo also includes a helper around the upstream `lod` and `diskmaker` tools for inspecting world-load bands and swapping them into the disk image. List built-in aliases: ```bash ./scripts/lod-helper.sh list-releases ``` Inspect the default public System 303 load band: ```bash ./scripts/lod-helper.sh inspect 303-dist ``` Install a different public load band into the disk image: ```bash ./scripts/lod-helper.sh install 303-dist ``` Built-in aliases currently include: - `303-dist` - `303-cold` - `100-dist` - `100-cold` ## Open Genera Open Genera is not included in this repo. You must supply your own purchased archive, for example: ```bash ~/opengenera2.tar.bz2 ``` Do not use the Open Genera archive that is commonly available on well known public piracy websites. Using infringing copies is illegal. Obtain Open Genera legitimately instead, for example by purchasing it from Symbolics: http://www.symbolics-dks.com/ Nothing extracted from that archive is checked into git. Runtime files are staged under `./.lm-home/opengenera/`. ### One-time host network setup Open Genera expects a host TAP device named `tun0`. Create or repair it with: ```bash sudo ./scripts/opengenera-host-net.sh up --user "$USER" ``` Check its current state with: ```bash ./scripts/opengenera-host-net.sh status ``` Despite the name, `tun0` must be a TAP device, not a TUN device. The helper script handles that for you. ### Writable site storage on the host To create a local site and save a reusable world, Genera needs a writable host file service. In this repo that is expected to be an NFS export visible to the VLM at the default Open Genera host paths: `HOST:/var/lib/symbolics/sys.sct/site/` and `HOST:/usr/opt/VLM200/lib/symbolics/`. Prepare it with: ```bash sudo ./scripts/opengenera-host-nfs.sh up ``` Check the export and the Genera-facing paths with: ```bash ./scripts/opengenera-host-nfs.sh status ``` This helper exports writable directories for: - site files under `/var/lib/symbolics/sys.sct/site/` - saved `.vlod` worlds under `/usr/opt/VLM200/lib/symbolics/` That means the standard Genera defaults from the installation guide can be used without editing them to repo-specific paths. If you want to remove just these dedicated exports later: ```bash sudo ./scripts/opengenera-host-nfs.sh down ``` ### NFSv2 fallback when the host kernel only offers NFSv3/v4 Some modern host kernels expose only NFSv3/v4, but Open Genera's built-in NFS client expects NFSv2. When `rpcinfo -p 127.0.0.1` does not show program `100003` version `2`, use the bundled Nimble userspace NFSv2 server instead. Start it with: ```bash sudo ./scripts/opengenera-host-nimble.sh up ``` Check it with: ```bash ./scripts/opengenera-host-nimble.sh status ``` This helper stops conflicting kernel RPC/NFS services if needed, starts Nimble, and exports the standard Open Genera paths directly, so inside Genera use: - `DIS-EMB-HOST:/var/lib/symbolics/sys.sct/site/` for site files - `DIS-EMB-HOST:/usr/opt/VLM200/lib/symbolics/` for saved worlds ### Launch ```bash ./scripts/opengenera-guix-container.sh --mode run --archive ~/opengenera2.tar.bz2 ``` The first run will: 1. start a Guix container with the required runtime tools 2. download the public `snap4.tar.gz` Linux VLM runtime into `./.lm-home/opengenera/downloads/` 3. extract the official `Genera-8-5.vlod`, `VLM_debugger`, and `sys.sct` tree from your archive 4. build a small local compatibility shim for modern Linux 5. start the VLM ### What a successful boot looks like You should see the VLM POST complete and a Cold Load stream appear. The usual non-fatal early warning is: ```text genera (Cold Load): Unable to allocate a modifier for the Hyper key. ``` That warning by itself is not a failed boot. ### Genera headless computer-use harness The Genera computer-use harness runs the real VLM client on an authenticated private Xvfb display and sends keyboard and mouse events through XTEST. Unlike the ordinary launcher above, it runs the native VLM in a Bubblewrap sandbox with separate user, network, PID, IPC, mount, and hostname namespaces. The sandbox sees a read-only Guix store, the exact private X socket and two read-only launch helpers, and its writable session runtime; it does not see the host home, repository, ordinary runtime sockets, or a default network route. Its private `tun0` exposes no NFS, Nimble, FTP, or other guest file service. The private Xvfb disables MIT-SHM and verifies its absence before launch, preventing the out-of-namespace X server from attaching host shared-memory segments for the VLM. Two tracked compatibility modules remain deliberately narrow. One suppresses only the redundant legacy `/sbin/ifconfig tun0 10.0.0.1 dstaddr 10.0.0.2 netmask 255.255.255.0` request after the private interface is configured; every other `system(3)` command retains normal libc behavior. The X module installs typed event converters only on displays returned by `XOpenDisplay`, replaces only zero timestamps on seven core input event types, locally handles the byte-exact typed modifier request, and pairs its typed grab suppression with the matching ungrab. Direct tracing also established that the main Genera display relays a guest X11 byte stream through `write(2)`. Only on descriptors belonging to those wrapped Displays, the module replaces the exact observed eight-byte `GrabServer`-plus-`GetModifierMapping` request and exact 148-byte `SetModifierMapping` request with sequence- and reply-compatible requests accepted by the private Xvfb. The replacement extension name must first be live-verified absent. No read-family API is interposed. The globally wrapped `write(2)` delegates every untracked or nonmatching write byte-for-byte, including TAP, world-image, ordinary-file, and unrelated-socket writes. A separate supervised process answers one observed RFC 868 request with one raw Ethernet reply entirely inside the throwaway network namespace. The harness reports `running` only after it has observed both exact X substitutions, validated packet evidence, and a successful responder exit. Check the harness tools and currently staged Open Genera inputs: ```bash ./scripts/genera-computer-use.sh doctor ``` Start a named session from your purchased archive and inspect its status: ```bash ./scripts/genera-computer-use.sh start \ --archive ~/opengenera2.tar.bz2 \ --session research \ --fresh ./scripts/genera-computer-use.sh status --session research ``` The first start verifies the purchased archive and exact known Genera 8.5 world, debugger, and public `snap4` VLM identities. It then places private copies of those inputs, both compatibility modules, the RFC 868 responder, generated host files, and configuration under the ignored session tree. Immediately before execution the supervisor rehashes every private artifact and tracked launch source. The ordinary launcher stages inputs but is not retained as another runtime layer. A later `start` with the same required `--archive` but without `--fresh` reuses the private inputs; `--fresh` replaces them from the verified base. Every start creates a new VLM process; the harness has no host-process snapshot or resume mechanism. A reused private world could contain an explicitly saved in-guest state, which requires separate verification. Wait for the main client, capture it, and send input only after verifying the current screen. `main` is the default target, but spelling it out makes a research transcript unambiguous: ```bash ./scripts/genera-computer-use.sh wait --session research --window-kind main ./scripts/genera-computer-use.sh screenshot \ --session research --window-kind main --label initial-display ./scripts/genera-computer-use.sh key \ --session research --window-kind main return ./scripts/genera-computer-use.sh type \ --session research --window-kind main 'text to type' ``` Open Genera changes X clients while moving from Cold Load to its main display. The harness therefore requires an exact `--window-kind` target on `wait`, `key`, `type`, `mouse`, and `screenshot`. The choices are `main`, `cold-load`, `debugger`, and `genera-other`; omitted means `main`. It rediscovers candidates for every operation and fails closed when zero or more than one client has the requested kind. Commands, action records, and screenshot sidecars identify the selected X window by kind, ID, title, and geometry. Mouse coordinates therefore refer to that observed client's geometry, not the fixed CADR dimensions: ```bash ./scripts/genera-computer-use.sh mouse \ --session research --window-kind main move 600 450 ./scripts/genera-computer-use.sh mouse \ --session research --window-kind main click 600 450 --button 1 ``` The preserved VLM Debugger normally uses the Cold Load client, so target it as `cold-load`. The `debugger` kind is a reserved title classifier for a distinct X client whose title explicitly contains `VLM Debugger`; D04 did not observe such a separate title and does not treat that selector as a verified VLM-debugger route. Portable Genera-key aliases are `select` (`F1`), `function` (`F3`), `suspend` (`F4`), `resume` (`F5`), `clear-input` (`F10`), `complete` (`F11`), `end` (`KP_End`), and `help` (`F12`). Existing aliases include `rubout`, `abort`, `super`, `return`/`enter`, `space`, and `escape`. These are host X-key translations; the meaning of a key still depends on the active Genera input context. For example, after choosing **Emergency Break** on the main System Menu, target the separate Cold Load client explicitly. The Cold Load reader activates a completed form with the Genera `End` key rather than Return: ```bash ./scripts/genera-computer-use.sh wait \ --session research --window-kind cold-load ./scripts/genera-computer-use.sh screenshot \ --session research --window-kind cold-load --label emergency-break ./scripts/genera-computer-use.sh type \ --session research --window-kind cold-load '(+ 40 2)' ./scripts/genera-computer-use.sh key \ --session research --window-kind cold-load end ./scripts/genera-computer-use.sh screenshot \ --session research --window-kind cold-load --label emergency-break-result ./scripts/genera-computer-use.sh key \ --session research --window-kind cold-load resume ./scripts/genera-computer-use.sh wait \ --session research --window-kind main ``` Capture the resulting exact client window and stop the VLM: ```bash ./scripts/genera-computer-use.sh screenshot \ --session research --window-kind main --label after-input ./scripts/genera-computer-use.sh stop --session research ``` On stop, the supervisor sends `SIGTERM` to the actual VLM process, waits for its prompt, and answers `yes`. A pipe trace proved that the current public VLM reads the answer and begins cleanup, including breaking its X connection. This VLM artifact then stalls while terminating its Cold Load channel, so the bounded stop finishes with `SIGKILL`. `stop` consequently returns status 2 and records `forced_after_confirmed_shutdown_stall: true`, `forced_stop: true`, and `state_may_be_incomplete: true`; it must not be described as orderly host shutdown. Neither the accepted confirmation nor forced cleanup invokes Genera's in-guest Save World operation. The harness does not create a process checkpoint or expose an NFS, Nimble, or FTP service. Absent a separately verified in-guest Save World action, unsaved Lisp memory, editor buffers, definitions, and processes are discarded with the VLM process. See the linked evidence guide for the mutex-level shutdown finding and the exact scope of that observation. Each generation has a generation-scoped run record, updated atomically while active and preserved before the next generation, plus an ordered action log. Input operations record intent before XTEST dispatch and a linked `succeeded` or `failed-or-partial` outcome afterward. Screenshots, sidecars, logs, Xauthority, configuration, and all licensed or runtime copies stay under ignored `build/genera-computer-use/<session>/`. Use `stop --discard` to delete a stopped named session. Selected runtime screenshots may be copied into the museum only after an image- and use-specific copyright review; permission or a documented U.S. fair-use basis can support publication. The raw session remains ignored, and curated screenshot files remain outside any blanket project license. See the [runtime screenshot publication policy](docs/screenshot-publication-rights-review.md) and the [Genera harness architecture and evidence guide](docs/genera/genera-computer-use-harness.md). ### Useful Open Genera commands Validate the container setup without launching the GUI: ```bash ./scripts/opengenera-guix-container.sh --mode run --verify --archive ~/opengenera2.tar.bz2 ``` Stage the runtime without starting it: ```bash ./scripts/opengenera-guix-container.sh --mode run --prepare-only --archive ~/opengenera2.tar.bz2 ``` Open a shell in the prepared runtime: ```bash ./scripts/opengenera-guix-container.sh --mode shell --archive ~/opengenera2.tar.bz2 ``` Extra arguments after `--` are passed through to `genera` itself. That lets you override the default `.VLM` configuration if needed. ### Open Genera notes - Only run one Open Genera instance at a time against `tun0`. - If you launch a second instance while one is already running, you can see `Device or resource busy`. - The launcher uses your purchased world/debugger, but the Linux-hosted VLM runtime comes from the historical public `snap4` package. - The launcher includes a small compatibility preload because the historical runtime still tries to use legacy Linux networking behavior and X11 keyboard modifier remapping that modern unprivileged/Xwayland setups reject. The same preload also answers the VLM's early RFC 868 time request locally, so no host `time` daemon or privileged UDP/37 listener is required. ## Font recovery Recover the public CADR font sources from a checkout of `mietek/mit-cadr-system-software`: ```bash python3 scripts/extract-cadr-fonts.py \ /path/to/mit-cadr-system-software/src/lmfont \ --output build/fonts/cadr \ --clean \ --strict ``` This reads the historical source representations under `src/lmfont`; it does not inspect a CADR load band or heap. The curated public outputs and full format notes are in [the CADR font recovery article](docs/mit-cadr/font-sources-and-recovery.md). Recover the fonts resident in your own licensed Genera world: ```bash python3 scripts/extract-genera-fonts.py \ .lm-home/opengenera/runtime/Genera-8-5.vlod \ --output build/fonts/genera \ --clean ``` That command writes BDF files, normalized JSON, and PNG font sheets. All Genera outputs are derived from licensed media and remain in the ignored local build tree; do not commit or redistribute them. See the [Genera extraction procedure](docs/genera/extracting-resident-fonts.md) and [evidence-graded font catalog](docs/genera/font-catalog.md). ## On-line help recovery Recover the source-integrated help from the pinned public MIT CADR System 46 tree: ```bash python3 scripts/extract-cadr-help.py \ --source /path/to/mit-cadr-system-software/src \ --output docs/assets/mit-cadr-online-help \ --clean ``` The checked-in result contains exact public source contexts, four standalone ZWEI artifacts, catalogs, and the source license. See the [CADR help recovery article](docs/mit-cadr/online-help-and-documentation-recovery.md) for the inclusion rule and optional metadata-only LM-3 cross-check. Recover the installed documentation from your own licensed Genera `sys.sct` tree: ```bash python3 scripts/extract-genera-help.py \ --sys-sct .lm-home/opengenera/runtime/sys.sct \ --output build/help/genera \ --clean ``` This decodes the Document Examiner's Sage Binary databases, copies three reviewed standalone help files, and inventories source-level help declarations without executing Genera code. Every output derived from Genera remains under the ignored `build/help/genera/` tree and must not be committed or redistributed. See the [Genera help recovery article](docs/genera/online-help-and-documentation-recovery.md). ## Day-to-day use Once either machine finishes booting, the normal place to work is a Lisp Listener. Practical first steps: 1. Click into the Lisp Machine window. 2. Try the help key for the emulator you launched. 3. Treat the Listener as your REPL and command entry point. If you stop the emulator process abruptly, unsaved in-memory state is lost. ## Files and caches The repo creates a few local working directories: - `./l/` for the LM-3 upstream working checkout - `./.lm-home/` for container home directories and runtime caches - `./*.fossil` for cached Fossil repositories These are intentionally ignored by git.