docs: rApp → applet mapping for canvas shape parity (Phase B)

Catalog of all rApp mini-canvas flow-node types proposed for promotion
to AppletDefinition so the main rSpace canvas can render them. 53
proposed applets across rsocials (planner + workflow), rminders,
rflows, rgov, rtime, rnetwork, rchoices. Review doc — no code changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-04-17 15:17:41 -04:00
parent d3e65a0522
commit 82663be934
1 changed files with 210 additions and 0 deletions

210
docs/RAPP-APPLET-MAPPING.md Normal file
View File

@ -0,0 +1,210 @@
# rApp → Applet Mapping (Phase B)
> **Purpose.** Every flow-node type inside an rApp mini-canvas should exist as an `AppletDefinition` so the main rSpace canvas can render it as a `folk-applet` with typed I/O ports. This is the asymmetric B-model: *rSpace understands every rApp shape; rApps don't need to understand every rSpace shape.*
>
> **Status legend** (for each proposed applet):
> - ✅ = already registered in `modules/<rapp>/applets.ts`
> - 🆕 = proposed new applet — user approves, I implement
> - 🟡 = covered by existing custom element (`folk-gov-*`) — should wrap into AppletDefinition for registry discoverability + template support
>
> **Review process.** Walk each section, mark ✓/✗/edit on proposed rows (id, label, icon, color, ports). I'll implement the ✓ set per-rApp in follow-up PRs.
---
## Currently-registered applets (27 total)
For reference only — these already work on the main canvas.
| rApp | Applet ID | Label | Icon |
|---|---|---|---|
| rbooks | `book-card` | Book Card | 📚 |
| rcal | `next-event` | Next Event | 📅 |
| rcal | `timeline-view` | Timeline | 🕒 |
| rchats | `unread-count` | Unread Count | 💬 |
| rchoices | `vote-tally` | Vote Tally | 🗳️ |
| rdata | `analytics-card` | Analytics Card | 📊 |
| rdocs | `doc-summary` | Doc Summary | 📄 |
| rexchange | `rate-card` | Rate Card | 💱 |
| rexchange | `trade-status` | Trade Status | 🔄 |
| rflows | `flow-summary` | Flow Summary | 💧 |
| rgov | `signoff-gate` | Signoff Gate | ⚖️ |
| rgov | `governance-circuit` | Governance Circuit | 🔀 |
| rinbox | `thread-feed` | Thread Feed | 📬 |
| rmaps | `location-pin` | Location Pin | 📍 |
| rmaps | `route-summary` | Route Summary | 🗺️ |
| rnetwork | `contact-card` | Contact Card | 👤 |
| rnotes | `vault-note` | Vault Note | 🗒️ |
| rphotos | `album-card` | Album Card | 🖼️ |
| rsocials | `post-draft` | Post Draft | ✏️ |
| rtasks | `task-counter` | Task Counter | 📋 |
| rtasks | `due-today` | Due Today | ⏰ |
| rtasks | `resource-coverage` | Resource Coverage | 🎯 |
| rtime | `commitment-meter` | Commitment Meter | ⏳ |
| rtime | `weaving-coverage` | Weaving Coverage | 🧶 |
| rwallet | `balance-card` | Balance Card | 💰 |
| rwallet | `token-balance` | Token Balance | 🪙 |
---
## Proposed new applets (51 total across 7 rApps)
Port type legend: `trigger` (flow control pulse), `data` (payload), `text`, `number`, `boolean`, `json`, `date`. Colors follow existing rApp accents (`modules/<rapp>/applets.ts`).
---
### rsocials — Campaign Planner (source: `modules/rsocials/schemas.ts`, `CampaignNodeType`)
Planner nodes represent the building blocks of a campaign *structure* (not runtime flow).
| # | id | label | icon | color | input ports | output ports | compact preview |
|---|---|---|---|---|---|---|---|
| 1 | 🆕 `planner-post` | Campaign Post | 📝 | #db2777 | `content:text` | `post:json` | platform + char-count + preview |
| 2 | 🆕 `planner-thread` | Thread | 🧵 | #db2777 | `tweets:json` | `thread:json` | tweet count + platform |
| 3 | 🆕 `planner-platform` | Platform Channel | 📡 | #db2777 | `post:json` | `scheduled:json` | platform logo + cadence |
| 4 | 🆕 `planner-audience` | Audience | 👥 | #db2777 | `segments:json` | `target:json` | segment count + size |
| 5 | 🆕 `planner-phase` | Campaign Phase | 🗓️ | #db2777 | `trigger:trigger` | `next:trigger` | phase name + date range |
| 6 | 🆕 `planner-goal` | Campaign Goal | 🎯 | #db2777 | — | `metric:data` | KPI name + target |
| 7 | 🆕 `planner-message` | Key Message | 💬 | #db2777 | — | `copy:text` | message + tone |
| 8 | 🆕 `planner-tone` | Brand Tone | 🎨 | #db2777 | — | `style:data` | tone name + examples |
| 9 | 🆕 `planner-brief` | Creative Brief | 📋 | #db2777 | — | `brief:json` | objective + constraints |
---
### rsocials — Campaign Workflow (source: `modules/rsocials/schemas.ts`, `CAMPAIGN_NODE_CATALOG`)
Workflow nodes are n8n-style runtime steps. These already have full typed I/O in the schema.
| # | id | label | icon | color | input ports | output ports |
|---|---|---|---|---|---|---|
| 10 | 🆕 `wf-campaign-start` | Campaign Start | ▶ | #3b82f6 | — | `trigger:trigger` |
| 11 | 🆕 `wf-schedule-trigger` | Schedule Trigger | ⏰ | #3b82f6 | — | `trigger:trigger`, `timestamp:data` |
| 12 | 🆕 `wf-webhook-trigger` | Webhook Trigger | 🔗 | #3b82f6 | — | `trigger:trigger`, `payload:data` |
| 13 | 🆕 `wf-wait-duration` | Wait Duration | ⏳ | #f59e0b | `trigger:trigger` | `done:trigger` |
| 14 | 🆕 `wf-wait-approval` | Wait for Approval | ✋ | #f59e0b | `trigger:trigger` | `approved:trigger`, `rejected:trigger` |
| 15 | 🆕 `wf-engagement-check` | Engagement Check | 📈 | #a855f7 | `trigger:trigger`, `metrics:data` | `above:trigger`, `below:trigger` |
| 16 | 🆕 `wf-time-window` | Time Window | 🕓 | #a855f7 | `trigger:trigger` | `in-window:trigger`, `outside:trigger` |
| 17 | 🆕 `wf-post-to-platform` | Post to Platform | 📤 | #10b981 | `trigger:trigger`, `content:data` | `done:trigger`, `postId:data` |
| 18 | 🆕 `wf-cross-post` | Cross-Post | 🔀 | #10b981 | `trigger:trigger`, `content:data` | `done:trigger`, `results:data` |
| 19 | 🆕 `wf-publish-thread` | Publish Thread | 🧵 | #10b981 | `trigger:trigger` | `done:trigger`, `threadId:data` |
| 20 | 🆕 `wf-send-newsletter` | Send Newsletter | ✉️ | #10b981 | `trigger:trigger`, `content:data` | `done:trigger`, `campaignId:data` |
| 21 | 🆕 `wf-post-webhook` | POST Webhook | 📡 | #10b981 | `trigger:trigger`, `data:data` | `done:trigger`, `response:data` |
> **Color groups:** trigger=blue `#3b82f6`, delay=amber `#f59e0b`, condition=purple `#a855f7`, action=emerald `#10b981`. Matches existing workflow palette.
---
### rminders — Automation Canvas (source: `modules/rminders/schemas.ts`, `NODE_CATALOG`)
| # | id | label | icon | color | input ports | output ports |
|---|---|---|---|---|---|---|
| 22 | 🆕 `auto-trigger-cron` | Cron Schedule | ⏰ | #3b82f6 | — | `fire:trigger` |
| 23 | 🆕 `auto-trigger-data-change` | Data Change | 🔄 | #3b82f6 | — | `fire:trigger`, `delta:data` |
| 24 | 🆕 `auto-trigger-webhook` | Webhook Incoming | 🔗 | #3b82f6 | — | `fire:trigger`, `payload:data` |
| 25 | 🆕 `auto-trigger-manual` | Manual Trigger | 👆 | #3b82f6 | — | `fire:trigger` |
| 26 | 🆕 `auto-trigger-proximity` | Location Proximity | 📍 | #3b82f6 | — | `enter:trigger`, `exit:trigger` |
| 27 | 🆕 `auto-condition-compare` | Compare Values | ⚖️ | #a855f7 | `trigger:trigger`, `a:data`, `b:data` | `true:trigger`, `false:trigger` |
| 28 | 🆕 `auto-condition-geofence` | Geofence Check | 🌐 | #a855f7 | `trigger:trigger`, `location:data` | `inside:trigger`, `outside:trigger` |
| 29 | 🆕 `auto-condition-time-window` | Time Window | 🕓 | #a855f7 | `trigger:trigger` | `in-window:trigger`, `outside:trigger` |
| 30 | 🆕 `auto-condition-data-filter` | Data Filter | 🔍 | #a855f7 | `trigger:trigger`, `data:data` | `pass:trigger`, `block:trigger` |
| 31 | 🆕 `auto-action-send-email` | Send Email | ✉️ | #10b981 | `trigger:trigger` | `done:trigger` |
| 32 | 🆕 `auto-action-post-webhook` | POST Webhook | 📡 | #10b981 | `trigger:trigger`, `body:data` | `done:trigger`, `response:data` |
| 33 | 🆕 `auto-action-create-event` | Create Calendar Event | 📅 | #10b981 | `trigger:trigger` | `done:trigger`, `eventId:data` |
| 34 | 🆕 `auto-action-create-task` | Create Task | ✅ | #10b981 | `trigger:trigger` | `done:trigger`, `taskId:data` |
| 35 | 🆕 `auto-action-send-notification` | Send Notification | 🔔 | #10b981 | `trigger:trigger` | `done:trigger` |
| 36 | 🆕 `auto-action-update-data` | Update Data | 💾 | #10b981 | `trigger:trigger`, `patch:data` | `done:trigger` |
---
### rflows — Funnel Canvas (source: `modules/rflows/lib/types.ts`, `FlowNode`)
Three node types with typed flow ports: `outflow / inflow / overflow / spending`. Already has a coarse `flow-summary` applet — propose splitting into per-node types.
| # | id | label | icon | color | input ports | output ports |
|---|---|---|---|---|---|---|
| 37 | 🆕 `flow-source` | Income Source | 💧 | #10b981 | — | `outflow:number` |
| 38 | 🆕 `flow-funnel` | Funnel | 🔽 | #60a5fa | `inflow:number` | `overflow:number`, `spending:number` |
| 39 | 🆕 `flow-outcome` | Outcome | 🎯 | #8b5cf6 | `inflow:number` | `overflow:number` |
> **Note:** port colors already defined in `PORT_DEFS` — reuse exactly so canvas-level wire colors match. Port type is `number` (monthly flow rate) not `data`.
---
### rgov — Governance Circuit (source: `modules/rgov/components/folk-gov-circuit.ts`, `GOV_NODE_CATALOG`)
These already exist as `folk-gov-*` custom elements rendered by the main canvas. But they are **not registered** as AppletDefinitions — which means users can only add them from within the circuit mini-canvas, not from the main canvas palette. Low-lift win: register the 8 that aren't already wrapped.
| # | id | label | icon | color | input ports | output ports | notes |
|---|---|---|---|---|---|---|---|
| 40 | 🟡 `gov-binary` | Signoff | ✓ | #7c3aed | `in:trigger` | `out:trigger` | duplicates existing `signoff-gate` applet — deprecate one? |
| 41 | 🆕 `gov-threshold` | Threshold | 📊 | #0891b2 | `in:number` | `out:trigger` | trips when input ≥ N |
| 42 | 🆕 `gov-knob` | Knob | 🎚️ | #b45309 | `in:trigger` | `out:number` | manual dial value |
| 43 | 🆕 `gov-project` | Project | 📁 | #10b981 | `in:trigger` | `out:data` | project card as flow node |
| 44 | 🆕 `gov-quadratic` | Quadratic Vote | ⊿ | #14b8a6 | `in:data` | `out:number` | quadratic tally |
| 45 | 🆕 `gov-conviction` | Conviction Vote | ⏱️ | #d97706 | `in:data` | `out:number` | conviction curve |
| 46 | 🆕 `gov-multisig` | Multisig Approval | 🔐 | #6366f1 | `in:trigger` | `out:trigger` | M-of-N signers |
| 47 | 🆕 `gov-sankey` | Sankey Flow | 〰️ | #f43f5e | `in:data` | `out:data` | fund-routing viz |
> **Alternative:** register as thin AppletDefinition wrappers that delegate `renderCompact` to the existing `folk-gov-*` component. Keeps rendering logic in one place. Recommend this approach.
---
### rtime — Weave Canvas (source: `modules/rtime/components/folk-timebank-app.ts`)
| # | id | label | icon | color | input ports | output ports |
|---|---|---|---|---|---|---|
| 48 | 🆕 `weave-commitment` | Commitment | 🤝 | #7c3aed | `trigger:trigger` | `fulfilled:trigger`, `progress:number` |
| 49 | 🆕 `weave-task` | Weave Task | 🧵 | #7c3aed | `assignee:data`, `trigger:trigger` | `done:trigger` |
> Existing `commitment-meter` + `weaving-coverage` applets aggregate all commitments. These new ones represent *individual* commitment/task nodes droppable on canvas.
---
### rnetwork — CRM Graph (source: `modules/rnetwork/components/folk-crm-view.ts`, `CrmGraphNode`)
Existing `contact-card` covers the person case well. Propose one additional for organizations.
| # | id | label | icon | color | input ports | output ports |
|---|---|---|---|---|---|---|
| 50 | 🆕 `org-card` | Organization | 🏢 | #4f46e5 | — | `members:json` | company card w/ member count |
---
### rchoices — other vote types
Currently only `vote-tally`. rChoices supports multiple vote types — each deserves its own applet.
| # | id | label | icon | color | input ports | output ports |
|---|---|---|---|---|---|---|
| 51 | 🆕 `choice-conviction` | Conviction Vote | ⏱️ | #7c3aed | `submit:data` | `result:data` |
| 52 | 🆕 `choice-rank` | Ranked Choice | 🏆 | #7c3aed | `submit:data` | `winner:data`, `round:data` |
| 53 | 🆕 `choice-spider` | Spider Vote | 🕸️ | #7c3aed | `submit:data` | `profile:data` |
> *These overlap with existing `folk-choice-*` custom elements the main canvas already renders — same pattern as rgov: wrap into AppletDefinitions so they appear in the palette.*
---
## Implementation order (proposed)
1. **rgov** (§40-47) — easiest, already custom elements. 🟡 ones delegate; 🆕 ones wrap existing components. ~1h.
2. **rflows** (§37-39) — only 3 types, clean port model already in `PORT_DEFS`. ~1h.
3. **rsocials planner** (§1-9) — 9 types, shared palette color. ~2h.
4. **rminders automation** (§22-36) — 15 types with clean catalog. ~2-3h (lots of glyph decisions).
5. **rsocials workflow** (§10-21) — 12 types, similar to rminders. ~2h.
6. **rtime, rnetwork, rchoices extras** (§48-53) — cleanup round. ~1h.
Total: ~10 hours of focused work, spread across 4-6 PRs. One rApp per PR for clean rollback.
---
## Open questions for review
1. **Naming prefix.** Should I use `planner-*` / `wf-*` / `auto-*` / `gov-*` / `flow-*` prefixes, or namespace only by `moduleId` (registry already does `moduleId:appletId`)? Prefixes improve readability in the palette; namespacing is already handled. **Default: use prefixes for readability.**
2. **Duplicate deprecation.** rgov `signoff-gate` and proposed `gov-binary` are the same concept. Keep one?
3. **Port name `trigger`.** Borrowed from the campaign workflow schema. Alternative: `pulse` or `step`. Consistent with automation catalog.
4. **Icons.** Most proposed icons are emoji for compactness. Some rApps prefer Lucide SVG icons — confirm preference.
5. **Compact preview.** For every 🆕, I've described the preview in prose. Want me to mock the actual `renderCompact()` HTML for one rApp as a sample before I scale?
6. **Live data.** Several proposed applets would benefit from `fetchLiveData()` pulling real metrics (engagement counts, commitment progress). Add at first implementation or in a second pass?
---
*Generated: 2026-04-17. Review and modify above; I'll implement per §Implementation order once approved.*