- audit-inflection-point.js: Identify fictional content in research paper - fix-inflection-point-fiction.js: Remove fabricated statistics - audit-all-card-sequences.js: Check card sequence quality - audit-card-category-sequences.js: Analyze pedagogical flow - resequence-cards-pedagogically.js: Reorder cards for better learning flow - apply-production-fixes.js: Production deployment script - inspect-*: Helper scripts for analysis Quality improvements: - Removed fictional content from Inflection Point document (3 sections) - Resequenced 21 documents pedagogically (22-67% jumpiness reduction) - Implemented proper learning flow: concepts → warnings → technical → reference
167 lines
6 KiB
JavaScript
167 lines
6 KiB
JavaScript
/**
|
|
* 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);
|