- 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
210 lines
7.5 KiB
JavaScript
210 lines
7.5 KiB
JavaScript
/**
|
||
* Resequence cards in documents for better pedagogical flow
|
||
*
|
||
* Pedagogical principles:
|
||
* 1. Conceptual foundation FIRST (context setting)
|
||
* 2. Critical constraints EARLY (understand boundaries)
|
||
* 3. Technical details MIDDLE (implementation)
|
||
* 4. Practical examples LATE (application)
|
||
* 5. Reference material LAST (lookup info)
|
||
*/
|
||
const { MongoClient } = require('mongodb');
|
||
|
||
// Define pedagogical ordering by document category
|
||
const ORDERING_STRATEGIES = {
|
||
'getting-started': {
|
||
name: 'Introduction/Tutorial Flow',
|
||
order: ['conceptual', 'critical', 'practical', 'technical', 'reference'],
|
||
description: 'Start with concepts, warn early, show examples, then technical details'
|
||
},
|
||
'research-theory': {
|
||
name: 'Research Paper Flow',
|
||
order: ['critical', 'conceptual', 'technical', 'practical', 'reference'],
|
||
description: 'Problem first, theory second, analysis third'
|
||
},
|
||
'technical-reference': {
|
||
name: 'Technical Documentation Flow',
|
||
order: ['conceptual', 'technical', 'practical', 'critical', 'reference'],
|
||
description: 'Overview, details, examples, edge cases, reference'
|
||
},
|
||
'advanced-topics': {
|
||
name: 'Advanced Concepts Flow',
|
||
order: ['critical', 'conceptual', 'technical', 'practical', 'reference'],
|
||
description: 'Warnings first, theory, implementation, applications'
|
||
},
|
||
'business-leadership': {
|
||
name: 'Business Case Flow',
|
||
order: ['conceptual', 'critical', 'practical', 'technical', 'reference'],
|
||
description: 'Vision, constraints, use cases, implementation, details'
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Resequence sections for better pedagogical flow
|
||
*/
|
||
function resequenceSections(sections, strategy) {
|
||
if (!sections || sections.length === 0) return sections;
|
||
|
||
const order = ORDERING_STRATEGIES[strategy]?.order || ORDERING_STRATEGIES['getting-started'].order;
|
||
|
||
// Create priority map
|
||
const priorityMap = {};
|
||
order.forEach((category, idx) => {
|
||
priorityMap[category] = idx;
|
||
});
|
||
|
||
// Sort by category priority, then by original order within category
|
||
const resequenced = [...sections].sort((a, b) => {
|
||
const priorityA = priorityMap[a.category] ?? 999;
|
||
const priorityB = priorityMap[b.category] ?? 999;
|
||
|
||
if (priorityA !== priorityB) {
|
||
return priorityA - priorityB;
|
||
}
|
||
|
||
// Within same category, maintain original order
|
||
return a.number - b.number;
|
||
});
|
||
|
||
// Renumber
|
||
resequenced.forEach((section, idx) => {
|
||
section.number = idx + 1;
|
||
});
|
||
|
||
return resequenced;
|
||
}
|
||
|
||
/**
|
||
* Analyze sequence improvement
|
||
*/
|
||
function analyzeImprovement(originalSections, resequencedSections) {
|
||
const originalSeq = originalSections.map(s => s.category);
|
||
const resequencedSeq = resequencedSections.map(s => s.category);
|
||
|
||
// Calculate jumpiness
|
||
const calculateJumpiness = (seq) => {
|
||
let changes = 0;
|
||
for (let i = 1; i < seq.length; i++) {
|
||
if (seq[i] !== seq[i-1]) changes++;
|
||
}
|
||
return Math.round((changes / (seq.length - 1)) * 100);
|
||
};
|
||
|
||
const originalJumpiness = calculateJumpiness(originalSeq);
|
||
const resequencedJumpiness = calculateJumpiness(resequencedSeq);
|
||
|
||
return {
|
||
originalJumpiness,
|
||
resequencedJumpiness,
|
||
improvement: originalJumpiness - resequencedJumpiness,
|
||
originalSeq,
|
||
resequencedSeq
|
||
};
|
||
}
|
||
|
||
async function run() {
|
||
const args = process.argv.slice(2);
|
||
const dryRun = !args.includes('--apply');
|
||
|
||
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(' RESEQUENCING CARDS FOR PEDAGOGICAL FLOW');
|
||
console.log('═══════════════════════════════════════════════════════════\n');
|
||
|
||
if (dryRun) {
|
||
console.log('🔍 DRY RUN MODE - No changes will be saved');
|
||
console.log(' Add --apply to commit changes\n');
|
||
} else {
|
||
console.log('✍️ APPLY MODE - Changes will be saved to database\n');
|
||
}
|
||
|
||
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'
|
||
];
|
||
|
||
let updatedCount = 0;
|
||
let improvedCount = 0;
|
||
|
||
for (const slug of PUBLIC_SLUGS) {
|
||
const doc = await collection.findOne({ slug });
|
||
|
||
if (!doc || !doc.sections || doc.sections.length === 0) {
|
||
continue;
|
||
}
|
||
|
||
const strategy = doc.category || 'getting-started';
|
||
const strategyInfo = ORDERING_STRATEGIES[strategy] || ORDERING_STRATEGIES['getting-started'];
|
||
|
||
console.log(`\n📄 ${doc.title}`);
|
||
console.log(` Strategy: ${strategyInfo.name}`);
|
||
console.log(` ${strategyInfo.description}`);
|
||
|
||
const originalSections = [...doc.sections];
|
||
const resequencedSections = resequenceSections(doc.sections, strategy);
|
||
|
||
const analysis = analyzeImprovement(originalSections, resequencedSections);
|
||
|
||
console.log(`\n Original sequence:`);
|
||
const ICONS = { conceptual: '📘', technical: '🔧', practical: '💡', reference: '📋', critical: '⚠️' };
|
||
console.log(` ${analysis.originalSeq.map(c => ICONS[c] || '❓').join(' ')}`);
|
||
console.log(` Jumpiness: ${analysis.originalJumpiness}%`);
|
||
|
||
console.log(`\n Resequenced:`);
|
||
console.log(` ${analysis.resequencedSeq.map(c => ICONS[c] || '❓').join(' ')}`);
|
||
console.log(` Jumpiness: ${analysis.resequencedJumpiness}%`);
|
||
|
||
if (analysis.improvement > 0) {
|
||
console.log(`\n ✅ Improvement: ${analysis.improvement}% reduction in jumpiness`);
|
||
improvedCount++;
|
||
|
||
if (!dryRun) {
|
||
await collection.updateOne(
|
||
{ slug },
|
||
{
|
||
$set: {
|
||
sections: resequencedSections,
|
||
updated_at: new Date()
|
||
}
|
||
}
|
||
);
|
||
console.log(` 💾 Saved to database`);
|
||
updatedCount++;
|
||
}
|
||
} else {
|
||
console.log(`\n ℹ️ No significant improvement needed`);
|
||
}
|
||
}
|
||
|
||
console.log('\n\n═══════════════════════════════════════════════════════════');
|
||
console.log(' SUMMARY');
|
||
console.log('═══════════════════════════════════════════════════════════\n');
|
||
|
||
console.log(`Documents analyzed: ${PUBLIC_SLUGS.length}`);
|
||
console.log(`Documents improved: ${improvedCount}`);
|
||
|
||
if (dryRun) {
|
||
console.log(`\n💡 Run with --apply to save changes`);
|
||
} else {
|
||
console.log(`\n✅ Documents updated: ${updatedCount}`);
|
||
}
|
||
|
||
await client.close();
|
||
}
|
||
|
||
run().catch(console.error);
|