되감기 범위의 반사실 검증: 파일 밖 그래프 삭제를 막다
가장 오래된 라이브 체크포인트에 구버전 알고리즘을 읽기 전용으로 적용하자 159,506쿼드 중 102,020개와 앵커 턴이 건드리지 않은 1,057문서의 그래프가 제거될 것으로 계산됐습니다. 실제 사고가 아니라 반사실 replay이며, 수정은 전체 그래프 교체를 touched-document 범위로 제한했습니다.
- 구버전이 제거했을 쿼드 · 라이브 상태 반사실 · 실제 삭제 아님
- 102,020 / 159,506
- 영향 문서 중 앵커 턴이 실제로 건드린 문서
- 0 / 1,057
질문 — 파일 몇 개만 되돌리는 작업이 왜 지식 그래프 전체를 과거 스냅샷으로 교체해야 하는가?
관찰 — 실제 볼트를 읽기 전용으로 재생한 반사실에서, 기존 알고리즘은 가장 오래된 라이브 체크포인트에 대해 현재 159,506쿼드 중 102,020쿼드를 제거하고, 그 턴이 건드린 문서가 0개인 1,057개 문서 그래프를 잃게 만들었다.
결정 — 사고가 발생했다고 쓰지 않고, 파일에서 실제로 복원·삭제된 문서의 네임드 그래프만 스냅샷으로 교체하도록 복원 범위를 맞췄다.
102,020은 관찰된 데이터 손실량이 아니라, 라이브 상태에 기존 알고리즘을 적용해 계산한 반사실 피해량이다.
1. 파일 복원과 그래프 복원의 범위가 달랐다
되감기 계획의 파일 절반은 체크포인트 범위에 기록된 경로만 복원하거나 삭제했다. 반면 그래프 절반은 앵커 시점의 graph.nq 스냅샷을 현재 파일 전체에 그대로 덮어썼다. 파일의 영향 범위는 “그 턴이 실제로 바꾼 경로”였지만, 파생 그래프의 영향 범위는 “스냅샷 뒤에 생긴 모든 그래프 작업”이었다.
이 비대칭은 백그라운드 수집기처럼 같은 볼트에 쓰는 다른 주체가 있을 때 위험하다. 앵커 뒤에 다른 주체가 추출한 문서는 현재 그래프에는 있고 과거 스냅샷에는 없다. 전체 교체는 그 문서의 바이트를 되돌리지 않으면서 파생 그래프만 없앤다.
2. 라이브 상태를 읽었지만 되감기를 실행하지는 않았다
2026-08-01 분석은 실제 설치본의 현재 N-Quads와 가장 오래된 라이브 체크포인트 스냅샷을 읽기 전용으로 파싱하고, 수정 전 전체 교체 알고리즘이 실행됐다면 생길 차이를 계산했다. Market 그래프는 파싱 오류 0건으로 파일의 159,506줄과 159,506쿼드가 정확히 일치했다.
| 반사실 결과 | n · 분석 단위 · 조건 |
|---|---|
| 제거될 현재 그래프 | 102,020 / 159,506쿼드 (64%) · 가장 오래된 라이브 체크포인트에 기존 전체 교체 적용 |
| 그래프를 잃을 문서 | 1,057개 문서 네임드 그래프 · 앵커 턴이 건드린 문서 0개 |
| 배경 수집 문서 | 1,056 / 1,057개 · live/ 아래 문서 |
| 되살아날 과거 그래프 | 50,550쿼드 · 디스크에 더는 없는 노트 400개 |
| 파일 작업 표시 | 복원·삭제 성공 0개 · UI는 Rewound 0 file(s)로 보고할 조건 |
앵커 턴이 기록한 경로는 추출 대상이 아닌 .scratch_seasonality.py 하나였다. 따라서 1,057개는 “되감기 범위에 있었지만 우연히 많았던 문서”가 아니라, 그 턴의 파일 영향권 밖에 있던 문서다.
3. 실제 사고와 자동 복구 가능성도 구분했다
이 수치는 프로덕션 되감기 실행 뒤의 손실 로그가 아니다. 라이브 체크포인트와 라이브 그래프에 예전 알고리즘을 적용한 반사실 재생이며, 분석 과정에서 사용자 그래프를 덮어쓰지 않았다. 커밋 제목과 일부 이전 문서의 “삭제했다”는 표현은 이 증거보다 강하므로 “삭제했을 것이다”로 고쳐 읽어야 한다.
다만 실행됐다면 자동 자가치유도 기대할 수 없었다. 영향 문서 1,057/1,057개에서 디스크 SHA-256이 저장된 last_tagged_hash와 일치했다. 파일 바이트가 바뀌지 않았으므로 추출 게이트는 재처리를 건너뛰었을 것이다. 이는 복구 자체가 불가능하다는 뜻이 아니라, 별도의 메타데이터 초기화나 강제 재추출 없이는 자동으로 돌아오지 않는다는 뜻이다.
4. 수정은 파생 상태의 범위를 파일 범위와 맞췄다
커밋 1cd80797은 현재 그래프를 기본값으로 유지하고, 이번 되감기가 파일 시스템에서 실제로 복원하거나 삭제한 경로의 문서 네임드 그래프와 #analysis 형제 그래프만 앵커 스냅샷에서 가져오도록 바꿨다.
| 상태 | 수정 전 | 수정 후 |
|---|---|---|
| 손대지 않은 문서 | 앵커의 과거 전체 그래프로 덮어씀 | 현재 그래프 유지 |
| 실제 복원한 문서 | 앵커 상태로 복원 | 앵커의 해당 네임드 그래프만 복원 |
| 현재에는 있고 앵커에는 없는, 실제 삭제 대상 문서 | 전체 파일 교체의 부수 효과로 결정 | 성공한 파일 삭제 경로일 때만 해당 그래프 제거 |
| 파일 변경 0개 | 그래프 전체를 바꿀 수 있음 | 그래프를 변경하지 않음 |
| N-Quads 행을 문서에 귀속할 수 없음 | 전체 덮어쓰기 결과에 종속 | 현재 행은 유지하고 스냅샷 행은 무시하는 보수적 실패 |
핵심은 “스냅샷을 덜 믿는다”가 아니다. 디스크에서 확인된 되감기 결과를 파생 상태의 권한 경계로 사용한다. 파일을 바꾸지 못한 되감기는 그 문서의 그래프도 바꿀 권한이 없다.
5. 회귀 테스트는 누락과 과잉 수정을 함께 막는다
rewind_graph_restore_keeps_documents_the_turn_never_touched는 현재 그래프에 두 문서를 둔다. 하나는 되감기 대상이고, 하나는 스냅샷 뒤 백그라운드 작성자가 추가한 문서다. 수정 후에는 대상 문서가 과거 엔티티로 돌아가고, 배경 문서는 그대로 남으며, 대상 문서의 사후 엔티티는 사라져야 한다. 마지막 조건은 “그래프 복원을 아예 없애서” 테스트를 통과시키는 과잉 수정을 막는다.
추가 가드 rewind_rolls_back_a_document_a_later_in_range_turn_touched는 여러 체크포인트를 접는 경우를 고정한다. 파일 목록은 앵커 이후 모든 턴을 접지만 그래프 스냅샷은 앵커 하나에서 읽는다. 뒤쪽 턴이 처음 건드린 문서도 과거 상태로 복원되고 사후 그래프가 남지 않아야 한다.
6. 현재 코드와 남은 설계 제약
현재 scope_graph_restore는 “현재 그래프에서 영향 문서 그래프를 제거한 뒤, 스냅샷에서 같은 문서 그래프만 더하는” 병합으로 구현돼 있다. apply_plan은 성공한 restored_paths와 deleted_paths만 영향 목록으로 넘기고, 목록이 비면 그래프 파일을 쓰지 않는다.
스냅샷 캡처 자체는 여전히 전체 그래프라 과대하다. 그러나 앵커 턴의 경로만 캡처하도록 단순히 좁히면, 같은 되감기 범위의 뒤쪽 턴이 처음 건드린 문서가 앵커 스냅샷에 없어 삭제로 해석될 수 있다. 안전하게 좁히려면 경로별 사전 그래프 해시를 범위 접기 과정에 전달해야 한다. 145 MiB라는 용량은 한 설치본의 시점 측정일 뿐이며, 이후 5일간 바이트가 동일했다는 재측정 때문에 월간 증가율로 외삽하지 않는다.
7. 재현성과 증거 경계
| 증거 | 관찰·조건 | 경계 | 원본 |
|---|---|---|---|
| 라이브 반사실 | 102,020/159,506쿼드, 1,057개 문서, 앵커가 건드린 문서 0개 · 라이브 체크포인트 5개 중 가장 오래된 것에 구 알고리즘 적용 | 실제 되감기 실행이나 관찰된 손실 사고가 아님 | 커밋 1cd80797 본문; src-tauri/src/checkpoints.rs:567-578 |
| 파싱 확인 | Market N-Quads 파싱 오류 0, 159,506줄=159,506쿼드 | 한 실제 볼트의 2026-08-01 상태 | 커밋 1cd80797 본문 |
| 자동 복구 조건 | 1,057/1,057 디스크 해시가 last_tagged_hash와 일치 |
강제 재추출·메타데이터 초기화까지 불가능하다는 뜻은 아님 | 커밋 1cd80797 본문; src-tauri/src/checkpoints.rs:573-578 |
| 범위 수정 | 현재 그래프 유지 + 성공한 파일 경로의 문서/분석 그래프만 스냅샷으로 교체 | 기본 그래프와 파싱 불가 행은 보수적으로 현 상태 유지 | src-tauri/src/checkpoints.rs:560-605,647-675 |
| 회귀 가드 | 대상 문서는 롤백, 비대상 배경 문서는 유지, 사후 대상 그래프는 제거 | 합성 픽스처이며 라이브 규모 성능을 재지 않음 | src-tauri/src/checkpoints.rs:856-922 |
| 캡처 제약 | 뒤쪽 범위 턴의 문서도 복원해야 해 앵커 스냅샷을 단순 축소할 수 없음 | 경로별 사전 해시 설계는 아직 구현하지 않음 | src-tauri/src/checkpoints.rs:924-1018; 커밋 98f10fe9 |
무엇을 측정한 것인가
- Consilience
사람이 편집하는 Markdown을 저자 기록으로, 파생 온톨로지를 에이전트의 관계 기억으로 사용하는 지속형 인간–AI 작업공간