feat(memory): 기억 정리 야간 루프 — sonnet 5·종류별 청크·JSON 복구·잔량/7MB/08:00 상한 - #428
Merged
Conversation
…KB, 줄 경계 절단), 주제 나열 프롬프트, JSON 복구 1회, 잔량·7MB·08:00·청구 5청크 상한 원인(실측 2026-09-04): 새벽 정리가 밤당 1청크(≈18KB)만 소화해 가져온(imported) 일지 17.5MB 뒤에 크루 일지 130개가 서 있었다(약 1,000일). 큰 파일은 통째로 읽고 잘라 버려 뒷부분이 정리에서 영영 빠졌다. haiku는 같은 청크에서 주제 1/3만 건지고 기존 노트 옆에 사본을 만들었다. - A/B(같은 청크·같은 프롬프트, 읽기 전용·도구 금지): sonnet 5 주제 3/3·기존 제목 재사용 3/3·JSON 정상·0.10~0.18$ / 4.6 2/3·JSON 1회 깨짐·0.09~0.28$ / 4.5 0~2/3·0.35~0.41$·2.5~3분 / haiku 1/3·사본 생성 → sonnet 5(유건 승인) - consolidate.mjs: CONSOLIDATE_MODEL='claude-sonnet-5', oneShot(readOnly, maxTurns 2 — 도구 턴이 열려 있으면 비용 5배 실측), gatherNewJournal 청킹(첫 미정리 파일 종류가 상한 결정, 상한 안 마지막 줄바꿈에서 절단, 자투리 4KB 미만이면 다음 파일 미시작, consumed/remaining 반환), parseNotes + REPAIR_PROMPT 복구 1회, consolidateBacklog 루프(잔량 소진·밤당 7MB·마감·청구 러너 5청크 중 먼저 닿는 것, 실패는 던져 스케줄러 재시도가 이어 받음), 프롬프트에 "주제 전부 나열 후 주제당 노트 1개" 단계 - scheduler.mjs: 04:00 이후 consolidateBacklog(마감 로컬 08:00, 캐치업이면 최소 1청크) → 롤업. 수동 API(vault/consolidate)는 단발 유지 - test/consolidate-backlog.test.mjs 7건(가짜 원샷·임시 루트): 청킹·이어받기·잔량, 종류별 상한, parseNotes, 본 호출 옵션·복구·실패 시 워터마크 미전진, 루프 상한 4종, 배선. 변이 8종 red. consolidate-retry 핀은 oneShot 오버라이드에 맞춤 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Owner
Author
격리 복사본 실측 — sonnet 5 실제 1청크(
|
…만 + UTF-8 안전 하드 컷, 청구 판정 fail-closed, 루프 중 선점 스탬프 연장, 수동 정리 라우트 900초 - HIGH-1: notes.slice(0, 8) 초과분이 워터마크만 전진한 채 영구 유실 → NOTE_CAP 40, 초과 시 memory 실패 이벤트(버려진 제목 명시)+경고 - HIGH-2: 창 안 유일한 줄바꿈이 시작 직후면 몇 바이트 청크가 되어 MIN_TEXT 미만 스킵 → 영구 스톨 → 줄 경계는 nl+1-done ≥ MIN_ROOM일 때만, 아니면 하드 컷(UTF-8 연속 바이트 앞으로 후퇴 — LOW 처방 동봉). 너무 작아 스킵하면 경고 로그 - MEDIUM-1: isBilledRunner 실패 시 undefined → 비용 상한 소멸 → .catch(() => true) - MEDIUM-2: vault/consolidate 라우트 maxDuration 120→900(청크 264초 + 복구 3분) - MEDIUM-3: 4시간 루프 중 선점 스탬프(nextRetryAt +5분) 만료로 다른 기기·재기동이 두 번째 루프를 열 수 있던 창 → bumpConsolidateClaim(청크마다 +15분, done·다른 날은 무시) + onChunk 배선 - LOW: readdir 뒤 사라진 파일 관용(per-file catch), 근거 링크 상한 20, 잘린 출력(>60KB)은 복구 생략, readOnly·비용 주석 정정 - 테스트 +3(진행 보장·UTF-8·노트 상한 이벤트·하트비트) 및 핀. 변이 16종 red(검수가 초록이던 nl≥done·slice 상한 포함) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…탬프 1회 연장 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
배경 (유건 승인 2026-09-04)
새벽 04:00 기억 정리(consolidate)가 밤당 1청크(≈18KB)만 소화해 가져온(imported) 일지 17.5MB 뒤에 크루 일지 130개가 서 있었다(이 속도로 약 1,000일). 큰 파일은 통째로 읽고 잘라 버려 뒷부분이 정리에서 영영 빠졌다. 모델 A/B(같은 청크·같은 프롬프트·읽기 전용·도구 금지)에서 haiku는 주제 1/3만 건지고 기존 노트 옆에 사본을 만들었고, sonnet 5는 주제 3/3·기존 제목 재사용 3/3·JSON 정상에 비용 0.10
0.18$로 4.6(0.090.28$, JSON 1회 깨짐)·4.5(0.350.41$, 2.53분)보다 나았다. 지시: 오래된 것부터 순서 유지, 21MB를 3밤에, sonnet 5.변경
src/consolidate.mjsCONSOLIDATE_MODEL = 'claude-sonnet-5'(claude 러너일 때 적용), 호출readOnly: true, maxTurns: 2(도구 턴이 열려 있으면 파일을 읽으러 다녀 비용 5배 — 실측).gatherNewJournal(export): 첫 미정리 파일의 종류가 청크 상한을 정함(크루 60KB·-imported.md200KB). 파일이 상한보다 크면 상한 안 마지막 줄바꿈에서 잘라 워터마크를 그만큼만 전진(멀티바이트 안전, 다음 청크가 이어 받음). 남은 자리 4KB 미만이면 다음 파일 미시작.consumed·remaining반환.parseNotes+ JSON 복구 1회(REPAIR_PROMPT, 1턴·읽기 전용). 그래도 실패면 종전대로 이벤트 + throw(워터마크 미전진).consolidateBacklog(wsId, { deadlineMs, nightlyBytes=7MB, billedMaxChunks=5, maxChunks }): 잔량 소진·밤당 바이트·마감·청구 러너 청크 상한 중 먼저 닿는 것까지 연속. 청크마다 로그. 실패는 던져 스케줄러 재시도(5·20·60분)가 이어 받는다(성공 청크까지 워터마크 전진)._setOneShotForTest오버라이드(테스트).src/scheduler.mjs: 04:00 이후consolidateBacklog(cid, { deadlineMs: 로컬 08:00 })→ 롤업. 08:00 뒤 캐치업이면 최소 1청크.vault/consolidate)는 단발consolidateMemory유지.검증
test/consolidate-backlog.test.mjs7건(임시 루트·가짜 원샷·실 러너 0): 줄 경계 절단·이어받기·잔량, 종류별 상한, parseNotes, 호출 옵션·복구·실패 시 워터마크 미전진, 루프 상한 4종(잔량·바이트·마감·청구), 배선. 변이 8종 red(haiku 복귀·readOnly 제거·복구 제거·줄 경계 제거·마감 제거·바이트 상한 제거·실패 시 전진·단발 복귀).5분 → 밤당 7MB ≈ 35회 ≈ 23시간(04:00~08:00 안). 병렬은 두지 않았다(YAGNI — 순차로 3밤 목표 충족).알려진 한계
slice(0, 8)상한에 걸릴 수 있다(9번째 이후 노트는 다음 청크에서 다시 제안되면 반영). 실측 후 상한 조정.🤖 Generated with Claude Code