---
name: event-contract-cross-platform
description: Web (chat.js) and native apps (iOS/Mac) validated against shared event vectors for chat/todo/remind events
metadata:
  type: project
---

## Cross-platform event contract

**Problem:** chat.js, todo.js, remind.js (web) and native implementations must stay in sync. Without a spec, fold handlers can drift.

**Solution:** Shared event vectors in `test/event-vectors/` (organized by app) + tests on both sides catch drift on PR.

**Structure:**
- `test/event-vectors/chat.json` — message/reaction/edit/delete vectors (web: source of truth)
- `test/event-vectors/todo.json` — to-do fold logic vectors (web: source of truth)
- `test/event-vectors/remind.json` — remind fold logic vectors (web: source of truth)
- `test/event-vectors/groupapps.json` — group-apps registry vectors: which trusted apps a group chat has added (web source of truth: the `groupapps` app in `web/static/apps.js`)
- `test/event-vectors/index.js` — loader for tests

**Maintenance:**
1. **Changing a web app's fold handlers** → update the app's vector file + run `npm test`
2. **Changing a native structure** (MessagePayload, etc.) → update native tests + run iOS tests
3. **Adding a feature** → add vector entry + test case to both sides

**Key invariants:**
- Todo: `done` items with `doneAt > (now - 750ms)` stay active; older → archived
- Remind: items always sorted by `when` (soonest first); fired with `firedAt > (now - 750ms)` stay active
- Both: grace period derived in render, never mutated by a timer
- Both: duplicate adds are deduped; unicode text preserved

**Why this matters:** Different rendering on different clients destroys trust. These tests prevent silent mismatches.

**Vectors are the spec.** If tests fail, code diverged—fix the implementations, not the vectors.
