Implements 7 additional architectural enforcement mechanisms: ✅ Prohibited Terms Detection (inst_016/017/018): - scripts/check-prohibited-terms.js - Scans for absolute assurance terms ("guarantee", "100% secure") - Detects maturity claims without evidence ("production-ready", "battle-tested") - Checks statistics require citation or [NEEDS VERIFICATION] - Integrated into .git/hooks/pre-commit (Check 2) ✅ Credential Exposure Prevention (inst_069/070): - scripts/check-credential-exposure.js - Detects real API keys, secrets, passwords in documentation - Validates example credentials use proper patterns (EXAMPLE/REDACTED) - CRITICAL: Runs first in pre-commit (Check 0) ✅ Confidential Document Protection (inst_012/015): - scripts/check-confidential-docs.js - Prevents deployment of internal/session-handoff documents - Scans filenames and content for [CONFIDENTIAL]/[INTERNAL] markers - Integrated into scripts/deploy.sh pre-flight checks ✅ Enhanced Pre-Commit Hook: Now runs 4 checks in order: 0. Credential exposure (CRITICAL) 1. CSP compliance 2. Prohibited terms 3. Test requirements ✅ Enhanced Deployment Script: - Added confidential document check to deploy.sh - Scans public/ and docs/ before deployment - Blocks deployment if confidential markers found ✅ Updated Enforcement Map: - Added all new mechanisms to audit-enforcement.js - Updated inst_008_CONSOLIDATED mapping - New mappings: inst_012, inst_015, inst_016, inst_017, inst_018, inst_069, inst_070 📊 Enforcement Progress: - Wave 1: 11/39 imperative instructions enforced (28%) - Wave 2: 18/39 imperative instructions enforced (46%) - Improvement: +7 instructions = +64% increase - Remaining gaps: 21/39 (54%) 🎯 Next Priority Gaps: - inst_013/043/045: API security validation - inst_019: Context pressure comprehensive accounting - inst_025: Deployment file mapping - inst_039/040: Batch operation verification - inst_079/080/081: Values/principles (process-based) 🔒 Security Posture: - CRITICAL security checks now run first (credential exposure) - All text files scanned before commit - All deployment candidates scanned before rsync 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
153 lines
4.1 KiB
JavaScript
Executable file
153 lines
4.1 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;
|
|
}
|
|
|
|
// Check filename
|
|
const pathCheck = checkFilePath(filePath);
|
|
if (pathCheck.confidential) {
|
|
return { file: filePath, ...pathCheck };
|
|
}
|
|
|
|
// Check content
|
|
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();
|