Rooms and crystals
The two working units of a palace: where context lives, and what persists.
Naming update
Earlier versions of this page described rooms backed by .room.json metadata files, a fixed six-room roster with glow colors, a "locus" file format, and a desktop app called Wizard. All of that is retired. The shipped model (0.6 open beta, v0.6.0-beta) is simpler: a room is a folder containing a CLAUDE.md, and the unit of permanent memory is a crystal. The project name keeps the memory-palace metaphor (loci are the places). The thing you actually create and retrieve is called a crystal.
What is a room
A room is a domain of work: your job, a creative project, research, ideas. Rooms keep a large palace legible. When you enter one, exactly its context loads, and nothing else.
A room is not a single conversation. Conversations are the activity; the room is the place the work accumulates. You return to a room across sessions, and it already has ground truth, behaviour rules, and open work waiting.
Structurally, the definition is one line: a room is a directory containing a CLAUDE.md. No registry, no separate metadata file, no hidden state. If a folder has a CLAUDE.md, the tools see a room. Rename the folder, the room is renamed. Delete it, the room is gone.
You choose your rooms. There is no default roster. Start tight (two or three rooms); you can always add more later.
The room file
Each room's CLAUDE.md is its context. The template lives in the repo at templates/room-template.md and covers:
- What this room is for: 1-3 sentences on the kind of work that happens here
- Ground truth: established facts the AI should never re-derive in this room
- Behaviour rules: how the AI should act here (some rooms are exploratory, others careful)
- Active projects: a small table of live work and next steps
- State summary: a 2-line "where we left off" updated each session
- Session strategy: when this room's context should load (below)
- Pinned crystals: facts protected from health-check passes
- Corridors: connections to other rooms ("Research feeds Writing: confirm facts there before using them here")
Keep room files room-scoped. Behavioural constants belong in your global layer, living project state in the project layer, room specifics here. That separation is what makes room-switching cheap.
Session strategy
Every room declares how it loads, in a session_strategy block inside its CLAUDE.md:
session_strategy:
scope: on-demand # always-load | on-demand | per-session
auto_detect: true # read first message for room signals before asking
crystals_to_load: global # global | room-only | [specific names]
handover_depth: 1 # recent handovers to surface at session start (0 = none)always-load: loads every session. Use for identity and master context.on-demand: loads when you enter the room or the topic clearly matches. The default.per-session: loads once, not reloaded mid-session.
This is the room's slot in the L0-L3 retrieval hierarchy: soul identity (L0) and active state (L1) always load, room context (L2) loads on room entry, deep history (L3) only on explicit request. The template is templates/retrieval-hierarchy.md.
Two palace layouts
The desktop app and the CLI both accept two layouts (since v0.6.0-beta):
| Layout | Shape |
|---|---|
| Rooms at root | PALACE.md or CLAUDE.md at the root, sibling directories each holding a CLAUDE.md |
Legacy _palace/ subdir | PALACE.md or CLAUDE.md at the root, rooms inside a _palace/ folder |
The marker for "this folder is a palace" is a PALACE.md or CLAUDE.md at the root. Hidden folders and build directories (node_modules, target, cron) are skipped during room discovery. Palaces that grew organically with rooms at the root work without restructuring.
Build a room
The full tutorial is in the repo at tutorials/build-a-room.md. The short version:
- Decide your rooms. Copy
templates/room-template.mdtorooms/<name>/CLAUDE.mdfor each. - Set the
session_strategyin each room file. - Add the room to the room table in your main
CLAUDE.md, so your AI can state the room at session open. - Keep the room file room-scoped only.
- Optional: draw a local map of how rooms connect (
templates/local-map-template.md) and track open work intracker.json.
You are done when you open a session, name a room, and only that room's context loads. The palace stops dumping everything at once.
There is no room create command. A room is a folder and a markdown file; mkdir and the template are the whole interface.
What is a crystal
A crystal is the palace's unit of permanent memory: a fact established once, never re-derived. Crystals carry a tier marker that signals how much to trust them:
| Tier | Symbol | Meaning |
|---|---|---|
| Confirmed | ◆ | Foundational. Ground truth. Rarely changes; if it does, note why. |
| Contextual | ◈ | True now, tied to the current phase. Carries a valid_until for review. |
| Exploratory | ◇ | Hypothesis. Promote once validated, or retire with a note. |
The lifecycle is promote, expire, pin, compost. Exploratory facts get promoted as they harden. Contextual facts expire on their valid_until date and get reviewed, not auto-deleted. Pinned crystals are protected from garden health passes. Retired crystals are composted with a note, not silently dropped.
Where they live: crystal entries sit in your palace and room CLAUDE.md files, so they load at session start. Standalone notes work too. To the CLI, every markdown file inside a room counts as a crystal, addressed by its filename stem (the slug). There is no special file extension and no separate crystal store.
The full guide is Crystals and, in the repo, templates/crystals-guide.md.
Creating one
In a session, say "Add this as a crystal" and your AI writes the fact into context with the right tier. Or write the markdown yourself; the file is the format. There is no crystallise command, and nothing is created automatically. A crystal is a deliberate act.
The test stays the same as it always was: would I want this fact available in a future session without re-deriving it? If yes, crystallise. If not, let it stay in the session's handover.
Rooms from the terminal
The CLI (loci-cli, Rust, v0.6.0-beta) is a small read-only door into the palace. No network, no inference, no daemons. Five commands:
| Command | What it does |
|---|---|
loci status | Palace path, layout, room and crystal counts |
loci crystals [--room <name>] | List crystal slugs, optionally scoped to one room |
loci read <slug> [--room <name>] | Print a crystal. --room disambiguates duplicate slugs. |
loci handover | Print the most recent handover |
loci init | Interactive wizard; writes ~/.config/loci/config.toml |
Example:
$ loci status
palace : /home/you/palace
layout : rooms-at-root
rooms : 3
dev (12 crystals)
research (8 crystals)
writing (5 crystals)
total : 25 crystalsThe palace is resolved in order: the --palace <path> flag, then the $LOCI_PALACE environment variable, then walking up from the current directory looking for a palace marker. Every command takes --json for machine-readable output. Setup details: the terminal path.
Rooms in the desktop app
The desktop app (Tauri, v0.6.0-beta) is a cockpit over the same folder:
- Operations: a native dashboard tab with room and palace state.
- Instrument tabs: one tab per instrument your palace generates for itself (self-contained HTML pages, discovered by convention at the palace root,
_palace/, orcockpit/). - Tool shelf, gate ledger: cards for foreign tooling with a quarantine verdict each (admitted, admitted-escorted, deferred, held-conditional, rejected). The shelf lists; it never loads.
The app reads the palace; it does not own it. Everything it shows is the same plain text the CLI and any file-aware AI read.
Rooms vs projects
Rooms are domains; projects are bounded work inside them. A project is a row in the room's Active projects table, tracked to completion, while the room persists. Open work across rooms can live in tracker.json. When a project ends, its crystals remain in the room.
Connections between rooms are corridors, noted in each room file. A local map (an ASCII diagram of the whole palace) keeps the shape legible once you have more than a few rooms.
What is not shipped
To be plain about the current surface:
- No
room createorroom archivecommands. Rooms are folders. - No conversation indexing or search. The palace stores distilled context, not transcripts.
- No
loci serveCLI command yet (deferred behind a threat-model pass; the desktop app's own MCP server is separate and already shipped, see MCP API), no sync, no team rooms. Nothing leaves your machine.
The substrate does not wait on any of this. A folder, a CLAUDE.md, and a file-aware AI are the whole requirement.