Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 3 additions & 23 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,29 +214,9 @@ env vars (see `docker-compose.yml`). `api_bootstrapper_config` builds the

## Vocabulary

A term is listed only when there is a synonym to reject, or a meaning subtle
enough that code and docs must agree on it.

- **Chat** — a row in `chats`: a type (`direct` or `group`), an optional title,
its creator, and a pointer to its newest non-deleted message. *Avoid:*
conversation, room, thread.
- **Direct chat** — a chat between exactly two users, identified by `direct_key`,
the canonical `min(user_id):max(user_id)` string under a unique constraint.
That key is what makes opening one twice an upsert instead of a read-then-race.
*Avoid:* DM, 1:1.
- **Member** — the `(chat_id, user_id)` row granting access to a chat, plus that
user's read marker. Necessary for every read or write on a chat; not
sufficient for editing or deleting a message. *Avoid:* participant, subscriber.
- **Idempotency key** — the client-supplied UUID on a send, unique per
`(chat_id, idempotency_key)`. Scoped to one chat, because the key identifies a
retry of "send this message to this chat". *Avoid:* dedupe key, request id.
- **Unread** — a count computed at read time against one marker per member, not
a set of per-message receipt rows. *Avoid:* unseen, badge count.
- **Cursor** — a message id passed as `before_id` or `after_id`. The two are
mutually exclusive on one request. *Avoid:* page token, offset.
- **Read marker** — a member's `last_read_message_id`, the highest id they have
acknowledged. Advances only forward, via `GREATEST` inside the UPDATE. *Avoid:*
read receipt, watermark.
The ubiquitous language lives in [`CONTEXT.md`](CONTEXT.md) at the repo root: a
glossary and nothing else, listing a term only when there is a synonym to reject
or a meaning subtle enough that code and docs must agree on it.

## Agent skills

Expand Down
50 changes: 50 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# chat-app

A chat backend: users open direct or group chats, send messages, and track what
they have read. This file is the glossary and nothing else. The decisions taken
live in [`docs/adr/`](docs/adr/); how the system works lives in `app/` and its
tests.

A term is listed only when there is a synonym to reject, or a meaning subtle
enough that code and docs must agree on it. Definitions name columns and
mechanisms where that is what makes them precise.

## Language

**Chat**:
A row in `chats`: a type (`direct` or `group`), an optional title, its creator,
and a pointer to its newest non-deleted message.
_Avoid_: conversation, room, thread

**Direct chat**:
A chat between exactly two users, identified by `direct_key`, the canonical
`min(user_id):max(user_id)` string under a unique constraint. That key is what
makes opening one twice an upsert instead of a read-then-race.
_Avoid_: DM, 1:1

**Member**:
The `(chat_id, user_id)` row granting access to a chat, plus that user's read
marker. Necessary for every read or write on a chat; not sufficient for editing
or deleting a message.
_Avoid_: participant, subscriber

**Idempotency key**:
The client-supplied UUID on a send, unique per `(chat_id, idempotency_key)`.
Scoped to one chat, because the key identifies a retry of "send this message to
this chat".
_Avoid_: dedupe key, request id

**Unread**:
A count computed at read time against one marker per member, not a set of
per-message receipt rows.
_Avoid_: unseen, badge count

**Cursor**:
A message id passed as `before_id` or `after_id`. The two are mutually exclusive
on one request.
_Avoid_: page token, offset

**Read marker**:
A member's `last_read_message_id`, the highest id they have acknowledged.
Advances only forward, via `GREATEST` inside the UPDATE.
_Avoid_: read receipt, watermark
2 changes: 1 addition & 1 deletion planning/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Against upstream convention 2.2.0:
PR body.
2. `architecture/` is removed; there is no capability-page home and no promotion
rule. Enforceable claims are `INVARIANT:`-marked tests; the ubiquitous
language lives in [`../CLAUDE.md`](../CLAUDE.md)'s Vocabulary section.
language lives in [`../CONTEXT.md`](../CONTEXT.md).
3. `deferred.md` is a `deferred/` directory of indexed, trigger-bearing items.
4. Decision frontmatter drops `status` and `supersedes`. Largely subsumed by 7:
decisions are no longer a `planning/` artifact at all.
Expand Down