chore(backlog): add DAO power-indices follow-up tasks (144-150)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5e5fcd7681
commit
d950e1a656
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
id: TASK-144
|
||||
title: Power Indices for DAO Governance Analysis
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-04-16 18:50'
|
||||
labels:
|
||||
- rnetwork
|
||||
- governance
|
||||
- encryptid
|
||||
- trust-engine
|
||||
dependencies: []
|
||||
references:
|
||||
- src/encryptid/power-indices.ts
|
||||
- src/encryptid/trust-engine.ts
|
||||
- src/encryptid/schema.sql
|
||||
- modules/rnetwork/components/folk-graph-viewer.ts
|
||||
- modules/rnetwork/mod.ts
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Banzhaf & Shapley-Shubik power index computation for rSpace delegation system. Reveals who actually controls outcomes vs raw delegation weights.
|
||||
|
||||
## Implemented
|
||||
- **Compute engine** (`src/encryptid/power-indices.ts`): Banzhaf DP O(n·Q), Shapley-Shubik DP O(n²·Q), Gini coefficient, HHI concentration
|
||||
- **DB schema**: `power_indices` table (PK: did, space_slug, authority) with materialized results
|
||||
- **Background job**: Hooks into trust engine 5-min recompute cycle
|
||||
- **API**: GET `/api/power-indices?space=X&authority=Y`, GET `/api/power-indices/:did`, POST `/api/power-indices/simulate` (coalition what-if)
|
||||
- **Visualization**: Power tab in rNetwork 3D graph viewer — animated Banzhaf bars, Gini/HHI gauges, node sizing by coalitional power
|
||||
- **On-demand compute**: First API hit computes + caches if DB empty
|
||||
|
||||
## Future Integration Opportunities
|
||||
- **Delegation Dashboard** (`folk-delegation-manager.ts`): Show each user their own Banzhaf power next to their delegation weights. "Your 10% weight gives you 23% voting power" insight.
|
||||
- **rVote conviction voting**: Weight votes by Shapley-Shubik instead of raw tokens — prevents plutocratic capture
|
||||
- **fin-ops blending**: Blend $MYCO token balances with delegation weights (configurable ratio) for fin-ops authority power indices
|
||||
- **Trust Sankey** (`folk-trust-sankey.ts`): Color/thickness flows by marginal power contribution, not just raw weight
|
||||
- **Space admin dashboard**: Alert when Gini > 0.6 or HHI > 0.25 (concentration warning)
|
||||
- **rData analytics**: Time-series of power concentration metrics (Gini trend, effective voters trend)
|
||||
- **Coalition builder UI**: Interactive "what if we form this coalition?" tool using the simulate endpoint
|
||||
- **Quadratic power weighting**: Use sqrt(Banzhaf) as vote weight to reduce inequality
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Banzhaf & Shapley-Shubik computed via DP (not brute force)
|
||||
- [ ] #2 Results materialized in PG, recomputed every 5 min
|
||||
- [ ] #3 3 API endpoints (list, per-user, simulate)
|
||||
- [ ] #4 Power tab in rNetwork graph viewer with animated bars + gauges
|
||||
- [ ] #5 Node sizes reflect Banzhaf power in power mode
|
||||
- [ ] #6 On-demand computation when DB empty
|
||||
<!-- AC:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
Implemented Banzhaf and Shapley-Shubik power index computation integrated into the trust engine's 5-min background cycle. Power indices table in PG stores materialized results per (did, space, authority). Three API endpoints on EncryptID server with rNetwork proxy routes. Visualization integrated into 3D graph viewer as Power tab — animated bar chart showing weight/Banzhaf/Shapley-Shubik per player, Gini and HHI concentration gauges, and Banzhaf-scaled node sizing. Also fixed encryptid Dockerfile missing welcome-email.ts and swapped mouse controls to left-drag=rotate.
|
||||
|
||||
Commits: 97c1b02 (feature), 1bc2a0a (Dockerfile fix). Deployed to Netcup, live at demo.rspace.online/rnetwork/power.
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
---
|
||||
id: TASK-145
|
||||
title: Power Badge in Delegation Manager
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-16 18:56'
|
||||
labels:
|
||||
- rnetwork
|
||||
- governance
|
||||
- power-indices
|
||||
dependencies:
|
||||
- TASK-144
|
||||
references:
|
||||
- modules/rnetwork/components/folk-delegation-manager.ts
|
||||
- src/encryptid/power-indices.ts
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Add Banzhaf power percentage badge to `folk-delegation-manager.ts` inbound delegation section.
|
||||
|
||||
## What
|
||||
Each user's inbound delegation count already shows "3 delegations received". Add a power badge: **"3 delegations → 23% power"** fetched from `/api/power-indices/:did`.
|
||||
|
||||
## Primitive
|
||||
- Fetch user's power index on component load: `GET /rnetwork/api/power-indices/{did}?space={space}`
|
||||
- Display per-authority: weight% vs Banzhaf% with color coding (green if proportional, red if disproportionate)
|
||||
- Tooltip: "You hold 10% of delegation weight but 23% of actual voting power because smaller players can't form winning coalitions without you"
|
||||
|
||||
## Implementation
|
||||
- `folk-delegation-manager.ts`: Add `fetchPowerBadge()` in `connectedCallback`, cache result
|
||||
- New `renderPowerBadge(authority)` method → returns HTML for the badge
|
||||
- Insert into the inbound delegations header row per authority
|
||||
- ~40 lines of code, one fetch call, zero new files
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Banzhaf % shown next to inbound delegation count per authority
|
||||
- [ ] #2 Color coded: green (proportional ±20%), red (overrepresented), blue (underrepresented)
|
||||
- [ ] #3 Tooltip explains power vs weight difference
|
||||
- [ ] #4 Graceful fallback when no power data available
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
id: TASK-146
|
||||
title: Sankey Power Overlay — dual-bar node sizing
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-16 18:56'
|
||||
labels:
|
||||
- rnetwork
|
||||
- governance
|
||||
- power-indices
|
||||
dependencies:
|
||||
- TASK-144
|
||||
references:
|
||||
- modules/rnetwork/components/folk-trust-sankey.ts
|
||||
- src/encryptid/power-indices.ts
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Add power index overlay to `folk-trust-sankey.ts` right-column nodes.
|
||||
|
||||
## What
|
||||
Right-column delegate nodes currently show rank badge + received weight %. Add a second bar showing Banzhaf power %, creating a visual comparison: raw weight vs actual coalitional power.
|
||||
|
||||
## Primitive
|
||||
- Fetch power indices once on authority change: `GET /rnetwork/api/power-indices?space={space}&authority={authority}`
|
||||
- Build `Map<did, { banzhaf, shapleyShubik }>` lookup
|
||||
- Right-column nodes get dual horizontal bars:
|
||||
- Top bar (gray): raw received weight %
|
||||
- Bottom bar (authority color): Banzhaf power %
|
||||
- Nodes where power >> weight glow red (disproportionate influence)
|
||||
|
||||
## Implementation
|
||||
- `folk-trust-sankey.ts`: Add `powerMap` field, fetch in `loadData()`
|
||||
- Modify `renderRightNodes()` to draw second bar below weight bar
|
||||
- Add CSS for `.power-bar` with transition animation
|
||||
- ~60 lines, one fetch, zero new files
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Dual bars on right-column nodes: weight % and Banzhaf %
|
||||
- [ ] #2 Red glow on nodes where Banzhaf > 1.5x weight share
|
||||
- [ ] #3 Bars animate on authority tab switch
|
||||
- [ ] #4 Toggle to show/hide power overlay
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
id: TASK-147
|
||||
title: Delegation-weighted voting mode for rVote
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-16 18:56'
|
||||
labels:
|
||||
- rvote
|
||||
- governance
|
||||
- power-indices
|
||||
dependencies:
|
||||
- TASK-144
|
||||
references:
|
||||
- modules/rvote/mod.ts
|
||||
- src/encryptid/power-indices.ts
|
||||
priority: high
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Optional voting mode where conviction vote weight is multiplied by the voter's Shapley-Shubik index.
|
||||
|
||||
## What
|
||||
Currently rVote uses credit-based quadratic voting (1 vote = 1 credit, 2 = 4 credits). Add an optional space-level toggle: "delegation-weighted voting" where each vote's effective weight = `creditWeight × shapleyShubikIndex`. This lets delegated authority flow into proposal ranking.
|
||||
|
||||
## Primitive: Power Weight Multiplier
|
||||
- New field in space voting config: `weightMode: 'credits-only' | 'delegation-weighted'`
|
||||
- When `delegation-weighted`: fetch voter's power index at vote time
|
||||
- `effectiveWeight = creditWeight × (1 + shapleyShubik × delegationMultiplier)`
|
||||
- Default `delegationMultiplier = 2.0` (configurable per space)
|
||||
- Fallback: if no power index data, effectiveWeight = creditWeight (graceful degradation)
|
||||
|
||||
## Implementation
|
||||
- `modules/rvote/mod.ts`: In `POST /api/proposals/:id/vote` handler, check space config
|
||||
- If delegation-weighted: fetch from EncryptID `/api/power-indices/:did?space={space}`
|
||||
- Multiply vote weight before storing in Automerge doc
|
||||
- Display in UI: "Your vote: 3 credits × 1.4x delegation = 4.2 effective weight"
|
||||
- ~50 lines server, ~20 lines UI display
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Space config toggle: credits-only vs delegation-weighted
|
||||
- [ ] #2 Vote weight multiplied by Shapley-Shubik when delegation-weighted
|
||||
- [ ] #3 Multiplier configurable per space (default 2.0)
|
||||
- [ ] #4 UI shows breakdown: credits × delegation multiplier = effective
|
||||
- [ ] #5 Graceful fallback to credits-only when no power data
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
id: TASK-148
|
||||
title: Concentration alerts for space admins
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-16 18:56'
|
||||
labels:
|
||||
- governance
|
||||
- encryptid
|
||||
- power-indices
|
||||
- notifications
|
||||
dependencies:
|
||||
- TASK-144
|
||||
references:
|
||||
- src/encryptid/power-indices.ts
|
||||
- src/encryptid/trust-engine.ts
|
||||
- src/encryptid/server.ts
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Alert space admins when power concentration exceeds healthy thresholds.
|
||||
|
||||
## What
|
||||
The power indices engine already computes Gini coefficient and HHI per space+authority every 5 minutes. Surface warnings when:
|
||||
- HHI > 0.25 (highly concentrated — fewer than ~4 effective voters)
|
||||
- Gini > 0.6 (severe inequality — top players hold most power)
|
||||
- Single player Banzhaf > 0.5 (near-dictator — one person controls majority)
|
||||
|
||||
## Primitive: Concentration Monitor
|
||||
- New function `checkConcentrationAlerts(spaceSlug)` in `power-indices.ts`
|
||||
- Called after `computeSpacePowerIndices()` in trust engine cycle
|
||||
- When threshold crossed: create notification via existing `createNotification()` for space admins
|
||||
- Notification: category='system', event_type='power_concentration_warning'
|
||||
- Debounce: only alert once per 24h per space+authority (store `last_alert_at` in power_indices or separate field)
|
||||
|
||||
## Implementation
|
||||
- `src/encryptid/power-indices.ts`: Add `checkConcentrationAlerts()` function
|
||||
- `src/encryptid/trust-engine.ts`: Call after power index computation
|
||||
- Uses existing notification system — zero new infrastructure
|
||||
- ~40 lines, zero new files, zero new tables
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Alert when HHI > 0.25, Gini > 0.6, or single-player Banzhaf > 0.5
|
||||
- [ ] #2 Notification sent to space admins via existing notification system
|
||||
- [ ] #3 24h debounce per space+authority to avoid spam
|
||||
- [ ] #4 Notification includes specific metric + suggestion (e.g. 'encourage more delegation diversity')
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
id: TASK-149
|
||||
title: Power index time-series snapshots
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-16 18:56'
|
||||
labels:
|
||||
- governance
|
||||
- analytics
|
||||
- power-indices
|
||||
dependencies:
|
||||
- TASK-144
|
||||
references:
|
||||
- src/encryptid/schema.sql
|
||||
- src/encryptid/power-indices.ts
|
||||
- modules/rnetwork/components/folk-graph-viewer.ts
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Store daily snapshots of power concentration metrics for trend analysis.
|
||||
|
||||
## What
|
||||
Currently power_indices table overwrites on each 5-min cycle. Add a `power_snapshots` table that stores one row per space+authority per day with aggregate metrics. Enables "is power becoming more or less concentrated over time?" analysis.
|
||||
|
||||
## Primitive: Daily Snapshot Aggregation
|
||||
- New table `power_snapshots`:
|
||||
```sql
|
||||
CREATE TABLE power_snapshots (
|
||||
space_slug TEXT NOT NULL,
|
||||
authority TEXT NOT NULL,
|
||||
snapshot_date DATE NOT NULL,
|
||||
player_count INTEGER,
|
||||
gini_coefficient REAL,
|
||||
herfindahl_index REAL,
|
||||
top3_banzhaf_sum REAL,
|
||||
effective_voters REAL,
|
||||
PRIMARY KEY (space_slug, authority, snapshot_date)
|
||||
);
|
||||
```
|
||||
- In trust engine cycle: after computing power indices, check if today's snapshot exists. If not, insert.
|
||||
- One INSERT per space+authority per day — negligible DB cost.
|
||||
|
||||
## Frontend: Sparkline in power panel
|
||||
- `folk-graph-viewer.ts` power panel: fetch `GET /api/power-snapshots?space=X&authority=Y&days=30`
|
||||
- Render 30-day sparkline of Gini + HHI below the gauge metrics
|
||||
- Red trend line = concentrating, green = dispersing
|
||||
|
||||
## Implementation
|
||||
- `src/encryptid/schema.sql`: New table
|
||||
- `src/encryptid/db.ts`: `upsertPowerSnapshot()`, `getPowerSnapshots(space, authority, days)`
|
||||
- `src/encryptid/power-indices.ts`: `snapshotIfNeeded()` called from trust engine
|
||||
- `src/encryptid/server.ts`: `GET /api/power-snapshots` endpoint
|
||||
- `folk-graph-viewer.ts`: 30-day sparkline SVG in power panel
|
||||
- ~80 lines backend, ~40 lines frontend
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 power_snapshots table with daily aggregates per space+authority
|
||||
- [ ] #2 Auto-insert one snapshot per day during trust engine cycle
|
||||
- [ ] #3 API endpoint returns N days of historical snapshots
|
||||
- [ ] #4 30-day sparkline in power panel showing Gini + HHI trend
|
||||
- [ ] #5 Red/green trend coloring based on direction
|
||||
<!-- AC:END -->
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
id: TASK-150
|
||||
title: Coalition simulator UI
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-16 18:57'
|
||||
labels:
|
||||
- rnetwork
|
||||
- governance
|
||||
- power-indices
|
||||
dependencies:
|
||||
- TASK-144
|
||||
references:
|
||||
- src/encryptid/power-indices.ts
|
||||
- modules/rnetwork/components/folk-graph-viewer.ts
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
Interactive coalition builder using the existing `/api/power-indices/simulate` endpoint.
|
||||
|
||||
## What
|
||||
Let users select a group of voters and instantly see: "Can this coalition pass a vote? Who is the swing voter?" Uses the simulate endpoint already built in TASK-144.
|
||||
|
||||
## Primitive: Coalition Picker Component
|
||||
- New `<folk-coalition-sim>` element (or inline in power panel)
|
||||
- Checkbox list of top N voters (sorted by Banzhaf)
|
||||
- As checkboxes toggle: POST to simulate endpoint, show result:
|
||||
- ✅ "Winning coalition (67% of weight, needs 50%+1)"
|
||||
- Per-member: "Alice: swing voter ⚡" / "Bob: not swing (coalition wins without them)"
|
||||
- "Add 1 more voter to win" suggestion when losing
|
||||
|
||||
## Implementation
|
||||
- Can be embedded in the power panel of `folk-graph-viewer.ts` as a collapsible section
|
||||
- Or standalone `folk-coalition-sim.ts` for embedding in delegation manager
|
||||
- POST `/rnetwork/api/power-indices/simulate` with `{ space, authority, coalition: [did1, did2...] }`
|
||||
- Response already returns `isWinning`, `marginalContributions[].isSwing`
|
||||
- ~80 lines, zero backend changes (endpoint exists)
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Checkbox selection of voters from top-N list
|
||||
- [ ] #2 Live POST to simulate endpoint on selection change
|
||||
- [ ] #3 Shows winning/losing status with weight vs quota
|
||||
- [ ] #4 Identifies swing voters in the coalition
|
||||
- [ ] #5 Suggests minimum additions to form winning coalition
|
||||
<!-- AC:END -->
|
||||
Loading…
Reference in New Issue