eleven / messenger Public

docs: member-apps โ€” record the platform's structural limitations + roadmap (#1220)

Building a 21-app "family" pack surfaced a consistent boundary: member
apps suit personal, cooperative, single-thread tools but structurally
can't express roles/authority, per-member privacy, targeted notification,
or enforcement โ€” though the server has the primitives (notably access
levels/tiers: admin-assignable roster roles with per-tier keys, invisible
to apps because ctx exposes no tiers and the sandbox withholds the roster).
Add a "Platform limitations" section to docs/member-apps.md with the
widen-it roadmap (tiers in ctx for role gating; host seal-to-tier/
seal-except; targeted notice), pointing at the family pack's DESIGN.md for
the fuller per-app evidence. Documentation only.
Co-authored-by: Claude <noreply@anthropic.com>
James Adam 365ab26421d98f7d860868195c0d7d3aa97992a8 parent 6dc5432
1 file changed, +38 −0
  • docs/member-apps.md +38 −0
diff --git a/docs/member-apps.md b/docs/member-apps.md
index ad3c6eb..e1d0b2e 100644
--- a/docs/member-apps.md
+++ b/docs/member-apps.md
@@ -307,3 +307,41 @@ surface above the composer). The trust posture is unchanged:
- The panel HEADER and โœ• are host-drawn, outside the frame โ€” dismissal can't
be trapped. A panel frame's `state` reports are ignored; the app-thread's
own frame stays the single writer.
+
+## ๐Ÿค– Platform limitations: what member apps structurally can't do (yet)
+
+Building a full pack of *real* apps (a 21-app "family" set;
+`web/static/apps-disabled/family/`) surfaced a consistent boundary worth
+recording so it isn't rediscovered each time: member apps are well-suited to
+**personal, cooperative, single-thread** tools (lists, trackers, journals,
+games) and structurally **can't express roles/authority, per-member privacy,
+targeted notification, or enforcement** โ€” even though the *server* already holds
+the primitives for most of it.
+
+- **No authority reaches apps.** Access levels (tiers, `docs/community-and-tiers.md`)
+ are admin-assignable roster roles โ€” not just paid โ€” *each carrying its own
+ key*: a ready-made "parents/children" or "moderators/members" primitive with
+ cryptographic backing. But `ctx` exposes no tiers and the sandbox withholds the
+ roster, so an app can gate nothing on a role. (In the family pack, an "ask a
+ parent" app degrades to "anyone but the asker".)
+- **No per-member privacy in a thread.** One symmetric thread key โ†’ every member
+ decrypts every event and snapshot. An app can only *render-hide* (a courtesy,
+ not a vault); asymmetric secrecy needs cryptographic sealing the keyless
+ sandbox can't perform.
+- **The fold can't authorise.** Pure reducers see only `e.uid`; every member can
+ emit every event, so "only X may do Y" is a render suggestion, never enforced.
+- **No roster, no targeting, no directed notice.** Apps rebuild a pseudo-roster
+ from participation (who has emitted an event); a `notice` reaches everyone who
+ receives the event, not a chosen person or role.
+- **Convergent fold vs asymmetry.** "The same events fold to the same state"
+ (load-bearing for snapshots + native parity + the event vectors) is exactly
+ what makes per-viewer or per-role state impossible except as a render illusion.
+
+**Widen-it path (roadmap, not built).** Expose tier membership to `ctx` for
+admin-defined **role gating** (Level 1 โ€” courtesy, but backed by a real role);
+add host-mediated **seal-to-tier / seal-except** primitives for real enforcement
+and privacy (Level 2 โ€” the keyless sandbox can't do it alone); give `notice` a
+target so an app can reach a person or a role. Fuller write-up, with per-app
+evidence and the three-level "who sees what" model, lives in the family
+reference pack's `DESIGN.md` (ยง "Fit for purpose?" and ยง "Viewer-aware
+rendering").