From dca0e46bcac5bc7d65e52d254bcad844256872a9 Mon Sep 17 00:00:00 2001 From: TheFlow Date: Sat, 25 Oct 2025 11:22:42 +1300 Subject: [PATCH] feat(cultural-sensitivity): implement Phase 2 - admin UI with cultural flags (inst_081) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2: Cultural Sensitivity Admin UI - Display cultural sensitivity analysis results in admin interfaces - Visual indicators for risk levels (LOW/MEDIUM/HIGH) - Show concerns and suggested adaptations to human reviewers - Human-in-the-loop workflow: AI flags, human decides Implementation: 1. Media Inquiry Admin (public/js/admin/media-triage.js:435-503) - Cultural Sensitivity Analysis section in inquiry details modal - Shows risk level with color-coded badges (green/yellow/red) - Lists cultural concerns with context - Displays suggested adaptations - Framework compliance note: "AI flags concerns but never blocks" - Appears after response is created (response.cultural_sensitivity) 2. Blog Curation Admin (public/js/admin/blog-curation.js:371-398) - Cultural risk badge in blog post queue list - Color-coded by risk level (LOW=green, MEDIUM=yellow, HIGH=red) - HIGH risk shows "⚠️ Human review recommended" - Lists cultural concerns inline - Shows count of suggested adaptations - Appears after publish (moderation.cultural_sensitivity) UI Features: - 🌍 Cultural Sensitivity icon for visibility - Risk-based color coding (traffic light pattern) - Expandable concern details - Suggested adaptations inline - Timestamps for audit trail - Non-blocking workflow (flags for review, doesn't prevent action) Human Approval Workflow: - Existing respond() API already stores cultural_sensitivity data - Existing publish() API already stores cultural_sensitivity data - UI displays flags and suggestions - Human reviewer makes final decision (inst_081 pluralism) - No new endpoints needed - workflow integrated into existing approval flow Next: Deploy Phase 2, monitor Phase 3 daily reminders for learning/refinement 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- public/js/admin/blog-curation.js | 29 +++++++++++++ public/js/admin/media-triage.js | 70 ++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/public/js/admin/blog-curation.js b/public/js/admin/blog-curation.js index 324e71cc..9679327a 100644 --- a/public/js/admin/blog-curation.js +++ b/public/js/admin/blog-curation.js @@ -367,6 +367,35 @@ async function loadDraftQueue() { ` : ''} + + + ${item.data.moderation?.cultural_sensitivity ? ` +
+ + 🌍 Cultural Risk: ${item.data.moderation.cultural_sensitivity.risk_level} + ${item.data.moderation.cultural_sensitivity.risk_level === 'HIGH' ? ' ⚠️ Human review recommended' : ''} + + ${item.data.moderation.cultural_sensitivity.concerns?.length > 0 ? ` +
+ ${item.data.moderation.cultural_sensitivity.concerns.map(c => ` +
+ ${c.type.replace(/_/g, ' ')}: + ${c.detail} +
+ `).join('')} +
+ ` : ''} + ${item.data.moderation.cultural_sensitivity.suggestions?.length > 0 ? ` +
+ 💡 ${item.data.moderation.cultural_sensitivity.suggestions.length} adaptation(s) suggested +
+ ` : ''} +
+ ` : ''}
diff --git a/public/js/admin/media-triage.js b/public/js/admin/media-triage.js index 0e57fa6f..0feed5d4 100644 --- a/public/js/admin/media-triage.js +++ b/public/js/admin/media-triage.js @@ -432,6 +432,76 @@ async function showInquiryDetails(inquiryId) { `; } + // Cultural Sensitivity Check (Phase 1: inst_081 pluralism) + if (currentInquiry.response?.cultural_sensitivity) { + const cultural = currentInquiry.response.cultural_sensitivity; + const riskColors = { + 'LOW': { bg: 'green', text: 'green' }, + 'MEDIUM': { bg: 'yellow', text: 'yellow' }, + 'HIGH': { bg: 'red', text: 'red' } + }; + const colors = riskColors[cultural.risk_level] || riskColors['LOW']; + + html += ` + +
+

🌍 Cultural Sensitivity Analysis

+ + +
+

+ ${cultural.risk_level === 'HIGH' ? '⚠️ ' : cultural.risk_level === 'MEDIUM' ? '⚡ ' : '✓ '}Risk Level: ${cultural.risk_level} +

+

+ Recommended Action: ${cultural.recommended_action} +

+ ${cultural.risk_level === 'HIGH' ? ` +

+ 🚨 Human review recommended before sending (inst_081 pluralism) +

+ ` : ''} +
+ + ${cultural.concerns?.length > 0 ? ` + +
+

Cultural Concerns (${cultural.concerns.length}):

+
    + ${cultural.concerns.map(concern => ` +
  • + ${concern.type.replace(/_/g, ' ')}: ${escapeHtml(concern.detail)} + ${concern.audience_context ? `
    Context: ${escapeHtml(concern.audience_context)}` : ''} +
  • + `).join('')} +
+
+ ` : ''} + + ${cultural.suggestions?.length > 0 ? ` + +
+

Suggested Adaptations (${cultural.suggestions.length}):

+
    + ${cultural.suggestions.map(suggestion => ` +
  • ${escapeHtml(suggestion.suggestion || suggestion)}
  • + `).join('')} +
+
+ ` : ''} + +
+

+ Framework: PluralisticDeliberationOrchestrator (inst_081) | + Checked: ${new Date(cultural.checked_at).toLocaleString()} +

+

+ Note: AI flags cultural concerns but never blocks. Human decides final approach. +

+
+
+ `; + } + content.innerHTML = html; // Update modal buttons visibility