tractatus/scripts/check-confidential-docs.js
TheFlow 8021197bf0 fix(deployment): only block files with explicit confidential markers, not filename patterns
- Removed filename pattern checks (session-handoff, draft, etc.)
- Now only blocks files with content markers: [INTERNAL], [CONFIDENTIAL], [DO NOT PUBLISH]
- Allows session handoff and internal documentation in docs/ directory
- Still blocks actual credentials and sensitive content

Rationale: Filename patterns were too broad and blocked legitimate internal documentation.
Session handoffs are fine in docs/ as long as they don't contain actual sensitive data.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-26 23:19:18 +13:00

151 lines
4.3 KiB
JavaScript
Executable file

#!/usr/bin/env node
/**
* Confidential Document Scanner - Enforces inst_012, inst_015
* Prevents deployment of internal/confidential documents
*/
const fs = require('fs');
const path = require('path');
// File patterns that indicate confidential/internal documents
const CONFIDENTIAL_PATTERNS = [
/session[-_]?handoff/i,
/phase[-_]?planning/i,
/cost[-_]?estimate/i,
/infrastructure[-_]?plan/i,
/progress[-_]?report/i,
/cover[-_]?letter/i,
/testing[-_]?checklist/i,
/internal/i,
/confidential/i,
/private/i,
/draft/i,
/wip[-_]/i, // work in progress
/todo/i
];
// Content markers that indicate confidential information
const CONFIDENTIAL_CONTENT_MARKERS = [
/\[INTERNAL\]/i,
/\[CONFIDENTIAL\]/i,
/\[DRAFT\]/i,
/\[DO NOT PUBLISH\]/i,
/\[WIP\]/i,
/CONFIDENTIAL:/i,
/INTERNAL ONLY:/i
];
function checkFilePath(filePath) {
const basename = path.basename(filePath);
for (const pattern of CONFIDENTIAL_PATTERNS) {
if (pattern.test(basename) || pattern.test(filePath)) {
return {
confidential: true,
reason: `Filename matches confidential pattern: ${pattern.source}`
};
}
}
return { confidential: false };
}
function checkFileContent(filePath) {
try {
const content = fs.readFileSync(filePath, 'utf8');
const lines = content.split('\n');
for (let i = 0; i < Math.min(20, lines.length); i++) {
for (const marker of CONFIDENTIAL_CONTENT_MARKERS) {
if (marker.test(lines[i])) {
return {
confidential: true,
reason: `Content contains confidential marker at line ${i+1}: ${marker.source}`,
line: i + 1,
text: lines[i].trim()
};
}
}
}
return { confidential: false };
} catch (err) {
// Can't read file (binary, etc.) - check by path only
return { confidential: false };
}
}
function scanFile(filePath) {
// Skip non-document files
const ext = path.extname(filePath).toLowerCase();
if (!['.md', '.txt', '.pdf', '.doc', '.docx', '.html'].includes(ext)) {
return null;
}
// ONLY check content markers, not filename patterns
// Rationale: Session handoffs and internal docs are fine in docs/ directory
// as long as they don't contain actual sensitive content (credentials, etc.)
// Filename patterns are too broad and catch legitimate internal documentation
const contentCheck = checkFileContent(filePath);
if (contentCheck.confidential) {
return { file: filePath, ...contentCheck };
}
return null;
}
function main() {
const args = process.argv.slice(2);
if (args.length === 0) {
console.log('Usage: check-confidential-docs.js <file1> [file2] ...');
console.log('');
console.log('Scans files to prevent deployment of internal/confidential documents');
process.exit(0);
}
console.log(`\n🔍 Scanning ${args.length} file(s) for confidential markers...\n`);
const findings = [];
args.forEach(file => {
if (!fs.existsSync(file)) return;
const result = scanFile(file);
if (result) {
findings.push(result);
}
});
if (findings.length === 0) {
console.log('✅ No confidential documents detected\n');
process.exit(0);
}
// Report findings
console.log(`❌ Found ${findings.length} confidential document(s):\n`);
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
findings.forEach(f => {
console.log(`🔴 ${f.file}`);
console.log(` Reason: ${f.reason}`);
if (f.text) {
console.log(` Line ${f.line}: ${f.text.substring(0, 60)}...`);
}
console.log('');
});
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
console.log('⚠️ DEPLOYMENT BLOCKED (inst_012/inst_015)\n');
console.log('These documents are marked confidential/internal.');
console.log('');
console.log('Actions:');
console.log(' 1. Remove confidential markers if approved for public release');
console.log(' 2. Move to a non-public directory');
console.log(' 3. Get explicit human approval before deploying\n');
process.exit(1);
}
main();