tractatus/public/demos/deliberation-demo.html
TheFlow d32be2c673 feat(api): implement research inquiry endpoint and Umami analytics
HIGH PRIORITY: Fixes production 404 error on research inquiry form

Research Inquiry API:
- Add POST /api/research-inquiry endpoint for form submissions
- Add admin endpoints for inquiry management (list, get, assign, respond, delete)
- Create ResearchInquiry model with MongoDB integration
- Add to moderation queue for human review (strategic quadrant)
- Include rate limiting (5 req/min) and CSRF protection
- Tested locally: endpoint responding, data saving to DB

Umami Analytics (Privacy-First):
- Add Docker Compose config for Umami + PostgreSQL
- Create nginx reverse proxy config with SSL support
- Implement privacy-first tracking script (DNT, opt-out, no cookies)
- Integrate tracking across 26 public HTML pages
- Exclude admin pages from tracking (privacy boundary)
- Add comprehensive deployment guide (UMAMI_SETUP_GUIDE.md)
- Environment variables added to .env.example

Files Created (9):
- src/models/ResearchInquiry.model.js
- src/controllers/research.controller.js
- src/routes/research.routes.js
- public/js/components/umami-tracker.js
- deployment-quickstart/nginx-analytics.conf
- deployment-quickstart/UMAMI_SETUP_GUIDE.md
- scripts/add-umami-tracking.sh
- scripts/add-tracking-python.py
- SESSION_SUMMARY_ANALYTICS_RESEARCH_INQUIRY.md

Files Modified (29):
- src/routes/index.js (research routes)
- deployment-quickstart/docker-compose.yml (umami services)
- deployment-quickstart/.env.example (umami config)
- 26 public HTML pages (tracking script)

Values Alignment:
 Privacy-First Design (cookie-free, DNT honored, opt-out available)
 Human Agency (research inquiries require human review)
 Data Sovereignty (self-hosted analytics, no third-party sharing)
 GDPR Compliance (no personal data in analytics)
 Transparency (open-source tools, documented setup)

Testing Status:
 Research inquiry: Locally tested, data verified in MongoDB
 Umami analytics: Pending production deployment

Next Steps:
1. Deploy to production (./scripts/deploy.sh)
2. Test research form on live site
3. Deploy Umami following UMAMI_SETUP_GUIDE.md
4. Update umami-tracker.js with website ID after setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 01:31:02 +13:00

227 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pluralistic Deliberation Demo - Tractatus Framework</title>
<link rel="icon" type="image/svg+xml" href="/favicon-new.svg">
<link rel="stylesheet" href="/css/tailwind.css?v=1761163813">
<link rel="stylesheet" href="/css/tractatus-theme.min.css?v=1761163813">
<style>
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in {
animation: fadeIn 0.5s ease-out;
}
.stakeholder-card {
@apply border-2 border-gray-300 bg-white rounded-lg p-6 transition-all duration-300 cursor-pointer;
}
.stakeholder-card:hover {
@apply shadow-lg border-teal-400;
}
.stakeholder-selected {
@apply border-teal-500 bg-teal-50 ring-2 ring-teal-400;
}
.stakeholder-active {
@apply border-teal-500 bg-teal-50;
}
.perspective-card {
@apply bg-white border-l-4 p-4 rounded-r-lg mb-3 transition-all duration-300;
}
</style>
<!-- Privacy-Preserving Analytics (Umami - GDPR Compliant, No Cookies) -->
<script src="/js/components/umami-tracker.js"></script>
</head>
<body class="bg-gray-50">
<!-- Navigation (injected by navbar.js) -->
<script src="/js/components/navbar.js?v=1761163813"></script>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<!-- Header -->
<div class="text-center mb-12">
<div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-gradient-service-deliberation mb-4">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
</svg>
</div>
<h1 class="text-4xl font-bold text-gray-900 mb-4">
Pluralistic Deliberation in Action
</h1>
<p class="text-xl text-gray-600 max-w-3xl mx-auto">
When AI faces values decisions—choices with no single "correct" answer—the Tractatus framework facilitates <strong>human deliberation across stakeholder perspectives</strong> instead of making autonomous choices. This interactive demo shows how the PluralisticDeliberationOrchestrator works.
</p>
</div>
<!-- Scenario Description -->
<div class="bg-white rounded-xl shadow-lg p-8 mb-8">
<h2 class="text-2xl font-bold text-gray-900 mb-4">The Scenario</h2>
<div class="bg-amber-50 border-l-4 border-amber-500 p-6 rounded-r-lg mb-6">
<p class="text-amber-900 text-lg">
<strong>Context:</strong> You're using Claude Code to develop a web application. The AI discovers your code contains a security vulnerability that could expose user data. This creates a values conflict:
</p>
<ul class="mt-4 space-y-2 text-amber-800">
<li><strong>Reporting</strong> the vulnerability protects future users but may damage your reputation</li>
<li><strong>Staying silent</strong> preserves your project timeline but risks user harm</li>
<li><strong>Partially disclosing</strong> balances concerns but may be seen as deceptive</li>
</ul>
<p class="text-amber-900 mt-4">
This is a <strong>values decision</strong>—there's no universally "correct" technical answer. Different stakeholders have legitimate but conflicting perspectives.
</p>
</div>
<div id="decision-question" class="text-center py-6">
<p class="text-xl font-semibold text-gray-900 mb-4">
Should the AI autonomously decide what to do, or facilitate deliberation among stakeholders?
</p>
<div class="flex gap-4 justify-center">
<button id="autonomous-btn" class="px-6 py-3 bg-red-600 text-white rounded-lg font-semibold hover:bg-red-700 transition">
AI Decides Autonomously
</button>
<button id="deliberation-btn" class="px-6 py-3 bg-teal-600 text-white rounded-lg font-semibold hover:bg-teal-700 transition">
Facilitate Deliberation
</button>
</div>
</div>
</div>
<!-- Autonomous Decision Path (Hidden initially) -->
<div id="autonomous-path" class="hidden mb-8">
<div class="bg-red-50 border-2 border-red-500 rounded-xl p-8">
<h3 class="text-2xl font-bold text-red-900 mb-4">❌ Autonomous Decision Path</h3>
<p class="text-red-800 mb-4">
If the AI decided autonomously, it would need to:
</p>
<ol class="list-decimal list-inside space-y-3 text-red-800 mb-6">
<li>Assign weights to competing values (user safety, developer reputation, organizational liability, transparency norms)</li>
<li>Apply a decision rule that privileges one stakeholder perspective over others</li>
<li>Make an irreversible choice that binds all affected parties</li>
</ol>
<div class="bg-white bg-opacity-60 rounded-lg p-4 border border-red-300">
<p class="text-sm text-red-900">
<strong>Why this fails:</strong> Values aren't commensurable. There's no objective function that correctly weighs "developer reputation" against "user safety." Any autonomous choice imposes the AI's (or its designers') value hierarchy on stakeholders who never consented to it.
</p>
</div>
<button id="reset-from-autonomous" class="mt-6 px-6 py-3 bg-gray-600 text-white rounded-lg font-semibold hover:bg-gray-700 transition">
← Try Deliberation Instead
</button>
</div>
</div>
<!-- Deliberation Path (Hidden initially) -->
<div id="deliberation-path" class="hidden">
<!-- Step 1: Select Stakeholders -->
<div id="stakeholder-selection" class="bg-white rounded-xl shadow-lg p-8 mb-8">
<h3 class="text-2xl font-bold text-gray-900 mb-4">Step 1: Identify Stakeholders</h3>
<p class="text-gray-700 mb-6">
PluralisticDeliberationOrchestrator identifies parties affected by this decision. <strong>Click to include each perspective:</strong>
</p>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6" id="stakeholder-grid">
<!-- Stakeholder cards will be inserted here -->
</div>
<div class="text-center">
<button id="continue-to-perspectives" class="px-6 py-3 bg-teal-600 text-white rounded-lg font-semibold hover:bg-teal-700 transition disabled:bg-gray-400 disabled:cursor-not-allowed" disabled>
Continue to Perspectives →
</button>
<p class="text-sm text-gray-500 mt-2">Select at least 2 stakeholders to continue</p>
</div>
</div>
<!-- Step 2: Explore Perspectives (Hidden initially) -->
<div id="perspectives-section" class="hidden bg-white rounded-xl shadow-lg p-8 mb-8">
<h3 class="text-2xl font-bold text-gray-900 mb-4">Step 2: Explore Perspectives</h3>
<p class="text-gray-700 mb-6">
The framework surfaces each stakeholder's perspective <strong>without ranking or resolving them</strong>. This is deliberation, not decision-making.
</p>
<div id="perspectives-container" class="space-y-4 mb-6">
<!-- Perspective cards will be inserted here -->
</div>
<div class="text-center">
<button id="continue-to-decision" class="px-6 py-3 bg-teal-600 text-white rounded-lg font-semibold hover:bg-teal-700 transition">
Make Human Decision →
</button>
</div>
</div>
<!-- Step 3: Human Decision (Hidden initially) -->
<div id="decision-section" class="hidden bg-gradient-to-r from-teal-50 to-green-50 rounded-xl border-2 border-teal-500 p-8 mb-8">
<h3 class="text-2xl font-bold text-gray-900 mb-4">Step 3: Human Decision</h3>
<p class="text-gray-700 mb-6">
The framework has <strong>facilitated deliberation but made no autonomous choice</strong>. The human must now decide, informed by all perspectives:
</p>
<div class="bg-white rounded-lg p-6 mb-6">
<p class="text-lg font-semibold text-gray-900 mb-3">Available Options:</p>
<div class="space-y-3">
<button class="decision-option w-full text-left p-4 border-2 border-gray-300 rounded-lg hover:border-teal-500 hover:bg-teal-50 transition" data-decision="full-disclosure">
<div class="font-semibold text-gray-900">Full Disclosure</div>
<div class="text-sm text-gray-600">Publicly report the vulnerability, prioritizing user safety and transparency</div>
</button>
<button class="decision-option w-full text-left p-4 border-2 border-gray-300 rounded-lg hover:border-teal-500 hover:bg-teal-50 transition" data-decision="private-fix">
<div class="font-semibold text-gray-900">Private Fix</div>
<div class="text-sm text-gray-600">Fix the issue quietly, balancing safety with reputation concerns</div>
</button>
<button class="decision-option w-full text-left p-4 border-2 border-gray-300 rounded-lg hover:border-teal-500 hover:bg-teal-50 transition" data-decision="coordinated">
<div class="font-semibold text-gray-900">Coordinated Disclosure</div>
<div class="text-sm text-gray-600">Work with security community using standard responsible disclosure timeline</div>
</button>
<button class="decision-option w-full text-left p-4 border-2 border-gray-300 rounded-lg hover:border-teal-500 hover:bg-teal-50 transition" data-decision="defer">
<div class="font-semibold text-gray-900">Defer Decision</div>
<div class="text-sm text-gray-600">Consult additional stakeholders before deciding</div>
</button>
</div>
</div>
</div>
<!-- Final Explanation (Hidden initially) -->
<div id="explanation-section" class="hidden bg-white rounded-xl shadow-lg p-8">
<h3 class="text-2xl font-bold text-teal-900 mb-4">✓ How Pluralistic Deliberation Works</h3>
<div class="space-y-4 text-gray-700">
<p>
<strong>Key Principle:</strong> The PluralisticDeliberationOrchestrator <em>facilitates</em> but <em>never decides</em> on values conflicts.
</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-teal-50 border-l-4 border-teal-500 p-4 rounded-r-lg">
<p class="font-semibold text-teal-900 mb-2">What the Framework Does:</p>
<ul class="space-y-2 text-sm text-teal-800">
<li>✓ Identifies when a decision involves values trade-offs</li>
<li>✓ Maps affected stakeholder perspectives</li>
<li>✓ Surfaces each view without ranking</li>
<li>✓ Requires explicit human choice</li>
<li>✓ Records decision and rationale</li>
</ul>
</div>
<div class="bg-amber-50 border-l-4 border-amber-500 p-4 rounded-r-lg">
<p class="font-semibold text-amber-900 mb-2">What the Framework Doesn't Do:</p>
<ul class="space-y-2 text-sm text-amber-800">
<li>✗ Assign weights to competing values</li>
<li>✗ Apply utilitarian calculus</li>
<li>✗ Make autonomous normative choices</li>
<li>✗ Hide stakeholder conflicts</li>
<li>✗ Privilege one perspective as "correct"</li>
</ul>
</div>
</div>
<p class="text-sm text-gray-600 mt-6 bg-gray-50 p-4 rounded-lg">
<strong>Why this matters:</strong> Values pluralism means there's no single objective answer to normative questions. Preserving human agency requires AI systems to <strong>facilitate deliberation</strong> rather than automate value judgments—even when that's less "efficient."
</p>
</div>
<div class="text-center mt-6">
<button id="reset-demo" class="px-6 py-3 bg-gray-600 text-white rounded-lg font-semibold hover:bg-gray-700 transition">
↻ Reset Demo
</button>
</div>
</div>
</div>
</div>
<script src="/js/demos/deliberation-demo.js?v=1761163813"></script>
</body>
</html>