docs(website): the in-app channel as built (engagement Phase 7) #188

Merged
whitlocktech merged 1 commits from docs/engagement-inapp-channel into edge 2026-08-31 07:23:07 +00:00
Member

The documentation §6.0b assigns engagement Phase 7. Companion to RunicGateway/website#175 and RunicGateway/runicgateway.com#24.

website/ENGAGEMENT.md

The Phase 7 as-built:

  • The four decisions the org lead settled before any code — in-app defaults to instant (the only channel that does); the phase takes push's deliver and the web preferences screen, neither of which its own acceptance line mentions; the inbox takes /notifications and the settings move under it; ctx.inbox.push respects a preference where one exists.
  • The block → column mapping, which is the whole of how a template with a subject and a document becomes a row with three fields — and why the body is text rather than the email HTML, which is what discharges the phase's own "sanitize path for body" guardrail by never letting markup into the column.
  • Five things the tree contradicted or the build found: the shipped inapp.event seed named variables nothing supplies; the dedupe index is scoped narrower than the outbox's; the tickle's ref needed an enqueue ordering to be worth anything; there was no retention policy at all; and the one only the live rig could see — staff had no reachable inbox, because /auth/me/notifications is role-agnostic while RequirePlayer is not.
  • What was verified, including the rig walk: two rules on one event → three outbox rows → exactly one inbox item.
  • A note on what this phase deliberately did not wire: news.post is declared and nothing emits it through the engine.

Two earlier passages amended where the phase made them false, both kept as history with the correction beside them:

  • Phase 2's "ctx.inbox.push — present and throws until Phase 7" (filling it in is not a version bump; the signature is the one 1.7.0 declared).
  • Phase 3's "inapp is declared off … so the first thing Phase 7 shipped would be a backlog" — the backlog it feared cannot happen against an empty table.

§6.0b's Phase 7 row is ticked.

website/BACKEND_DESIGN.md

  • The four inbox routes in the /auth/me table, including why unread-count is its own route (it is polled), why mark-read 404s identically for "no such row" and "somebody else's", and that no parameter names a user.
  • user_notifications in the table inventory: the user-scoped dedupe index and why it is narrower than the outbox's, why body is the text render rather than the email HTML, the block-role mapping, and the retention policy.

(This branch was force-pushed once: BACKEND_DESIGN.md is committed with CRLF line endings, and rewriting it through a tool that normalised them turned a two-hunk edit into a 1714/1670 whole-file diff. Re-applied against the original bytes and staged with core.autocrlf=false, so what you see is 43 added lines and nothing else.)


  • AI-assisted: written with Claude Code; commits carry Co-Authored-By: Claude.
The documentation §6.0b assigns engagement **Phase 7**. Companion to **RunicGateway/website#175** and **RunicGateway/runicgateway.com#24**. ## `website/ENGAGEMENT.md` The Phase 7 as-built: - **The four decisions** the org lead settled before any code — in-app defaults to `instant` (the only channel that does); the phase takes push's `deliver` and the web preferences screen, neither of which its own acceptance line mentions; the inbox takes `/notifications` and the settings move under it; `ctx.inbox.push` respects a preference where one exists. - **The block → column mapping**, which is the whole of how a template with a subject and a document becomes a row with three fields — and why the body is text rather than the email HTML, which is what discharges the phase's own "sanitize path for `body`" guardrail by never letting markup into the column. - **Five things the tree contradicted or the build found**: the shipped `inapp.event` seed named variables nothing supplies; the dedupe index is scoped narrower than the outbox's; the tickle's `ref` needed an enqueue ordering to be worth anything; there was no retention policy at all; and the one only the live rig could see — **staff had no reachable inbox**, because `/auth/me/notifications` is role-agnostic while `RequirePlayer` is not. - **What was verified**, including the rig walk: two rules on one event → three outbox rows → exactly one inbox item. - A note on what this phase deliberately did **not** wire: `news.post` is declared and nothing emits it through the engine. Two earlier passages amended where the phase made them false, both kept as history with the correction beside them: - Phase 2's "`ctx.inbox.push` — present and **throws** until Phase 7" (filling it in is not a version bump; the signature is the one 1.7.0 declared). - Phase 3's "`inapp` is declared `off` … so the first thing Phase 7 shipped would be a backlog" — the backlog it feared cannot happen against an empty table. §6.0b's Phase 7 row is ticked. ## `website/BACKEND_DESIGN.md` - The **four inbox routes** in the `/auth/me` table, including why `unread-count` is its own route (it is polled), why mark-read 404s identically for "no such row" and "somebody else's", and that no parameter names a user. - **`user_notifications`** in the table inventory: the user-scoped dedupe index and why it is narrower than the outbox's, why `body` is the text render rather than the email HTML, the block-role mapping, and the retention policy. *(This branch was force-pushed once: `BACKEND_DESIGN.md` is committed with CRLF line endings, and rewriting it through a tool that normalised them turned a two-hunk edit into a 1714/1670 whole-file diff. Re-applied against the original bytes and staged with `core.autocrlf=false`, so what you see is 43 added lines and nothing else.)* --- - [x] AI-assisted: written with Claude Code; commits carry `Co-Authored-By: Claude`.
wtclaude added 1 commit 2026-08-31 07:08:58 +00:00
ENGAGEMENT.md gains the Phase 7 as-built: the four decisions the org lead
settled before any code (in-app defaults to `instant`; the phase takes push's
`deliver` and the web preferences screen; the inbox takes `/notifications` and
the settings move under it; `ctx.inbox.push` respects a preference where one
exists), the block-role mapping that turns a template into a row, and five
things the tree contradicted or the build found — including the one only the
live rig could see, that staff had no reachable inbox at all.

Two earlier passages amended where the phase made them false: Phase 2's
"`ctx.inbox.push` throws until Phase 7" and Phase 3's "`inapp` is declared
`off`". Both kept as history with the correction beside them.

BACKEND_DESIGN.md gains the four inbox routes in the `/auth/me` table and a
`user_notifications` entry in the table inventory — the user-scoped dedupe
index, why `body` is text rather than the email HTML, and the retention policy.

Code: RunicGateway/website#TBD

Co-Authored-By: Claude <noreply@anthropic.com>
wtclaude added 2 commits 2026-08-31 07:11:52 +00:00
ENGAGEMENT.md gains the Phase 7 as-built: the four decisions the org lead
settled before any code (in-app defaults to `instant`; the phase takes push's
`deliver` and the web preferences screen; the inbox takes `/notifications` and
the settings move under it; `ctx.inbox.push` respects a preference where one
exists), the block-role mapping that turns a template into a row, and five
things the tree contradicted or the build found — including the one only the
live rig could see, that staff had no reachable inbox at all.

Two earlier passages amended where the phase made them false: Phase 2's
"`ctx.inbox.push` throws until Phase 7" and Phase 3's "`inapp` is declared
`off`". Both kept as history with the correction beside them.

BACKEND_DESIGN.md gains the four inbox routes in the `/auth/me` table and a
`user_notifications` entry in the table inventory — the user-scoped dedupe
index, why `body` is text rather than the email HTML, and the retention policy.

Code: RunicGateway/website#TBD

Co-Authored-By: Claude <noreply@anthropic.com>
ENGAGEMENT.md gains the Phase 7 as-built: the four decisions the org lead
settled before any code (in-app defaults to `instant`; the phase takes push's
`deliver` and the web preferences screen; the inbox takes `/notifications` and
the settings move under it; `ctx.inbox.push` respects a preference where one
exists), the block-role mapping that turns a template into a row, and five
things the tree contradicted or the build found — including the one only the
live rig could see, that staff had no reachable inbox at all.

Two earlier passages amended where the phase made them false: Phase 2's
"`ctx.inbox.push` throws until Phase 7" and Phase 3's "`inapp` is declared
`off`". Both kept as history with the correction beside them.

BACKEND_DESIGN.md gains the four inbox routes in the `/auth/me` table and a
`user_notifications` entry in the table inventory — the user-scoped dedupe
index, why `body` is text rather than the email HTML, and the retention policy.

Code: RunicGateway/website#TBD

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit 3274c7864c into edge 2026-08-31 07:23:07 +00:00
whitlocktech deleted branch docs/engagement-inapp-channel 2026-08-31 07:23:09 +00:00
Sign in to join this conversation.
No description provided.