Skip to content

feat(memory): 기억 정리 야간 루프 — sonnet 5·종류별 청크·JSON 복구·잔량/7MB/08:00 상한 - #428

Merged
beyondworks merged 4 commits into
mainfrom
claude/consolidate-backlog-sonnet
Sep 4, 2026
Merged

feat(memory): 기억 정리 야간 루프 — sonnet 5·종류별 청크·JSON 복구·잔량/7MB/08:00 상한#428
beyondworks merged 4 commits into
mainfrom
claude/consolidate-backlog-sonnet

Conversation

@beyondworks

Copy link
Copy Markdown
Owner

배경 (유건 승인 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.100.18$로 4.6(0.090.28$, JSON 1회 깨짐)·4.5(0.350.41$, 2.53분)보다 나았다. 지시: 오래된 것부터 순서 유지, 21MB를 3밤에, sonnet 5.

변경

  • src/consolidate.mjs
    • 모델 CONSOLIDATE_MODEL = 'claude-sonnet-5'(claude 러너일 때 적용), 호출 readOnly: true, maxTurns: 2(도구 턴이 열려 있으면 파일을 읽으러 다녀 비용 5배 — 실측).
    • gatherNewJournal(export): 첫 미정리 파일의 종류가 청크 상한을 정함(크루 60KB·-imported.md 200KB). 파일이 상한보다 크면 상한 안 마지막 줄바꿈에서 잘라 워터마크를 그만큼만 전진(멀티바이트 안전, 다음 청크가 이어 받음). 남은 자리 4KB 미만이면 다음 파일 미시작. consumed·remaining 반환.
    • 프롬프트(ko/en)에 "먼저 주제를 전부 나열한 뒤 주제당 노트 1개" 단계.
    • 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청크.
  • 수동 API(vault/consolidate)는 단발 consolidateMemory 유지.

검증

  • test/consolidate-backlog.test.mjs 7건(임시 루트·가짜 원샷·실 러너 0): 줄 경계 절단·이어받기·잔량, 종류별 상한, parseNotes, 호출 옵션·복구·실패 시 워터마크 미전진, 루프 상한 4종(잔량·바이트·마감·청구), 배선. 변이 8종 red(haiku 복귀·readOnly 제거·복구 제거·줄 경계 제거·마감 제거·바이트 상한 제거·실패 시 전진·단발 복귀).
  • 전체 스위트 1443건 fail 0, lint 통과.
  • 격리 복사본(가짜 토큰)에서 sonnet 5 실제 1청크 실행 — 결과는 코멘트로.
  • 산정: 회당 오버헤드 ≈20K 토큰 고정이라 청크를 키워 회수를 10분의 1로. 21MB ÷ 200KB ≈ 105회, sonnet 5 회당 35분 → 밤당 7MB ≈ 35회 ≈ 23시간(04:00~08:00 안). 병렬은 두지 않았다(YAGNI — 순차로 3밤 목표 충족).

알려진 한계

  • 청크가 커지면 한 번에 다시 쓰는 노트 수가 늘어 slice(0, 8) 상한에 걸릴 수 있다(9번째 이후 노트는 다음 청크에서 다시 제안되면 반영). 실측 후 상한 조정.
  • 구독 러너는 청구 0이나 사용량 창을 소모한다(밤당 2~3시간). 청구 러너는 5청크 상한.

🤖 Generated with Claude Code

…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>
@beyondworks

Copy link
Copy Markdown
Owner Author

격리 복사본 실측 — sonnet 5 실제 1청크(consolidateBacklog(ws, { maxChunks: 1 }), 가짜 토큰 워크스페이스, 실 러너 = Claude 구독)

  • 청크 195KB(가져온 일지, 2월분 57개 파일 줄 경계 절단 포함) → 노트 6개 생성·갱신, 264초, 사용량 입력 106K(캐시 생성)+15K(캐시 읽기)·출력 22.6K 토큰, SDK 보고 비용 0.74$, billed=false(구독), memory 이벤트 ok, 워터마크 57파일 전진, 잔량 18.6MB.
  • 노트: OpenClaw AWS 배포 운영 / Claude Code 글로벌 설정 최적화 / Linkbrain v-2 설계 시스템 / Linkbrain 수익화 업그레이드 / AI 콘텐츠 자동화 멀티에이전트 / TTStudio v2 오디오 끝음 끊김 — 6개 모두 기존 노트 제목 재사용·통합.
  • 산정 갱신: 회당 264초·0.74$ → 밤당 7MB ≈ 36청크 ≈ 2.6시간(04:00~08:00 안), 21MB ≈ 105청크 ≈ 78$(가격표 기준, 구독은 청구 0·사용량 창 소모). 출력 토큰이 예상(10K)보다 커서(22.6K) 비용은 앞선 추정(47$)보다 높다.

beyondworks and others added 3 commits September 4, 2026 12:31
…만 + 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>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@beyondworks
beyondworks merged commit 67ceb1f into main Sep 4, 2026
2 checks passed
@beyondworks
beyondworks deleted the claude/consolidate-backlog-sonnet branch September 4, 2026 03:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant