3-4. 파일 패널과 영속 세션 (7/17 ~ 7/31)

7월 후반은 두 개의 큰 축이 겹친 구간이다. 하나는 파일을 열고 편집하는 패널, 다른 하나는 앱을 종료해도 살아남는 터미널 세션이다. 그리고 이 시기에 스스로 만든 것을 폐기하는 결정이 두 번 나온다.

파일 패널 FP1~FP8

7월 17일 하루에 FP1부터 FP6까지 갔다. 단일 출처 문서를 새로 만들고 웹 스택을 vanilla TS + remark/rehype + 리치 렌더로 확정한 뒤, 모드명을 "읽기 / 소스 편집"으로 정확히 했다.

슬라이스내용
FP1도크 모델과 workspace 영속
FP2web renderer와 sanitizer
FP3도크 슬롯 배관
FP4격리 뷰어 브리지
FP5HTML 열기 라우팅
FP6Markdown 편집
FP7·FP8프로젝트 트리, 도크 분할 UI (7/18)

이어 7월 19~20일에 라이브 프리뷰 축을 열었다. 계약 문서 → 프리뷰 기반 → Markdown 라이브 프리뷰 worker → 기본 활성화 순으로 올리고 Mermaid helper 기반을 깔았으며, 다음 날 Obsidian형 라이브 프리뷰를 CM6 투영으로 본격 구현했다(원자형 프리뷰, 표 상호작용, Mermaid 연결, 전용 하니스와 성능 게이트).

영속 세션 호스트 P1~P3

발단은 tmux와 herdr을 보며 나온 요구다.

"지금 계획에 티먹스 계획이 있긴하잖아요? helder이나 이런거처럼 터미널 종료해도 백그라운드엔 살아있고, 바로 동작되게 하고..." — 2026-07-21

"대신 설정에, 앱이 종료되어도 세션 유지하기 설정을 넣고 그게 기본값이면 될 것 같은데요" — 2026-07-21

범위는 오히려 좁히는 쪽으로 정리됐다. 어디까지 살릴 것인가를 두고 나온 답이 명확했다.

"아뇨 어차피 호스트 크래쉬나 프로세스 종료 뒤는 상정하지 않겠습니다 문서에도 제거해주고 이번 계획 때 제거 잡아주세여" — 2026-07-21

7월 21일, 계약과 범위를 문서로 먼저 확정했다 — 호스트 프로토콜, 워크스페이스 상세, 외부 attach·resize 범위, P1 제거 계약. 그다음 provider 세션 연속성 잔여를 걷어내고 P2로 TermRuntimeBackend seam 계약과 in-process 어댑터를 만들어 GUI를 handle 계약으로 배선했다. P3는 MRSH wire codec부터 순서대로 쌓았다.

7월 22일에 session.keep-alive-after-quit 게이트가 들어가면서 실제로 살아남기 시작했다. connect-or-launch 오케스트레이션, host 연결을 앱 전역으로 승격해 멀티 윈도우 지원, workspace에 runtime_id를 영속시켜 재접속 경로를 열었다.

다음 날은 패리티 정리다. IME 조합 표시가 영속 터미널과 구 host 양쪽에서 깨져 있던 것을 복구하고, host-backed 마우스 리포팅(휠·클릭·드래그·우클릭)과 붙여넣기의 bracketed-paste 패리티를 맞췄다.

live-upgrade

7월 24일은 실행 중인 host를 무중단으로 갈아끼우는 작업이다. U0 계약을 고정하고 U1·U2 기반을 구현한 뒤, 업그레이드 타깃 inode 고정, staged target preflight, handoff 권위 저장과 attempt 기록, 승인·호스트별 업그레이드 권위 연결로 트랜잭션을 강화했다. 실패 대비도 같은 비중으로 다뤄 rollback self-image 권위와 rollback image staging을 함께 넣었다.

사라진 세션은 어떻게 되는가

7월 25일은 "세션이 사라졌을 때 무슨 일이 벌어지는가"를 계약으로 못박은 날이다. R0 영속 계약을 정렬하고 durable ended tombstone을 영속시켰으며, 복구 세션 inventory와 secure recovery discovery 코어, manifest runtime binding 검증을 붙였다. 복원이 누락된 runtime은 종료 placeholder로 잇고, 묘비에 화면 일부를 남겼다.

7월 26일에는 외부 터미널에서 붙는 public attach 경로를 완성했다. attach 정책 파서와 controller 전환 capability 협상, canonical attachment 요청 조립, 원격 attachment 권위의 엄격 해석, attach host 결정을 완전증거로 제한, 동일 TTY 사전 검증까지 권위 경계를 닫았다.

두 번의 철회

7월 27일 — FP16 계획 철회. PoC 4건과 스파이크 6건을 돌려 PanelKind 확장을 철회했고, 2차 검증에서 rename 반례가 나오자 불변식을 한정하며 EntryId 삭제도 철회했다. 결론은 파일 콘텐츠를 워크스페이스 Term으로 되돌리고 도크는 탐색기 전용으로 축소하는 것. eviction 대신 "surface 수명 == Term 수명" 불변식을 택했다.

다음 날 그 대공사를 하루에 끝냈다. Term에 파일 entry 소유 슬롯을 만들고 entry 창구·생성 경로·복원 파이프라인·entry 제거를 차례로 Term 쪽으로 옮기면서, 반대편에서 도크 editor chrome·기하·드래그 기계와 DockGroup/DockTree, FocusOwner.dock_surface 축, 옛 도크 포맷 읽기를 걷어냈다.

7월 29일 — 라이브 프리뷰 폐기. 오래 붙들고 있던 라이브 프리뷰를 폐기로 확정하고 네이티브·웹 양쪽 구현을 걷어냈다. 그 자리에 셋째 모드로 리치 편집 모드를 들이고 툴바를 가진 편집기를 붙였다. 콘텐츠 영역 UI 스택은 React·Tailwind·shadcn으로 정하고 실제 빌드까지 세웠다.

이 결정은 일주일에 걸쳐 기대 → 시도 → 후퇴 순서로 흘렀다.

"그리고 지금 읽기 라이브 프리뷰 소스 이렇게 나뉘어져있는데 그냥 제대로 구현되면 라이브 프리뷰가 모든걸 다 대체할 수 있을거라 보는데" — 2026-07-18

"사실 노션, 옵시디언 수준의 편집 기능을 원하는데 해보니까 제대로 되질 않아서요" — 2026-07-21

"일단 문서 어디까지 작업했는지 업데이트 해주시고, 라이브 프리뷰 일단 가려주세요 소스랑 읽기만 있으면 됩니다" — 2026-07-22

먼저 UI에서 가리고, 일주일 뒤 구현을 걷어냈다. 파일 패널이 다룰 파일 종류를 넓힌 것도 같은 시기다 — "지금 .md, .html 만 열 수 있는데 다른것도 다 열 수 있었으면 좋겠어요 일단 가능한것들은 json, txt, image, video, svg 등"(7/21).

그리고 코드 에디터

에디터 엔진 논의는 7월 11일부터 이어졌다. 처음 질문은 "어디에 그릴 것인가"였고,

"gif diff 보는 기능도 만들 예정인데, 이건 웹뷰로 넣는게 좋을까요? 아니면 터미널 그냥 자체 UI에 넣는게 좋을까요?" — 2026-07-11

그다음은 "무엇으로 그릴 것인가"였다. 처음엔 Monaco 쪽으로 기울어 있었다.

"넵 모나코는 유지할거고 cdn 형식이 아닌 실제 모나코 다운로드 받는 형태로 할건데 react 모나코에 그런 형태가 지원되나요?" — 2026-07-12

"근데 git diff는 CM6에선 어렵지 않아요? 모나코는 지원하는 기능인데" — 2026-07-17

7월 31일, 코드 에디터·git diff surface Phase 0을 설계하고 첫 조각을 붙였다. 설계는 스스로를 여러 번 뒤집는 과정이었다 — 결국 에디터 엔진은 Monaco를 기각하고 CodeMirror 6로 확정했고, PoC 3건으로 CSP 결론을 뒤집었다가 낡은 브랜치를 대조했음을 확인하고 CSP 결함 주장을 철회했다. 소켓 push 스트림 오인, file-panel 진행상태 오인, "전체 턴 enumerate" 과장 같은 자기 진술의 과장도 함께 정정했다.

7월 30일에는 하루가 거의 통째로 session-host의 외부 RX 경로를 봉인하는 데 들어갔다. 게이트를 문서로 정의하고, 구현으로 봉인하고, 완료를 다시 문서에 표시하는 순환이 반복된다.