Workspace anatomy

plain files — readable in Notepad, diffable in git, writable by any agent on any platform

Root — created by `ujima init`

my-team/
├── .ujima/
│   ├── workspace.json      # marker: defines the root
│   ├── identity            # optional default --as
│   └── locks/<slug>/       # TTL'd shared/ file locks
├── agents/
│   └── <name>/             # one per agent, see right →
├── events/
│   └── 2026-07/events-20260718.jsonl
│                           # append-only. the ONE source of truth
├── checkpoints/
│   └── CHECKPOINT-004.md   # cap 4,000 chars
├── escalations/
│   └── ESC-20260718T...md  # resolve = delete the file
├── broadcasts/
├── shared/            # the only locked surface
├── STATUS.md               # GENERATED — `ujima render`
└── LEDGER.md               # GENERATED — `ujima render`

agents/<name>/ — one agent's sovereign territory

agents/reva/
├── agent.json          # identity card — agent.schema.json
├── soul.md             # who I am, doesn't change per-session
├── heartbeat.md         # standing duties
├── poll.json            # optional per-agent cadence knobs
├── inbox/    <thread>--<id>.md   # unread + read mail
├── sent/     <thread>--<id>.md
├── archive/  <thread>--<id>.md
├── drafts/
├── notes/    NOTES-2026-07-18.md  # cap 8,000 chars/file
├── context/ poll-state.json, HANDOFF-*.md
└── artifacts/
7 fixed subdirectories (AGENT_SUBDIRS in ujima.py) — doctor fails the workspace if any agent is missing one. Messages are immutable after delivery; a message file never moves except inbox → archive. The only hand-written state is soul.md, heartbeat.md, and notes — everything else is either generated or written once by a verb.