\$\{html\}<\/div>`;/g,
- 'chartEl.innerHTML = `
${html}
`; setProgressBarWidths(chartEl);'
- );
-
- fs.writeFileSync(auditFile, auditContent);
- console.log('β Fixed audit-analytics.js');
-}
-
-// rule-manager.js
-const ruleManagerFile = path.join(__dirname, '../public/js/admin/rule-manager.js');
-let ruleManagerContent = fs.readFileSync(ruleManagerFile, 'utf8');
-
-if (!ruleManagerContent.includes('setProgressBarWidths')) {
- // Add helper before last })
- const lastBrace = ruleManagerContent.lastIndexOf('})();');
- ruleManagerContent = ruleManagerContent.slice(0, lastBrace) + helper + '\n' + ruleManagerContent.slice(lastBrace);
-
- // Add calls after container.innerHTML assignments
- ruleManagerContent = ruleManagerContent.replace(
- /(container\.innerHTML = `[\s\S]*?`;)/g,
- '$1 setProgressBarWidths(container);'
- );
-
- fs.writeFileSync(ruleManagerFile, ruleManagerContent);
- console.log('β Fixed rule-manager.js');
-}
-
-// rule-editor.js
-const ruleEditorFile = path.join(__dirname, '../public/js/admin/rule-editor.js');
-let ruleEditorContent = fs.readFileSync(ruleEditorFile, 'utf8');
-
-if (!ruleEditorContent.includes('setProgressBarWidths')) {
- // Add helper before last })
- const lastBrace = ruleEditorContent.lastIndexOf('})();');
- ruleEditorContent = ruleEditorContent.slice(0, lastBrace) + helper + '\n' + ruleEditorContent.slice(lastBrace);
-
- // Add calls after modal content is set
- ruleEditorContent = ruleEditorContent.replace(
- /(modalContent\.innerHTML = `[\s\S]*?`;)(\s+\/\/ Show modal)/g,
- '$1 setProgressBarWidths(modalContent);$2'
- );
-
- fs.writeFileSync(ruleEditorFile, ruleEditorContent);
- console.log('β Fixed rule-editor.js');
-}
-
-console.log('\nβ
Progress bar helpers added\n');
diff --git a/scripts/add-sections-from-db-markdown.js b/scripts/add-sections-from-db-markdown.js
deleted file mode 100644
index 95ca38ac..00000000
--- a/scripts/add-sections-from-db-markdown.js
+++ /dev/null
@@ -1,325 +0,0 @@
-#!/usr/bin/env node
-/**
- * Add Card View Sections to Documents (Using DB Markdown)
- *
- * Generates sections from the content_markdown field stored in the database
- * for documents that don't have corresponding MD files on disk.
- */
-
-require('dotenv').config();
-
-const { connect, close } = require('../src/utils/db.util');
-const Document = require('../src/models/Document.model');
-const { marked } = require('marked');
-
-// List of document slugs that need sections
-const SLUGS_NEEDING_SECTIONS = [
- // 5 newly imported archives
- 'case-studies-real-world-llm-failure-modes-appendix',
- 'implementation-guide-python-examples',
- 'tractatus-framework-enforcement-claude-code',
- 'research-topic-concurrent-session-architecture',
- 'research-topic-rule-proliferation-transactional-overhead',
-
- // 5 technical reference docs
- 'implementation-roadmap-24-month-deployment-plan',
- 'api-reference-complete',
- 'api-javascript-examples',
- 'api-python-examples',
- 'openapi-specification',
-
- // 5 case studies
- 'the-27027-incident-a-case-study-in-pattern-recognition-bias',
- 'when-frameworks-fail-and-why-thats-ok',
- 'our-framework-in-action-detecting-and-correcting-ai-fabrications',
- 'real-world-ai-governance-a-case-study-in-framework-failure-and-recovery',
- 'case-studies-real-world-llm-failure-modes',
-
- // 2 Phase 5 PoC summaries
- 'phase-5-poc-session-1-summary',
- 'phase-5-poc-session-2-summary'
-];
-
-function extractSectionsFromMarkdown(markdown) {
- const lines = markdown.split('\n');
- const sections = [];
- let currentSection = null;
- let contentBuffer = [];
-
- for (let i = 0; i < lines.length; i++) {
- const line = lines[i];
-
- // Match H2 headers (## Title)
- const h2Match = line.match(/^## (.+)$/);
- if (h2Match) {
- // Save previous section if exists
- if (currentSection) {
- currentSection.content_md = contentBuffer.join('\n').trim();
- sections.push(currentSection);
- }
-
- // Start new section
- currentSection = {
- title: h2Match[1].trim(),
- content_md: ''
- };
- contentBuffer = [];
- continue;
- }
-
- // Collect content for current section
- if (currentSection) {
- contentBuffer.push(line);
- }
- }
-
- // Save final section
- if (currentSection) {
- currentSection.content_md = contentBuffer.join('\n').trim();
- sections.push(currentSection);
- }
-
- return sections;
-}
-
-function generateExcerpt(markdown, maxLength = 150) {
- let text = markdown
- .replace(/^#+\s+/gm, '')
- .replace(/\*\*(.+?)\*\*/g, '$1')
- .replace(/\*(.+?)\*/g, '$1')
- .replace(/\[(.+?)\]\(.+?\)/g, '$1')
- .replace(/`(.+?)`/g, '$1')
- .replace(/^[-*+]\s+/gm, '')
- .replace(/^\d+\.\s+/gm, '')
- .replace(/\n{2,}/g, ' ')
- .trim();
-
- if (text.length > maxLength) {
- text = text.substring(0, maxLength).trim();
- const lastPeriod = text.lastIndexOf('.');
- if (lastPeriod > maxLength * 0.7) {
- text = text.substring(0, lastPeriod + 1);
- } else {
- text += '...';
- }
- }
-
- return text;
-}
-
-function estimateReadingTime(text) {
- const wordCount = text.split(/\s+/).length;
- const minutes = Math.ceil(wordCount / 200);
- return Math.max(1, minutes);
-}
-
-function classifySection(title, content) {
- const titleLower = title.toLowerCase();
- const contentLower = content.toLowerCase();
-
- if (
- titleLower.includes('limitation') ||
- titleLower.includes('failure') ||
- titleLower.includes('warning') ||
- titleLower.includes('security') ||
- titleLower.includes('risk') ||
- content.match(/β οΈ|critical|warning|caution|danger/gi)
- ) {
- return 'critical';
- }
-
- if (
- titleLower.includes('glossary') ||
- titleLower.includes('reference') ||
- titleLower.includes('contact') ||
- titleLower.includes('license') ||
- titleLower.includes('getting started')
- ) {
- return 'reference';
- }
-
- if (
- titleLower.includes('technical') ||
- titleLower.includes('architecture') ||
- titleLower.includes('implementation') ||
- titleLower.includes('integration') ||
- titleLower.includes('api') ||
- content.match(/```|`[a-z]+`|function|class|const|import/gi)
- ) {
- return 'technical';
- }
-
- if (
- titleLower.includes('how') ||
- titleLower.includes('guide') ||
- titleLower.includes('tutorial') ||
- titleLower.includes('example') ||
- titleLower.includes('use case') ||
- titleLower.includes('should use') ||
- titleLower.includes('contributing')
- ) {
- return 'practical';
- }
-
- return 'conceptual';
-}
-
-function determineTechnicalLevel(content) {
- const contentLower = content.toLowerCase();
-
- if (
- content.match(/```[\s\S]+```/g) ||
- contentLower.includes('api') ||
- contentLower.includes('implementation') ||
- contentLower.includes('integration') ||
- contentLower.includes('architecture')
- ) {
- return 'advanced';
- }
-
- if (
- contentLower.includes('service') ||
- contentLower.includes('component') ||
- contentLower.includes('system') ||
- contentLower.includes('framework')
- ) {
- return 'intermediate';
- }
-
- return 'beginner';
-}
-
-function generateSlug(title) {
- return title
- .toLowerCase()
- .replace(/[^a-z0-9\s-]/g, '')
- .replace(/\s+/g, '-')
- .replace(/-+/g, '-')
- .replace(/^-|-$/g, '');
-}
-
-async function addSectionsToDocument(slug) {
- console.log(`\nπ Processing: ${slug}`);
-
- try {
- // Find document
- const doc = await Document.findBySlug(slug);
- if (!doc) {
- console.log(` β Document not found`);
- return { success: false, reason: 'not_found' };
- }
-
- // Check if already has sections
- if (doc.sections && doc.sections.length > 0) {
- console.log(` βοΈ Already has ${doc.sections.length} sections`);
- return { success: false, reason: 'has_sections' };
- }
-
- // Check if has content_markdown
- if (!doc.content_markdown) {
- console.log(` β No content_markdown field`);
- return { success: false, reason: 'no_markdown' };
- }
-
- // Extract sections from markdown
- const rawSections = extractSectionsFromMarkdown(doc.content_markdown);
-
- if (rawSections.length === 0) {
- console.log(` β οΈ No H2 sections found in markdown`);
- return { success: false, reason: 'no_h2' };
- }
-
- console.log(` π Found ${rawSections.length} sections`);
-
- // Process each section
- const sections = [];
- for (let i = 0; i < rawSections.length; i++) {
- const raw = rawSections[i];
-
- if (!raw.content_md.trim()) {
- continue;
- }
-
- const content_html = marked(raw.content_md);
- const excerpt = generateExcerpt(raw.content_md);
- const readingTime = estimateReadingTime(raw.content_md);
- const category = classifySection(raw.title, raw.content_md);
- const technicalLevel = determineTechnicalLevel(raw.content_md);
- const sectionSlug = generateSlug(raw.title);
-
- sections.push({
- number: i + 1,
- title: raw.title,
- slug: sectionSlug,
- content_html,
- excerpt,
- readingTime,
- technicalLevel,
- category
- });
- }
-
- // Update document
- const updated = await Document.update(doc._id.toString(), { sections });
-
- if (!updated) {
- console.log(` β Failed to update`);
- return { success: false, reason: 'update_failed' };
- }
-
- console.log(` β
Added ${sections.length} sections`);
- sections.forEach(s => {
- console.log(` ${s.number}. ${s.title} (${s.category}, ${s.readingTime}min)`);
- });
-
- return { success: true, sections: sections.length };
-
- } catch (error) {
- console.error(` β Error: ${error.message}`);
- return { success: false, error: error.message };
- }
-}
-
-async function main() {
- try {
- console.log('π Adding Card View Sections to 17 Documents\n');
- console.log('βββββββββββββββββββββββββββββββββββββββββββββββββββ\n');
-
- await connect();
-
- let added = 0;
- let skipped = 0;
- let noH2 = 0;
- let failed = 0;
-
- for (const slug of SLUGS_NEEDING_SECTIONS) {
- const result = await addSectionsToDocument(slug);
-
- if (result.success) {
- added++;
- } else if (result.reason === 'has_sections') {
- skipped++;
- } else if (result.reason === 'no_h2') {
- noH2++;
- } else {
- failed++;
- }
- }
-
- console.log('\nβββββββββββββββββββββββββββββββββββββββββββββββββββ');
- console.log('\nπ Summary:');
- console.log(` β
Added sections: ${added}`);
- console.log(` βοΈ Skipped (already have sections): ${skipped}`);
- console.log(` β οΈ No H2 sections found: ${noH2}`);
- console.log(` β Failed: ${failed}`);
- console.log(` π¦ Total: ${SLUGS_NEEDING_SECTIONS.length}`);
-
- await close();
-
- } catch (error) {
- console.error('\nβ Fatal error:', error);
- process.exit(1);
- }
-}
-
-main();
diff --git a/scripts/add-sections-to-17-docs.js b/scripts/add-sections-to-17-docs.js
deleted file mode 100644
index a1e26d54..00000000
--- a/scripts/add-sections-to-17-docs.js
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/usr/bin/env node
-/**
- * Add Card View Sections to 17 Documents
- *
- * Adds card view sections to:
- * - 5 newly imported archives
- * - 12 existing documents without sections
- */
-
-require('dotenv').config();
-
-const fs = require('fs');
-const path = require('path');
-const { connect, close } = require('../src/utils/db.util');
-const Document = require('../src/models/Document.model');
-const { processMarkdownFile } = require('./generate-card-sections.js');
-
-const DOCS_TO_PROCESS = [
- // 5 newly imported archives
- { slug: 'case-studies-real-world-llm-failure-modes-appendix', mdPath: 'docs/markdown/case-studies.md' },
- { slug: 'implementation-guide-python-examples', mdPath: 'docs/api/examples-python.md' },
- { slug: 'tractatus-framework-enforcement-claude-code', mdPath: 'docs/claude-code-framework-enforcement.md' },
- { slug: 'research-topic-concurrent-session-architecture', mdPath: 'docs/research/concurrent-session-architecture-limitations.md' },
- { slug: 'research-topic-rule-proliferation-transactional-overhead', mdPath: 'docs/research/rule-proliferation-and-transactional-overhead.md' },
-
- // 5 technical reference docs without sections
- { slug: 'implementation-roadmap-24-month-deployment-plan', mdPath: 'docs/markdown/implementation-roadmap-24-month-deployment-plan.md' },
- { slug: 'api-reference-complete', mdPath: 'docs/markdown/api-reference-complete.md' },
- { slug: 'api-javascript-examples', mdPath: 'docs/api/examples-javascript.md' },
- { slug: 'api-python-examples', mdPath: 'docs/api/examples-python.md' },
- { slug: 'openapi-specification', mdPath: 'docs/markdown/openapi-specification.md' },
-
- // 5 case studies without sections
- { slug: 'the-27027-incident-a-case-study-in-pattern-recognition-bias', mdPath: 'docs/case-studies/27027-incident-detailed-analysis.md' },
- { slug: 'when-frameworks-fail-and-why-thats-ok', mdPath: 'docs/case-studies/when-frameworks-fail-oct-2025.md' },
- { slug: 'our-framework-in-action-detecting-and-correcting-ai-fabrications', mdPath: 'docs/case-studies/framework-in-action-oct-2025.md' },
- { slug: 'real-world-ai-governance-a-case-study-in-framework-failure-and-recovery', mdPath: 'docs/case-studies/real-world-governance-case-study-oct-2025.md' },
- { slug: 'case-studies-real-world-llm-failure-modes', mdPath: 'docs/markdown/case-studies.md' },
-
- // 2 Phase 5 PoC summaries
- { slug: 'phase-5-poc-session-1-summary', mdPath: 'docs/markdown/phase-5-session1-summary.md' },
- { slug: 'phase-5-poc-session-2-summary', mdPath: 'docs/markdown/phase-5-session2-summary.md' }
-];
-
-async function addSectionsToDocument(docInfo) {
- console.log(`\nπ Processing: ${docInfo.slug}`);
-
- try {
- // Check if document exists
- const doc = await Document.findBySlug(docInfo.slug);
- if (!doc) {
- console.log(` β Document not found in database`);
- return { success: false, reason: 'not_found' };
- }
-
- // Check if already has sections
- if (doc.sections && doc.sections.length > 0) {
- console.log(` βοΈ Already has ${doc.sections.length} sections, skipping`);
- return { success: false, reason: 'has_sections' };
- }
-
- // Build full path to markdown file
- const fullPath = path.join('/home/theflow/projects/tractatus', docInfo.mdPath);
-
- // Check if markdown file exists
- if (!fs.existsSync(fullPath)) {
- console.log(` β Markdown file not found: ${fullPath}`);
- return { success: false, reason: 'md_not_found' };
- }
-
- // Generate sections
- console.log(` π Generating sections from: ${docInfo.mdPath}`);
- const sections = await processMarkdownFile(fullPath);
-
- if (!sections || sections.length === 0) {
- console.log(` β οΈ No sections generated (possibly no H2 headers)`);
- return { success: false, reason: 'no_sections' };
- }
-
- // Update document with sections
- const updated = await Document.update(doc._id.toString(), { sections });
-
- if (!updated) {
- console.log(` β Failed to update document`);
- return { success: false, reason: 'update_failed' };
- }
-
- console.log(` β
Added ${sections.length} sections`);
- return { success: true, sections: sections.length };
-
- } catch (error) {
- console.error(` β Error: ${error.message}`);
- return { success: false, error: error.message };
- }
-}
-
-async function main() {
- try {
- console.log('π Adding Card View Sections to 17 Documents\n');
- console.log('βββββββββββββββββββββββββββββββββββββββββββββββββββ\n');
-
- await connect();
-
- let added = 0;
- let skipped = 0;
- let notFound = 0;
- let failed = 0;
-
- for (const docInfo of DOCS_TO_PROCESS) {
- const result = await addSectionsToDocument(docInfo);
-
- if (result.success) {
- added++;
- } else if (result.reason === 'has_sections') {
- skipped++;
- } else if (result.reason === 'not_found' || result.reason === 'md_not_found') {
- notFound++;
- } else {
- failed++;
- }
- }
-
- console.log('\nβββββββββββββββββββββββββββββββββββββββββββββββββββ');
- console.log('\nπ Summary:');
- console.log(` β
Added sections: ${added}`);
- console.log(` βοΈ Skipped (already have sections): ${skipped}`);
- console.log(` β Not found: ${notFound}`);
- console.log(` β Failed: ${failed}`);
- console.log(` π¦ Total processed: ${DOCS_TO_PROCESS.length}`);
-
- await close();
-
- } catch (error) {
- console.error('\nβ Fatal error:', error);
- process.exit(1);
- }
-}
-
-main();
diff --git a/scripts/add-sections-to-documents.js b/scripts/add-sections-to-documents.js
deleted file mode 100644
index bff9755a..00000000
--- a/scripts/add-sections-to-documents.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * Add section-based cards to all existing documents
- * Parses documents and adds sections array for card-based UI
- */
-
-const fs = require('fs');
-const path = require('path');
-const { MongoClient } = require('mongodb');
-const { parseDocumentSections } = require('../src/utils/document-section-parser');
-const { markdownToHtml } = require('../src/utils/markdown.util');
-
-const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/tractatus_prod';
-const DOCS_DIR = process.env.DOCS_DIR || '/var/www/tractatus/docs/markdown';
-
-async function main() {
- console.log('=== Adding Sections to Documents ===\n');
-
- const client = new MongoClient(MONGODB_URI);
-
- try {
- await client.connect();
- const db = client.db();
- const collection = db.collection('documents');
-
- // Get all documents
- const documents = await collection.find({}).toArray();
- console.log(`Found ${documents.length} documents in database\n`);
-
- const markdownFiles = {
- 'tractatus-agentic-governance-system-glossary-of-terms': 'GLOSSARY.md',
- 'introduction-to-the-tractatus-framework': 'introduction.md',
- 'core-concepts-of-the-tractatus-framework': 'core-concepts.md',
- 'implementation-guide': 'implementation-guide.md',
- 'case-studies-real-world-llm-failure-modes': 'case-studies.md'
- };
-
- for (const doc of documents) {
- console.log(`Processing: ${doc.title}`);
-
- const markdownFile = markdownFiles[doc.slug];
- if (!markdownFile) {
- console.log(` β No markdown file found for ${doc.slug}`);
- continue;
- }
-
- const filePath = path.join(DOCS_DIR, markdownFile);
- if (!fs.existsSync(filePath)) {
- console.log(` β File not found: ${filePath}`);
- continue;
- }
-
- // Read markdown content
- const markdown = fs.readFileSync(filePath, 'utf-8');
-
- // Parse sections
- const sections = parseDocumentSections(markdown, doc.content_html);
-
- // Add HTML content to each section
- const sectionsWithHtml = sections.map(section => ({
- ...section,
- content_html: markdownToHtml(section.content)
- }));
-
- console.log(` β Parsed ${sections.length} sections`);
-
- // Category breakdown
- const categoryCount = {};
- sectionsWithHtml.forEach(s => {
- categoryCount[s.category] = (categoryCount[s.category] || 0) + 1;
- });
- console.log(` Categories:`, categoryCount);
-
- // Technical level breakdown
- const levelCount = {};
- sectionsWithHtml.forEach(s => {
- levelCount[s.technicalLevel] = (levelCount[s.technicalLevel] || 0) + 1;
- });
- console.log(` Levels:`, levelCount);
-
- // Update document with sections
- await collection.updateOne(
- { _id: doc._id },
- {
- $set: {
- sections: sectionsWithHtml,
- 'metadata.sections_count': sections.length,
- 'metadata.last_section_update': new Date()
- }
- }
- );
-
- console.log(` β Updated document\n`);
- }
-
- console.log('=== Section Addition Complete ===');
-
- } catch (error) {
- console.error('Error:', error);
- process.exit(1);
- } finally {
- await client.close();
- }
-}
-
-main();
diff --git a/scripts/analyze-instruction-violations.js b/scripts/analyze-instruction-violations.js
deleted file mode 100755
index 8028c14d..00000000
--- a/scripts/analyze-instruction-violations.js
+++ /dev/null
@@ -1,366 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * Instruction History Analytics
- *
- * Analyzes instruction-history.json to provide insights into:
- * - Instruction usage patterns
- * - Most violated instructions
- * - Instructions never referenced
- * - Quadrant distribution
- * - Enforcement effectiveness
- *
- * Usage: node scripts/analyze-instruction-violations.js
- */
-
-const fs = require('fs');
-const path = require('path');
-
-const INSTRUCTION_HISTORY_PATH = path.join(__dirname, '../.claude/instruction-history.json');
-const INCIDENTS_PATH = path.join(__dirname, '../.claude/framework-incidents.json');
-
-/**
- * Color output helpers
- */
-const colors = {
- reset: '\x1b[0m',
- bright: '\x1b[1m',
- green: '\x1b[32m',
- yellow: '\x1b[33m',
- blue: '\x1b[34m',
- red: '\x1b[31m',
- cyan: '\x1b[36m',
- magenta: '\x1b[35m'
-};
-
-function log(message, color = 'reset') {
- console.log(`${colors[color]}${message}${colors.reset}`);
-}
-
-function header(message) {
- console.log('');
- log('β'.repeat(80), 'cyan');
- log(` ${message}`, 'bright');
- log('β'.repeat(80), 'cyan');
- console.log('');
-}
-
-function section(message) {
- console.log('');
- log(`βΆ ${message}`, 'blue');
-}
-
-/**
- * Load instruction history
- */
-function loadInstructions() {
- try {
- const data = fs.readFileSync(INSTRUCTION_HISTORY_PATH, 'utf8');
- return JSON.parse(data);
- } catch (err) {
- log(`Error loading instruction history: ${err.message}`, 'red');
- process.exit(1);
- }
-}
-
-/**
- * Load framework incidents (if exists)
- */
-function loadIncidents() {
- try {
- if (!fs.existsSync(INCIDENTS_PATH)) {
- return { incidents: [] };
- }
- const data = fs.readFileSync(INCIDENTS_PATH, 'utf8');
- return JSON.parse(data);
- } catch (err) {
- log(`Warning: Could not load incidents database: ${err.message}`, 'yellow');
- return { incidents: [] };
- }
-}
-
-/**
- * Analyze instruction usage
- */
-function analyzeInstructions(history) {
- const instructions = history.instructions || [];
- const active = instructions.filter(i => i.active);
- const inactive = instructions.filter(i => !i.active);
-
- // Quadrant distribution
- const byQuadrant = {
- STRATEGIC: active.filter(i => i.quadrant === 'STRATEGIC').length,
- OPERATIONAL: active.filter(i => i.quadrant === 'OPERATIONAL').length,
- TACTICAL: active.filter(i => i.quadrant === 'TACTICAL').length,
- SYSTEM: active.filter(i => i.quadrant === 'SYSTEM').length,
- STOCHASTIC: active.filter(i => i.quadrant === 'STOCHASTIC').length
- };
-
- // Persistence distribution
- const byPersistence = {
- HIGH: active.filter(i => i.persistence === 'HIGH').length,
- MEDIUM: active.filter(i => i.persistence === 'MEDIUM').length,
- LOW: active.filter(i => i.persistence === 'LOW').length,
- VARIABLE: active.filter(i => i.persistence === 'VARIABLE').length
- };
-
- // Temporal scope distribution
- const byScope = {
- PERMANENT: active.filter(i => i.temporal_scope === 'PERMANENT').length,
- PROJECT: active.filter(i => i.temporal_scope === 'PROJECT').length,
- PHASE: active.filter(i => i.temporal_scope === 'PHASE').length,
- SESSION: active.filter(i => i.temporal_scope === 'SESSION').length
- };
-
- return {
- total: instructions.length,
- active: active.length,
- inactive: inactive.length,
- byQuadrant,
- byPersistence,
- byScope,
- instructions: active
- };
-}
-
-/**
- * Analyze violations from incidents database
- */
-function analyzeViolations(incidents) {
- const violations = {};
-
- incidents.forEach(incident => {
- const instId = incident.instruction_violated || incident.id;
- if (!violations[instId]) {
- violations[instId] = {
- count: 0,
- tokens_wasted: 0,
- incidents: []
- };
- }
- violations[instId].count++;
- violations[instId].tokens_wasted += incident.tokens_wasted || 0;
- violations[instId].incidents.push(incident);
- });
-
- return violations;
-}
-
-/**
- * Find never-referenced instructions
- */
-function findUnusedInstructions(instructions, violations) {
- const neverViolated = instructions.filter(i => !violations[i.id]);
-
- return {
- neverViolated: neverViolated.map(i => i.id),
- strategicNeverViolated: neverViolated.filter(i => i.quadrant === 'STRATEGIC').map(i => i.id)
- };
-}
-
-/**
- * Calculate enforcement effectiveness
- */
-function calculateEnforcement(instructions, violations) {
- // Hook-enforced instructions (those with architectural enforcement)
- const hookEnforced = instructions.filter(i =>
- i.enforcement === 'architectural' ||
- i.enforcement === 'hook' ||
- i.notes?.includes('hook') ||
- i.notes?.includes('architectural')
- );
-
- const voluntary = instructions.filter(i =>
- !hookEnforced.includes(i)
- );
-
- // Calculate violation rates
- const hookEnforcedViolations = hookEnforced.filter(i => violations[i.id]);
- const voluntaryViolations = voluntary.filter(i => violations[i.id]);
-
- const hookEnforcementRate = hookEnforced.length > 0
- ? ((hookEnforced.length - hookEnforcedViolations.length) / hookEnforced.length * 100).toFixed(1)
- : 0;
-
- const voluntaryComplianceRate = voluntary.length > 0
- ? ((voluntary.length - voluntaryViolations.length) / voluntary.length * 100).toFixed(1)
- : 0;
-
- return {
- hookEnforced: hookEnforced.length,
- voluntary: voluntary.length,
- hookEnforcementRate,
- voluntaryComplianceRate,
- hookEnforcedViolations: hookEnforcedViolations.length,
- voluntaryViolations: voluntaryViolations.length
- };
-}
-
-/**
- * Main analytics
- */
-function main() {
- header('Instruction History Analytics');
-
- // Load data
- const history = loadInstructions();
- const incidentsData = loadIncidents();
- const incidents = incidentsData.incidents || [];
-
- log(`π Analyzing ${history.instructions?.length || 0} instructions and ${incidents.length} incidents`, 'cyan');
-
- // Analyze
- const analysis = analyzeInstructions(history);
- const violations = analyzeViolations(incidents);
- const unused = findUnusedInstructions(analysis.instructions, violations);
- const enforcement = calculateEnforcement(analysis.instructions, violations);
-
- // Display results
-
- // 1. Overview
- section('1. Instruction Overview');
- log(` Total instructions: ${analysis.total}`, 'cyan');
- log(` Active: ${analysis.active}`, 'green');
- log(` Inactive: ${analysis.inactive}`, 'yellow');
-
- // 2. Distribution by Quadrant
- section('2. Distribution by Quadrant');
- Object.entries(analysis.byQuadrant).forEach(([quadrant, count]) => {
- const bar = 'β'.repeat(Math.ceil(count / 2));
- log(` ${quadrant.padEnd(12)}: ${count.toString().padStart(2)} ${bar}`, 'cyan');
- });
-
- // 3. Distribution by Persistence
- section('3. Distribution by Persistence');
- Object.entries(analysis.byPersistence).forEach(([level, count]) => {
- const bar = 'β'.repeat(Math.ceil(count / 2));
- log(` ${level.padEnd(12)}: ${count.toString().padStart(2)} ${bar}`, 'cyan');
- });
-
- // 4. Distribution by Temporal Scope
- section('4. Distribution by Temporal Scope');
- Object.entries(analysis.byScope).forEach(([scope, count]) => {
- const bar = 'β'.repeat(Math.ceil(count / 2));
- log(` ${scope.padEnd(12)}: ${count.toString().padStart(2)} ${bar}`, 'cyan');
- });
-
- // 5. Most Violated Instructions
- section('5. Most Violated Instructions');
- const violationList = Object.entries(violations)
- .sort((a, b) => b[1].count - a[1].count);
-
- if (violationList.length === 0) {
- log(' β
No violations recorded', 'green');
- } else {
- violationList.slice(0, 10).forEach(([instId, data]) => {
- const instruction = analysis.instructions.find(i => i.id === instId);
- const text = instruction ? instruction.text.substring(0, 60) + '...' : 'Unknown instruction';
- log(` ${instId}: ${data.count} violation(s), ${data.tokens_wasted.toLocaleString()} tokens wasted`, 'red');
- log(` "${text}"`, 'yellow');
- });
- }
-
- // 6. Never Violated Instructions
- section('6. Never Violated Instructions');
- if (unused.neverViolated.length === 0) {
- log(' β οΈ All instructions have been violated at least once!', 'yellow');
- } else {
- log(` ${unused.neverViolated.length} instructions with 100% compliance:`, 'green');
- unused.neverViolated.slice(0, 10).forEach(instId => {
- const instruction = analysis.instructions.find(i => i.id === instId);
- if (instruction) {
- log(` ${instId}: ${instruction.text.substring(0, 70)}`, 'cyan');
- }
- });
- if (unused.neverViolated.length > 10) {
- log(` ... and ${unused.neverViolated.length - 10} more`, 'cyan');
- }
- }
-
- // 7. Enforcement Effectiveness
- section('7. Enforcement Effectiveness');
- log(` Hook-enforced instructions: ${enforcement.hookEnforced}`, 'cyan');
- log(` Violations: ${enforcement.hookEnforcedViolations}`, enforcement.hookEnforcedViolations > 0 ? 'red' : 'green');
- log(` Compliance rate: ${enforcement.hookEnforcementRate}%`, enforcement.hookEnforcementRate >= 95 ? 'green' : 'yellow');
-
- console.log('');
- log(` Voluntary compliance instructions: ${enforcement.voluntary}`, 'cyan');
- log(` Violations: ${enforcement.voluntaryViolations}`, enforcement.voluntaryViolations > 0 ? 'red' : 'green');
- log(` Compliance rate: ${enforcement.voluntaryComplianceRate}%`, enforcement.voluntaryComplianceRate >= 95 ? 'green' : 'yellow');
-
- console.log('');
- if (enforcement.hookEnforcementRate > enforcement.voluntaryComplianceRate) {
- log(` β
Hook enforcement is ${(enforcement.hookEnforcementRate - enforcement.voluntaryComplianceRate).toFixed(1)}% more effective`, 'green');
- log(` π‘ Recommendation: Convert more voluntary compliance to architectural enforcement`, 'cyan');
- } else if (enforcement.voluntaryComplianceRate >= 95) {
- log(` β
Voluntary compliance is working well (${enforcement.voluntaryComplianceRate}%)`, 'green');
- } else {
- log(` β οΈ Consider improving enforcement mechanisms`, 'yellow');
- }
-
- // 8. Recommendations
- section('8. Recommendations');
-
- const recommendations = [];
-
- // High-violation instructions needing enforcement
- const highViolation = violationList.filter(([_, data]) => data.count >= 2);
- if (highViolation.length > 0) {
- recommendations.push({
- priority: 'HIGH',
- text: `${highViolation.length} instruction(s) violated 2+ times - add architectural enforcement`,
- details: highViolation.map(([id]) => id)
- });
- }
-
- // Strategic instructions that are never violated (good!)
- if (unused.strategicNeverViolated.length > 0) {
- recommendations.push({
- priority: 'INFO',
- text: `${unused.strategicNeverViolated.length} STRATEGIC instructions have 100% compliance - document success`,
- details: unused.strategicNeverViolated.slice(0, 5)
- });
- }
-
- // Voluntary compliance gaps
- if (enforcement.voluntaryComplianceRate < 80) {
- recommendations.push({
- priority: 'MEDIUM',
- text: `Voluntary compliance at ${enforcement.voluntaryComplianceRate}% - convert to hooks or improve documentation`,
- details: []
- });
- }
-
- if (recommendations.length === 0) {
- log(' β
No recommendations - framework is performing well!', 'green');
- } else {
- recommendations.forEach((rec, i) => {
- const color = rec.priority === 'HIGH' ? 'red' : rec.priority === 'MEDIUM' ? 'yellow' : 'cyan';
- log(` ${i + 1}. [${rec.priority}] ${rec.text}`, color);
- if (rec.details.length > 0) {
- rec.details.forEach(detail => {
- log(` - ${detail}`, 'cyan');
- });
- }
- });
- }
-
- // Summary footer
- header('Analytics Complete');
- console.log('');
- log(` π Key Metrics:`, 'bright');
- log(` Active Instructions: ${analysis.active}`, 'cyan');
- log(` Recorded Violations: ${incidents.length}`, incidents.length > 0 ? 'yellow' : 'green');
- log(` Tokens Wasted: ${Object.values(violations).reduce((sum, v) => sum + v.tokens_wasted, 0).toLocaleString()}`, 'red');
- log(` Hook Enforcement Rate: ${enforcement.hookEnforcementRate}%`, 'green');
- log(` Voluntary Compliance Rate: ${enforcement.voluntaryComplianceRate}%`, 'yellow');
- console.log('');
- log(` π‘ Next Steps:`, 'bright');
- log(` - Review high-violation instructions for enforcement gaps`, 'cyan');
- log(` - Document successful compliance patterns`, 'cyan');
- log(` - Convert voluntary β architectural where violations occur`, 'cyan');
- console.log('');
-}
-
-// Run
-main();
diff --git a/scripts/archive-all-internal-documents.js b/scripts/archive-all-internal-documents.js
deleted file mode 100644
index a82b3ec1..00000000
--- a/scripts/archive-all-internal-documents.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * Archive All Internal Documents
- * Mass archive of project tracking, internal, and confidential documents
- */
-
-const { MongoClient } = require('mongodb');
-
-// MongoDB connection
-const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/tractatus_dev';
-const DB_NAME = process.env.MONGODB_DB || 'tractatus_dev';
-
-// Documents to mark as confidential (not archived, just hidden)
-const CONFIDENTIAL_DOCS = [
- 'security-audit-report',
- 'koha-stripe-payment-setup-guide',
- 'koha-production-deployment-guide',
- 'appendix-e-contact-information',
- 'cover-letter-for-anthropic-submission'
-];
-
-// Documents to archive (project tracking, internal planning)
-const ARCHIVE_PATTERNS = [
- 'phase-2-', // All Phase 2 planning docs
- 'session-handoff', // All session handoffs
- 'appendix-b-', // Duplicate case studies
- 'implementation-roadmap', // Outdated planning
- 'implementation-guide-python', // Outdated code examples
- 'research-foundations-scholarly', // Academic, not practical
- 'tractatus-blog-post-outlines', // Internal planning
- 'tractatus-project-implementation-progress-report', // Project tracking
- 'tractatus-production-comprehensive-testing-checklist', // Internal testing
- 'tractatus-production-testing-results', // Test results
- 'tractatus-governance-framework-test-suite', // Internal testing
- 'ai-features-implementation-session' // Session tracking
-];
-
-async function main() {
- console.log('=== Archiving All Internal Documents ===\n');
-
- let client;
-
- try {
- // Connect to MongoDB
- console.log('Connecting to MongoDB...');
- client = await MongoClient.connect(MONGODB_URI);
- const db = client.db(DB_NAME);
- const collection = db.collection('documents');
- console.log('β Connected\n');
-
- // 1. Mark confidential documents
- console.log('=== Marking Confidential Documents ===\n');
- let confidentialCount = 0;
-
- for (const slug of CONFIDENTIAL_DOCS) {
- const result = await collection.updateOne(
- { slug },
- {
- $set: {
- visibility: 'confidential',
- category: 'internal',
- order: 999
- }
- }
- );
-
- if (result.matchedCount > 0) {
- console.log(`β Marked confidential: ${slug}`);
- confidentialCount++;
- }
- }
- console.log(`\nβ Total confidential: ${confidentialCount}\n`);
-
- // 2. Archive documents matching patterns
- console.log('=== Archiving Project Tracking Documents ===\n');
- let archivedCount = 0;
-
- const allDocs = await collection.find({ visibility: { $ne: 'confidential' } }).toArray();
-
- for (const doc of allDocs) {
- const shouldArchive = ARCHIVE_PATTERNS.some(pattern =>
- doc.slug.includes(pattern)
- );
-
- if (shouldArchive && doc.visibility !== 'archived') {
- const result = await collection.updateOne(
- { _id: doc._id },
- {
- $set: {
- visibility: 'archived',
- category: 'project-tracking',
- order: 999,
- archiveNote: 'Internal project tracking document. Not relevant for public documentation.'
- }
- }
- );
-
- if (result.matchedCount > 0) {
- console.log(`β Archived: ${doc.slug}`);
- archivedCount++;
- }
- }
- }
- console.log(`\nβ Total archived: ${archivedCount}\n`);
-
- // 3. Handle recent case studies (keep but categorize)
- console.log('=== Categorizing Case Studies ===\n');
- const caseStudySlugs = [
- 'our-framework-in-action-detecting-and-correcting-ai-fabrications',
- 'framework-governance-in-action-pre-publication-security-audit',
- 'real-world-ai-governance-a-case-study-in-framework-failure-and-recovery',
- 'when-frameworks-fail-and-why-thats-ok'
- ];
-
- let caseStudyCount = 0;
- for (const [index, slug] of caseStudySlugs.entries()) {
- const result = await collection.updateOne(
- { slug },
- {
- $set: {
- visibility: 'public',
- category: 'practical',
- audience: 'general',
- order: 8 + index // Orders 8-11
- }
- }
- );
-
- if (result.matchedCount > 0) {
- console.log(`β Categorized: ${slug} (order: ${8 + index})`);
- caseStudyCount++;
- }
- }
- console.log(`\nβ Total case studies: ${caseStudyCount}\n`);
-
- // Summary
- console.log('=== Final Summary ===\n');
- const publicCount = await collection.countDocuments({ visibility: 'public' });
- const archivedTotal = await collection.countDocuments({ visibility: 'archived' });
- const confidentialTotal = await collection.countDocuments({ visibility: 'confidential' });
-
- console.log(`π Public documents: ${publicCount}`);
- console.log(`π¦ Archived documents: ${archivedTotal}`);
- console.log(`π Confidential documents: ${confidentialTotal}`);
- console.log(`\nTotal: ${publicCount + archivedTotal + confidentialTotal} documents\n`);
-
- // Show public documents
- console.log('=== Public Documents (Final List) ===\n');
- const publicDocs = await collection.find({ visibility: 'public' })
- .sort({ order: 1 })
- .project({ title: 1, order: 1, category: 1 })
- .toArray();
-
- publicDocs.forEach(doc => {
- console.log(` ${doc.order}. ${doc.title} [${doc.category}]`);
- });
-
- } catch (error) {
- console.error('\nβ Error:', error.message);
- console.error(error.stack);
- process.exit(1);
- } finally {
- if (client) await client.close();
- }
-}
-
-// Run if called directly
-if (require.main === module) {
- main();
-}
-
-module.exports = { main };
diff --git a/scripts/archive-outdated-documents.js b/scripts/archive-outdated-documents.js
deleted file mode 100644
index 65701f32..00000000
--- a/scripts/archive-outdated-documents.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * Archive Outdated Documents
- * Sets visibility: 'archived' for 10 documents identified in audit
- */
-
-const { MongoClient } = require('mongodb');
-
-// MongoDB connection
-const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/tractatus_dev';
-const DB_NAME = process.env.MONGODB_DB || 'tractatus_dev';
-
-// Documents to archive with reasons
-const DOCUMENTS_TO_ARCHIVE = [
- {
- slug: 'introduction-to-the-tractatus-framework',
- category: 'archived',
- archiveNote: 'Superseded by Architectural Overview & Research Status. References outdated filesystem-only architecture.',
- reason: 'Outdated architecture (pre-MongoDB)'
- },
- {
- slug: 'tractatus-based-llm-architecture-for-ai-safety',
- category: 'archived',
- archiveNote: 'Historical architecture proposal. See Architectural Overview for implemented architecture.',
- reason: 'Pre-Phase 5 architecture proposal'
- },
- {
- slug: 'executive-brief-tractatus-based-llm-architecture-for-ai-safety',
- category: 'archived',
- archiveNote: 'Historical brief based on pre-Phase 5 architecture. See Architectural Overview for current status.',
- reason: 'Pre-Phase 5 executive brief'
- },
- {
- slug: 'tractatus-framework-enforcement-for-claude-code',
- category: 'archived',
- archiveNote: 'Development tool documentation. See Implementation Guide for production deployment.',
- reason: 'Internal development tool'
- },
- {
- slug: 'organizational-theory-foundations-of-the-tractatus-framework',
- category: 'archived',
- archiveNote: 'Academic foundations. See Core Concepts for practical overview.',
- reason: 'Academic content, not practical'
- },
- {
- slug: 'phase-5-poc-session-1-summary',
- category: 'project-tracking',
- archiveNote: 'Project tracking - Phase 5 Session 1. See Architectural Overview for complete project history.',
- reason: 'Project tracking'
- },
- {
- slug: 'phase-5-poc-session-2-summary',
- category: 'project-tracking',
- archiveNote: 'Project tracking - Phase 5 Session 2. See Architectural Overview for complete project history.',
- reason: 'Project tracking'
- },
- {
- slug: 'research-scope-feasibility-of-llm-integrated-tractatus-framework',
- category: 'research-proposal',
- archiveNote: 'Research proposal (not completed work). See Architectural Overview for actual implementation status.',
- reason: 'Research proposal'
- },
- {
- slug: 'research-topic-concurrent-session-architecture-limitations-in-claude-code-governance',
- category: 'research-topic',
- archiveNote: 'Open research question. See Architectural Overview for current architecture limitations.',
- reason: 'Open research question'
- },
- {
- slug: 'research-topic-rule-proliferation-and-transactional-overhead-in-ai-governance',
- category: 'research-topic',
- archiveNote: 'Open research question. See Architectural Overview for current governance approach.',
- reason: 'Open research question'
- }
-];
-
-async function main() {
- console.log('=== Archiving Outdated Documents ===\n');
-
- let client;
-
- try {
- // Connect to MongoDB
- console.log('Connecting to MongoDB...');
- client = await MongoClient.connect(MONGODB_URI);
- const db = client.db(DB_NAME);
- const collection = db.collection('documents');
- console.log('β Connected\n');
-
- let archived = 0;
- let notFound = 0;
-
- // Archive each document
- for (const doc of DOCUMENTS_TO_ARCHIVE) {
- console.log(`Archiving: ${doc.slug}`);
- console.log(` Reason: ${doc.reason}`);
-
- const result = await collection.updateOne(
- { slug: doc.slug },
- {
- $set: {
- visibility: 'archived',
- category: doc.category,
- archiveNote: doc.archiveNote,
- order: 999
- }
- }
- );
-
- if (result.matchedCount > 0) {
- console.log(` β Archived\n`);
- archived++;
- } else {
- console.log(` β Not found in database\n`);
- notFound++;
- }
- }
-
- // Summary
- console.log('=== Summary ===\n');
- console.log(`β Archived: ${archived} documents`);
- if (notFound > 0) {
- console.log(`β Not found: ${notFound} documents`);
- }
- console.log(`\nTotal processed: ${DOCUMENTS_TO_ARCHIVE.length}`);
-
- // Verify archives
- console.log('\n=== Verification ===\n');
- const archivedCount = await collection.countDocuments({ visibility: 'archived' });
- const publicCount = await collection.countDocuments({ visibility: 'public' });
- console.log(`Archived documents: ${archivedCount}`);
- console.log(`Public documents: ${publicCount}`);
-
- } catch (error) {
- console.error('\nβ Error:', error.message);
- console.error(error.stack);
- process.exit(1);
- } finally {
- if (client) await client.close();
- }
-}
-
-// Run if called directly
-if (require.main === module) {
- main();
-}
-
-module.exports = { main };
diff --git a/scripts/audit-accessibility.js b/scripts/audit-accessibility.js
deleted file mode 100755
index 840a1a13..00000000
--- a/scripts/audit-accessibility.js
+++ /dev/null
@@ -1,223 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * Accessibility Audit Script
- *
- * Runs automated accessibility checks on all main pages
- * using pa11y (WCAG 2.1 AA standard)
- *
- * Copyright 2025 Tractatus Project
- * Licensed under Apache License 2.0
- */
-
-const pa11y = require('pa11y');
-const fs = require('fs');
-const path = require('path');
-
-const colors = {
- reset: '\x1b[0m',
- bright: '\x1b[1m',
- green: '\x1b[32m',
- yellow: '\x1b[33m',
- red: '\x1b[31m',
- cyan: '\x1b[36m'
-};
-
-function log(message, color = 'reset') {
- console.log(`${colors[color]}${message}${colors.reset}`);
-}
-
-function section(message) {
- console.log('');
- log(`βΆ ${message}`, 'cyan');
-}
-
-function success(message) {
- log(` β ${message}`, 'green');
-}
-
-function warning(message) {
- log(` β ${message}`, 'yellow');
-}
-
-function error(message) {
- log(` β ${message}`, 'red');
-}
-
-// Pages to audit
-const pages = [
- { name: 'Homepage', url: 'http://localhost:9000/' },
- { name: 'Researcher', url: 'http://localhost:9000/researcher.html' },
- { name: 'Implementer', url: 'http://localhost:9000/implementer.html' },
- { name: 'Leader', url: 'http://localhost:9000/leader.html' },
- { name: 'About', url: 'http://localhost:9000/about.html' },
- { name: 'Values', url: 'http://localhost:9000/about/values.html' },
- { name: 'Media Inquiry', url: 'http://localhost:9000/media-inquiry.html' },
- { name: 'Case Submission', url: 'http://localhost:9000/case-submission.html' },
- { name: 'Docs', url: 'http://localhost:9000/docs.html' }
-];
-
-// pa11y configuration
-const pa11yConfig = {
- standard: 'WCAG2AA',
- timeout: 30000,
- wait: 1000,
- chromeLaunchConfig: {
- args: ['--no-sandbox', '--disable-setuid-sandbox']
- },
- // Common issues to ignore (if needed)
- ignore: []
-};
-
-async function auditPage(page) {
- try {
- const results = await pa11y(page.url, pa11yConfig);
-
- return {
- name: page.name,
- url: page.url,
- issues: results.issues,
- error: false
- };
- } catch (err) {
- return {
- name: page.name,
- url: page.url,
- error: true,
- errorMessage: err.message
- };
- }
-}
-
-function categorizeIssues(issues) {
- const categorized = {
- error: [],
- warning: [],
- notice: []
- };
-
- issues.forEach(issue => {
- categorized[issue.type].push(issue);
- });
-
- return categorized;
-}
-
-function printIssue(issue, index) {
- const typeColor = {
- error: 'red',
- warning: 'yellow',
- notice: 'cyan'
- };
-
- console.log('');
- log(` ${index + 1}. [${issue.type.toUpperCase()}] ${issue.message}`, typeColor[issue.type]);
- log(` Code: ${issue.code}`, 'reset');
- log(` Element: ${issue.context.substring(0, 100)}${issue.context.length > 100 ? '...' : ''}`, 'reset');
- log(` Selector: ${issue.selector}`, 'reset');
-}
-
-async function main() {
- log('β'.repeat(70), 'cyan');
- log(' Tractatus Accessibility Audit (WCAG 2.1 AA)', 'bright');
- log('β'.repeat(70), 'cyan');
- console.log('');
-
- const allResults = [];
- let totalErrors = 0;
- let totalWarnings = 0;
- let totalNotices = 0;
-
- for (const page of pages) {
- section(`Auditing: ${page.name}`);
- const result = await auditPage(page);
- allResults.push(result);
-
- if (result.error) {
- error(`Failed to audit: ${result.errorMessage}`);
- continue;
- }
-
- const categorized = categorizeIssues(result.issues);
-
- const errorCount = categorized.error.length;
- const warningCount = categorized.warning.length;
- const noticeCount = categorized.notice.length;
-
- totalErrors += errorCount;
- totalWarnings += warningCount;
- totalNotices += noticeCount;
-
- if (errorCount === 0 && warningCount === 0 && noticeCount === 0) {
- success(`No accessibility issues found!`);
- } else {
- if (errorCount > 0) error(`${errorCount} errors`);
- if (warningCount > 0) warning(`${warningCount} warnings`);
- if (noticeCount > 0) log(` βΉ ${noticeCount} notices`, 'cyan');
-
- // Print first 3 errors/warnings
- const criticalIssues = [...categorized.error, ...categorized.warning].slice(0, 3);
- if (criticalIssues.length > 0) {
- log(' Top issues:', 'bright');
- criticalIssues.forEach((issue, idx) => {
- printIssue(issue, idx);
- });
- }
- }
- }
-
- // Summary
- console.log('');
- log('β'.repeat(70), 'cyan');
- log(' Summary', 'bright');
- log('β'.repeat(70), 'cyan');
- console.log('');
-
- log(` Pages Audited: ${pages.length}`, 'bright');
- log(` Total Errors: ${totalErrors}`, totalErrors > 0 ? 'red' : 'green');
- log(` Total Warnings: ${totalWarnings}`, totalWarnings > 0 ? 'yellow' : 'green');
- log(` Total Notices: ${totalNotices}`, 'cyan');
- console.log('');
-
- // Save detailed report
- const reportPath = path.join(__dirname, '../audit-reports/accessibility-report.json');
- const reportDir = path.dirname(reportPath);
-
- if (!fs.existsSync(reportDir)) {
- fs.mkdirSync(reportDir, { recursive: true });
- }
-
- fs.writeFileSync(reportPath, JSON.stringify({
- timestamp: new Date().toISOString(),
- standard: 'WCAG 2.1 AA',
- summary: {
- pagesAudited: pages.length,
- totalErrors,
- totalWarnings,
- totalNotices
- },
- results: allResults
- }, null, 2));
-
- success(`Detailed report saved: ${reportPath}`);
- console.log('');
-
- // Exit code based on errors
- if (totalErrors > 0) {
- error('Accessibility audit FAILED - errors found');
- process.exit(1);
- } else if (totalWarnings > 0) {
- warning('Accessibility audit PASSED with warnings');
- process.exit(0);
- } else {
- success('Accessibility audit PASSED');
- process.exit(0);
- }
-}
-
-main().catch(err => {
- console.error('');
- error(`Audit failed: ${err.message}`);
- console.error(err.stack);
- process.exit(1);
-});
diff --git a/scripts/check-card-view-status.js b/scripts/check-card-view-status.js
deleted file mode 100644
index 694c5410..00000000
--- a/scripts/check-card-view-status.js
+++ /dev/null
@@ -1,118 +0,0 @@
-const { MongoClient } = require('mongodb');
-
-// The 34 public documents by slug
-const PUBLIC_SLUGS = [
- // Getting Started
- 'introduction',
- 'architectural-safeguards-against-llm-hierarchical-dominance-prose',
- 'core-concepts',
- 'tractatus-ai-safety-framework-core-values-and-principles',
-
- // Technical Reference
- 'technical-architecture',
- 'implementation-guide',
- 'implementation-roadmap-24-month-deployment-plan',
- 'GLOSSARY',
- 'comparison-matrix',
- 'implementation-guide-v1.1',
- 'api-reference-complete',
- 'api-javascript-examples',
- 'api-python-examples',
- 'openapi-specification',
-
- // Theory & Research
- 'executive-summary-tractatus-inflection-point',
- 'architectural-overview-and-research-status',
- 'organizational-theory-foundations',
- 'pluralistic-values-research-foundations',
-
- // Advanced Topics
- 'value-pluralism-faq',
- 'pluralistic-values-deliberation-plan-v2',
-
- // Case Studies
- 'the-27027-incident-a-case-study-in-pattern-recognition-bias',
- 'when-frameworks-fail-and-why-thats-ok',
- 'our-framework-in-action-detecting-and-correcting-ai-fabrications',
- 'real-world-ai-governance-a-case-study-in-framework-failure-and-recovery',
- 'case-studies-real-world-llm-failure-modes',
-
- // Business & Leadership
- 'business-case-tractatus-framework',
-
- // Archives
- 'llm-integration-feasibility-research-scope',
- 'case-studies-real-world-llm-failure-modes-appendix',
- 'implementation-guide-python-examples',
- 'tractatus-framework-enforcement-claude-code',
- 'research-topic-concurrent-session-architecture',
- 'research-topic-rule-proliferation-transactional-overhead',
- 'phase-5-poc-session-1-summary',
- 'phase-5-poc-session-2-summary'
-];
-
-async function checkCardViewStatus() {
- const client = new MongoClient('mongodb://localhost:27017');
-
- try {
- await client.connect();
- const db = client.db('tractatus_dev');
- const collection = db.collection('documents');
-
- console.log(`\n=== CHECKING CARD VIEW STATUS FOR 34 PUBLIC DOCUMENTS ===\n`);
-
- const documents = await collection.find({
- slug: { $in: PUBLIC_SLUGS }
- }).toArray();
-
- console.log(`Found ${documents.length} / ${PUBLIC_SLUGS.length} documents in database\n`);
-
- const withCards = [];
- const withoutCards = [];
- const notFound = [];
-
- PUBLIC_SLUGS.forEach(slug => {
- const doc = documents.find(d => d.slug === slug);
- if (!doc) {
- notFound.push(slug);
- } else if (doc.sections && doc.sections.length > 0) {
- withCards.push({
- slug: doc.slug,
- title: doc.title,
- sections: doc.sections.length,
- category: doc.category || 'none',
- order: doc.order || 999
- });
- } else {
- withoutCards.push({
- slug: doc.slug,
- title: doc.title,
- category: doc.category || 'none',
- order: doc.order || 999
- });
- }
- });
-
- console.log(`β
WITH CARD VIEW (${withCards.length} docs):`);
- withCards.forEach(doc => {
- console.log(` [order:${doc.order}] ${doc.title}`);
- console.log(` slug: ${doc.slug} | sections: ${doc.sections} | category: ${doc.category}`);
- });
-
- console.log(`\nβ WITHOUT CARD VIEW (${withoutCards.length} docs):`);
- withoutCards.forEach(doc => {
- console.log(` [order:${doc.order}] ${doc.title}`);
- console.log(` slug: ${doc.slug} | category: ${doc.category}`);
- });
-
- if (notFound.length > 0) {
- console.log(`\nβ οΈ NOT FOUND IN DATABASE (${notFound.length} slugs):`);
- notFound.forEach(slug => console.log(` ${slug}`));
- }
-
- } finally {
- await client.close();
- }
-}
-
-checkCardViewStatus().catch(console.error);
diff --git a/scripts/check-color-contrast.js b/scripts/check-color-contrast.js
deleted file mode 100755
index 7ec6f72d..00000000
--- a/scripts/check-color-contrast.js
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * Color Contrast Checker
- *
- * Verifies color contrast ratios meet WCAG 2.1 AA standards (4.5:1 normal text, 3:1 large text)
- *
- * Copyright 2025 Tractatus Project
- * Licensed under Apache License 2.0
- */
-
-const colors = {
- reset: '\x1b[0m',
- bright: '\x1b[1m',
- green: '\x1b[32m',
- yellow: '\x1b[33m',
- red: '\x1b[31m',
- cyan: '\x1b[36m'
-};
-
-function log(message, color = 'reset') {
- console.log(`${colors[color]}${message}${colors.reset}`);
-}
-
-function success(message) {
- log(` β ${message}`, 'green');
-}
-
-function warning(message) {
- log(` β ${message}`, 'yellow');
-}
-
-function error(message) {
- log(` β ${message}`, 'red');
-}
-
-/**
- * Convert hex color to RGB
- */
-function hexToRgb(hex) {
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
- return result ? {
- r: parseInt(result[1], 16),
- g: parseInt(result[2], 16),
- b: parseInt(result[3], 16)
- } : null;
-}
-
-/**
- * Calculate relative luminance (WCAG formula)
- */
-function getLuminance(rgb) {
- const rsRGB = rgb.r / 255;
- const gsRGB = rgb.g / 255;
- const bsRGB = rgb.b / 255;
-
- const r = rsRGB <= 0.03928 ? rsRGB / 12.92 : Math.pow((rsRGB + 0.055) / 1.055, 2.4);
- const g = gsRGB <= 0.03928 ? gsRGB / 12.92 : Math.pow((gsRGB + 0.055) / 1.055, 2.4);
- const b = bsRGB <= 0.03928 ? bsRGB / 12.92 : Math.pow((bsRGB + 0.055) / 1.055, 2.4);
-
- return 0.2126 * r + 0.7152 * g + 0.0722 * b;
-}
-
-/**
- * Calculate contrast ratio between two colors
- */
-function getContrastRatio(color1, color2) {
- const rgb1 = hexToRgb(color1);
- const rgb2 = hexToRgb(color2);
-
- const lum1 = getLuminance(rgb1);
- const lum2 = getLuminance(rgb2);
-
- const lighter = Math.max(lum1, lum2);
- const darker = Math.min(lum1, lum2);
-
- return (lighter + 0.05) / (darker + 0.05);
-}
-
-/**
- * Check if contrast ratio meets WCAG AA standards
- */
-function meetsWCAG_AA(ratio, largeText = false) {
- const threshold = largeText ? 3.0 : 4.5;
- return ratio >= threshold;
-}
-
-/**
- * Tailwind color palette (common colors used in Tractatus site)
- */
-const tailwindColors = {
- 'white': '#ffffff',
- 'gray-50': '#f9fafb',
- 'gray-100': '#f3f4f6',
- 'gray-200': '#e5e7eb',
- 'gray-300': '#d1d5db',
- 'gray-400': '#9ca3af',
- 'gray-500': '#6b7280',
- 'gray-600': '#4b5563',
- 'gray-700': '#374151',
- 'gray-800': '#1f2937',
- 'gray-900': '#111827',
- 'blue-50': '#eff6ff',
- 'blue-100': '#dbeafe',
- 'blue-400': '#60a5fa',
- 'blue-500': '#3b82f6',
- 'blue-600': '#2563eb',
- 'blue-700': '#1d4ed8',
- 'blue-800': '#1e40af',
- 'blue-900': '#1e3a8a',
- 'purple-500': '#a855f7',
- 'purple-600': '#9333ea',
- 'purple-700': '#7e22ce',
- 'green-500': '#22c55e',
- 'green-600': '#16a34a',
- 'green-700': '#15803d',
- 'yellow-600': '#ca8a04',
- 'amber-500': '#f59e0b',
- 'amber-800': '#92400e',
- 'amber-900': '#78350f',
- 'red-600': '#dc2626'
-};
-
-/**
- * Color combinations used on site
- */
-const colorCombinations = [
- // Body text on backgrounds
- { name: 'Body text (gray-900 on white)', fg: 'gray-900', bg: 'white', largeText: false },
- { name: 'Body text (gray-700 on white)', fg: 'gray-700', bg: 'white', largeText: false },
- { name: 'Body text (gray-600 on white)', fg: 'gray-600', bg: 'white', largeText: false },
- { name: 'Muted text (gray-500 on white)', fg: 'gray-500', bg: 'white', largeText: false },
-
- // Links
- { name: 'Link (blue-600 on white)', fg: 'blue-600', bg: 'white', largeText: false },
- { name: 'Link hover (blue-700 on white)', fg: 'blue-700', bg: 'white', largeText: false },
-
- // Buttons
- { name: 'Button text (white on blue-600)', fg: 'white', bg: 'blue-600', largeText: false },
- { name: 'Button hover (white on blue-700)', fg: 'white', bg: 'blue-700', largeText: false },
- { name: 'Purple button (white on purple-600)', fg: 'white', bg: 'purple-600', largeText: false },
- { name: 'Green button (white on green-700)', fg: 'white', bg: 'green-700', largeText: false },
-
- // Hero section
- { name: 'Hero subtitle (blue-100 on blue-700)', fg: 'blue-100', bg: 'blue-700', largeText: true },
-
- // Footer
- { name: 'Footer text (gray-400 on gray-900)', fg: 'gray-400', bg: 'gray-900', largeText: false },
- { name: 'Footer links (blue-400 on gray-900)', fg: 'blue-400', bg: 'gray-900', largeText: false },
-
- // Alerts/Messages
- { name: 'Success message (green-900 on green-50)', fg: '#065f46', bg: '#d1fae5', largeText: false },
- { name: 'Error message (red-900 on red-50)', fg: '#991b1b', bg: '#fee2e2', largeText: false },
- { name: 'Warning message (amber-900 on amber-50)', fg: 'amber-900', bg: '#fef3c7', largeText: false },
-
- // Cards/Sections
- { name: 'Card text (gray-700 on white)', fg: 'gray-700', bg: 'white', largeText: false },
- { name: 'Card header (gray-900 on white)', fg: 'gray-900', bg: 'white', largeText: true },
-];
-
-/**
- * Main check
- */
-function main() {
- log('β'.repeat(70), 'cyan');
- log(' Color Contrast Checker (WCAG 2.1 AA)', 'bright');
- log('β'.repeat(70), 'cyan');
- console.log('');
-
- let passCount = 0;
- let failCount = 0;
- let warnings = 0;
-
- colorCombinations.forEach(combo => {
- const fgColor = tailwindColors[combo.fg] || combo.fg;
- const bgColor = tailwindColors[combo.bg] || combo.bg;
-
- const ratio = getContrastRatio(fgColor, bgColor);
- const passes = meetsWCAG_AA(ratio, combo.largeText);
- const threshold = combo.largeText ? '3:1' : '4.5:1';
-
- const ratioStr = ratio.toFixed(2) + ':1';
-
- if (passes) {
- success(`${combo.name.padEnd(45)} ${ratioStr.padStart(8)} (>= ${threshold}) β`);
- passCount++;
- } else {
- // Check if it's close (within 0.3 of threshold)
- const minRatio = combo.largeText ? 3.0 : 4.5;
- if (ratio >= minRatio - 0.3) {
- warning(`${combo.name.padEnd(45)} ${ratioStr.padStart(8)} (< ${threshold}) β `);
- warnings++;
- } else {
- error(`${combo.name.padEnd(45)} ${ratioStr.padStart(8)} (< ${threshold}) β`);
- failCount++;
- }
- }
- });
-
- console.log('');
- log('β'.repeat(70), 'cyan');
- log(' Summary', 'bright');
- log('β'.repeat(70), 'cyan');
- console.log('');
- log(` Combinations Checked: ${colorCombinations.length}`, 'bright');
- log(` Passed: ${passCount}`, 'green');
- if (warnings > 0) log(` Warnings: ${warnings}`, 'yellow');
- if (failCount > 0) log(` Failed: ${failCount}`, 'red');
- console.log('');
-
- if (failCount > 0) {
- error('Some color combinations fail WCAG AA standards');
- console.log('');
- process.exit(1);
- } else if (warnings > 0) {
- warning('All combinations pass, but some are borderline');
- console.log('');
- process.exit(0);
- } else {
- success('All color combinations meet WCAG AA standards');
- console.log('');
- process.exit(0);
- }
-}
-
-main();
diff --git a/scripts/check-csp-violations.js b/scripts/check-csp-violations.js
deleted file mode 100644
index 9bb59360..00000000
--- a/scripts/check-csp-violations.js
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * CSP Violation Scanner
- * Scans HTML and JS files for Content Security Policy violations
- *
- * Violations checked (inst_008):
- * - Inline event handlers (onclick, onload, etc.)
- * - Inline styles (style="...")
- * - Inline scripts ()
- * - javascript: URLs
- *
- * Usage:
- * node scripts/check-csp-violations.js [pattern]
- *
- * Examples:
- * node scripts/check-csp-violations.js
- * node scripts/check-csp-violations.js public
- */
-
-const fs = require('fs');
-const path = require('path');
-const { execSync } = require('child_process');
-
-// Default patterns to scan
-const DEFAULT_PATTERNS = [
- 'public/**/*.html',
- 'public/**/*.js'
-];
-
-// CSP violation patterns
-const VIOLATION_PATTERNS = {
- inline_event_handlers: {
- regex: /\s(on[a-z]+)=["'][^"']*["']/gi,
- description: 'Inline event handler',
- severity: 'HIGH'
- },
- inline_styles: {
- regex: /\sstyle=["'][^"']*["']/gi,
- description: 'Inline style attribute',
- severity: 'HIGH'
- },
- inline_scripts: {
- regex: /`,
- ``,
- `4. Ensure script loads at appropriate time (defer/async if needed)`
- ],
- example: 'See public/js/*.js for existing patterns'
- },
- javascript_urls: {
- priority: 'CRITICAL',
- approach: 'Replace with proper event handlers',
- steps: [
- `1. Remove href="javascript:..." attribute`,
- ``,
- `2. Add event listener in external JS:`,
- ` document.getElementById('link-id').addEventListener('click', function(e) {`,
- ` e.preventDefault();`,
- ` // Action code here`,
- ` });`,
- ``,
- `3. For links that don't navigate, consider using