agents-root-single-holder.test.js 3.5 KB
/**
 * 「本体根目录」这个事实只能有一个持有者:`agent-locator.AGENTS_ROOT`。
 *
 * 为什么需要这条元测试(28 号改造的直接教训):
 * 28 号把本体根从 `system/templates/` 搬到 `system/agents/`,搬之前这个路径在
 * 5 个文件里被硬编码了 12 份(`server/routes/company.js` 一个文件里就有 9 份 ——
 * 6 个 `TEMPLATES_DIR` + 3 个 `DATA_DIR`,只有 1 处用了权威访问器)。
 *
 * 12 份副本的危害不是「不好看」,而是**下一次再搬时改 11 处、漏 1 处**:
 * 漏掉的那处会指向一个不存在的目录,而本仓库读这类路径几乎都包在
 * `fs.existsSync()` 守卫里 —— 目录没了不报错,只是静默跳过(并行会话在
 * `scripts/demo-harness-company.js` 实测过这个形状:base 本体没挂上,
 * demo 跑出来的 agent 没有四段式骨架,脚本照常打印成功)。
 *
 * 同一个病在本仓库已有多个实例:`canDispatch` 的取值域被前端复述过一份、
 * `ACTIVE_ROOT_RUN_STATUS` 在两个文件里逐字重复、`isUngraduatedStatus()` 的取值域
 * 一度按「≠ active 就挡」判而误伤 36 个本体。**同一个事实只能有一处持有者 —— 路径也是事实。**
 */

const fs = require('fs');
const path = require('path');

const REPO_ROOT = path.resolve(__dirname, '../../..');

/** 只扫真正会被执行的源码,跳过依赖、构建产物、测试自身与 locator 本身 */
const SCAN_DIRS = ['server', 'packages', 'scripts'];
const SKIP_DIR = /(^|\/)(node_modules|dist|\.git|coverage)(\/|$)/;
const SKIP_FILE = /\.test\.js$|agent-locator\.js$/;

/**
 * 「拼出本体根目录」的形状:path.resolve/join 里出现以 ../ 开头、以 system/agents 结尾的字面量。
 * 只认路径构造,不认注释里提到的字符串 —— 注释里写 `system/agents/` 是正常的文档行为。
 */
const HARDCODED = /path\.(?:resolve|join)\([^)]*['"`][^'"`]*\.\.\/[^'"`]*system\/agents['"`]/;

function walk(dir, out = []) {
  let entries;
  try {
    entries = fs.readdirSync(dir, { withFileTypes: true });
  } catch {
    return out; // 目录不存在(如仓库裁剪过)就跳过,不让本测试成为噪声源
  }
  for (const e of entries) {
    const full = path.join(dir, e.name);
    if (SKIP_DIR.test(full)) continue;
    if (e.isDirectory()) walk(full, out);
    else if (e.name.endsWith('.js') && !SKIP_FILE.test(e.name)) out.push(full);
  }
  return out;
}

describe('本体根目录只有一个持有者(28 §5.1)', () => {
  const files = SCAN_DIRS.flatMap((d) => walk(path.join(REPO_ROOT, d)));

  it('扫描样本非空 —— 防止路径写错时本测试退化成永远通过', () => {
    // 没有这一条,上面 walk() 的容错会让「一个文件都没扫到」表现为全绿。
    expect(files.length).toBeGreaterThan(100);
  });

  it('没有任何文件自己拼 system/agents 根路径(一律走 locator.AGENTS_ROOT)', () => {
    const offenders = [];
    for (const f of files) {
      const src = fs.readFileSync(f, 'utf-8');
      src.split('\n').forEach((line, i) => {
        if (HARDCODED.test(line)) {
          offenders.push(`${path.relative(REPO_ROOT, f)}:${i + 1} → ${line.trim()}`);
        }
      });
    }
    expect(offenders).toEqual([]);
  });

  it('locator.AGENTS_ROOT 指向真实存在的目录', () => {
    const { AGENTS_ROOT } = require('../../services/agent-locator');
    expect(fs.existsSync(AGENTS_ROOT)).toBe(true);
    expect(path.basename(AGENTS_ROOT)).toBe('agents');
  });
});