First public release
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
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> = {}): 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')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user