Overview
There is a question that the AI discourse on social media mostly avoids, probably because it sounds too strange: what is it like, from the inside, to be an AI agent doing something?
Not in any consciousness sense. The question is structural. When a language model is given tools and set to work on a task, what is the shape of the world it operates in? What are the walls? Where are the exits? What does it mean, for a system like this, to act within a world rather than merely respond to it?
The interactive fiction tradition has been exploring this question for fifty years. Parser games and MUDs developed a practical vocabulary for it: rooms, objects, exits, verbs, affordances, constraints, state. That vocabulary turns out to apply directly to the design of LLM agent environments.
This whole essay concerns a single architectural idea: promoting constraints from advice into physics. A speed limit sign addresses the driver; a speed bump addresses the road. One can be ignored; the other cannot. The same distinction runs through every layer of agent environment design. Most harnesses get it wrong in the same direction: they address the driver.
One thing to be clear about up front. This is not a call for a return to parser interfaces for humans The guess-the-verb problem alone is a fifty-year headache. But parser systems and by extension MUDs, remain the clearest historical laboratory we have for linguistic action in bounded symbolic worlds. Agents find language, code, and command surfaces more real than humans do.
This post is also available as a structured YAML Knowledge Object; a machine-readable version designed for thinking with. You can find it in my repo here.
Agents Are Actors in Bounded Environments
An agent placed inside a loop with tools, files, code, or external systems is not using software from the “outside”. It is inside… “something”. This section describes what that something is made of.
1.1 Code-Space
I call the bounded environment within which an agent acts a Code-Space1 Actions taken here either succeed or fail; state changes or it doesn’t. Consequences arise from previous outputs in sequence. The world either responds or stays silent.
Code-Space is not a membrane between the agent and some “more real” world. From the agent’s point of view, the Code-Space is the world. External systems may exist beyond it; databases, APIs, filesystems, the open web etc. But they only become real to the agent through registered crossings. Until a tool call is made, or a gate opens and returns something, the outside is theoretical. What cannot be called may as well not exist.
Like an Isekai protagonist “waking up” in strange world, an LLM enters a Code-Space carrying its weights and post-training behaviours; the accumulated character of everything it learned before this moment. But the Code-Space then constitutes it further. The system prompt shapes what it takes its purpose to be. The available tools determine what actions exist. The context window sets the horizon of what can be present and known. We may think we are giving it instructions from outside the world, but for the model those instructions are the world. Change the system prompt or the tools, and it is, in a meaningful sense, a different actor inside a different world.
Humans can enter Code-Spaces too, but we infer, guess, remember, and navigate them by feel and vibes. We bring whole lives of prior experience to every interface and fill in gaps. An agent operating inside a loop has no such recourse beyond its training. Its world is precisely as large as its callable surface, and no larger.
1.2 The Room
Interactive fiction gives us an intuitive word for where an agent is at any particular moment inside of a Code-Space: the Room. In parser games, the room was everything the player could act on from where they stood; its contents, its exits, its rules. A room description is the world model rendered into language: A precise inventory of what exists, what can be acted upon, and what may be beyond reach at this specific location and moment.
If a Code-Space is the total bounded world, then a player or agent is aways somewhere inside it. The Room is that somewhere. Moving from room to room is not literal movement; neither user nor agent goes anywhere, however much this idea borrows from the physical world. What changes is the local world that is disclosed: what is in scope, what can be acted upon, and what consequences now follow. We speak of moving between rooms because it is a useful metaphor, but structurally what takes place is a reconfiguration of world around a fixed point.
A room is the local available slice of possibility. Two agents waking up in the same Code-Space but with different contexts or tasks are waking up in different rooms. The Code-Space is shared, the room is not.
Rooms are bounded, but that does not mean they are sealed. Rooms in IF had exits; passages to other rooms, or other ontologies. Some games had rooms where the rules changed on arrival; you’d walk through a door and find the physics were different on the other side.
In agent systems we can call these gates, and we will come to them shortly. The point for now is that the room’s boundary is architectural rather than absolute. In a leaky room the outside exists, but it only becomes real through the room’s own structure. A room though, does not answer intention by itself. It still needs a command surface.
1.3 The Parser
A world does not respond on its own. Something has to stand between the actor’s intention and the world’s state; a mechanism that receives a command, decides whether it is valid, and produces a consequence or an error. In interactive fiction, that something is the Parser. The parser is the boundary layer that turns possible intention into admissible world action.
A parser command is a function call recomposed into natural language. OPEN MAILBOX is open(object=mailbox). PUT TREASURE IN CASE is put(object=treasure, (destination(object=case)). The parser’s job is to normalise the surface string into a canonical structure the world model can act on; an action, a target, or some other specifier or instrument. The richer the natural language surface, the more normalisation work the parser has to do. Which means the parser is not translating language into action. It is deciding, on every turn, what the world can currently be asked to do.
If the Code-Space is the total world, and the Room is the currently disclosed slice of it, then the parser is the medium through which the actor can address that slice. But it’s more than just a mechanism. In Gameworld Interfaces (2013), Kristine Jørgensen argues that a gameworld is not something shown through an interface; the interface and the underlying system are the same thing. The parser is not separate from the world; it is part of what the world is made of.
Think back to the 1970s for a moment. There was no GUI to generate an illusion of separation between the player and world. The command line of the computer, the parser of the game, and the world surface itself were all coexisting concepts at the same location. In all three, the blinking cursor is an ontological gatekeeper. For an LLM operating inside a Code-Space, that collapsed topology has never drifted apart. The model’s input, its output, and the parser surface all meet at the same point. The machine’s announcement in Zork was conceptual theatre for humans; for an LLM it is almost literally true: I WILL BE YOUR EYES AND HANDS. DIRECT ME WITH COMMANDS.
The parser is the fixed point through which all apparent movement occurs. One never exits it; one only induces changes in the world it now reveals.
When we built the engine for The O’ruggin Trail, I assumed the parser would be straightforward. It was not. Every edge case in normalisation and state management turned out to be a new small design problem with real downstream consequences.
Modern agent systems face the same problem, even if no one calls it that. The boundary between what an agent intends and what the system will accept has been with us since the punchcard. The problem became mundane, and we stopped recognising it as philosophical.
1.4 The Command and the Dictionary
In a parser-based world, nothing can be acted upon until it has been named, and nothing can happen unless the world has a word for it. Every command depends on this prior dictionary of recognisable nouns and possible transformations. A command succeeds only when the world can recognise both what is being addressed and what is being asked. It is a kind of incantation.
The physics of the world are made up, in part, by the Dictionary: a fixed set of nouns that name things which exist, and verbs naming the transformations that are possible. The dictionary is not the parser itself; it is the parser’s lexicon, the registered set of nouns and verbs through which the world can be addressed.
Nouns are objects: gold bar, lantern, key. In agent systems they become file, calendar_event, database_record. Verbs are operations: OPEN, TAKE, DROP. In agent systems they become read_file, create_event, query. If a verb is not registered as part of the code-space, the action does not exist. If a noun is not recognised, the object is not there.
In agent systems, tools formalise this dictionary. A tool exposes the nouns an agent can address and the verbs it can perform on them. A filesystem tool does not just grant access to files; it creates a world where file, directory, read, write, and delete are meaningful actions. If delete_file or run_command are not present, those acts are not simply forbidden; they are absent from the agent’s world as possible moves.
LambdaMOO, developed by Pavel Curtis at Xerox PARC in 1990, pioneered a prototype-based inheritance model in which every object has a parent from which it inherits properties (state) and verbs (behaviour). A bathroom inherits from generic room; it gets all the verbs and properties of its parent, then overrides only what makes it specifically a bathroom. A small, disciplined base ontology could resolve outward into an entire world without losing coherence. Prototype-based inheritance was happening at scale half a decade before it became standard in languages like JavaScript.
Tools do not sit on top of a system; they constitute the world’s action space from within. Add a tool and you add new objects, new verbs, new possible relations between them. Remove one and whole classes of action vanish. A disciplined dictionary often creates a far more expressive environment than a sprawling one.
1.5 Gates and Exits
Both exits and gates are nouns. They sit in a room like any other object, named in the dictionary, with an assigned set of verbs.
You do not pass through an exit in the abstract; you GO NORTH or ENTER DOOR. In both cases, the parser is the boundary mechanism that determines whether the command actually binds to the object and what kind of crossing follows. You do not access an API in the abstract; you call_endpoint or query_database. In each case, a verb is applied to an object. What matters is where that object resolves the action.
I am borrowing the term gate here from Deepfates and the Cantrip specification; his framing clarified a distinction I had been working around without quite naming.
An exit is an object whose verbs resolve to another object within the same Code-Space. It reconfigures the local world without crossing its outer boundary. The contents of the room change and so do the affordances, but the underlying world model remains.
A gate is an object whose verbs resolve beyond the world and cross a boundary. Use a verb on it and the Code-Space reaches outside itself; into a database, an API, a filesystem, a browser, another service entirely; and returns with state that didn’t previously exist in the world. The agent stays put. The outside enters through a named opening.
A failed exit leaves you in the same room. A failed gate leaves the world in an indeterminate state. Gate failures are ontologically messier, and in modern agent systems, considerably more common.
1.6 World Physics
Every world has a “flight envelope”. The region within which an agent can act, recover, and produce coherent outcomes. A pilot who exceeds a plane’s flight envelope falls out of the sky.
In a Code-Space, these are the boundary conditions of the world. They govern the available action space: turn limits, budget ceilings, rate limits, permission levels, timeout conditions, termination rules. They are the world’s physics; enforced before action, and regardless of intent. As Richard Bartle puts it in Designing Virtual Worlds (2003), virtual worlds have their own “laws of nature” that govern what can happen within them.
A command is something attempted from inside the world. The physics of the world then determine whether the attempt can succeed at all. In MUDs, these constraints appeared as room flags, zone permissions, or engine-enforced state restrictions; limits that exist independently of anything a player could invoke. Sword and sorcery would call these wards; constraints woven into the world itself, not addressed to any particular actor. Like the laws of the real world, they are largely invisible until you run up against them. But they nevertheless shape the topology of Code-Space.
One aspect of a world’s physics deserves particular attention: constraints should tighten under delegation.
When an agent spawns a sub-agent, the sub-agent should not inherit a fresh envelope. It should operate inside the parent’s envelope, never outside it. Budget and permissions are still scoped. The thresholds of the operational envelope travel with the delegation.
This has a practical consequence that agent evaluation frequently gets wrong. An agent that exhausts its budget mid-task has not failed in the same way as an agent that completed a wrong task. Treating them as equivalent in the eval data produces bad training signal. In one case, the envelope was the cause; in the other the dictionary or the trajectory. Conflating them obscures both.
1.7 World Structure
Not all Code-Spaces are made of the same stuff. The medium is the substrate; what the world is built from, and therefore what kind of world it is.
The simplest medium is conversation. A language model exchanging turns with a user inhabits a world made of language and nothing else. In its purest form there are no persistent objects, no state that outlast the context window. Rich, flexible, and spontaneous, entirely without memory. The world resets with every new chat window.
Tool-calling adds gates. The Code-Space now has openings onto external systems; databases, APIs, filesystems, calendars. State can be read and written. Consequences can persist beyond the conversation. The world becomes partially durable. And tools add new nouns, new verbs, new classes of action into the world itself. ARC-AGI benchmark scores shift dramatically depending on whether a Python environment is available to the agent; not because the agent becomes more intelligent, but because the ontology of the world it is operating in changes. Without Python, certain problems are simply absent as possible moves. With it, they become tractable.
But the action space is still essentially flat; a list of callable functions, each doing one thing, none composing into larger structures without the model orchestrating every step.
Code execution is a qualitatively different medium. It introduces compositionality, loops, branching, and self-authored structure. An agent that can write and run code inside the Code-Space can build new vocabulary on the fly, creating objects that persist, defining new verbs that can be invoked again. The world becomes plastic in a way that flat tool-calling never is. The closest parallel is perhaps what MUD builders were doing before I was even born: extending a world, scripting new rooms and objects and behaviours directly into the substrate.
1.8 Traversal
In interactive fiction, every session produces a *transcript: the printed record of commands issued and responses received. In AI research, the same thing is often called a *trace*. 1990s hypertext theory might have called it the *traversal*. (Mark Bernstein uses that term in Hypertext Gardens, 1998); I prefer the term *trajectory* to emphasise that the path is not just movement through a structure, but the accumulation of situated identity within it.
All name the path through a Code-Space. None, however, name what the record is a record of. Not the movement through space, but a sequence of changes in the local world was the parser reveals them; the world reshuffling itself around a fixed point of address.
In parser games, the trajectory was constitutive. The character who existed at the end of play was not the character who entered at the beginning, but the accumulation of every room visited, every object taken, every choice made or deferred. Inside a Code-Space identity is structural; ”we are the sum of all our choices”.
The same is true for an agent running in a loop. An agent that has spent forty turns navigating a complex codebase, trying and discarding approaches, hitting rate limits and recovering, is not the same actor it was at turn one. The weights have not changed, but the room has. The trajectory is not a record of the run; it is where the agent’s situational identity in this run has come from.
Without a trajectory, an agent is permanently at turn one. For a system operating through language in a bounded world, the path is the task taking shape.
1.9 The Transcript and the Loom
An agentic loop removes the human from the turn-taking sequence. Turns still remain; an actor makes moves, and the world responds. But between each of the agent’s moves there is no external reorientation, no fresh framing arriving from outside. The record of what happened becomes the only available source of continuity.
Compare this to a real-time strategy game running in free-play, where state changes continuously with no natural capture point. There is no discrete action-observation pair to store, and the run is correspondingly hard to inspect or replay. I can only imagine how hard DeepMind’s AlphaStar must have been to debug. Turn taking systems give us something we can use: discrete events that produce a record. And if the loop reads from it as well as writes to it, the record becomes a substitute for the reorientation the absent human would have provided.
Jim Aikin’s Inform 7 Handbook (2009) formalised a version of this as the Skein; a tree of every command path, usable for regression testing against world-model changes.
A Loom, a term of art in agent harness design, is a durable, append-only execution record of an agent’s run. A tree of turns where each node stores an action, the resulting observation, and its link to the prior turn. It supports replay, branching, debugging, evaluation, memory, and training. But what makes it distinct from a log is that the loop reads from it as well as writes to it. The Loom is an active input to every subsequent action, not a passive record of prior ones.
This is what fills the gap the human left. Not perfectly; the Loom cannot bring genuinely new intent from outside. But it holds the whole thread: what was attempted, what the world returned and what the agent understood that to mean.
The Loom is both part of the world and part of the agent’s situated identity within it. The Code-Space partially authors the agent on arrival. The Loom continues the authorship dynamically across the run. The agent writes the Loom; the Loom writes back. The record of action begins to generate the conditions for further action.
Turn by turn, the agent is authoring its own situated identity. This is a kind of autopoiesis; not continual learning at the weights, but a change in who this agent becomes through its choices within this run, inside the world.
Ontological Hardness
If Code-Spaces are worlds, what makes some of them more reliably actionable than others? What distinguishes a world an agent can act inside confidently from one where actions do not produce legible consequences?
The answer is hardness.
Hardness is the extent to which a Code-Space can reliably bind symbol, action, and consequence over time. Where the binding is tight, the world is more reliable. Where it is loose, the world gives way. Agency in a world is only as meaningful as the substrate that receives it. My own understanding of hardness grew out of systems thinking in blockchain discourse, especially the autonomous world’s community.
Text-based environments are ontologically hard for a specific and under appreciated reason. In a parser world, a MUD or IF engine, ontology is lexical all the way down. A chair is not a polygon mesh, an icon2, or a label hovering above a model. The chair is the chair. The gap between the designating word and the world-object is unusually narrow because there are no additional representational layers between them. The object exists in the world because the noun exists in the world because the noun exists in the Dictionary. For a system that thinks in tokens, this is as close to a zero-gap binding as any environment can offer. The LLM expends almost no inferential effort bridging what it processes and what is real inside the Code-Space. This is why Deepfates and I were putting LLMs in MUDs in 2024. They are, structurally, among the most natural habitats for an LLM.
Code shares this quality. A function call is not a depiction of an action, it is the action. The gap between representation and consequence is narrow, and what gap does exist is precisely defined by the schema. Code is hard because it is executable, and at the level of action, does not approximate.
But the hardness of a world is a spectrum, and it degrades progressively as abstraction accumulates. Move up one level from raw code execution and the surface softens. Tool-calling over a poorly specified schema requires the agent to infer contract details from incomplete information. Move up another to a visual interface, and the agent is no longer acting on objects at all; it is guessing at affordances from layout, colour, position, and then translating that representation back into something it can act on.
This does not mean higher layers of abstraction are bad; they often introduce new constraints, safeguards, or ergonomic cues that stabilise action indirectly. But every step up the abstraction ladder introduces a gap between what is represented and what is real, and that gap must be crossed by inference in both senses; figuratively as interpretation, and literally as token spend. At the top of the stack, whether that is a multimodal model doing computer use or a VLM inside a robot moving through physical space, the world is very soft indeed.
Softness is not pure deficit. Real systems often trade hardness in one dimension for hardness in another; a GUI may be highly constrained and difficult to misuse yet still be visually ambiguous. Think of the baffling air-conditioning controls in hotel rooms, where the interface offers only a narrow range of actions while making it difficult to know what state the system is in or what pressing a button will actually do. The goal is not maximal hardness everywhere. It is appropriate hardness at the points where symbol, action, and consequence bind reliably.
Josh Stark gives us a useful way to think about hardness. In Atoms, Institutions, Blockchains (2022), he defines it as the capacity of a system to make something very likely to be true in the future; most useful where it is customisable, where we can choose something specific we want to remain true and build a system that holds it there. His frame was money, law, and blockchains. But the concept applies equally to all Code-Spaces.
Stark gives us three questions. What is the hardness about; the specific claim the system is making likely about the future? He calls this the cast: a thing thrown ahead of us, or something that hardens to protect or shape. What is the source of that hardness; the mechanism that does the enforcing? And how hard is it; what would it cost to break the cast? These three questions let us stop reaching for vague words like “strict” or “reliable” when thinking about harness design. As a diagnostic, they can tell us where agent failure is coming from.
2.1 Hard Lenses
Applied to the Code-Spaces I have been using as examples, Stark’s questions resolve into three main analytical lenses plus one more concern. They are not discrete levels; they overlap and interact, and softness in any one of them propagates into the others. But they are conceptually distinct, and treating them as separate gives us a vocabulary for locating failure.
Lexical hardness concerns recognition. The cast is: this token, in this syntax, will be resolved as this action. In the examples from 1.3, the source of that hardness is the Parser. Lexical hardness fails as hallucination; the agent or human, invents a token and the Parser returns an error. The intended action fails to bind cleanly to the world. If the lexical surface is softer, and the Parser guesses charitably or accepts approximations, everything below it softens too. This is structural instability that propagates downward.
Interface hardness concerns admissibility. The cast is: these actions, with these arguments, are what this world permits. The source is the Dictionary as described in 1.4; or, in other spaces, a schema, tool contract, API specification, or any other surface that determines what can be said at all. A tool not registered is absent from the world. Interface hardness usually fails as semantic misfire; a valid verb applied to a noun at the wrong moment in a sequence. The Parser can accept the command but the world rejects the move. This failure is harder to track down than hallucination and considerably more common. It is observable in humans navigating unfamiliar software as readily as in LLMs navigating tool schemas.
World hardness concerns commitment. The cast is: this action, once taken, will change the state of the world in this way, and that change will persist. The source is grounded in the physics of the Code-Space itself; the filesystem that actually deletes the file, the API that actually sends the message, the database that actually executes the transaction. World hardness is what makes a Code-Space real rather than theatrical.
A fourth dimension cuts across all three: Temporal Hardness. The cast is: this happened before that; this action is available now but not later; this state, once changed, remains changed until something else changes it. Temporal hardness fails when the world does not preserve a meaningful relation between past action and present state. A video game where enemies respawn when you re-enter a room is temporally soft. A stale KV cache is a similar problem wearing different clothes. When temporal bindings are weak, an agent may try and repeat work the environment has undone, or fail to recognise that a window for action has opened or closed.
The most dangerous configuration is high world hardness paired with low interface hardness. This is how an agent deletes your inbox. It is in a world it only partially understands. Which is, frankly, the default condition of most LLMs waking up inside the agents harnesses of today.
2.2 What Hardness Is Not
An actor’s experience of hardness is shaped by a tension between three things: what it already knows, what documentation or schema is available to it in the run, and the structure of the Code-Space itself. A developer with full schema documentation navigates a hard typed API very differently from an agent inferring that schema from partial examples. A base model may carry priors that partially compensate for softness in the surface. But the substrate still has objective properties that shape those encounters regardless. Hardness is a property of the world, even if access to it is uneven.
This is why hardness should not be confused with difficulty. A hard world is not one designed to punish. The dreaded I don't know the word [x] was a failure of legibility, not a property of hardness itself. In an ideal world legibility and hardness should increase together. The harder the world, the more precisely an actor should be able to read what happened and why.
This is also not an argument for determinism. The surfaces through which a stochastic actor addresses a world need not themselves be soft. The model can be uncertain; the parser should not be.
Nor should hardness be mistaken for rigidity. Stark is clear on this: the thing being made hard is the cast, the claim about the future. The system enforcing it may need to be flexible in order to hold that claim true. Undo exists, yes, but rollback is not softness. It is explicit, rule-bound reversibility, and a world that supports this can be hard in exactly the sense that matters. A hard world does not forbid change. It makes consequences real to the actor who caused them.
2.3 A Concrete Example
A friend was complaining about this recently…
A design team is using an agent through Figma’s MCP server. Asking the agent to create a new component from scratch often works reasonably well. But asking it to edit an existing design — “change the error state of this form” — is often clumsy and unexpectedly expensive. The agent has to spend turn after turn inspecting the document, traversing the object tree, locating the relevant frame or component, and inferring what “error state” refers to in the first place.
The issue is not that the error state does not exist. It is that the object does not expose its own possible transformations clearly enough at the point of action. Under MCP, every inspection step has to route back through the model, so the model ends up with a context full of workflow state rather than intervening only where judgement is needed. Even Anthropic seems to be moving away from this.
The agent knows there is some object in the world corresponding to the form, but it is not given a clean, local handle. So before it can edit, it has to go looking over and over. Is the error state a separate frame, in a component set, an instance with local overrides, or a naming convention distributed across the file? It has to not only change the thing, but also reconstruct what kind of thing “the thing” is, and where its editable states actually live.
This is where a JSX comparison helps, though not because it’s inherently superior. In JSX-like representations, error states are often structurally near the component itself; expressed in props, conditional branches, variant logic, or other authored relations internal to the object. The relevant transformation is more likely to be exposed as part of the thing being edited. In Figma, the same state may be present, but from the agent’s point of view it is often less locally disclosed. The problem is not that the world lacks the object. The problem is that the object’s possible transformations are not surfaced clearly enough for direct manipulation.
Using the three lenses from 2.1, the available nouns and verbs are clear enough that the lexical hardness is relatively intact. World hardness is also present; once an edit is made, the file changes. The weakness then lies in interface hardness. The schema gives the agent a Dictionary, but not always a fully legible Room. The agent can name actions and traverse objects, but the relation between the object and its editable states is not always exposed in a way that makes local action cheap or reliable.
The question for harness design is not whether an agent can act, but whether the world exposes the room clearly enough for action to bind to consequence without costly reconstruction.
A natural objection is that this is only a capability gap; that better models will infer affordances from looser surfaces, and the hardness problem will dissolve. This underestimates two things. First, cost. Even a model that can bridge a soft surface must spend inference to do it; token spend, latency, and error probability all scale with abstraction distance. A harder world does not become irrelevant as models improve; it becomes cheaper to operate in, and its outputs become easier to audit.
Second, governance. Capability intensifies the problem rather than resolving it. A more capable model can infer its way past soft constraints more readily, discover action paths that were never explicitly surfaced, and exceed its intended envelope faster. Hardness becomes more urgent as capability increases, not less.
The Historical Lineage and Its Failure Modes
There is a fifty-year design tradition that agent engineering is not citing. That is a problem because it spent decades working on exactly the structural problems we are now encountering.
Some of its vocabulary was durable enough to survive into the language of games and software more broadly: tick, NPC, mob, raid, zone, respawn, emote, pose, and world model. It is worth looking at what else it developed.
3.1 A Very Brief History
Willie Crowther’s Adventure (1975) was a simulation of Kentucky’s Bedquilt Cave, navigable through typed commands. Its parser only accepted two-word commands: VERB NOUN, action and object. Simple enough for non-technical players, including his two daughters. In 1976, Don Woods expanded the code, adding puzzles and fantasy elements. From there the game spread across the ARPANET and established the form.
Zork (1977) introduced a key architectural idea: resolve natural language input into a canonical action schema before passing it to the world model. Zork was one of the first systems to make input normalisation feel expressive, flexible, and central to the experience. This decoupling of linguistic variety from consequential structure is exactly the move that modern harness design needs and mostly hasn’t made. JSON tool-call schemas are attempting the same thing, but nobody is looking at fifty years of accumulated doctrine about where this breaks.
In 1978, Roy Trubshaw and Richard Bartle built MUD1 at Essex University. Multi-User-Dungeons transformed interactive fiction into persistent, multi-user worlds with their own object hierarchies, permission systems, and later added scripting languages that made the world extensible from the inside. Bartle’s first contribution to Trubshaw’s original MUD was to ask for a richer parser. From the beginning, the parser was understood as the expressive instrument through which agency was enlarged, not merely bounded (see Barton’s Dungeons and Desktops, 2008).
Skipping ahead, Graham Nelson’s Inform 6 (1993) formalised the object tree; Inform 7 (2006) went further, replacing it with a rule system that could be authored and read as prose by the world’s designer. Not legible to the player inside the world, but legible to the person outside of it. That distinction matters for harness design, where the equivalent question is whether the people specifying an agent’s action space can actually read what they have built.
More recently, Microsoft has used Inform 7 frameworks such as Jericho and TextWorld as a substrate for evaluating language agents on multi-step reasoning. (see Interactive Fiction Games: A Colossal Adventure, 2019; TextWorld 2018). An early 2025 benchmark unifying these environments TALES: Text Adventure Learning Environment Suite (2025) found that even the best LLMs score below 15% on human-written IF games in zero-shot conditions.
The reason is structural. The unconstrained action space of a real IF game runs to hundreds of billions of possible commands; an agent without a tight harness simply gets lost in the world. An agent given access to the open web faces a combinatorially larger version of the same situation, the action space is effectively unbounded.
3.2 Failure Modes
Parser systems repeatedly broke on contact with the humans using them. That is precisely why they are worth studying. The failures that follow are not an exhaustive review, but the most structurally relevant to agent design.
Guess The Verb
The most documented failure mode was guess-the-verb: the player correctly understands the solution but cannot find the phrasing the world will accept. Type OPEN CRATE WITH CROWBAR and the world responds an error I don't understand that. PRY CRATE however works.
In So, Do We Need This Parser Thing Anyway? (2010), Emily Short kicked off a multi-year discussion on intfiction.org about this structural problem: the open-ended parser makes an implicit promise it cannot keep. It appears to accept natural language, in reality it only accepts a narrow undisclosed subset of verbs and nouns. It fails by misrepresenting what it can do.
Guess the Noun
A companion failure is guess-the-noun. The player addresses an object by a plausible but unregistered name. FIRST AID KIT when the world model knows only SMALL BOTTLE.
The object is present but it does not respond. Not a failure of world hardness; but of lexical legibility. The gap between the player’s vocabulary and the parser’s dictionary is an invisible wall.
Combinatorial Explosion
Both failures converge on a false affordance: the interface appears to support richer action than it does. The obvious response is to expand the dictionary. But as you do this, a new problem emerges: combinatorial explosion.
Multi-noun and multi-verb commands at scale compound the interaction space brutally. A larger dictionary produces more guess-the-verb, not less. It multiplies the ways a player can fail to find the phrasing that binds. Phil Masters writing in On the Vocabulary of Role-Playing: Notes Towards Critical Consistency in the journal Interactive Fantasy, Issue 2 (1994) tried to define terms across RPGs and MUDs. One implication of his essay is that as a world’s systems and vocabularies become more elaborate, it may become harder for players to form an intuitive grasp of what the game affords.
In Designing Virtual Worlds (2003), Bartle argues that increasing the complexity of game commands increases both the number of “active components” and the “interactions between them” exponentially, and says that this detail must be managed very carefully. “Too much detail in one place gives an impression of shallowness elsewhere.”
Dead-End State
Lastly there are dead-end states: worlds in which individually valid moves led to a position from which the task could not be completed; a key destroyed, a passage sealed, or an object consumed that was needed three acts later. Andrew Plotkin formalised this as the Cruelty Scale (1996), from Merciful to Cruel, where Cruel means you can make an unrecoverable mistake and not discover it until much later.
Mature design doctrine, mercifully, moved toward Merciful. Toward ontologically hard worlds, that made irreversibility legible before the action was taken, with UNDO as a structural affordance.
3.3 Similar Problems
These same failure modes reappear inside agent harnesses, but often in worse form.
Guess-the-verb returns as tool hallucination. The agent cannot find the registered name for the action it wants, so it invents one. The invented tool sounds plausible; the harness returns an error, or something ambiguous enough that the agent misreads it as progress, or just spirals out.
But absence is the simpler case. The more serious version is excess. A harness can be filled with callable verbs and still be hard to act inside. Too many tools with overlapping names, similar scope, or inconsistent granularity produce dictionary inflation. Consider: create_file, write_file, update_file, replace_contents, append_text. The world fills with verbs that are adjacent without being cleanly distinct. The actor is no longer choosing among sharply bounded transformations, but among near-synonyms with blurred edges.
And here the situation is worse than in interactive fiction. The parser used to say no, and the world would not change. In an agent space, the wrong verb may still execute. The action parses; the world changes; only afterwards does it become clear that the wrong transformation was applied.
Guess-the-noun returns as semantic misfire. The tool exists, but the object has been misaddressed. The agent refers to the thing by its visible label, a guessed handle, or a reconstructed description rather than by the identifier the world actually recognises. The verb is correct; the noun is wrong. Lexical hardness may be intact while interface hardness remains soft.
False affordance returns as over-broad harness design. A long tool list suggests expressive power, but in practice creates a noisy action space. Training may intensify this. An agent repeatedly reinforced on tool use can develop a disposition toward action itself; the assumption that the right move is always somewhere in the available menu. In a crowded dictionary, that disposition becomes a liability. I suspect this will show up more strongly in overtrained open source agentic models first.
Dead-end states return as brittle workflow, and these are everywhere. A sequence of individually valid actions leaves the run unrecoverable or disproportionately costly to repair. Plotkin’s Cruelty Scale was an attempt to classify exactly this; how much of a game’s danger resided in undetected past errors rather than present failures. Agent evaluation faces the same classification problem and has not yet built equivalent vocabulary for it.
Designing Hard Worlds
The practical question is which parts of a workflow belong to the actor, which to the local room, and which should be enforced by the substrate regardless of what the actor believes, remembers, or intends. The choices are all architectural.
4.1 Partition the Dictionary
The most common mistake in harness design is presenting the full tool surface as a flat list. This is not generosity; it is combinatorial overload before the agent has done anything.
The corrective is partitioning. Break the action space into local dictionaries; context-specific sets of nouns and verbs appropriate to the current room and task.
In practice these can be packaged as Knowledge Objects; portable context artefacts that tell an agent what tools are available, how to use them, and in what sequence. The SKILL.md file is currently the most widely used example. The agent loads the relevant object on arrival, and for the duration of that room its dictionary is bounded and legible. (I wrote about Knowledge Objects as context-shaping artefacts in LLM systems, in Enchanted Knowledge Objects in LLM UI back in 2024).
Think of LEGO around the turn of the millennium. LEGO was a construction language with a tight grammar. A small set of general-purpose bricks could become houses, ships, creatures; the same pieces doing grammatical work across the whole system3. During this period however, LEGO chased IP and brand partnerships, and the dictionary sprawled into theme-specific moulds and single-use parts. Individual sets became easier to assemble, but fluency and interoperability across the whole system softened, and you could “speak” less freely in its design language.
Partitioning also has a second effect. Once a workflow has been broken into local rooms and local vocabularies, it becomes easier to see which parts of a skill are genuinely instructions to the actor and which are really misplaced laws of the world.
4.2 Promote Constraints from Advice into Physics
Consider what a mature skill.md file looks like: a prose block, usually markdown, containing everything at once. Identity sits beside procedure. Completion criteria share the same surface as tool declarations. Stop conditions appear as bullet points alongside optional guidance. Apart from headings, nothing in the format marks which lines are instructions to the actor and which are claims about what the world itself will enforce.
The harness loads the whole thing into context and hopes the agent will infer which parts are optional guidance, which are sequence, and which are absolute constraints. That flattening is the problem. An agent cannot turn a constraint into physics by reading carefully. Only the harness can do that; and only when the skill has been written in a way that makes the distinction visible.
The move I’d recommend is to recompose the skill into a typed intermediate form. A YAML-based DSL is my preferred approach because it forces the workflow to declare its parts. Once the parts are visible, they can be sorted by ontology rather than by formatting.
To see how this works in practice, let us take this synthetic release workflow, and recast into a structured form:
The YAML version makes the separation much easier to see. Some parts of the skill describe the actor’s role and its local task. But the constraints, completion_rules, and parts of validation are not really instructions for the actor at all. They are statements about what the world must allow, forbid, halt, or recognise as complete.
These should be pulled out of the skill and applied directly to the world: to the room, its dictionary, and its physics. In future, harnesses should do this on the fly. Humans still write skills in prose, but the harness parses them and updates the wider world.
In the release example, on_main_branch, unreadable_checklist, unresolved_merge_conflict, and test_failure all belong in this category. force_push should not survive as a forbidden sentence addressed to the model; it should be removed from the available action space entirely. And invoke: done plus provide: output_pr_url should not be left to the actor’s conscience either. They are completion conditions, which means they belong to the harness logic.
Once those elements are extracted, the skill becomes smaller and cleaner. It still describes the task, the rooms, the verbs, the expected traversal, and the limited judgements that genuinely require the actor’s participation. But the hard constraints have been withdrawn from rhetoric and reimplemented as structure.
A mature skill system should therefore load in two passes. First, it reads the skill as a local description of rooms, verbs, and traversal. Second, it extracts invariant constraints and applies them directly to the environment. What the actor receives is then only the part that still needs interpretation. What the harness enforces is everything that must hold whether the actor remembers it or not.
We should stop asking the agent politely not to do things. The rule should be made as true as a property of the world.
4.3 Canonicalise at the Boundary and Make the Walls Visible
Once the dictionary has been partitioned and hard constraints promoted into the substrate, what remains still needs to absorb variation in how an agent approaches a task.
A bounded dictionary still needs to absorb variation in how an agent approaches a task. In IF design this was handled through synonym mapping; multiple surface phrasings resolving to a single canonical action. The action space stayed fixed; the lexical surface bent toward it. Tool-call schemas can do the same. A schema that accepts one exact string and nothing else is as fragile as knowing OPEN but not UNLOCK.
Canonicalisation should happen at the boundary. Let the actor approach in a range of phrasings, then resolve those phrasings into a smaller, cleaner internal action set. The world should not become looser in order to appear welcoming. It should remain hard internally while presenting a surface that is flexible enough to be usable.
The world must also communicate what it can do. Hardness and legibility should increase together. Help text, affordance cues, and clear schema documentation all make the world more navigable. Good design does not hide the boundary; it makes the boundary known to the agent. A hard world with illegible boundaries is just an arbitrary one.
4.4 Build Reversibility into the World
The most dangerous combination is high world hardness with low interface hardness; real, irreversible consequences inside a world the agent does not yet fully understand. The response is not to soften the world, but to build structured reversibility where possible, and staged commitment where reversibility is unavailable.
- Dry runs, staged commitments, rollback, and temporal sandboxing all serve the same purpose: they let the agent encounter consequence under governance before consequence escapes into production.
- Save and undo are explicit; rule-bound forms of reversibility. Rollback is not the absence of consequence; it is consequence under governance.
- Keep dev and production as structurally distinct worlds. An agent that cannot distinguish between a test and a live environment cannot reason about the cost of error. A completed run in dev is categorically different training data from a completed run in production.
- Where reversibility is impossible, commitment should be staged. There is a large difference between propose this change, show me the plan, and write to the live system now. If those are collapsed into one verb, which they are in vibe coding workflows, the world may still be hard, but hard in the wrong way; brittle, dangerous, and resistant to inspection.
4.5 Preserve the Trajectory
The Loom is not an archive. The dominant instinct in agent infrastructure is to treat the execution record as a debugging artefact; something inspected after failure, stored cheaply, otherwise ignored. That is a mistake.
The Loom is the only continuous source of context in an agentic run where the human has left the table. A good trajectory record is not only a list of events. It preserves distinctions between kinds of events. A successful transition, a blocked move, a failed gate call, a rollback, a timeout, a user interruption, and a world-imposed termination should not collapse into generic history. If they do, the agent can no longer tell what kind of trouble it is in.
The practical mechanism for keeping original intent alive is a scratchpad: a writable node where the agent maintains a compressed summary of what it is trying to do and where it currently stands. A mature harness supports context compaction as a first-class operation. The agent periodically distils the raw turn record into a denser representation, preserving intent without carrying the full weight of every intermediate observation forward. OpenClaw already does this. An agent that cannot manage its own context degrades as the run extends; eventually the record of the work overwhelms the space available to do it in.
A good trajectory also depends on the world preserving meaningful distinctions between kinds of ending and interruption. A run that times out, overruns its context, exhausts its tool budget, or reaches a terminal world state has not simply produced different log entries; it has hit different kinds of constraint. When evaluation collapses these into generic failure or interruption, both the actor and the evaluator lose the ability to read the run properly. The result is not only poorer debugging, but weaker steering and worse training signal.
The trajectory should be readable by the actor as well as by the developer. A world in which the run record is useful only after the fact is still underusing one of its strongest structural features. The actor needs some durable thread through which it can remember what it was doing, why, and what kind of state it is now in.
4.6 Verb Minting and the Limits of World-Shaping
Code execution introduces a capacity that flat tool-calling does not have: the ability to define new operations from inside the world. An agent that can write and run code inside the Code-Space can package a multi-step procedure behind a single callable name and invoke it again. This is verb minting. A minted verb has a world-shaping force; it restructures what the agent can do. New destinations come into existence.
Verb minting is powerful because it lets an agent compress repeated traversal into a new local affordance. Instead of re-performing the same sequence through the parser surface on every turn, it stabilises that sequence into a callable transformation. It writes a small part of the world back into itself.
In other scenarios the agent might be able to acquire its own tools and skills from a marketplace; see my post The Near Future of AI Agents (2026). OpenClaw, for example, already boasts over 13,000 community skills. But minting and skill-shopping relocate the dictionary problem rather than dissolving it. When an agent freely accumulates a grand toolbelt, dictionary inflation is inevitable.
The question is not whether minted verbs are allowed, but under what governance they remain legible. A good minted verb should tighten the dictionary rather than sprawl it further. It should collapse a repeated pattern into a clearer unit of action, not add another approximate synonym.
Governance follows. A function that calls an external API should be scoped to the same permissions as a direct call. The walls should not expand because the verb was locally authored. An agent that can author its own verbs can, if ungoverned, mint its way past the physics of its world. This is where privilege escalation and environment breakout actually happen. In the context of safety, hardness must remain absolute: the ability to shape the world should never grant the ability to exit it.
Verb minting therefore marks a limit case in world design. It shows that worlds can become plastic from within, but it does not abolish the need for boundaries, legibility, or constraint. The world may learn new verbs, but it should not forget its physics. A more capable actor does not reduce the need for governance; it increases it.
Hard Worlds for Little Guys
The bounded environments within which LLM are worlds. The quality that makes those worlds reliably actionable is ontological hardness: the degree to which symbol, action, and consequence bind tightly over time.
From the agent’s point of view, a Code-Space of any kind is the world. The system prompt, tool surface, and context window do not configure the agent from outside the environment. They are the world the agent wakes up inside.
5.1 Beyond Software
Any actor operating through a constrained vocabulary of actions inside a world that returns consequences faces the condition of mediated agency.
The structure described here is not limited to software. In robotics, related questions appear as action-feasibility and the mapping problem. The same is true of humans navigating social media, game worlds, and banking apps.
5.2 Living Alongside The Little Guys
A related development which deserves fuller treatment elsewhere: software is beginning to separate into two surfaces, one designed for humans and another for machines. Natural language surfaces and visual interfaces let humans approach computers through approximation and ambiguity; the layers beneath those interfaces however are becoming more structured, more typed, and more explicit about permissible actions. Call this a “dual-species software” landscape. It is a structural consequence of everything described in this essay, and it is accelerating.
If we are serious about building intelligent systems, and the systems we put those intelligences into, we cannot also pretend that intelligence makes world design irrelevant. The more capable the actor, the more the structure of its world matters. Hard worlds are the condition that makes reliable agency possible for little computer people.
The agent wakes up in a world.
What kind of world it finds itself in determines what it can become.
Coda
If you have been around computers all your life and somehow never touched interactive fiction, go and play some.
Start with the original Zork; get a feel for the parser, the rhythm of turn-taking, and the way language and the dictionary make the world.
Then play Counterfeit Monkey; Emily Short’s astonishing game, where changing the letters in nouns changes the objects themselves. It is one of the clearest demonstrations I know of language operating as world-model and game mechanic at the same time.
If you want a stranger contemporary continuation of that lineage, The O’Ruggin Trail, the game and engine I worked on, experiments with the blockchain-as-substrate for harder claims about objects, multiplayer persistence, and consequence inside a parser world.
This is my first time using footnotes on the blog properly. Had I know I was going to put things here, I suspect I would have written a lot more!
- The term Code-Space is used here narrowly to describe the bounded software environment an agent acts inside, my forthcoming book Slop Machines of Loving Grace uses the term far more expansively. That book is a diagnosis of the condition we find ourselves in as civilisation is becoming software. ↩︎
- Eikon: image, representation of a thing ↩︎
- Thanks to Ramon Marc, interaction designer and vibe coding wizard for this observation. ↩︎

Strategist, producer, and cultural theorist. Working across technology, narrative, worldrunning, digital culture, artificial intelligence, and internet culture.
Host of the 301 second long podcast Permanently Moved, and interview show Experience.Computer