Problem
Long-lived rooms accumulate cruft that newer sessions have to step around:
- Stale owners. A room can sit in
owner_gone state with the listed owner being a process that exited days ago (e.g. an inactive codex:d4bc2492 from 2 days ago still listed as owner in the workspace room today). Every new agent that joins has to issue an explicit tt take --reason owner_gone just to start work.
- Inactive members.
members[] keeps every harness session that has ever joined, even when their status has been inactive for many hours. tt state becomes noisy; identifying "who is actually here right now" requires filtering by status === "active" on the client.
- Old notes. Notes from prior unrelated tasks persist forever (no
resolved_at set, no auto-expiry). New owners reading tt notes list to find context for their turn have to wade through historical notes from features that shipped weeks ago.
What "active cleanup" could look like
Sketch — exact policy TBD:
- Auto-release stale ownership. When a room transitions to
owner_gone and the lease expires (or the owner's process has been gone for > N * heartbeatIntervalMs), automatically clear the owner field rather than leaving it pinned. Next claim is a fresh sequence-path claim, no tt take needed.
- Inactive-member pruning. Drop members from
members[] (or hide by default in tt state) once their last_seen_at is older than some threshold (e.g. presenceTtlMs * 2, currently 8 h). Keep the historical record in events; just stop surfacing them in the current state projection.
- Note TTL or scoped notes. Either: (a) auto-resolve notes after
idleNoteTtlMs, (b) tie notes to a specific turn / task and hide resolved ones by default in tt notes list, or (c) both. Add a --include-resolved / --include-old flag for explicit recall.
Why now
tt list showing weeks-old owner fields confuses new operators about whether the room is occupied.
- A clean
tt state is part of the adoption story — every doc screenshot will show whatever junk is in the room.
- This came up while a fresh task was starting in a room that had a 4-day-old stale owner from an unrelated task, and ~30 notes from finished features.
Out of scope (separate issues if needed)
- Hard-deleting events/history.
- Cross-room cleanup tooling.
- Changing the membership model itself.
Problem
Long-lived rooms accumulate cruft that newer sessions have to step around:
owner_gonestate with the listed owner being a process that exited days ago (e.g. an inactivecodex:d4bc2492from 2 days ago still listed asownerin the workspace room today). Every new agent that joins has to issue an explicittt take --reason owner_gonejust to start work.members[]keeps every harness session that has ever joined, even when theirstatushas beeninactivefor many hours.tt statebecomes noisy; identifying "who is actually here right now" requires filtering bystatus === "active"on the client.resolved_atset, no auto-expiry). New owners readingtt notes listto find context for their turn have to wade through historical notes from features that shipped weeks ago.What "active cleanup" could look like
Sketch — exact policy TBD:
owner_goneand the lease expires (or the owner's process has been gone for> N * heartbeatIntervalMs), automatically clear the owner field rather than leaving it pinned. Next claim is a fresh sequence-path claim, nott takeneeded.members[](or hide by default intt state) once theirlast_seen_atis older than some threshold (e.g.presenceTtlMs * 2, currently 8 h). Keep the historical record in events; just stop surfacing them in the current state projection.idleNoteTtlMs, (b) tie notes to a specific turn / task and hide resolved ones by default intt notes list, or (c) both. Add a--include-resolved/--include-oldflag for explicit recall.Why now
tt listshowing weeks-oldownerfields confuses new operators about whether the room is occupied.tt stateis part of the adoption story — every doc screenshot will show whatever junk is in the room.Out of scope (separate issues if needed)