#!/usr/bin/env node // L1b 测试: 验证跨域 boost 仲裁顺序无关 + self-auditor 抢回 primary 'use strict'; const path = require('path'); const os = require('os'); const ra = require(path.join(os.homedir(), '.claude', 'scripts', 'route-analyzer.js')); // Mock results: project-audit-expert 高基线分 (BM25 直接命中), self-auditor 虚拟注入低基线 function mkResults() { return [ { name: 'project-audit-expert', score: 1.0, matchedKeywords: [], weights: {} }, { name: 'self-auditor', score: 0.6, _virtual: true, _isAgent: true, matchedKeywords: [], weights: {} }, { name: 'developer-expert', score: 0.4, matchedKeywords: [], weights: {} }, { name: 'review', score: 0.3, matchedKeywords: [], weights: {} } ]; } const queries = [ { q: 'bookworm 系统自检 路由消歧引擎', expectTop: 'self-auditor', desc: 'R81/R84 + R27 同时 fire' }, { q: 'bookworm 全量梳理 工作流', expectTop: 'self-auditor', desc: 'R86 vs R27' } ]; let pass = 0, fail = 0; for (const t of queries) { // 跑 N 次, 验证排名稳定 (顺序无关) const tops = new Set(); for (let i = 0; i < 5; i++) { const r = ra.applyDisambiguation(mkResults(), t.q, { skills: [] }); tops.add(r.results[0].name); } const stable = tops.size === 1; const top = Array.from(tops)[0]; const ok = stable && top === t.expectTop; console.log(`[${ok ? 'PASS' : 'FAIL'}] ${t.desc}`); console.log(` query: ${t.q}`); console.log(` expect top: ${t.expectTop}, got: ${top} (stable: ${stable})`); if (ok) pass++; else fail++; // 详细分数 dump const r = ra.applyDisambiguation(mkResults(), t.q, { skills: [] }); console.log(' fired rules:', r.firedRules.join(',')); console.log(' top 3 scores:', r.results.slice(0, 3).map(x => `${x.name}=${x.score.toFixed(3)}${x._arbitratedBy ? '(arb<-' + x._arbitratedBy + ')' : ''}` ).join(', ')); } console.log(`\n=== ${pass} pass, ${fail} fail ===`); process.exit(fail > 0 ? 1 : 0);