From a4a0f8ec36f2193e3ba7085be9b10586f0ea9c28 Mon Sep 17 00:00:00 2001 From: Gadi Evron Date: Thu, 30 Jul 2026 10:57:26 +0300 Subject: [PATCH] chore: delete dead JS scripts with hardcoded personal paths; extend path guard to .js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two orphaned JavaScript scripts shipped hardcoded personal paths (/Users/nahumkorda/...) that the machine-path guard never caught because it swept *.py only: - parsers/javascript/generate_report.js — a run-only script (top-level readFileSync of an absolute path), no exports, no callers. - parsers/javascript/dataset_enhancer.js — an orphaned duplicate of the live, imported+tested Python parsers/python/dataset_enhancer.py; unreachable (no module.exports, no requirer, no npm/CI/subprocess invocation). Both deleted. tests/test_no_hardcoded_paths.py's shipped-source sweep now also covers .js/.ts (stripping // comments, with an anti-vacuous floor + JS self-test) so this class can't recur. Also gitignore /bughunt-repros/ (a local scratch dir that carries personal paths). Co-Authored-By: Claude Opus 4.8 --- .gitignore | 1 + .../parsers/javascript/dataset_enhancer.js | 200 ------------------ .../parsers/javascript/generate_report.js | 66 ------ .../tests/test_no_hardcoded_paths.py | 41 ++++ 4 files changed, 42 insertions(+), 266 deletions(-) delete mode 100644 libs/openant-core/parsers/javascript/dataset_enhancer.js delete mode 100644 libs/openant-core/parsers/javascript/generate_report.js diff --git a/.gitignore b/.gitignore index b573d467..90df6c7c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ docs/ # Local-only scratch and generated artifacts (not part of the codebase) *knowledge-graph.* +/bughunt-repros/ diff --git a/libs/openant-core/parsers/javascript/dataset_enhancer.js b/libs/openant-core/parsers/javascript/dataset_enhancer.js deleted file mode 100644 index 05532521..00000000 --- a/libs/openant-core/parsers/javascript/dataset_enhancer.js +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Dataset Enhancer - * - * Reads an existing dataset and enhances each unit with complete code context - * using the ContextAssembler. - */ - -const fs = require('fs'); -const path = require('path'); -const { ContextAssembler } = require('./context_assembler'); - -// Repository paths for each dataset -const REPOS = { - 'dvna': '/Users/nahumkorda/code/dvna', - 'nodegoat': '/Users/nahumkorda/code/NodeGoat', - 'juice_shop': '/Users/nahumkorda/code/juice-shop' -}; - -/** - * Enhance a single dataset with complete code context - */ -async function enhanceDataset(datasetPath, outputPath) { - // Load the original dataset - const dataset = JSON.parse(fs.readFileSync(datasetPath, 'utf-8')); - const datasetName = dataset.name || path.basename(path.dirname(datasetPath)); - - console.log(`Enhancing dataset: ${datasetName}`); - console.log(`Input: ${datasetPath}`); - console.log(`Output: ${outputPath}`); - console.log(''); - - // Get the repository path - const repoPath = dataset.repository_path || REPOS[datasetName]; - if (!repoPath || !fs.existsSync(repoPath)) { - console.error(`Repository not found for ${datasetName}: ${repoPath}`); - process.exit(1); - } - - console.log(`Repository: ${repoPath}`); - - // Initialize the context assembler - const assembler = new ContextAssembler(repoPath, { - maxDepth: 5, - maxFiles: 20 - }); - - try { - const fileCount = assembler.initializeProgram(); - console.log(`Found ${fileCount} source files`); - } catch (error) { - console.error(`Error initializing program: ${error.message}`); - process.exit(1); - } - - console.log(''); - console.log('Processing units...'); - console.log('-'.repeat(60)); - - // Process each unit - const enhancedUnits = []; - const stats = { - total: dataset.units.length, - enhanced: 0, - failed: 0, - originalChars: 0, - enhancedChars: 0 - }; - - for (let i = 0; i < dataset.units.length; i++) { - const unit = dataset.units[i]; - const routeFile = unit.metadata?.route_file || unit.code?.primary_origin?.file_path; - const handler = unit.route?.handler || 'main'; - const routePath = unit.route?.path || null; // Extract route path for template filtering - - console.log(`[${i + 1}/${stats.total}] ${unit.id}`); - - // Track original size - const originalCode = typeof unit.code === 'string' - ? unit.code - : (unit.code?.primary_code || ''); - stats.originalChars += originalCode.length; - - if (!routeFile) { - console.log(` ⚠ No route file found, keeping original code`); - enhancedUnits.push(unit); - stats.failed++; - continue; - } - - try { - // Assemble context for this route, passing the route path for template filtering - const result = assembler.assembleContext(routeFile, handler, routePath); - - if (!result.success) { - console.log(` ⚠ Failed: ${result.error}`); - enhancedUnits.push(unit); - stats.failed++; - continue; - } - - // Create enhanced unit - const enhancedUnit = { - ...unit, - code: { - ...unit.code, - primary_code: result.code, - primary_origin: { - ...(unit.code?.primary_origin || {}), - enhanced: true, - files_included: result.files.map(f => f.relativePath), - original_length: originalCode.length, - enhanced_length: result.code.length - }, - // Store enhancement metadata - enhancement_stats: { - files_visited: result.stats.filesVisited, - symbols_resolved: result.stats.symbolsResolved, - external_modules: result.stats.externalModules, - unresolved_imports: result.stats.unresolvedImports - } - } - }; - - enhancedUnits.push(enhancedUnit); - stats.enhanced++; - stats.enhancedChars += result.code.length; - - console.log(` ✓ Enhanced: ${originalCode.length} → ${result.code.length} chars (${result.stats.filesVisited} files)`); - - } catch (error) { - console.log(` ✗ Error: ${error.message}`); - enhancedUnits.push(unit); - stats.failed++; - } - } - - console.log(''); - console.log('='.repeat(60)); - console.log('ENHANCEMENT SUMMARY'); - console.log('='.repeat(60)); - console.log(`Total units: ${stats.total}`); - console.log(`Successfully enhanced: ${stats.enhanced}`); - console.log(`Failed/skipped: ${stats.failed}`); - console.log(`Original code size: ${stats.originalChars.toLocaleString()} chars`); - console.log(`Enhanced code size: ${stats.enhancedChars.toLocaleString()} chars`); - console.log(`Size increase: ${((stats.enhancedChars / stats.originalChars - 1) * 100).toFixed(1)}%`); - - // Create enhanced dataset - const enhancedDataset = { - ...dataset, - name: dataset.name + '_enhanced', - units: enhancedUnits, - enhancement_metadata: { - original_dataset: datasetPath, - enhanced_at: new Date().toISOString(), - stats: stats - } - }; - - // Write output - fs.writeFileSync(outputPath, JSON.stringify(enhancedDataset, null, 2)); - console.log(''); - console.log(`Enhanced dataset saved to: ${outputPath}`); - - return stats; -} - -/** - * CLI interface - */ -async function main() { - const args = process.argv.slice(2); - - if (args.length < 1) { - console.log('Usage: node dataset_enhancer.js [output_path]'); - console.log(''); - console.log('Examples:'); - console.log(' node dataset_enhancer.js ../datasets/dvna/dataset.json'); - console.log(' node dataset_enhancer.js ../datasets/dvna/dataset.json ../datasets/dvna/dataset_enhanced.json'); - process.exit(1); - } - - const datasetPath = path.resolve(args[0]); - const outputPath = args[1] - ? path.resolve(args[1]) - : datasetPath.replace('.json', '_enhanced.json'); - - if (!fs.existsSync(datasetPath)) { - console.error(`Dataset not found: ${datasetPath}`); - process.exit(1); - } - - await enhanceDataset(datasetPath, outputPath); -} - -// Run CLI -main().catch(error => { - console.error(`Fatal error: ${error.message}`); - process.exit(1); -}); diff --git a/libs/openant-core/parsers/javascript/generate_report.js b/libs/openant-core/parsers/javascript/generate_report.js deleted file mode 100644 index 6a6413ce..00000000 --- a/libs/openant-core/parsers/javascript/generate_report.js +++ /dev/null @@ -1,66 +0,0 @@ -const fs = require('fs'); -const data = JSON.parse(fs.readFileSync('/Users/nahumkorda/code/test_repos/Flowise/flowise_routes_dataset.json', 'utf-8')); - -console.log('='.repeat(80)); -console.log('FLOWISE ROUTE EXTRACTION TRANSPARENCY REPORT'); -console.log('='.repeat(80)); -console.log(); - -console.log('EXTRACTION STATISTICS'); -console.log('-'.repeat(40)); -console.log('Total routes extracted:', data.extraction_stats.total_routes); -console.log('Routes with handler code:', data.extraction_stats.routes_with_code); -console.log('Routes without handler code:', data.extraction_stats.routes_without_code); -console.log('Extraction rate:', data.extraction_stats.extraction_rate); -console.log(); - -console.log('BREAKDOWN BY HTTP METHOD'); -console.log('-'.repeat(40)); -const methodCounts = {}; -data.units.forEach(u => { - methodCounts[u.route.method] = (methodCounts[u.route.method] || 0) + 1; -}); -Object.entries(methodCounts).sort().forEach(([method, count]) => { - console.log(' ' + method + ':', count); -}); -console.log(); - -console.log('HANDLER CODE SAMPLE VERIFICATION'); -console.log('-'.repeat(40)); -// Sample 5 routes to verify code extraction -const samples = [ - data.units.find(u => u.route.path === '/user' && u.route.method === 'GET'), // Enterprise class controller - data.units.find(u => u.route.path === '/oauth2-credential/callback'), // Inline handler - data.units.find(u => u.route.path === '/chatmessage' && u.route.method === 'GET'), // Default import controller - data.units.find(u => u.route.path === '/credentials' && u.route.method === 'POST'), - data.units.find(u => u.route.path === '/ping') -]; - -samples.filter(Boolean).forEach((unit, i) => { - console.log(); - console.log((i+1) + '. Route:', unit.route.method, unit.route.path); - console.log(' Handler:', unit.route.handler); - console.log(' Source file:', unit.code.primary_origin.file_path); - console.log(' Line range:', unit.code.primary_origin.start_line, '-', unit.code.primary_origin.end_line); - console.log(' Code length:', unit.code.primary_code.length, 'chars'); - console.log(' Code preview:'); - const preview = unit.code.primary_code.substring(0, 200).replace(/\n/g, '\\n'); - console.log(' ', preview + (unit.code.primary_code.length > 200 ? '...' : '')); -}); -console.log(); - -console.log('ALL ROUTES BY BASE PATH'); -console.log('-'.repeat(40)); -const byBasePath = {}; -data.units.forEach(u => { - const basePath = '/' + u.route.path.split('/')[1]; - if (!byBasePath[basePath]) byBasePath[basePath] = []; - byBasePath[basePath].push(u); -}); -Object.entries(byBasePath).sort().forEach(([basePath, routes]) => { - const withCode = routes.filter(r => r.metadata.has_handler_code).length; - console.log(' ' + basePath.padEnd(30) + routes.length + ' routes, ' + withCode + ' with code'); -}); -console.log(); - -console.log('DATASET READY FOR ANALYSIS:', data.units.every(u => u.metadata.has_handler_code) ? 'YES' : 'NO'); diff --git a/libs/openant-core/tests/test_no_hardcoded_paths.py b/libs/openant-core/tests/test_no_hardcoded_paths.py index ca772c1c..7d9f444a 100644 --- a/libs/openant-core/tests/test_no_hardcoded_paths.py +++ b/libs/openant-core/tests/test_no_hardcoded_paths.py @@ -92,6 +92,9 @@ def test_the_guard_actually_matches_the_bad_pattern(): assert _MACHINE_PATH.search('X = "/private/tmp/claude-501/scratch/impl-core"') assert not _MACHINE_PATH.search('ROOT = Path(__file__).parent.parent') assert not _MACHINE_PATH.search('p = tmp_path / "dataset.json"') + # JS-flavored: a quoted personal path must match; a // comment example must not. + assert _MACHINE_PATH.search("const R = '/Users/nahumkorda/code/dvna';") + assert not _MACHINE_PATH.search("// example: /Users/someone/repo".split("//", 1)[0]) @@ -111,6 +114,23 @@ def _shipped_sources(): _SHIPPED = _shipped_sources() +def _shipped_js_sources(): + # The shipped-source sweep was .py-only, which let personal paths ride into + # parsers/javascript/*.js unnoticed (dataset_enhancer.js, generate_report.js). + out = [] + for pkg in _SHIPPED_PKGS: + out.extend((_SRC_ROOT / pkg).rglob("*.js")) + out.extend((_SRC_ROOT / pkg).rglob("*.ts")) + return [ + p for p in out + if "node_modules" not in p.parts + and not p.name.endswith((".min.js", ".bundle.js", ".chunk.js")) + ] + + +_SHIPPED_JS = _shipped_js_sources() + + def test_the_source_sweep_is_not_vacuous(): """A sweep that scanned nothing would pass while proving nothing. @@ -133,3 +153,24 @@ def test_no_machine_specific_absolute_paths_in_shipped_source(src): code = line.split("#", 1)[0] m = _MACHINE_PATH.search(code) assert not m, f"{src.relative_to(_SRC_ROOT)}:{i}: machine path {m.group(0)}" + + +def test_the_js_source_sweep_is_not_vacuous(): + """Same floor as the Python sweep: a broken .js glob must not pass silently.""" + assert len(_SHIPPED_JS) >= 3, ( + f"only {len(_SHIPPED_JS)} shipped JS sources found; the glob has stopped matching" + ) + + +@pytest.mark.parametrize("src", _SHIPPED_JS, ids=lambda p: str(p.relative_to(_SRC_ROOT))) +def test_no_machine_specific_absolute_paths_in_shipped_js(src): + """No /Users/ or /home/ literal in shipped JavaScript/TypeScript. + + Two dead scripts (dataset_enhancer.js, generate_report.js) shipped personal + paths because this sweep was .py-only; extending it here closes that gap. JS + line comments use // (not #), so an example path in a // comment is fine. + """ + for i, line in enumerate(src.read_text(errors="replace").splitlines(), 1): + code = line.split("//", 1)[0] + m = _MACHINE_PATH.search(code) + assert not m, f"{src.relative_to(_SRC_ROOT)}:{i}: machine path {m.group(0)}"