/* * ★ **지금은 조용한 것이 정상이다** — 밤마다 나던 거짓 빨강. * * ── 무엇이 틀렸나 (2026-09-04) ────────────────────────────────────────────── * 유입 건강이 **한 자로 전부를 쟀다.** 10분 안에 아무것도 오지 않으면 「유입 없음」이다. 그런데 * 태양광은 밤에 발전하지 않고, 업무시간만 도는 원천은 저녁에 아무것도 내지 않는다. 정상인데 * **매일 밤 절반이 빨갛게 났다.** * * 거짓 빨강이 쌓이면 진짜 빨강도 같이 안 읽힌다. 오늘 UX 레인이 「늘 참인 경고는 벽지가 된다」고 * 한 것과 같은 부류다 — 사흘이면 그 자리에 무엇이 적혀도 안 읽는다. * * 그리고 15분마다 긷는 원천은 긷는 사이마다 빨갛다. 이 파일이 고치는 코드가 그 한계를 **스스로 * 주석에 적어 두고 있었다**: 「주기를 알게 되면 그 값으로 견주는 것이 맞다」. * * ── 초록도 빨강도 아닌 셋째 값 ────────────────────────────────────────────── * 조용한 시간을 초록으로 칠하면 **밤에 정말 끊긴 원천**을 아침까지 아무도 모른다. 그래서 답은 * 「지금은 안 오는 것이 맞다」이고, 그것은 다른 값이어야 한다. */ import { test } from 'node:test' import assert from 'node:assert/strict' import { syncVerdictOf, STALE_AFTER_MS } from '../server/engine/ingest-health.js' const NOW = 1_800_000_000_000 const long = NOW - STALE_AFTER_MS - 60_000 /* 한 창을 넘긴 침묵 */ const at = (over: Record = {}) => syncVerdictOf({ feedState: 'attached', recent: { offered: 100, rejected: 0 }, lastAtMs: NOW - 1_000, nowMs: NOW, lastUndeliveredAtMs: -1, offeredTotal: 100, ...over } as any) /* ── 조용한 시간 ──────────────────────────────────────────────────────────── */ test('★ 조용한 시간의 긴 침묵은 「유입 없음」이 아니다', () => { assert.equal(at({ lastAtMs: long, quietNow: true }), 'expected-quiet') }) test('★ 같은 침묵이 활동 시간이면 「유입 없음」이다', () => { assert.equal(at({ lastAtMs: long, quietNow: false }), 'no-traffic') }) test('★ 달력을 선언하지 않았으면 지금까지처럼 답한다 — 모르는 것을 「조용할 때」로 읽지 않는다', () => { /* * `quietNow` 를 주지 않은 원천이 전부 「지금은 조용한 시간」이 되면, 정말 끊긴 원천이 통째로 * 조용해진다. 없으면 옛 거동 그대로다. */ assert.equal(at({ lastAtMs: long }), 'no-traffic') }) test('★ 조용한 시간이어도 사실이 사라지고 있으면 그것이 먼저다', () => { /* * 버려지는 중은 **몇 시든 문제**다. 밤이라고 덮으면 밤새 새는 것을 아침에 안다. */ const v = at({ lastAtMs: long, quietNow: true, lastUndeliveredAtMs: NOW - 1_000 }) assert.equal(v, 'twin-not-running') }) test('★ 조용한 시간이어도 결선이 없으면 그것이 먼저다', () => { assert.equal(at({ feedState: 'detached', lastAtMs: long, quietNow: true }), 'not-connected') }) test('★ 한 번도 받지 않았는데 지금이 조용한 시간이면 「모른다」가 아니다', () => { /* * 밤에 처음 붙인 태양광 연결이 「기다린다」로 보이면, 사람이 아침까지 무엇을 기다리는지 모른다. */ assert.equal(at({ lastAtMs: -1, recent: null, offeredTotal: 0, quietNow: true }), 'expected-quiet') assert.equal(at({ lastAtMs: -1, recent: null, offeredTotal: 0 }), 'unknown') }) test('★ 창이 비었어도 조용한 시간이면 정상이다', () => { assert.equal(at({ recent: { offered: 0, rejected: 0 }, quietNow: true }), 'expected-quiet') assert.equal(at({ recent: { offered: 0, rejected: 0 } }), 'no-traffic') }) test('조용한 시간에도 받고 있으면 받는 중이다 — 침묵이 아니면 이 축이 개입하지 않는다', () => { assert.equal(at({ quietNow: true }), 'syncing') }) /* ── 원천이 선언한 주기 ──────────────────────────────────────────────────── */ test('★ 15분마다 긷는 원천은 그 주기 안에서 정상이다', () => { /* * 창 하나(10분)로 재면 긷는 사이마다 빨갛다. 원천이 주기를 선언하면 그것으로 견준다. */ const twelveMin = NOW - 12 * 60_000 assert.equal(at({ lastAtMs: twelveMin }), 'no-traffic', '선언이 없으면 옛 거동') assert.equal(at({ lastAtMs: twelveMin, expectedSilenceMs: 20 * 60_000 }), 'syncing') }) test('★ 선언한 주기를 넘기면 그때는 「유입 없음」이다 — 선언이 면죄부가 아니다', () => { const thirtyMin = NOW - 30 * 60_000 assert.equal(at({ lastAtMs: thirtyMin, expectedSilenceMs: 20 * 60_000 }), 'no-traffic') }) test('0이나 음수 주기는 선언이 아니다 — 창 하나로 돌아간다', () => { for (const bad of [0, -1, NaN]) { assert.equal(at({ lastAtMs: long, expectedSilenceMs: bad }), 'no-traffic', `${bad} 를 주기로 받았다`) } }) test('★ 주기와 달력은 다른 축이다 — 주기를 넘겼는데 조용한 시간이면 정상이다', () => { const thirtyMin = NOW - 30 * 60_000 assert.equal(at({ lastAtMs: thirtyMin, expectedSilenceMs: 20 * 60_000, quietNow: true }), 'expected-quiet') })