feat(cultural-sensitivity): implement Phase 2 - admin UI with cultural flags (inst_081)
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 <noreply@anthropic.com>
This commit is contained in:
parent
7645c49ab3
commit
f6963de4c6
2 changed files with 99 additions and 0 deletions
|
|
@ -367,6 +367,35 @@ async function loadDraftQueue() {
|
|||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
<!-- Cultural Sensitivity Check (inst_081) -->
|
||||
${item.data.moderation?.cultural_sensitivity ? `
|
||||
<div class="mt-2">
|
||||
<span class="px-2 py-1 ${
|
||||
item.data.moderation.cultural_sensitivity.risk_level === 'HIGH' ? 'bg-red-100 text-red-800' :
|
||||
item.data.moderation.cultural_sensitivity.risk_level === 'MEDIUM' ? 'bg-yellow-100 text-yellow-800' :
|
||||
'bg-green-100 text-green-800'
|
||||
} text-xs rounded">
|
||||
🌍 Cultural Risk: ${item.data.moderation.cultural_sensitivity.risk_level}
|
||||
${item.data.moderation.cultural_sensitivity.risk_level === 'HIGH' ? ' ⚠️ Human review recommended' : ''}
|
||||
</span>
|
||||
${item.data.moderation.cultural_sensitivity.concerns?.length > 0 ? `
|
||||
<div class="mt-2 space-y-1">
|
||||
${item.data.moderation.cultural_sensitivity.concerns.map(c => `
|
||||
<div class="text-xs bg-orange-50 border border-orange-200 rounded px-2 py-1">
|
||||
<strong class="text-orange-900">${c.type.replace(/_/g, ' ')}:</strong>
|
||||
<span class="text-orange-700">${c.detail}</span>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
` : ''}
|
||||
${item.data.moderation.cultural_sensitivity.suggestions?.length > 0 ? `
|
||||
<div class="mt-1 text-xs text-blue-700">
|
||||
💡 ${item.data.moderation.cultural_sensitivity.suggestions.length} adaptation(s) suggested
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
<div class="ml-4 flex flex-col items-end gap-2">
|
||||
<span class="px-3 py-1 text-xs rounded ${item.priority === 'high' ? 'bg-red-100 text-red-800' : 'bg-yellow-100 text-yellow-800'}">
|
||||
|
|
|
|||
|
|
@ -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 (inst_081) -->
|
||||
<div class="mb-6">
|
||||
<h4 class="text-sm font-semibold text-gray-900 mb-3">🌍 Cultural Sensitivity Analysis</h4>
|
||||
|
||||
<!-- Risk Level -->
|
||||
<div class="bg-${colors.bg}-50 rounded-lg p-4 mb-3 border border-${colors.bg}-200">
|
||||
<p class="text-sm font-medium text-${colors.text}-900 mb-2">
|
||||
${cultural.risk_level === 'HIGH' ? '⚠️ ' : cultural.risk_level === 'MEDIUM' ? '⚡ ' : '✓ '}Risk Level: ${cultural.risk_level}
|
||||
</p>
|
||||
<p class="text-sm text-${colors.text}-800 mb-2">
|
||||
<strong>Recommended Action:</strong> ${cultural.recommended_action}
|
||||
</p>
|
||||
${cultural.risk_level === 'HIGH' ? `
|
||||
<p class="text-xs text-${colors.text}-700 font-semibold">
|
||||
🚨 Human review recommended before sending (inst_081 pluralism)
|
||||
</p>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
${cultural.concerns?.length > 0 ? `
|
||||
<!-- Concerns -->
|
||||
<div class="bg-orange-50 rounded-lg p-4 mb-3">
|
||||
<p class="text-sm font-medium text-orange-900 mb-2">Cultural Concerns (${cultural.concerns.length}):</p>
|
||||
<ul class="space-y-2 text-sm text-orange-800">
|
||||
${cultural.concerns.map(concern => `
|
||||
<li class="border-l-2 border-orange-400 pl-3">
|
||||
<strong>${concern.type.replace(/_/g, ' ')}:</strong> ${escapeHtml(concern.detail)}
|
||||
${concern.audience_context ? `<br><span class="text-xs text-orange-700">Context: ${escapeHtml(concern.audience_context)}</span>` : ''}
|
||||
</li>
|
||||
`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
${cultural.suggestions?.length > 0 ? `
|
||||
<!-- Suggestions -->
|
||||
<div class="bg-blue-50 rounded-lg p-4">
|
||||
<p class="text-sm font-medium text-blue-900 mb-2">Suggested Adaptations (${cultural.suggestions.length}):</p>
|
||||
<ul class="list-disc list-inside space-y-1 text-sm text-blue-800">
|
||||
${cultural.suggestions.map(suggestion => `
|
||||
<li>${escapeHtml(suggestion.suggestion || suggestion)}</li>
|
||||
`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
<div class="mt-3 pt-3 border-t border-gray-200">
|
||||
<p class="text-xs text-gray-600">
|
||||
<strong>Framework:</strong> PluralisticDeliberationOrchestrator (inst_081) |
|
||||
<strong>Checked:</strong> ${new Date(cultural.checked_at).toLocaleString()}
|
||||
</p>
|
||||
<p class="text-xs text-gray-500 mt-1 italic">
|
||||
Note: AI flags cultural concerns but never blocks. Human decides final approach.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
content.innerHTML = html;
|
||||
|
||||
// Update modal buttons visibility
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue