/** * D8's three states, asserted one branch at a time: only "used to jail and has * stopped" raises. Steady-state unjailed — a Mac that never jailed — is a * configuration fact the doctor reports, never an alert. */ import { describe, expect, test } from 'bun:test'; import type { JailModeRecord } from '../../hooks/jail'; import { hookJailFailingKeys } from './hook-jail'; const HOST = 'celilo-mgr'; const regressed: JailModeRecord = { mode: 'unjailed', backend: 'none', reason: 'bubblewrap is installed but could not build a namespace, so hooks run unjailed.', host: HOST, recordedAt: '2026-08-28T09:00:00.000Z', lastJailed: { backend: 'bubblewrap', recordedAt: '2026-08-27T09:00:00.000Z' }, }; describe('hookJailFailingKeys', () => { test('a host that used to jail and has stopped raises, naming the host and the reason', () => { const failing = hookJailFailingKeys({ record: regressed, host: HOST }, 'critical'); expect(failing).toHaveLength(1); expect(failing[0]?.key).toBe(`builtin:hook_jail/host:${HOST}`); expect(failing[0]?.severity).toBe('critical'); expect(failing[0]?.message).toContain(HOST); expect(failing[0]?.message).toContain('until 2026-08-27T09:00:00.000Z'); expect(failing[0]?.message).toContain('could not build a namespace'); }); test('steady-state unjailed is not an event', () => { const neverJailed: JailModeRecord = { mode: 'unjailed', backend: 'none', reason: 'macOS has no hook jail yet', host: HOST, recordedAt: '2026-08-28T09:00:00.000Z', }; expect(hookJailFailingKeys({ record: neverJailed, host: HOST }, 'critical')).toEqual([]); }); test('a jailed host raises nothing, which is also how the alert resolves', () => { const healthy: JailModeRecord = { mode: 'jailed', backend: 'bubblewrap', host: HOST, recordedAt: '2026-08-28T09:00:00.000Z', }; expect(hookJailFailingKeys({ record: healthy, host: HOST }, 'critical')).toEqual([]); }); test('no record yet raises nothing', () => { expect(hookJailFailingKeys({ record: undefined, host: HOST }, 'critical')).toEqual([]); }); test("a record written by another host is a move, not this host's regression", () => { expect(hookJailFailingKeys({ record: regressed, host: 'a-new-box' }, 'critical')).toEqual([]); }); test("the monitor's severity is the alert's severity", () => { const failing = hookJailFailingKeys({ record: regressed, host: HOST }, 'warning'); expect(failing[0]?.severity).toBe('warning'); }); });