From 260adb9da7c0dfd205dd508df21245780e179fbe Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Sun, 23 Aug 2026 14:15:47 +0300 Subject: [PATCH] Extract the glossary to a root CONTEXT.md --- CLAUDE.md | 26 +++--------------------- CONTEXT.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++ planning/README.md | 2 +- 3 files changed, 54 insertions(+), 24 deletions(-) create mode 100644 CONTEXT.md diff --git a/CLAUDE.md b/CLAUDE.md index ae3ceba..4724f4f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 diff --git a/CONTEXT.md b/CONTEXT.md new file mode 100644 index 0000000..d613601 --- /dev/null +++ b/CONTEXT.md @@ -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 diff --git a/planning/README.md b/planning/README.md index fd67162..ca6d5b8 100644 --- a/planning/README.md +++ b/planning/README.md @@ -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.