/* * ★ **셈이 닫혀야 한다** — 두 갈래로는 큰 수가 「사라졌다」로 떠 있게 된다. * * ── 실측 (2026-09-05, 인티그레이션·plant 레인) ───────────────────────────── * plant 아웃박스와 저널을 손으로 맞춰 보니 정확히 닫혔다. * * 나간 것 157 = 앉은 것 46 + 거절 2 + 어휘 1 + 되풀이 108 * * 되풀이 108은 하네스가 같은 실적을 같은 시각으로 다시 보낸 것이고 **합친 것이 옳은 거동**이다. * 어휘 1은 저널에 안 가는 것이 옳다(시각축이 없다). * * ── 왜 두 갈래로는 안 되나 ──────────────────────────────────────────────── * 두 갈래 157 − 46 − 2 = 109 「설명 못 함」 * 네 갈래 157 − 46 − 2 − 108 − 1 = 0 * * **109 를 「사라졌다」로 내면 그날부터 아무도 그 수를 안 본다.** 늘 큰 수가 떠 있으면 진짜로 하나 * 사라진 날을 못 본다 — 오늘 이 저장소에서 「늘 참인 경고는 벽지가 된다」로 여러 번 나온 것이다. * * ── 그리고 되풀이 108은 잰 값이 아니었다 ────────────────────────────────── * 뺄셈으로만 구할 수 있었다. 어휘 항이 없어서다. 그 뺄셈을 코드가 하려면 넷이 다 있어야 한다. */ import { test } from 'node:test' import assert from 'node:assert/strict' import { newIngestLedger, recordIngest, recordDuplicates, recordVocabulary, recordJournalWrite } from '../server/engine/ingest-health.js' const T0 = 1_757_000_000_000 test('★ 넷을 다 세면 셈이 0으로 닫힌다 — 실측한 그 수로', () => { const ledger = newIngestLedger() /* 나간 것 157 · 거절 2 */ recordIngest(ledger, 157, [{ errors: ['x'] }, { errors: ['y'] }], T0) /* 저널에 앉은 것 46 */ recordJournalWrite(ledger, 46, T0) /* 합친 것 108 */ recordDuplicates(ledger, 108, T0) /* 저널에 안 가는 어휘 1 */ recordVocabulary(ledger, 1) const w = ledger.window const unexplained = w.offered - w.rows - w.rejected - ledger.duplicates - w.vocabulary assert.equal(unexplained, 0, `설명 못 한 것이 ${unexplained} 남았다 — 셈이 안 닫힌다`) }) test('★ 어휘 항이 없으면 그 수가 「사라졌다」로 남는다 — 이 항의 존재 이유', () => { const ledger = newIngestLedger() recordIngest(ledger, 20, undefined, T0) recordJournalWrite(ledger, 17, T0) recordVocabulary(ledger, 1) const w = ledger.window /* 어휘를 안 빼면 셋이 빈 것으로 보인다 — 실제로 사라진 것은 둘이다. */ assert.equal(w.offered - w.rows, 3, '실측 상황을 못 만들고 있다') assert.equal(w.offered - w.rows - w.vocabulary, 2, '어휘를 빼도 수가 안 맞는다') }) test('★ 어휘는 저널 수에 안 들어간다 — 두 번 세면 셈이 음수가 된다', () => { const ledger = newIngestLedger() recordIngest(ledger, 1, undefined, T0) recordVocabulary(ledger, 1) assert.equal(ledger.window.rows, 0, '어휘가 저널 수에 섞였다') assert.equal(ledger.window.vocabulary, 1) }) test('★ 창이 갈리면 각 창이 자기 어휘를 든다 — 누적으로 비교하면 안 된다', () => { /* * 인티그레이션 레인이 짚은 것: `mes-line-a` 가 커서 48 · 저널 11 인데 결함이 아니다(그 사이 * 저널을 비웠다). **창 단위로** 맞춰야 한다. */ const ledger = newIngestLedger() recordIngest(ledger, 5, undefined, T0) recordVocabulary(ledger, 2) assert.equal(ledger.window.vocabulary, 2) /* 창을 넘긴다 — 새 창은 0에서 시작한다. */ recordIngest(ledger, 5, undefined, T0 + 700_000) assert.equal(ledger.window.vocabulary, 0, '새 창이 앞 창의 어휘를 물고 왔다') assert.equal(ledger.vocabulary, 2, '누적은 남아야 한다') }) test('★ 이 검사가 실제로 무언가를 잰다 — 견준 것이 0이면 빨강', () => { const ledger = newIngestLedger() assert.equal(ledger.window.vocabulary, 0, '새 창에 그 항이 없다') recordVocabulary(ledger, 0) assert.equal(ledger.vocabulary, 0, '0을 세었다 — 모르면 안 적는다') recordVocabulary(ledger, -3) assert.equal(ledger.vocabulary, 0, '음수를 세었다') })