import { describe, expect, it } from 'vitest' import { overall, validateReport } from '@extant2000/evidence-record' import { formatReplan, replan, toReport, type Assumption, type Plan } from '../src/index.js' const disk = (p: Partial = {}): Assumption => ({ id: 'disk-headroom', description: 'the host has room for the new image', condition: 'disk free bytes', comparison: 'at-least', required: 5_000_000_000, observed: 20_000_000_000, where: 'df -P /var/lib/docker', ...p, }) const plan = (assumptions: Assumption[]): Plan => ({ name: 'suite rollout', assumptions }) describe('a plan that records no assumptions cannot be invalidated', () => { it('holds rather than proceeding', () => { const d = replan(plan([])) expect(d.decision).toBe('hold') expect(d.reason).toContain('cannot be invalidated cannot be trusted') expect(overall(toReport(plan([])))).toBe('not-assessed') }) }) describe('unread is not fine', () => { it('holds — not proceeds — when a condition was never re-measured', () => { const d = replan(plan([disk(), disk({ id: 'registry', observed: null })])) expect(d.decision).toBe('hold') expect(d.reason).toContain('decision taken on unread conditions') expect(d.unverified.map(a => a.id)).toEqual(['registry']) }) it('reports the unread condition as not-assessed', () => { const r = toReport(plan([disk({ observed: null })])) expect(r.findings[0]!.determination).toBe('not-assessed') expect(r.findings[0]!.detail).toContain('"We did not look" is not "it is fine"') }) it('refuses to order non-numeric values lexically', () => { // A string comparison would silently pass or fail on lexical order, // which is not what the plan meant. const r = toReport(plan([disk({ condition: 'window state', comparison: 'at-least', required: 'open', observed: 'closing', })])) expect(r.findings[0]!.determination).toBe('not-assessed') expect(r.findings[0]!.detail).toContain('rather than compared lexically') }) it('compares equality on non-numeric values happily', () => { const ok = disk({ condition: 'window', comparison: 'equals', required: 'open', observed: 'open' }) expect(replan(plan([ok])).decision).toBe('proceed') }) }) describe('a fallback without a floor cannot fail', () => { const broken = disk({ observed: 1_000_000_000 }) it('stops on a broken assumption whose fallback has no floor', () => { const d = replan(plan([{ ...broken, fallback: { description: 'reduce concurrency and continue' } }])) expect(d.decision).toBe('stop') const r = toReport(plan([{ ...broken, fallback: { description: 'reduce concurrency and continue' } }])) expect(r.findings[0]!.severity).toBe('critical') expect(r.findings[0]!.detail).toContain('a way of never stopping') }) it('pivots when the fallback states a floor', () => { const d = replan(plan([{ ...broken, fallback: { description: 'reduce concurrency to 1', floor: 'stop below 500 MB free' }, }])) expect(d.decision).toBe('pivot') expect(d.reason).toContain('reduce concurrency to 1') }) it('stops on a broken assumption with no fallback at all', () => { const d = replan(plan([broken])) expect(d.decision).toBe('stop') expect(toReport(plan([broken])).findings[0]!.detail) .toContain('rather than proceeding on an assumption known to be false') }) it('a broken assumption outranks an unread one in the decision', () => { // Stop is more urgent than hold. const d = replan(plan([broken, disk({ id: 'x', observed: null })])) expect(d.decision).toBe('stop') }) }) describe('proceed', () => { it('proceeds only when every assumption was re-checked and holds', () => { const d = replan(plan([disk(), disk({ id: 'registry', condition: 'registry reachable', comparison: 'equals', required: 'yes', observed: 'yes' })])) expect(d.decision).toBe('proceed') expect(overall(toReport(plan([disk()])))).toBe('pass') }) it('honours at-most comparisons', () => { expect(replan(plan([disk({ comparison: 'at-most', required: 100, observed: 50 })])).decision).toBe('proceed') expect(replan(plan([disk({ comparison: 'at-most', required: 100, observed: 150 })])).decision).toBe('stop') }) }) describe('conformance with the evidence-record standard', () => { it('prints the decision in the output', () => { expect(formatReplan(plan([disk()]))).toContain('decision: PROCEED') expect(formatReplan(plan([disk({ observed: 1 })]))).toContain('decision: STOP') }) it('every conclusion carries a citation', () => { expect(validateReport(toReport(plan([disk(), disk({ id: 'b', observed: 1 })])))).toEqual([]) }) it('carries the reading into the citation as a measurement', () => { expect(formatReplan(plan([disk()]), { evidence: 'inline' })).toContain('disk free bytes = 20000000000') }) })