Every cognitive agent faces the same problem: how do you evaluate an action before committing to it? You imagine the outcome. But imagination is dangerous. If the agent cannot distinguish between what it perceived and what it simulated, the simulation results leak into the world model as if they were real observations. This is confabulation—and it is fundamentally a type safety failure.
The solution is to treat imagination as a context switch: fork the world state into a virtual copy, run the simulation, tag every result with source: IMAGINED, and only merge the evaluations back—never the raw percepts. Below is an interactive demonstration.
An 8×8 world. The agent (◆) navigates among items: food (●), tools (▲), obstacles (■), and the goal (★). Click a direction to move, or use the action buttons. Enter imagination mode to simulate without consequences.
Real actions appear in green. Imagined outcomes appear in purple italic with the [IMAGINED] tag. This is type safety—the provenance of every observation is preserved.
What happens when we remove the source tags? The log becomes a flat list of events with no way to distinguish real from imagined. This is exactly what happens in confabulation: the type information is erased, and simulated outcomes are treated as real memories.
[IMAGINED] tags and color coding from the log. Notice how impossible it becomes to tell which events actually happened and which were only simulated. This is why type safety in cognitive architecture is not optional—it is the difference between imagination and delusion.
The structure above is not just a toy. It maps onto real problems in cognitive architecture:
Imagination is useful—it is how agents plan, evaluate, and learn from counterfactuals. But it requires discipline: fork the world, tag the results, merge only the evaluations, discard the sandbox. The recursion depth limit prevents infinite regress (imagining imagining imagining…). The type tags prevent confabulation. Together they make imagination safe.
This is the same structure as a database transaction, a VM snapshot, a git branch. Context switch, do work, merge or discard. The pattern is universal because the problem is universal: how do you explore possibilities without corrupting your ground truth?