import { describe, expect, it } from 'vitest' import { overall, validateReport } from '@extant2000/evidence-record' import { assessLog, formatLog, repeatOffenders, type Deviation } from '../src/index.js' const dev = (p: Partial = {}): Deviation => ({ id: 'd1', procedure: 'septic-install', step: 'step-7 backfill compaction', operator: 'crew-a', what: 'compacted in one lift instead of three', where: 'work order 4412', ...p, }) describe('a logged deviation is not a handled one', () => { it('reports an unadjudicated deviation as not-assessed', () => { const r = assessLog([dev()]) expect(r.findings[0]!.determination).toBe('not-assessed') expect(r.findings[0]!.detail).toContain('an entry in a list, not a finding') expect(overall(r)).toBe('not-assessed') }) it('fails an adjudicated deviation with no action — the open loop', () => { const r = assessLog([dev({ cause: 'procedure-defect' })]) expect(r.findings[0]!.determination).toBe('fail') expect(r.findings[0]!.severity).toBe('critical') expect(r.findings[0]!.detail).toContain('looks handled because someone wrote it down') }) it('fails while the action is still open', () => { const r = assessLog([dev({ cause: 'procedure-defect', action: { description: 'rewrite step 7 for single-lift equipment', status: 'open' }, })]) expect(r.findings[0]!.determination).toBe('fail') expect(r.findings[0]!.detail).toContain('the next crew meets the same step unchanged') }) it('passes only when the action is applied', () => { const r = assessLog([dev({ cause: 'procedure-defect', action: { description: 'rewrite step 7', appliedTo: 'SOP-114 rev C', status: 'applied' }, })]) expect(overall(r)).toBe('pass') expect(formatLog([dev({ cause: 'procedure-defect', action: { description: 'rewrite step 7', appliedTo: 'SOP-114 rev C', status: 'applied' }, })], { evidence: 'full' })).toContain('SOP-114 rev C') }) it('records a rejection as not-applicable and still prints it', () => { // Printed so a rejection can be reviewed when the same step recurs. const r = assessLog([dev({ cause: 'environment', action: { description: 'no change — frozen ground is seasonal', status: 'rejected' }, })]) expect(r.findings[0]!.determination).toBe('not-applicable') expect(formatLog([dev({ cause: 'environment', action: { description: 'no change — frozen ground is seasonal', status: 'rejected' }, })])).toContain('frozen ground is seasonal') }) }) describe('repeat deviations indict the procedure, not the operator', () => { const closedAsError = (id: string, operator: string): Deviation => dev({ id, operator, cause: 'execution-error', action: { description: 'retrained operator', status: 'applied' }, }) const repeated = [ closedAsError('d1', 'crew-a'), closedAsError('d2', 'crew-b'), closedAsError('d3', 'crew-c'), ] it('counts DISTINCT operators, not incidents', () => { // One person five times is a conversation. Five people once each is the step. const sameGuy = [ closedAsError('d1', 'crew-a'), closedAsError('d2', 'crew-a'), closedAsError('d3', 'crew-a'), ] expect(repeatOffenders(sameGuy)).toEqual([]) expect(repeatOffenders(repeated)).toHaveLength(1) expect(repeatOffenders(repeated)[0]!.operators).toEqual(['crew-a', 'crew-b', 'crew-c']) }) it('THE POINT: every incident closed clean, and the procedure is still indicted', () => { // Each entry says "execution error, retrained, applied" — individually a // pass. The aggregate is the only thing that sees the defect. const r = assessLog(repeated) expect(r.findings.filter(f => f.id.startsWith('repeat/'))).toHaveLength(1) expect(overall(r)).toBe('fail') const repeat = r.findings.find(f => f.id.startsWith('repeat/'))! expect(repeat.severity).toBe('critical') expect(repeat.detail).toContain('the mechanism by which a defective procedure survives') }) it('leads with the aggregate, above the individual entries', () => { const text = formatLog(repeated) expect(text.indexOf('deviated from by 3 different operators')) .toBeLessThan(text.indexOf('closed: retrained operator')) }) it('does not group across different steps of the same procedure', () => { expect(repeatOffenders([ dev({ id: 'd1', operator: 'a', step: 'step-7' }), dev({ id: 'd2', operator: 'b', step: 'step-9' }), ])).toEqual([]) }) it('honours a custom operator threshold', () => { expect(repeatOffenders(repeated, { minOperators: 4 })).toEqual([]) expect(repeatOffenders(repeated, { minOperators: 3 })).toHaveLength(1) }) }) describe('conformance with the evidence-record standard', () => { it('an empty log is not-assessed, and says what empty means', () => { const r = assessLog([]) expect(overall(r)).toBe('not-assessed') expect(formatLog([])).toContain('evidence that none were written down') }) it('every conclusion carries a citation', () => { expect(validateReport(assessLog([ dev({ id: 'd1', cause: 'procedure-defect' }), dev({ id: 'd2', operator: 'crew-b', cause: 'execution-error', action: { description: 'x', status: 'applied' } }), ]))).toEqual([]) }) it('cites the work order behind each deviation', () => { expect(formatLog([dev({ cause: 'procedure-defect' })], { evidence: 'full' })) .toContain('deviations#d1') }) })