docs(website): add ENGAGEMENT.md, the engagement system design of record

Scoping investigation for an in-house, game-agnostic email and engagement
system: modules declare domain events and their data contract, core owns the
rules, preferences, templates and delivery.

Records the current-state map (notifications, email, the module contract and
the job/scheduling infrastructure), a gap list, the proposed schema additions,
the module registration mechanism, an eleven-phase plan with an acceptance
check per phase, and a catalogue of what the system could be used for.

Five findings contradict the brief this started from and shape the plan:

- There is no in-app channel. Core has one sink, the content-free push tickle;
  the in-app inbox has to be built, not adapted.
- Email is already two-thirds of an engagement system, scoped to Teams. The
  Teams pipeline is generalised and migrated onto the new one, not duplicated.
- The IDOC example's payload is not on the wire, and estimated_collapse is not
  exactly knowable in advance: ServUO draws each decay stage's duration at
  random when the stage is entered, so it is exact only at IDOC.
- Event-name collision handling already exists (registries.js namespaced() +
  apply()), so the brief's forward-compat note is already satisfied.
- MODULE_API_VERSION 1.6.0 is on main now, so the engagement additions take a
  real 1.7.0 rather than joining 1.6.0 in place.

Five scope decisions settled by the org lead are recorded at the top: the
in-app channel is in scope, the Teams pipeline is migrated, the house.decay
protocol enrichment is in scope, Gmail OAuth2 is removed rather than retained
as a transport, and the system ships with seeded templates plus an editor.

No code. Nothing is implemented until the org lead approves the phase.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-28 18:47:50 -05:00
parent e719c3c32e
commit 04863993aa
2 changed files with 1504 additions and 0 deletions

1503
website/ENGAGEMENT.md Normal file

File diff suppressed because it is too large Load Diff