Rooms and crystals
The two working units of a palace: where context lives, and what persists.
Naming update
Earlier versions of this page described .room.json metadata files, a fixed six-room roster with glow colors, and a "locus" file format. All of that is retired. In v0.6.0-beta a room is a folder containing a CLAUDE.md, and the unit of permanent memory is a crystal. The name keeps the memory-palace metaphor (loci are the places); what you create and retrieve is 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 CLI accepts 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, v0.6.0-beta) reads rooms and crystals without touching them. loci crystals --room <name> lists one room's crystals, loci read <slug> prints one, and loci status shows the whole palace:
$ loci status
palace : /home/you/palace
layout : rooms-at-root
rooms : 3
dev (12 crystals)
research (8 crystals)
writing (5 crystals)
total : 25 crystalsCommands, flags, and palace resolution: the terminal path.
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), no MCP server, 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.