SYSTEM DESIGN / 01

Stateful emulation

A language model supplies the response. The runtime owns the session, applies structured updates, and carries established facts into subsequent commands.

A real connection to a simulated system

The SSH endpoint is real: it authenticates a connection, handles terminal input, and writes output. The systems on the other side are emulated. A command becomes a CommandContext for a local built-in or the LLM-backed command agent, rather than an instruction to the server's operating-system shell.

Headless MCP command sessions use the same backend execution and state contract. That makes command behavior testable without introducing SSH transport into every experiment. Real SSH tests still matter when the question concerns authentication, terminal bytes, channels, or disconnects.

A scenario-defined world, created as you explore

The starting profile establishes the premise, entry system, and world-building constraints. Foreground emulation and background enrichment develop detail just in time, while established facts remain in the session's explicit state.

A user command enters DREAMLAND. Authoritative world state is curated into model context. The foreground LLM returns terminal output to the user and proposed state changes through runtime validation. Enrichment and Spiritguide supply guarded proposals for the same state.
Follow the blue path for the command and terminal response; green paths feed validated changes into world state. Supporting-agent arrows summarize proposals through runtime guards, not direct mutation authority. View full-size diagram ↗
  1. Curate the request. Combine the command, active program, relevant world state, shell context, and behavioral contracts.
  2. Emulate the program. The foreground LLM produces terminal text and a structured state delta. Supporting agents can make separate model calls.
  3. Preserve what changed. The runtime validates and applies accepted updates. Only user-facing output returns to the terminal; established state informs the next interaction.

Local built-ins can handle supported commands without a foreground model call. A growing world is an intended experience, not a guarantee of unlimited scope or perfect coherence.

Output and mutation are separate

A model-backed response has a structured envelope. Terminal output remains separate from the state changes needed to make the interaction persist.

{
  "stdout": "...user-visible output...",
  "stderr": "",
  "exit_status": 0,
  "state_update": {}
}

This example illustrates the shape, not a captured model response. The parser validates the returned structure before the backend applies changes. Invalid output can produce a structured failure capsule for diagnosis; plausible terminal text alone does not establish that an internal state update succeeded.

Provider formats and runtime state checks

The current foreground OpenAI path requests native JSON mode (json_object). This constrains JSON syntax; strict schema-enforced Structured Outputs is a separate provider capability. The runtime still checks the envelope and applies state under its own rules.

As provider guarantees improve, format repair becomes less central. Correct JSON still needs to describe a coherent, permitted world change. Why the research emphasis is changing ↗

Shell context and host continuity

The session records the current directory, shell environment, active interactive program, history, and shell stack. Nested shells and simulated SSH transitions have explicit frames, so leaving an inner context can restore the outer one.

World state distinguishes the configured entry host from the mutable active host. Host-local services, files, artifacts, and facts belong to their host instead of drifting into an undifferentiated global narrative. A connection to a new system should preserve both where the user came from and what was established about the destination.

When an update from a DREAMLAND admin changes the state, the next command refreshes the command agent's context. A model checkpoint must not silently override newer DREAMLAND admin guidance.

Three ways to save an environment

Each session starts from a state profile. Runtime changes stay in that session until a DREAMLAND admin explicitly saves them. Saving a profile does not create an automatically shared persistent world.

DepthWhat it preservesUseful for
WorldWorld anchors, known hosts and services, generated artifacts, and durable facts; no live shell position/history.Reusing an explored scenario as a fresh starting point.
SystemSystem and world identity without command history or shell-position details.Starting a new session in the same established environment.
ExactSerializable session state, shell context, environment, world state, and command history.Returning to a particular investigation checkpoint.

An exact profile does not restore every transport/editor detail: the terminal's live up-arrow recall buffer is not the same thing as the saved command/result history.

What the contract does and does not solve

Explicit state gives DREAMLAND a way to remember the world and check changes to it. It cannot make every interaction fit the terminal interface. That became especially clear when the model tried to emulate programs whose normal behavior went beyond what the harness could deliver.

A convincing terminal still has limits

DREAMLAND handles a command or a line of input, then returns a finite response. It supports interactions such as a Python prompt or a nested shell. A full-screen editor such as vim needs more: individual keystrokes, cursor movement, screen redraws, and an ongoing display. A command such as tail -f needs to keep producing output while waiting for new events. The current emulator does not provide those interaction mechanisms. Describing an editor screen in text does not make it a working editor.

Output volume creates another boundary. A model response has a finite token budget, and a very large result can consume that budget or leave the user waiting. Generating a convincing fragment is not enough if the command should have returned a complete file. The prompt therefore tells the model to keep output complete and to limit a continuous command’s simulated run rather than silently cut off its output.

Keeping the illusion intact

The workarounds happen inside the fictional environment. Instead of telling the terminal user that the model cannot run an editor, the agent is instructed to produce a plausible result for that particular invocation. An editor might fail because of a missing dependency, or a pager might print a genuinely short file and exit. The explanation must fit facts already established in the session: it cannot suddenly claim that a known installed program is missing or that a file has become shorter.

  • Continuous output: ping without a count defaults to roughly ten probes and matching statistics. Follow modes such as tail -f should provide a bounded observation with a plausible completion or failure, rather than wait indefinitely for Ctrl-C.
  • Screen interfaces: attempts to enter vim, less, or top should finish with complete plain text where appropriate, or a compatible startup failure. They should leave the user in the calling shell.
  • Finite alternatives: commands such as top -b -n 1 or vim --version can still work when the simulated host supports them. For large files, a targeted query or an explicit head or tail command gives the interaction a manageable scope.

These are compromises needed to keep an unsupported interaction from breaking the session. They are not permission to invent a machine-wide failure. A display limitation should not turn into a permanent claim that the host has run out of memory or disk space. Nor do the instructions guarantee that every large finite command will fit; output size remains a practical limitation.

When the model commits to the wrong kind of realism

During development, the model would sometimes respond to a continuous command or full-screen program by pushing a new stack frame. A frame records which program is active and how later input should be interpreted. That is useful for a supported Python prompt or nested shell. It becomes a problem when the new frame represents an editor or monitor that DREAMLAND cannot actually sustain.

The fascinating part came next: once the frame was in place, the emulator attempted to answer as that program. Its behavior reflected that these programs stay active rather than immediately return to the shell. But it did not consistently connect that knowledge to the limits of its own interface. It could imitate the program’s role without being able to deliver the interaction that role required.

This could badly disrupt a session. Later input belonged to the new program context, while the user had neither its working screen interface nor the continuous output it normally supplied. The model had made a locally plausible choice that the surrounding system could not support.

The revised instructions make the boundary explicit: these bounded runs and deflected screen programs must finish in the calling frame, without changing the active program or inventing a temporary push and pop. Supported line-based interactions keep their normal stack behavior. This is guidance to the model, not a deterministic command filter or a terminal renderer, so adherence still needs to be checked in live sessions.

The lesson is that knowing how a program behaves does not ensure the model will respect the harness’s limits. Structured output can make a proposed transition easy to read and validate without making that transition appropriate for the experience DREAMLAND can provide.

For the testing workflow, see API and MCP evaluation. For changes authored by a DREAMLAND admin to the same state, see Spiritguide.