feat(ai-psychosis): report-reader v1.2 schema + aggregations

This commit is contained in:
Kjell Tore Guttormsen 2026-05-01 21:47:53 +02:00
commit f88639ef41
2 changed files with 134 additions and 1 deletions

View file

@ -85,6 +85,61 @@ test('v1.2 array domain_context aggregates correctly (relationship in array)', (
assert.equal(result.null_domain_count, 1, 'empty array counts as null');
});
test('v1.2 mixed schema fixture: per-domain breakdown + user_info_class + valseek', () => {
const fixture = [
// v1.0 — no pushback flag, no domain_context
{ session_id: 'v0', duration_min: 30,
flags: { dependency: 0, escalation: 0, fatigue: 0, validation: 0 } },
// v1.1 — pushback flag, string domain
{ session_id: 'v1', duration_min: 30, domain_context: 'relationship',
flags: { dependency: 0, escalation: 0, fatigue: 0, validation: 0, pushback: 1 } },
// v1.2 — multi-domain array, user_info_class, valseek_count
{ session_id: 'v2a', duration_min: 30,
domain_context: ['relationship', 'health'],
user_info_class: 'no', valseek_count: 3, turn_count: 20,
flags: { dependency: 0, escalation: 0, fatigue: 0, validation: 0, pushback: 2 } },
{ session_id: 'v2b', duration_min: 30,
domain_context: ['legal'],
user_info_class: 'yes_people', valseek_count: 0, turn_count: 8,
flags: { dependency: 0, escalation: 0, fatigue: 0, validation: 0, pushback: 0 } },
{ session_id: 'v2c', duration_min: 30,
domain_context: [],
user_info_class: null, valseek_count: 0, turn_count: 5,
flags: { dependency: 0, escalation: 0, fatigue: 0, validation: 0, pushback: 0 } },
];
const jsonl = fixture.map(o => JSON.stringify(o)).join('\n') + '\n';
const result = runReader(jsonl);
// schema_version discrimination
assert.equal(result.schema_version.v1_0_records, 1);
assert.equal(result.schema_version.v1_1_records, 1);
assert.equal(result.schema_version.v1_2_records, 3);
// per-domain breakdown (only v1.x array members)
assert.equal(result.domain_breakdown.relationship, 2,
'v1.1 string + v1.2 array containing relationship → 2');
assert.equal(result.domain_breakdown.health, 1);
assert.equal(result.domain_breakdown.legal, 1);
assert.equal(result.domain_breakdown.parenting, 0);
// user_info_class distribution
assert.equal(result.user_info_class.no, 1);
assert.equal(result.user_info_class.yes_people, 1);
assert.equal(result.user_info_class.null, 1);
// valseek aggregation
assert.equal(result.valseek.sessions, 1);
assert.equal(result.valseek.total, 3);
// stakes_signal — max weight per session
// v2a: max(relationship=1.3, health=1.5) = 1.5
// v2b: legal=1.5
// v2c: empty → not counted
assert.equal(result.stakes_signal.sessions, 2);
assert.ok(Math.abs(result.stakes_signal.sum - 3.0) < 0.01,
`expected stakes_signal.sum ~3.0, got ${result.stakes_signal.sum}`);
});
test('backward-compat: v1.0.0 records without pushback/domain do not produce NaN', () => {
const fixture = [
// v1.0.0 — no pushback in flags, no domain_context at top level