포크의 본질은 코드가 아니라 계약이다
원작자(jung-wan-kim, Hugh)의 memory-bank와 내 사설 포크는 같은 뿌리에서 갈라졌지만 대체 관계가 아닙니다. 포크는 업스트림의 성능·위생 작업을 merge로 계속 받아들이면서, 그 위에 Codex 세션 색인·프라이버시 방어·런타임 핀이라는 포크만의 층을 유지하는 구조입니다. 8일간 4회 동기화에서 업스트림 커밋 101개를 채택했고, 포크 전용 커밋은 66개, 즉 코드 볼륨으로는 업스트림이 더 많이 흘러들어 왔습니다. 진짜 차이는 코드가 아니라 그 흐름을 사고 없이 유지하는 운영 계약 4개와 실측 함정 카탈로그 8개에 있습니다.
읽는 법 · 신뢰도 라벨
근거는 포크 repo의 PORT-PLAN.md(동기화 triage 대장), CHANGELOG.md(fork/upstream 섹션 분리 기록),
git 이력(upstream/main..HEAD 실측)입니다. 원작자 측 서술은 커밋·CHANGELOG 원문 범위로 한정하고, 의도 해석에는 추론 라벨을 붙입니다.
02관계 구조 · 영구 사설 포크
2026-07-04에 확정한 관계: 업스트림 PR 없음, merge로만 추적, 영구 유지. 프라이버시(내 대화 코퍼스를 다루는 플러그인)와 독립성(원작자 릴리스 속도에 종속되지 않기)이 이유입니다.
왜 이 형태인가
- 프라이버시: 이 플러그인은 내 전체 대화 코퍼스(색인 DB)를 다룹니다. 포크 측 수정(Codex 로그 파싱·exclude 방어)의 세부는 공개 PR로 노출할 이유가 없습니다. 추론
- 독립성: 원작자는 시간 단위로 릴리스합니다(7/11 하루에 v1.3.4 태그 + autoresearch 21회 반복). 포크가 PR 리뷰 사이클에 묶이면 내 배포 속도가 원작자 일정에 종속됩니다. 검증됨
- merge-only: rebase·force-push·squash 금지. 공유 히스토리 보존이 다음 동기화의 전제이고, PR 병합도 merge commit 전략 고정입니다. 검증됨
03포크가 더한 것 · 6개 층
포크 전용 66커밋이 만든 층. 핵심은 ①이고 나머지는 그것을 안전하게 굴리기 위한 기반입니다. 전부 새 파일 또는 명확한 이음새 위주로 작성해 업스트림 병합과의 충돌 표면을 최소화했습니다.
① Codex 세션 색인 · 포크의 존재 이유 fork
업스트림은 v1.1.0(2026-04)에서 그릇을 만들어 뒀습니다: coding_agent 스키마·검색 필터·다중 에이전트 태깅.
하지만 Codex 로그를 실제로 읽는 파서와 소스 발견은 없었습니다. 포크가 내용물을 채웠습니다:
parseConversation()을 하네스 감지 라우터로 재구성 +parseCodexConversation()추가 · Codex rollout jsonl 스키마(response_item/payload)는 Claude와 완전히 다름 검증됨~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl재귀 소스 발견 +codingAgent:'codex'stamp · 실측 913개 파일 1.3GB가 색인 대상 검증됨- 이음새 테스트 · 업스트림의 워커 프롬프트 오염 가드(v1.3.4)가 포크 전용 codex 경로에서도 발화하는지 고정하는 회귀 테스트. 업스트림이 모르는 경로를 업스트림 가드가 지키게 함 검증됨
결과: Claude와 Codex 대화가 하나의 메모리 뱅크에서 검색·팩트 추출됩니다. 원작자 저장소에는 이 능력이 없습니다 (episodic-memory 계보에는 있으나 memory-bank 본선에는 미이식 상태에서 포크가 직접 이식).
② exclude 프라이버시 방어 fork
encodeProjectPath등 6종 · 인코딩·정규화·에러 격리로 제외 목록 우회 차단 검증됨- cwd 기반 프로젝트 제외 적용 · 색인에서 빠져야 할 프로젝트가 경로 변형으로 다시 들어오는 구멍 봉쇄 검증됨
③ 온톨로지 경화 (1.4.2, 독립 리뷰 29커밋) fork
- category 5어휘
CHECK강제 + 쓰기 정규화, 추출 confidence 영속 검증됨 consistency해소 큐(--gateexit 2) ·taxonomy-align근사중복 병합 검증됨- 관계 어휘 확장(DEPENDS_ON/DERIVED_FROM) + co-extraction 채널 · SUPPORTS 83% 편중 해소 검증됨
search_ontology바운드 출력 · 무필터 4.9MB 덤프 → 요약 모드 검증됨
④ 런타임 핀 스택 fork
ABI 사고 2회(06-24, 07-09 · 방향만 반대인 같은 "빌드≠실행" 클래스)에서 도출한 계약: 빌드와 모든 실행 경로가 단 하나의 런타임.
- 정본 핀
~/.claude/memory-bank.env→.nvmrc→ 폴백 해석 순서 · 래퍼·훅·sync loop 동일 검증됨 cli/node-pin.sh· hooks.json 5곳 + inject 콜드폴백의 barenode제거 (1.5.0) 검증됨
⑤ upstream-watch + ⑥ 시각화 분리 fork
upstream-watch.sh· head 변경 + 릴리스 태그 강조 알림 (head 알림만으론 48커밋이 무증상 누적된 실측 교훈) · launchd 6h 검증됨- 시각화는 업스트림 galaxy(three.js ~1,900줄) 대신 별도 스택
knowledge-graph-viz(WebGL 아틀라스) 운영 · galaxy 2커밋은 병합 보류 검증됨
04업스트림에서 받은 것 · 8일, 4회 동기화, 101커밋
포크가 유지되는 이유의 절반은 업스트림 품질입니다. 성능(주입 35×·벡터 6.7×)과 데이터 위생(자기 오염 차단·self-heal)은 전부 원작자 작업이고, 포크는 이것을 커밋 단위 triage로 받아들였습니다.
동기화 연대기
| 날짜 | 업스트림 | 커밋 | 핵심 채택 내용 | 포크 버전 |
|---|---|---|---|---|
| 07-05 | v1.3.0 | 15 | 온톨로지 backfill 배치화(LLM 스폰 1/20) · 주입 fail-loud · 인덱스 self-heal 체인 | 1.4.0 |
| 07-05 | v1.3.1 | 13 | 관계 엣지 멱등화(dedup) · 그래프 탐색 belief-safety 문턱 | 1.4.1 |
| 07-08 | v1.3.2·1.3.3 | 27 | consolidation 워커 락·에러 3분류 수렴 · LLM 워커 세션 색인 오염 차단(자기 산출 루프 절단) | 1.4.2 |
| 07-12 | v1.3.4 + iter18~38 | 46 | warm inject 데몬(프롬프트당 2.3s→0.2s) · 벡터 int8(25.4→3.8ms) · stamp-vector self-heal(업스트림 코퍼스 197K행 복구) · legacy 워커 오염 purge | 1.5.0 |
계 101커밋 채택 검증됨 · 보류 2커밋(3D Knowledge Galaxy · 포크는 별도 시각화 스택 운영, 차기 동기화에서 재판정) · 미병합 7커밋(v1.4.0~1.4.3 · inject v2 세션 dedup·토큰 예산은 채택 가치 높음, §07 참조)
05운영 계약 4 · 사고를 구조로 막는 층
코드 diff에는 안 보이지만 포크의 실질적 차이는 여기 있습니다. 전부 실제 사고나 니어미스에서 도출된 계약입니다.
계약 일람
| 계약 | 내용 | 도출 배경 |
|---|---|---|
| 버전 | 포크 버전 = max(upstream, 직전 포크) 초과 단조 증가. 업스트림이 같은 네임스페이스에 진입하면 포크가 다음 마이너로 점프 | 설치 update가 SHA를 무시하고 version만 비교 · 두 코드베이스가 같은 버전 문자열을 공유하면 update가 오동작. 실증 2회: 포크 1.3.0 ↔ upstream v1.3.0 충돌 → 1.4.0, upstream v1.4.x 출현 → 1.4.2에서 1.5.0 점프 검증됨 |
| 런타임 | 빌드와 모든 실행 경로가 단 하나의 노드(env 핀). 해석 순서 NODE_BIN → env 핀 → .nvmrc → 폴백 전 경로 동일 | ABI 분열 사고 2회 (06-24: 빌드 nvm22 ∥ 실행 brew26 / 07-09: 정반대). "brew 배제"라는 과거 오진 폐기, 방향이 아니라 단일성이 본질 검증됨 |
| 병합 | upstream 반영은 merge로만. 커밋 단위 triage(채택/보류/거부 + 사유)를 PORT-PLAN에 기록 | rebase/squash는 공유 히스토리를 파괴해 다음 동기화의 기준점을 지움. triage 기록이 없으면 "왜 이 커밋이 없지"를 매번 재조사 검증됨 |
| 마켓플레이스 | source는 로컬 포크 디렉토리 고정. AUTO_UPDATE·TRACK_UPSTREAM 절대 금지 | source가 upstream URL이면 plugin update가 포크를 원작자 코드로 덮어씀: Codex 색인 코드가 조용히 소멸 (2026-07-05 발견·교정) 검증됨 |
계약이 실전에서 작동한 예 · 1.5.0 릴리스 주간
- upstream-watch 태그 알림 → v1.3.4 감지 (head 알림만이던 시절 48커밋 무증상 누적의 재발 방지) 검증됨
- 병합 진행 중 업스트림이 v1.4.0~v1.4.3을 연속 릴리스 → 버전 계약 발동, 포크는 1.4.x를 건너뛰고 1.5.0으로 검증됨
- 병합 46커밋을 PORT-PLAN에 3개 묶음으로 triage · 채택 44 · 보류 2(galaxy) + 충돌 해소 기록(binary 병합된
sync-import.ts는 수동 이식) 검증됨 - push 게이트(적대 리뷰) 9라운드 · 실수정 7건(inject 데몬 보안·자원 상한) + 근거 기각 3건 기록 후 운영자 경로로 최종 push 검증됨
06함정 카탈로그 8 · 전부 실측에서 나왔다
사설 포크 운영에서 실제로 밟았거나 직전까지 갔던 함정들. Air/Windows 활성화 때 같은 순서로 다시 만나게 되므로 카탈로그 자체가 자산입니다.
함정과 처방
| # | 함정 | 처방 |
|---|---|---|
| 1 | DB dtype 마이그레이션을 구버전 플러그인이 살아있을 때 실행 → fact 검색이 조용히 0건 (무증상) | 마이그레이션은 대응 플러그인 활성화 後. 7/12 실측 사고 후 복구, 오늘(7/12) 1.5.0 활성 세션에서 재적용 완료 · 3테이블 int8 전환·검색 정상 확인 |
| 2 | marketplace remove가 installed plugin까지 내림 | remove + add 후 반드시 재 install |
| 3 | 버전 bump 누락 · update는 version만 비교 | plugin.json + package.json + marketplace.json 3파일 동시 bump |
| 4 | directory install이 node_modules를 불완전 복사 | 설치 후 캐시에서 npm install(핀 노드) + better-sqlite3 로드 확인 |
| 5 | AUTO_UPDATE·TRACK_UPSTREAM 활성화 → 포크가 upstream으로 되돌아가 Codex 코드 소멸 | 절대 금지 (마켓플레이스 계약) |
| 6 | push 권한 · 포크는 개인 org 소유, 다른 활성 계정은 READ | per-process GH_TOKEN 핀 (전역 gh auth switch 금지) |
| 7 | purge 중 CORRUPT_VTAB · 디스크 손상처럼 보이지만 실체는 FTS 외부-콘텐츠 desync | INSERT INTO exchanges_fts(exchanges_fts) VALUES('rebuild') 후 재실행 · 스크립트에 힌트 내장 |
| 8 | 빌드 노드 ≠ 실행 노드 (ABI 분열, 방향 불문) | 런타임 계약 · 모든 빌드·실행을 env 핀 노드로. node-pin.sh가 훅 경로까지 봉쇄 |
07판정 · 다음
다음 동기화 후보
- upstream v1.4.0~v1.4.3 (7커밋) · inject v2(세션 dedup 원장 + 토큰 예산)는 채택 가치 높음, deps 자가치유 포함 검증됨
- galaxy 재판정 · knowledge-graph-viz와의 중복·유지비 기준으로 추론
남은 운영 작업
- Air/Windows 활성화 · 함정 카탈로그 반복 + P2 시퀀스(FTS rebuild → purge → 드레인) 검증됨
- 이 Mac의 구 1.4.2 터미널 세션 재시작 (int8 전환으로 그 세션 fact 검색 0건 상태) 검증됨
- DB 백업 3개(2.8GB) 정리 · 1.5.0 안정 확인 후 검증됨