docs: Phase 69 lurker role + Phase 70 guild icon live mesh (v0.8.34)

Add LURKER_ROLE.md, Phases 69–70 roadmap, live mesh testing for guild
icons, parity P65-5 complete, and automated test index entries.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-22 02:00:15 -04:00
co-authored by Cursor
parent 0da3b7f70c
commit 386f527771
6 changed files with 98 additions and 3 deletions
+2
View File
@@ -79,6 +79,8 @@ Pearcord validates itself without manual QA.
| `npm run test:role-permissions` | Custom role bitmask grants channel create (`ROLE_PERMISSIONS_SMOKE_OK`) |
| `npm run test:guild-icon` | Guild icon staging + GUILD_UPDATE sync (`GUILD_ICON_SMOKE_OK`) |
| `npm run test:message-jump` | Cross-channel jump-to-reply (`MESSAGE_JUMP_SMOKE_OK`) |
| `npm run test:lurker-role` | Read-only lurker cannot send (`LURKER_ROLE_SMOKE_OK`) |
| `npm run test:guild-icon-live` | Guild icon bytes over attach mesh (`GUILD_ICON_LIVE_SMOKE_OK`) |
| `npm run test:dm-read-receipt` | DM `CHANNEL_READ` read receipts (`DM_READ_RECEIPT_SMOKE_OK`) |
| `npm run test:group-dm-read` | Group DM read cursors (`GROUP_DM_READ_SMOKE_OK`) |
| `npm run test:dm` | DM channel id + message sync (`DM_SMOKE_OK`) |
+11
View File
@@ -44,11 +44,22 @@ Response: `guild-icon-image` with `preview: { attachmentId, mimeType, dataBase64
- **Channel header** — small icon beside guild name when active.
- **Server settings** — upload + remove controls.
## Live mesh fetch (v0.8.34+)
When host and guest share a guild Hyperswarm topic:
1. Guest ingests `iconAttachment` from `GUILD_UPDATE` (metadata only).
2. Guest calls `fetchAttachmentFromPeers` on attach mesh (`pearcord-attach-v1`).
3. Host serves bytes; guest `readGuildIconPreview` returns base64.
`npm run test:guild-icon-live``GUILD_ICON_LIVE_SMOKE_OK`. Same patterns as [ATTACH_MESH_LIVE.md](./ATTACH_MESH_LIVE.md).
## Tests
| Script | Marker |
|--------|--------|
| `npm run test:guild-icon` | `GUILD_ICON_SMOKE_OK` |
| `npm run test:guild-icon-live` | `GUILD_ICON_LIVE_SMOKE_OK` |
| `npm run test:boot` | Pear app boots |
## Related
+56
View File
@@ -0,0 +1,56 @@
# Lurker read-only role (v0.8.34+)
Built-in **`lurker`** role for observers who can read guild history but cannot participate until promoted or granted a custom role.
## Permissions
| Builtin | Bitmask | Send / react / voice |
|---------|---------|----------------------|
| `lurker` | `0` | Blocked by default |
**Override:** Assign one or more **custom roles** with any permission bits — effective mask is OR'd (same as other members). A lurker with a custom role that includes `manageMessages` can post in announcement channels.
## Enforcement (`memberCanParticipate`)
Blocked actions for lurkers without custom role permissions:
- `sendMessage` / forum posts / slash replies
- `toggleReaction`
- `editMessage` / `deleteMessage` (via `_assertCanParticipate` before modify)
- `joinVoiceChannel`
- Typing indicators skipped when announcement rules already block
## Owner controls
| Action | IPC | Result |
|--------|-----|--------|
| Make lurker | `set-member-role` `role: lurker` | Member → lurker |
| Restore member | `set-member-role` `role: member` | Lurker → member |
| Promote / demote | unchanged | member ↔ moderator |
Gossip: `MEMBER_ROLE_UPDATE` (RPC 13).
## UI
- Member list **Lurker** tag (muted pill)
- **Make lurker** / **Restore member** buttons (Manage Guild)
- Composer placeholder: `Read-only (lurker) — you can view but not send`
- `view.canPostInActiveChannel === false`
## Platform API
| Method | Notes |
|--------|-------|
| `setMemberRole(userId, 'lurker')` | Requires Manage Guild |
| `memberCanParticipate(member, customRoles)` | `pearcord-shared` helper |
## Tests
| Script | Marker |
|--------|--------|
| `npm run test:lurker-role` | `LURKER_ROLE_SMOKE_OK` |
## Related
- [PERMISSIONS.md](./PERMISSIONS.md) — built-in roles
- [ROLE_PERMISSIONS.md](./ROLE_PERMISSIONS.md) — custom role overrides
+2 -2
View File
@@ -145,7 +145,7 @@ Phases **02** and **4** are largely complete; **3** (live audio) and **5** (n
| P63-1 | Role-restricted emoji manage UI (v0.8.28) | [x] |
| P64-1 | Discovery mesh live sync (v0.8.29) | [x] |
**Next tranches (Phase 68+):** Read-only lurker role · guild icon live mesh smoke · notification pin jump.
**Next tranches (Phase 70+):** Notification / pin jump-to-message · `pearcord://` link scheme · voice lurker listen-only.
When Phase 5 checklist is `[x]`, copy open items here into tracked rows in `PLATFORM_ROADMAP.md`.
@@ -157,7 +157,7 @@ When Phase 5 checklist is `[x]`, copy open items here into tracked rows in `PLAT
| P65-2 | Role permission editor (bitmask UI, not just promote/demote) | [x] |
| P65-3 | Guild icon upload + P2P gossip (`iconHash` + attach mesh) | [x] v0.8.32 |
| P65-4 | Message deep links / jump-to-reply in UI | [x] v0.8.33 |
| P65-5 | Read-only lurker role preset | Low |
| P65-5 | Read-only lurker role preset | [x] v0.8.34 |
## Holepunch stack references
+1
View File
@@ -9,6 +9,7 @@ Local role strings map to a permission bitmask in `pearcord-shared`.
| Owner | `owner` | All flags (manage guild, channels, delete any message, moderate, manage messages) |
| Moderator | `moderator` | Channels, delete any message, moderate, manage messages |
| Member | `member` | Own messages only |
| Lurker | `lurker` | Read-only (no send, reactions, or voice) — see [LURKER_ROLE.md](./LURKER_ROLE.md) |
New joins via invite receive `member`. Guild creator receives `owner`.
+26 -1
View File
@@ -249,6 +249,30 @@ When completing work, change `[ ]` → `[x]` and add a one-line note under **Cha
---
### Phase 70 — Guild icon live mesh (v0.8.34)
| ID | Item | Status |
|----|------|--------|
| P70-1 | `smoke-guild-icon-live` attach-mesh byte fetch for icon | [x] |
| P70-2 | GUILD_ICON_P2P.md live mesh section | [x] |
**Next:** Pin/notification jump-to-message · pearcord:// deep link scheme.
---
### Phase 69 — Lurker read-only role (v0.8.34)
| ID | Item | Status |
|----|------|--------|
| P69-1 | `MEMBER_ROLES.LURKER` + `memberCanParticipate` | [x] |
| P69-2 | Platform send/react/voice guards + `canPostInActiveChannel` | [x] |
| P69-3 | Member list Make lurker / Restore member UI | [x] |
| P69-4 | smoke-lurker-role + LURKER_ROLE.md | [x] |
**Next:** ~~Lurker~~ · ~~guild icon live~~ (Phase 70) · notification deep links.
---
### Phase 68 — Message deep links (v0.8.33)
| ID | Item | Status |
@@ -258,7 +282,7 @@ When completing work, change `[ ]` → `[x]` and add a one-line note under **Cha
| P68-3 | `jump-to-message` IPC + highlight animation | [x] |
| P68-4 | smoke-message-jump + MESSAGE_DEEP_LINKS.md | [x] |
**Next:** Read-only lurker role · guild icon live mesh smoke · pin jump from notifications.
**Next:** ~~Read-only lurker~~ (Phase 69) · ~~guild icon live mesh~~ (Phase 70) · pin jump from notifications.
---
@@ -846,6 +870,7 @@ When completing work, change `[ ]` → `[x]` and add a one-line note under **Cha
### Changelog
- **2026-05-22** — v0.8.34: lurker read-only role + guild icon live mesh smoke (`test:lurker-role`, `test:guild-icon-live`, LURKER_ROLE.md).
- **2026-05-22** — v0.8.33: message deep links (`jumpToMessage`, reply quote jump, `#m/` hash, `test:message-jump`, MESSAGE_DEEP_LINKS.md).
- **2026-05-22** — v0.8.32: guild icon P2P (`setGuildIconImage`, `GUILD_UPDATE` `iconAttachment`, `GUILD_SYNC` guild snapshot, server rail UI, `test:guild-icon`, GUILD_ICON_P2P.md).
- **2026-05-22** — v0.8.31: role permission editor (`pearcord-guild-roles`, bitmask UI, `test:role-permissions`, ROLE_PERMISSIONS.md).