Ctrl K
ComunidadGuías…

__tests__/readiness.test.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/*
 * THE READINESS ENGINE, AND THE CONFIDENT WRONG ANSWERS IT MUST NOT GIVE.
 *
 * A screen that says "ready" over blind data trains a model that collapses; one that says "not
 * ready" over a good set because `hover` has no examples never trains anything. Each test is one
 * of those two mistakes.
 */
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import fs from 'fs';
import os from 'os';
import path from 'path';
import readiness from '../src/readiness.js';
import coverage from '../src/coverage.js';

const { scoreOf } = readiness;

const cov = (over = {}) => ({
  total: 5000, sighted: 1000,
  perTool: { look: { all: 1500, sighted: 200, gold: 150 }, read: { all: 1200, sighted: 200, gold: 150 }, open: { all: 1000, sighted: 200, gold: 150 }, finish: { all: 300, sighted: 200, gold: 150 }, dig: { all: 200, sighted: 200, gold: 100 } },
  sightedTiers: { gold: 700, silver: 250, bronze: 50, void: 0 },
  ...over,
});

describe('the six checks', () => {
  it('is ready when every gate passes, and says so', () => {
    const r = scoreOf({ coverage: cov(), exam: { overlap: 0 }, sliceTurns: 440 });
    expect(r.ok).toBe(true);
    expect(r.why).toMatch(/ready/);
    expect(r.checks.map((c) => c.name)).toEqual(['sight', 'coverage', 'balance', 'labels', 'freshness', 'exam']);
  });

  it('refuses a set that cannot see its pages, in the planner\'s own words', () => {
    const r = scoreOf({ coverage: cov({ sighted: 98 }), exam: { overlap: 0 }, sliceTurns: 440 });
    expect(r.ok).toBe(false);
    expect(r.why).toMatch(/only 98 turn/);
    expect(r.checks[0].score).toBe(22);
  });

  it('does NOT stop the first round over a tool with no examples, but names it for the collector', () => {
    const r = scoreOf({ coverage: cov(), exam: { overlap: 0 }, catalogue: ['look', 'read', 'open', 'finish', 'dig', 'hover', 'type'] });
    expect(r.ok).toBe(true);
    expect(r.aim).toEqual(['hover', 'type']);
    expect(r.checks.find((c) => c.name === 'coverage').ok).toBe(false);
  });

  it('DOES stop a round over coverage once something is serving', () => {
    const r = scoreOf({ coverage: cov(), exam: { overlap: 0 }, catalogue: ['look', 'hover'], serving: { adapter: 'x' }, corpus: { usableSinceLastRound: 500 } });
    expect(r.ok).toBe(false);
    expect(r.why).toMatch(/fewer than 4 sighted/);
  });

  it('refuses a set that is mostly the model\'s own word', () => {
    const r = scoreOf({ coverage: cov({ sightedTiers: { gold: 200, silver: 800, bronze: 0 } }), exam: { overlap: 0 } });
    expect(r.ok).toBe(false);
    expect(r.why).toMatch(/only 20% of the sighted turns are gold/);
  });

  it('refuses an exam that overlaps the train set', () => {
    const r = scoreOf({ coverage: cov(), exam: { overlap: 3 } });
    expect(r.ok).toBe(false);
    expect(r.why).toMatch(/3 exam job/);
  });

  it('wants new runs only once something is serving', () => {
    expect(scoreOf({ coverage: cov(), exam: { overlap: 0 }, corpus: { usableSinceLastRound: 0 } }).ok).toBe(true);
    const r = scoreOf({ coverage: cov(), exam: { overlap: 0 }, corpus: { usableSinceLastRound: 12 }, serving: { adapter: 'x' } });
    expect(r.ok).toBe(false);
    expect(r.why).toMatch(/only 12 new usable/);
  });

  it('scores the weakest check, never an average', () => {
    /* Half the slice sighted scores sight at 50; but with only 220 sighted turns the loudest tool
       owns 91% of them, so balance is weaker still - and the weakest one is the score. */
    const r = scoreOf({ coverage: cov({ sighted: 220 }), exam: { overlap: 0 }, sliceTurns: 440 });
    expect(r.checks.find((c) => c.name === 'sight').score).toBe(50);
    expect(r.score).toBe(Math.min(...r.checks.map((c) => c.score)));
    expect(r.score).toBeLessThan(50);
  });

  it('survives an empty set', () => {
    const r = scoreOf({});
    expect(r.ok).toBe(false);
    expect(r.score).toBe(0);
  });
});

describe('reading coverage off the set', () => {
  let dir;
  beforeEach(() => { dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gb-cov-')); });
  afterEach(() => { try { fs.rmSync(dir, { recursive: true, force: true }); } catch { /* gone */ } });

  const line = (tool, { sighted = false, tier = 'gold', job = 'j1' } = {}) => JSON.stringify({
    messages: [{ role: 'system', content: 's' }, { role: 'user', content: 'u' }, { role: 'assistant', content: JSON.stringify({ tool, args: {} }) }],
    meta: { jobId: job, tier, grade: tier, verified: [], role: 'general', at: 'x', sighted },
  });

  it('counts per tool, sighted and blind, and the tiers of the sighted ones', () => {
    const p = path.join(dir, 'train.jsonl');
    fs.writeFileSync(p, [line('look', { sighted: true }), line('look'), line('open', { sighted: true, tier: 'silver', job: 'j2' }), ''].join('\n'));
    const c = coverage.scan(p);
    expect(c.total).toBe(3);
    expect(c.sighted).toBe(2);
    expect(c.perTool.look).toEqual({ all: 2, sighted: 1, gold: 1 });
    expect(c.perTool.open).toEqual({ all: 1, sighted: 1, gold: 0 });
    expect(c.sightedTiers.gold).toBe(1);
    expect(c.sightedTiers.silver).toBe(1);
    expect([...c.jobIds].sort()).toEqual(['j1', 'j2']);
  });

  it('finds an exam job that leaked into the train set', () => {
    const t = path.join(dir, 'train.jsonl'); const e = path.join(dir, 'eval.jsonl');
    fs.writeFileSync(t, [line('look', { job: 'a' }), line('open', { job: 'b' })].join('\n'));
    fs.writeFileSync(e, [line('look', { job: 'b' }), line('open', { job: 'c' })].join('\n'));
    expect(coverage.overlap(coverage.scan(t), coverage.scan(e))).toBe(1);
  });

  it('caches by the file, and re-reads when the file changes', () => {
    const p = path.join(dir, 'train.jsonl');
    fs.writeFileSync(p, line('look'));
    expect(coverage.cached(p).total).toBe(1);
    fs.writeFileSync(p, [line('look'), line('read'), line('open')].join('\n'));
    const s = fs.statSync(p); fs.utimesSync(p, s.atime, new Date(s.mtimeMs + 5000));
    expect(coverage.cached(p).total).toBe(3);
    expect(coverage.summary(coverage.cached(p)).perTool.length).toBe(3);
  });
});