--- name: feedback_generic_safety description: THE #1 locked rule — the kernel must never hardcode chat/domain vocabulary metadata: type: feedback --- **The kernel must stay generic.** No `'dm'` / `'group'` / `'reaction'` / `'emoji'` / `'mention'` literals in kernel or messaging *logic*. If a reviewer asked "is this a chat backend now?" the answer must stay **no**. **Why:** IIOS is a generic interaction OS; chat is one consumer. Baking chat meaning into the kernel destroys reuse (support/community/meetings share the same core). **How to apply:** domain meaning lives in exactly three places, never the kernel — 1. **OPA policy** (`DevOpaPort` → real OPA): DM-cap, group-admin, governed-join, media limits, notification triggers. 2. **Opaque attributes** the kernel stores but never interprets: `thread.metadata.membership` (`dm`/`group`), interaction annotations (opaque `annotationType`+`value` → app writes `reaction`/`pin`/`save`), `mentions[]` (opaque userId notify-list; kernel never parses `@`). 3. **The app** (chat-web): rendering + product semantics. Reading an opaque attr inside a **policy/notification gate** (`membership === 'dm'` in `DevOpaPort` or `notification.projector.ts`) is OK — that file IS the policy plane. Everywhere else, keep generic. Verify before committing: `grep -rniE "'dm'|'group'|reaction|emoji" packages/iios-service/src | grep -v spec` — hits only in policy/notification/app-facing layers or comments. Also run `pnpm boundary`. Related: [[project_iios_overview]].