/** * Audit card category sequences across all public documents * Show pedagogical flow issues */ const { MongoClient } = require('mongodb'); const PUBLIC_SLUGS = [ 'introduction', 'core-concepts', 'executive-summary-tractatus-inflection-point', 'implementation-guide-v1.1', 'implementation-guide', 'implementation-guide-python-examples', 'tractatus-framework-research', 'pluralistic-values-research-foundations', 'the-27027-incident-a-case-study-in-pattern-recognition-bias', 'real-world-ai-governance-a-case-study-in-framework-failure-and-recovery', 'llm-integration-feasibility-research-scope', 'research-topic-concurrent-session-architecture', 'research-topic-rule-proliferation-transactional-overhead', 'technical-architecture', 'api-reference-complete', 'api-javascript-examples', 'api-python-examples', 'openapi-specification', 'value-pluralism-faq', 'tractatus-ai-safety-framework-core-values-and-principles', 'organizational-theory-foundations', 'business-case-tractatus-framework' ]; const CATEGORY_ICONS = { 'conceptual': 'šŸ“˜', 'technical': 'šŸ”§', 'practical': 'šŸ’”', 'reference': 'šŸ“‹', 'critical': 'āš ļø' }; function analyzeSequence(sections) { if (!sections || sections.length === 0) return null; const sequence = sections.map(s => s.category); const categoryChanges = []; for (let i = 1; i < sequence.length; i++) { if (sequence[i] !== sequence[i-1]) { categoryChanges.push(i); } } // Calculate "jumpiness" - how often categories change const jumpiness = categoryChanges.length / (sections.length - 1); // Identify poor patterns const issues = []; // Issue 1: Critical/warning at the end (should be near start) const criticalIndices = sequence.map((cat, idx) => cat === 'critical' ? idx : -1).filter(i => i >= 0); if (criticalIndices.some(idx => idx > sequence.length * 0.7)) { issues.push('Critical content appears late in sequence'); } // Issue 2: Reference at the beginning (should be at end) const referenceIndices = sequence.map((cat, idx) => cat === 'reference' ? idx : -1).filter(i => i >= 0); if (referenceIndices.some(idx => idx < sequence.length * 0.3)) { issues.push('Reference content appears early (should be at end)'); } // Issue 3: Technical before conceptual (usually bad pedagogy) for (let i = 0; i < sequence.length - 1; i++) { if (sequence[i] === 'technical' && i < 2) { issues.push('Technical content appears before conceptual foundation'); break; } } // Issue 4: High jumpiness (categories bouncing around) if (jumpiness > 0.6) { issues.push(`High category jumpiness (${Math.round(jumpiness * 100)}%) - cards bounce between types`); } return { sequence, categoryChanges: categoryChanges.length, jumpiness: Math.round(jumpiness * 100), issues }; } async function run() { const client = new MongoClient('mongodb://localhost:27017'); await client.connect(); const db = client.db('tractatus_dev'); const collection = db.collection('documents'); console.log('═══════════════════════════════════════════════════════════'); console.log(' CARD CATEGORY SEQUENCE AUDIT'); console.log('═══════════════════════════════════════════════════════════\n'); const poorSequences = []; for (const slug of PUBLIC_SLUGS) { const doc = await collection.findOne({ slug }); if (!doc || !doc.sections) continue; console.log(`\nšŸ“„ ${doc.title}`); console.log(` Slug: ${slug}`); console.log(` Category: ${doc.category || 'none'}`); console.log(` Cards: ${doc.sections.length}`); const analysis = analyzeSequence(doc.sections); if (!analysis) { console.log(' āŒ No sections to analyze'); continue; } // Show category sequence visually console.log(`\n Sequence:`); const sequenceDisplay = analysis.sequence.map((cat, idx) => { const icon = CATEGORY_ICONS[cat] || 'ā“'; return `${icon} ${cat}`; }).join(' → '); // Wrap long sequences const parts = []; let currentPart = ''; analysis.sequence.forEach((cat, idx) => { const icon = CATEGORY_ICONS[cat] || 'ā“'; const item = `${icon}`; if (currentPart.length + item.length > 50) { parts.push(currentPart); currentPart = ' '; } currentPart += item + ' '; }); if (currentPart.trim()) parts.push(currentPart); parts.forEach(part => console.log(part)); console.log(`\n Metrics:`); console.log(` - Category changes: ${analysis.categoryChanges}`); console.log(` - Jumpiness: ${analysis.jumpiness}%`); if (analysis.issues.length > 0) { console.log(`\n āš ļø ISSUES:`); analysis.issues.forEach(issue => console.log(` - ${issue}`)); poorSequences.push({ slug, doc: doc.title, issues: analysis.issues }); } else { console.log(`\n āœ… Sequence looks reasonable`); } } console.log('\n\n═══════════════════════════════════════════════════════════'); console.log(' SUMMARY'); console.log('═══════════════════════════════════════════════════════════\n'); console.log(`Documents audited: ${PUBLIC_SLUGS.length}`); console.log(`Documents with poor sequences: ${poorSequences.length}\n`); if (poorSequences.length > 0) { console.log('Documents needing resequencing:\n'); poorSequences.forEach((item, idx) => { console.log(`${idx + 1}. ${item.doc}`); console.log(` Slug: ${item.slug}`); item.issues.forEach(issue => console.log(` - ${issue}`)); console.log(''); }); } await client.close(); } run().catch(console.error);