Problem
PR #133 added a swarm tab that shows contradicts, quarantine status, and tier promotions — but offers no resolution actions. SWARM_SPEC §10.3 explicitly calls for "operator decision" on contradicts; without UI, contradicts pile up forever.
Scope
Three small operator surfaces, all in the existing schwarm tab:
1. Resolve contradict pair
For each row in swarm_lesson_contradictions, add three buttons:
- Behalten A → DELETE swarm_lesson
b_id, log tier_promotion_log entry B → A for a_id with reason 'operator-resolved-contradict'.
- Behalten B → mirror.
- Beide parken → keep both at Tier-B, set a
swarm_lesson_contradictions.resolved_at timestamp (new column) and exclude from the active list.
2. Override peer trust
For each peer row, add:
- Vertrauen aufheben →
record_trust_edge_change(node_id, -1.0, 'operator-override-distrust'). Pushes to quarantine immediately.
- Vertrauen wiederherstellen → reset to 0.0 + clear
quarantined_until. Reason 'operator-override-restore'.
3. Pin local lesson tier
For each Tier-B local lesson (visible in the existing memory tab, not schwarm — but link from schwarm), add:
- Auf Tier-A pinnen → manual override of the §10.6 promotion path, bypassing REM. Logged as
'operator-pinned' in tier_promotion_log.
Wiring
- Backend: three new endpoints on dashboard-server.mjs:
POST /swarm/contradict-resolve — body {pair_id, decision: 'a'|'b'|'park'}.
POST /swarm/peer-trust-override — body {node_id, action: 'distrust'|'restore'}.
POST /swarm/lesson-pin — body {lesson_id, tier}.
- Frontend: small action menus per row, confirm-dialog before destructive ops.
- All three write through PostgREST (or direct SQL via dashboard's service-role JWT) into the same RPC functions used elsewhere — no new DB write paths.
Acceptance
Out of scope
- Multi-operator approval workflows.
- Undo (audit log is the trail).
- Bulk actions (one row at a time).
Problem
PR #133 added a swarm tab that shows contradicts, quarantine status, and tier promotions — but offers no resolution actions. SWARM_SPEC §10.3 explicitly calls for "operator decision" on contradicts; without UI, contradicts pile up forever.
Scope
Three small operator surfaces, all in the existing schwarm tab:
1. Resolve contradict pair
For each row in
swarm_lesson_contradictions, add three buttons:b_id, logtier_promotion_logentryB → Afora_idwith reason'operator-resolved-contradict'.swarm_lesson_contradictions.resolved_attimestamp (new column) and exclude from the active list.2. Override peer trust
For each peer row, add:
record_trust_edge_change(node_id, -1.0, 'operator-override-distrust'). Pushes to quarantine immediately.quarantined_until. Reason'operator-override-restore'.3. Pin local lesson tier
For each Tier-B local lesson (visible in the existing memory tab, not schwarm — but link from schwarm), add:
'operator-pinned'intier_promotion_log.Wiring
POST /swarm/contradict-resolve— body{pair_id, decision: 'a'|'b'|'park'}.POST /swarm/peer-trust-override— body{node_id, action: 'distrust'|'restore'}.POST /swarm/lesson-pin— body{lesson_id, tier}.Acceptance
tier_promotion_log/trust_edge_log)./swarm-overviewand re-render).service_rolealready has.Out of scope