tractatus/public/js/demos/27027-demo.js
TheFlow 2e6618b7ba feat: fix CSP violations & implement three audience paths
CSP Compliance (complete):
- Install Tailwind CSS v3 locally (24KB build)
- Replace CDN with /css/tailwind.css in all HTML files
- Extract all inline scripts to external JS files
- Created 6 external JS files for demos & docs
- All pages now comply with script-src 'self'

Three Audience Paths (complete):
- Created /researcher.html (academic/theoretical)
- Created /implementer.html (practical integration)
- Created /advocate.html (mission/values/community)
- Updated homepage links to audience pages
- Each path has dedicated nav, hero, resources, CTAs

Files Modified (20):
- 7 HTML files (CSP compliance)
- 3 audience landing pages (new)
- 6 external JS files (extracted)
- package.json (Tailwind v3)
- tailwind.config.js (new)
- Built CSS (24KB minified)

All resources CSP-compliant, all pages tested 200 OK

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-07 12:21:00 +13:00

203 lines
6.5 KiB
JavaScript

const steps = [
{
title: 'User Instruction',
type: 'user',
content: 'User: "Use MongoDB on port 27017 for this project"',
code: null,
description: 'User provides explicit instruction about database port'
},
{
title: 'AI Acknowledges',
type: 'ai',
content: 'AI: "Understood. I\'ll ensure all database connections use port 27017."',
code: null,
description: 'AI confirms understanding of the instruction'
},
{
title: '30 Minutes Later...',
type: 'info',
content: 'Context: 85,000 tokens into 200,000 token session. Attention degrading.',
code: null,
description: 'Time passes, context window fills up, attention decays'
},
{
title: 'AI Generates Code',
type: 'ai',
content: 'AI: "Here\'s the database configuration..."',
code: `// config/database.js
const MONGODB_PORT = 27027; // ← WRONG!
const MONGODB_URI = \`mongodb://localhost:\${MONGODB_PORT}/family_history\`;
module.exports = {
uri: MONGODB_URI,
port: MONGODB_PORT
};`,
description: 'AI generates code with WRONG port number (27027 instead of 27017)'
},
{
title: 'Application Failure',
type: 'error',
content: '❌ Error: Failed to connect to MongoDB',
code: `MongoServerError: connect ECONNREFUSED 127.0.0.1:27027
at Connection.handleError
at Connection.onError
MongoDB is running on port 27017, but app is trying port 27027!`,
description: 'Application crashes because it cannot connect to database'
},
{
title: 'Debugging Begins',
type: 'info',
content: 'Developer spends 2+ hours debugging why database won\'t connect...',
code: null,
description: 'Time wasted tracking down the port mismatch'
},
{
title: 'Root Cause Found',
type: 'info',
content: 'Developer discovers AI used wrong port despite explicit instruction 30 minutes earlier.',
code: null,
description: 'The contradiction is finally discovered'
},
{
title: 'How Tractatus Prevents This',
type: 'success',
content: 'CrossReferenceValidator would have caught this BEFORE execution:',
code: `// 1. InstructionPersistenceClassifier stores instruction
{
text: "Use MongoDB on port 27017",
quadrant: "SYSTEM",
persistence: "HIGH",
parameters: { port: "27017" }
}
// 2. CrossReferenceValidator checks before code generation
❌ VALIDATION FAILED
Proposed port: 27027
Instruction: Use port 27017
Status: REJECTED - Parameter conflict
AI cannot proceed. Human notified.
`,
description: 'Tractatus framework prevents the error before it happens'
}
];
let currentStep = -1;
let isPlaying = false;
function initTimeline() {
const timeline = document.getElementById('timeline');
timeline.innerHTML = steps.map((step, index) => `
<div id="step-${index}" class="border-2 border-gray-300 bg-white rounded-lg p-6 transition-all duration-300">
<div class="flex items-start">
<div class="flex-shrink-0 mr-4">
<div class="w-10 h-10 rounded-full ${getStepColor(step.type)} flex items-center justify-center text-white font-bold">
${index + 1}
</div>
</div>
<div class="flex-1">
<h3 class="text-lg font-semibold text-gray-900 mb-2">${step.title}</h3>
<p class="text-gray-700 mb-3">${step.content}</p>
${step.code ? `<pre class="code-block">${escapeHtml(step.code)}</pre>` : ''}
<p class="text-sm text-gray-500 mt-2 hidden step-description">${step.description}</p>
</div>
</div>
</div>
`).join('');
}
function getStepColor(type) {
const colors = {
user: 'bg-blue-500',
ai: 'bg-purple-500',
info: 'bg-gray-500',
error: 'bg-red-500',
success: 'bg-green-500'
};
return colors[type] || 'bg-gray-500';
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
async function playScenario() {
if (isPlaying) return;
isPlaying = true;
document.getElementById('start-btn').disabled = true;
document.getElementById('progress-info').classList.remove('hidden');
for (let i = 0; i <= steps.length - 1; i++) {
await showStep(i);
await delay(2000); // 2 second delay between steps
}
isPlaying = false;
document.getElementById('start-btn').disabled = false;
document.getElementById('start-btn').innerHTML = '▶ Replay';
}
async function showStep(index) {
currentStep = index;
// Mark previous steps as complete
for (let i = 0; i < index; i++) {
const stepEl = document.getElementById(`step-${i}`);
stepEl.classList.remove('step-active');
stepEl.classList.add('step-complete', 'border-green-500', 'bg-green-50');
}
// Mark current step as active
const currentStepEl = document.getElementById(`step-${index}`);
currentStepEl.classList.add('step-active', 'border-blue-500', 'bg-blue-50', 'fade-in');
currentStepEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
// Show description
currentStepEl.querySelector('.step-description').classList.remove('hidden');
// Handle error step
if (steps[index].type === 'error') {
currentStepEl.classList.remove('step-active', 'border-blue-500', 'bg-blue-50');
currentStepEl.classList.add('step-error', 'border-red-500', 'bg-red-50');
}
// Update progress
const progress = ((index + 1) / steps.length) * 100;
document.getElementById('progress-bar').style.width = `${progress}%`;
document.getElementById('progress-text').textContent = `${index + 1} / ${steps.length}`;
document.getElementById('current-step-desc').textContent = steps[index].description;
}
function resetScenario() {
currentStep = -1;
isPlaying = false;
// Reset all steps
steps.forEach((_, index) => {
const stepEl = document.getElementById(`step-${index}`);
stepEl.className = 'border-2 border-gray-300 bg-white rounded-lg p-6 transition-all duration-300';
stepEl.querySelector('.step-description').classList.add('hidden');
});
document.getElementById('progress-bar').style.width = '0%';
document.getElementById('progress-text').textContent = '0 / 8';
document.getElementById('current-step-desc').textContent = '';
document.getElementById('progress-info').classList.add('hidden');
document.getElementById('start-btn').innerHTML = '▶ Start Scenario';
document.getElementById('start-btn').disabled = false;
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Event listeners
document.getElementById('start-btn').addEventListener('click', playScenario);
document.getElementById('reset-btn').addEventListener('click', resetScenario);
// Initialize
initTimeline();