397777089e
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
46 lines
2.0 KiB
JavaScript
46 lines
2.0 KiB
JavaScript
// tools/judge-anchor.test.mjs
|
|
import { describe, it, expect } from 'vitest';
|
|
import { classifyObjection, partitionObjections, ANCHOR_KINDS } from './judge-anchor.mjs';
|
|
|
|
describe('classifyObjection (§9.3 anchor gate)', () => {
|
|
it('anchored objection (valid kind + ref) → can block', () => {
|
|
const r = classifyObjection({ text: 'X не закрыто', anchor: { kind: 'spec_section', ref: '§3' } });
|
|
expect(r.anchored).toBe(true);
|
|
expect(r.disposition).toBe('block');
|
|
});
|
|
it('every valid anchor kind is accepted', () => {
|
|
for (const kind of ANCHOR_KINDS) {
|
|
expect(classifyObjection({ text: 't', anchor: { kind, ref: 'r' } }).anchored).toBe(true);
|
|
}
|
|
});
|
|
it('anchorless objection → demoted to advice (not silenced)', () => {
|
|
const r = classifyObjection({ text: 'вообще тревожно' });
|
|
expect(r.anchored).toBe(false);
|
|
expect(r.disposition).toBe('advice');
|
|
});
|
|
it('invalid anchor kind → not anchored → advice', () => {
|
|
expect(classifyObjection({ text: 't', anchor: { kind: 'vibes', ref: 'x' } }).disposition).toBe('advice');
|
|
});
|
|
it('anchor present but empty ref → not anchored → advice', () => {
|
|
expect(classifyObjection({ text: 't', anchor: { kind: 'test_name', ref: ' ' } }).disposition).toBe('advice');
|
|
});
|
|
});
|
|
|
|
describe('partitionObjections (both-ways gate)', () => {
|
|
it('splits into blocking (anchored) and advisory (anchorless)', () => {
|
|
const objs = [
|
|
{ text: 'a', anchor: { kind: 'failed_criterion', ref: 'tY' } },
|
|
{ text: 'b' },
|
|
{ text: 'c', anchor: { kind: 'card_need', ref: 'frontend.mobile' } },
|
|
];
|
|
const r = partitionObjections(objs);
|
|
expect(r.blocking).toHaveLength(2);
|
|
expect(r.advisory).toHaveLength(1);
|
|
});
|
|
it('a ghost NO with no anchor never reaches the blocking set', () => {
|
|
const r = partitionObjections([{ text: 'НЕТ, не нравится', verdict: 'NO' }]);
|
|
expect(r.blocking).toEqual([]);
|
|
expect(r.advisory).toHaveLength(1);
|
|
});
|
|
});
|