2026-08-16
요약 (AI 작성)
UI 문자열 국제화를 doc-first 로 열고 하루 만에 실사용 단계까지 민 날입니다. 표시 문자열 테이블·조회·보간의 중립 leaf 를 세우고(I3-0) platform 문자열 40건, 세팅 배너·토스트, notice 토스트 97건, 분기·보간형 notice 13건을 차례로 키로 옮겼습니다(I3a 슬라이스 1~5). 옮긴 문자열이 아무도 안 보는 테이블에 쌓이고 있다는 것을 발견해 ui.language 를 실제로 배선했고(I4a), 전환 도중 화면이 영어로 바뀌던 회귀와 두 언어 테이블의 정합을 테스트로 잠갔습니다.
Windows 는 헤드리스 세로 슬라이스가 실제로 서는 데까지 갔습니다. ConPTY 백엔드를 붙이고 자식 attach 를 실측으로 닫았으며(W4), 셸 통합 주입을 cmd PROMPT 와 PowerShell 인라인 -Command 로 갈랐고(W5), 상대 경로 링크 감지의 접두 갈래 둘을 열었습니다(W5.5). SpawnRequest 를 중립화해 경로를 입구에서 정규화하고, 통합 주입 seam 을 "갈리는 축은 OS 가 아니라 메커니즘"으로 정리했습니다.
파일 패널은 커밋을 실제로 실행하는 데까지 갔습니다. 커밋 메시지 입력(P3c-1)과 실행·저장소별 초안 보관·워크트리 감시(P3c-2)를 올린 뒤, 목록의 첫 층을 저장소·워크트리로 만들고(P3d-①②) 비활성 저장소의 머리 줄을 하나씩 읽어 채웠습니다(P3d-③). 편집기는 랩과 가로 스크롤의 성능을 파고들어 첫 가로 휠에 501ms 멈추던 것과 5만 줄에서 프레임당 498ms 를 쓰던 것을 고치고, 긴 한글 줄의 조각 수를 21배 적게 세던 계산 오류를 잡았습니다. 모바일은 config 를 실제로 읽어 화면에 닿게 하고(M10b·M10c) 설정 화면을 스키마에서 만들었으며, 세션 목록을 뿌리로 세우고(U3) 포인터에 손가락 id 를 실어 소유권을 코어가 들게 했습니다(T0~T2). session-host 는 CR4 catch-up barrier 계약과 controller takeover 를 봉인했습니다.
커밋
ohah/maru
- fix(file-panel): 변경이 없을 때 도크가 빈 면 대신 문장을 낸다
- fix(file-panel): 깨끗한 저장소에서 소스 컨트롤 도크가 통째로 사라지던 것을 고친다
- fix(file-panel): 커밋 버튼이 도크 폭을 꽉 채운다
- feat(file-panel): 커밋 줄을 목록 위로 올리고 채운 버튼으로 만든다 (§3.5 3판)
- feat(file-panel): 커밋 입력·버튼을 도크에 배치한다 (P3b)
- style(ios): loadConfigFile 전방 선언을 둔다
- docs(plan): M10b0·M10b 를 완료로 옮긴다
- test(mobile): config 를 여러 번 갈아 끼우는 경로를 잠근다
- fix(mobile): 새 export 를 ABI 헤더에 싣는다
- fix(mobile): 코어보다 먼저 읽은 config 가 조용히 버려지던 것을 고친다
- fix(mobile): config 크기 상한과 읽는 시점을 두 host 에서 맞춘다
- feat(ios): config 파일을 읽어 브리지에 넘긴다
- fix(session-host): pass initial snapshot frontier
- feat(session-host): enforce CR4a screen frontiers
- docs(config): 예제의 줄 끝 주석을 줄 위로 옮긴다
- chore(config): 적대적 검증 후속 — 죽은 코드 제거와 문서 한 줄
- docs(mobile): shell.windows-shell을 모바일 판정 표에 싣는다
- fix(config): 코드 리뷰가 잡은 것을 닫고, 그 수정을 다시 검증한다
- feat(config): OS별 값과 Windows 기본 셸 선택을 넣는다
- fix(config): 엔진을 열며 움직인 external source digest 를 갱신한다
- feat(mobile): config 를 실제로 읽어 화면에 닿게 한다 (M10b0·M10b)
- feat(session-host): prepare CR4a observer candidate
- feat(session-host): CR4 catch-up admission을 연결한다
- docs(mobile): "고를 수 없으면 없는 값" 을 계약에 적는다
- fix(mobile): 숫자 줄이 눌린 티만 내고 아무 일도 안 하던 것을 없앤다
- fix(config): 적대적 검증 수정으로 움직인 digest 를 갱신한다
- fix(mobile): 적대적 검증 셋 — 잘린 목록·거짓 이름·넘치는 팝업
- docs: M10c 를 완료로 옮기고 색 줄의 경계를 적는다
- feat(mobile): 설정 화면을 스키마에서 만들고 바꾼 값을 저장한다 (M10c)
- test(cli): "cli/는 순수" 를 주석에서 게이트로 옮긴다
- feat(windows): SpawnRequest를 중립화하고 경로를 입구에서 정규화한다
- feat(session-host): catch-up host 상태 계약을 고정한다
- fix(windows): W3 적대적 검증 후속 — 조립기 불일치와 낡은 주석
- style(session-host): catch-up barrier 계약 포맷을 맞춘다
- feat(session-host): CR4 catch-up barrier wire 계약을 고정한다
- docs(windows): W5·W5.5의 선행 실측을 계약에 기록하고 §3.3↔§4.2 모순을 닫는다
- fix(windows): W4 코드리뷰 + 적대적 검증 8라운드 후속
- docs(windows): W4·W6을 계약·계획 밖 문서와도 맞춘다
- feat(session-host): CR4 client barrier demux를 추가한다
- fix(ci): 리베이스 뒤 digest를 맞춘다
- fix(chrome): 탭 줄 상하 여백을 늘린다 (사용자 지적)
- fix(file-panel): 첫 읽기가 늦게 와도 쓰던 커밋 메시지가 사라지지 않는다
- feat(file-panel): 커밋을 실행하고, 초안을 저장소별로 들고, 워크트리 감시를 고친다 (P3c-2)
- fix(windows): cmd fixture의 따옴표 함정을 테스트로 막고 한글 실측을 기록한다
- chore: 실수로 커밋된 쓰레기 파일을 지운다
- docs(i18n): UI 문자열 로컬라이제이션 전략과 구현 계획 (doc-first)
- feat(file-panel): 터미널이 선 저장소와 그 워크트리를 목록으로 모은다 (P3d-①)
- feat(session): 도크가 세울 저장소·워크트리 목록의 순서·중복·상한을 정한다 (P3d-①)
- feat(session): 워크트리 목록을 읽는다 + P3d 설계를 확정한다 (P3d-①)
- refactor(mobile): 죽은 텍스트 경로를 지우고 재발을 판정자로 막는다 (U3c)
- test(mobile): iOS 제스처를 스크립트로 미는 길을 연다
- docs(mobile): 에뮬레이터 컷아웃 정책과 좌우 inset 공백을 적는다
- fix(mobile): Android 가 컷아웃 inset 도 묻는다 — 본문이 카메라 구멍 뒤에 깔렸다
- feat(mobile): 세션 목록을 뿌리로 세우고 설정 입구를 그리로 옮긴다 (U3b)
- feat(mobile): 죽은 chrome 을 걷어낸다 (U3a)
- feat(session-host): CR4 actual candidate stage를 완료한다
- feat(windows): 셸 통합 주입 (W5) — cmd PROMPT와 PowerShell 인라인 -Command
- feat(session-host): CR4 same-adapter Client replacement를 게시한다
- fix(i18n): rebase 후 digest 를 맞춘다
- fix(i18n): 폴백 복원 후 digest 를 맞춘다
- fix(i18n): 자동 복구 안내의 폴백 키를 되살린다 — 축약이 아니라 다른 행동이다
- fix(i18n): 슬라이스 4 의 digest 를 맞춘다
- feat(i18n): 분기·보간형 notice 13건을 키로 옮긴다 (I3a 슬라이스 4)
- test(i18n): 좌표를 재는 확인 모달 테스트의 픽스처 폭을 되살린다
- refactor(i18n): showConfirm 을 키 타입으로 바꾼다 — 진입점 옆에 리터럴이 남아 있었다
- fix(i18n): rebase 뒤 원장을 다시 수렴시킨다 — 로컬은 통과하고 CI 만 깨졌다
- fix(i18n): 슬라이스 5 의 digest 를 맞춘다
- fix(i18n): 전환 도중의 초기 언어를 ko 로 둔다 — 화면이 영어로 바뀌고 있었다
- fix(ci): 리베이스 뒤 digest를 다시 맞춘다
- fix(ci): 리베이스 뒤 digest를 맞춘다
- feat(file-panel): 비활성 저장소의 머리 줄을 하나씩 읽어 채운다 (P3d-③)
- refactor(path): 후행 구분자 다듬기를 path_shape로 모은다
- feat(session-host): CR4 host frontier barrier를 게시한다
- refactor(cli): main.zig 를 얇은 디스패처로 되돌린다
- fix(ci): 리베이스 뒤 app_session digest를 맞춘다
- fix(file-panel): 커밋 상자 caret이 깜빡인다 (적대적 검증 ⑧)
- fix(file-panel): 적대적 검증이 찾은 일곱을 고친다 (P3c-1)
- feat(file-panel): 커밋 메시지를 실제로 입력한다 (P3c-1)
- docs(structure): 소스 트리 문서를 실제 구조에 맞춘다
- docs(chrome): chrome doc comment 를 저장소 언어로 되돌린다
- docs(windows): ConPTY 자식 attach를 실측으로 닫는다
- feat(windows): ConPTY 백엔드 (W4) — 헤드리스 세로 슬라이스가 선다
- docs(mobile): 적대적 검증 다섯 회차 — 공유 경계와 게이트 구멍
- docs(mobile): 섹션은 빌려도 안 따라온다 — 정정
- docs(mobile): 엔진 공유의 경계를 적대적 검증으로 다시 긋는다
- fix(editor): 안 넘쳐도 가로 축을 뺏고 있었다 — 뮤턴트를 커밋했고, 그것을 잡는 테스트가 없었다
- docs(editor): 계약이 열어 둔 "초장문 단일 줄 임계"를 가로 축에서 닫는다
- test(editor): 셈 상한의 여유분이 무엇을 지키는지 테스트가 없었다
- docs(editor): 랩의 대가를 약하게 적어 뒀다 — 한 줄짜리 문서는 아예 못 움직인다
- perf(editor): 상한을 넣고도 520만 열을 세고 있었다 — 셈에도 상한을 둔다
- perf(editor): 가로로 멀리 밀면 프레임당 498ms였다 — 싸게 건너뛰고, §3.8 상한을 둔다
- perf(editor): 첫 가로 휠이 5만 줄에서 501ms 멈췄다 — 흔한 걸음을 먼저 끝낸다
- refactor(editor): 랩 불변식을 상태로 지키지 말고 읽는 자리에서 세운다
- fix(editor): 창이 커지면 화면이 통째로 비었다 — 그리기 직전에 두 축을 되돌린다
- feat(editor): 랩을 끄면 긴 줄의 오른쪽을 볼 수 없었다 — 가로 스크롤
- feat(input): Windows 상대 경로 링크 감지 — 접두 갈래 둘 (W5.5)
- docs(editor): 랩+비교 정렬은 Vim 선례를 따라 적고 둔다 — 레퍼런스 셋을 확인한 결과
- docs(editor): 랩을 켠 비교는 좌우가 어긋난다 — 사실을 고정하고 답을 미룬다
- fix(editor): 4096줄이 넘는 랩 문서는 끝에 못 닿았다 — 상한을 뒤에서 직접 센다
- fix(editor): 긴 한글 줄의 조각 수를 21배 적게 세고 있었다 — 그 줄의 5%만 볼 수 있었다
- fix(editor): 비교 뷰의 조각 수를 절반으로 세고 있었다 — 두 라운드 전에 표시해 둔 지뢰
- feat(editor): 랩을 켜면 한 줄짜리 문서를 못 봤다 — 조각 단위 세로 스크롤
- feat(session-host): CR4 catch-up receipt를 봉인한다
- fix(i18n): 경계 원장을 맞춘다 — 새 leaf 의 반사 하나를 등재한다
- test(i18n): 보간 문법의 경계를 테스트로 좁힌다
- feat(i18n): 세팅 배너/토스트를 키로 바꾸고 보간 진입점을 연다 (I3a 슬라이스 2)
- feat(i18n): 파일 탐색기 루트 안내를 키로 바꾼다 — 1차 방어 첫 사례 (I3a 슬라이스 1)
- feat(i18n): 표시 문자열 테이블·조회·보간의 중립 leaf 를 세운다 (I3-0)
- fix(input): W5.5 적대적 검증 — 이스케이프 판정을 목록에서 규칙으로 (§5.2 ⒜)
- chore(mobile): 하네스 폴더 이름에서 poc 를 뗀다
- docs(mobile): 남은 터치 구멍과 그 방아쇠를 적는다
- fix(mobile): 관성이 배경 복귀에 튀지 않고, 꼬리 표본이 flick 을 안 죽인다
- fix(mobile): 관성을 시간으로 돌린다 — 기기마다 다르게 미끄러지지 않게
- fix(mobile): 흐르는 것을 세우려 짚은 손가락은 누른 것이 아니다
- refactor(mobile): 스크롤·관성을 ScrollArea 컴포넌트 하나로 모은다
- feat(mobile): 설정의 숫자 칸을 입력 대상으로 만든다 (M10e)
- docs(windows): 통합 주입 seam을 정한다 — 갈리는 축은 OS가 아니라 메커니즘 (§4.2a)
- feat(session-host): CR4 actual issuer Client를 backend job에 봉인한다
- feat(mobile): 포인터에 손가락 id 를 싣고 소유권을 코어가 든다 (T1)
- feat(link): hover 밑줄도 클릭과 같은 존재검증을 통과한다 (§8)
- docs(scm-dock): 읽기 규약의 근거를 락에서 비용으로 정정한다
- fix(ci): 리베이스 뒤 digest를 맞춘다
- fix(tests): cwd 축 재고에 테스트 픽스처를 등재한다
- feat(file-panel): 목록의 첫 층을 저장소·워크트리로 만든다 (P3d-②)
- docs(mobile): 다음 세 덩이의 순서를 정한다 (U3 → T → R)
- docs(mobile): 손가락별 기준으로 바꾼다 — 이어받기 코드를 없앤다
- docs(mobile): 레퍼런스 근거를 확인한 것만 남긴다
- docs(mobile): 손가락 id 와 소유권을 계약으로 정한다 (T0)
- fix(i18n): rebase 후 digest 를 다시 실측으로 맞춘다
- feat(i18n): 클립보드 안내 둘을 보간으로 흡수한다 — 죽은 API 를 없앤다
- fix(i18n): 검증 후속으로 움직인 digest 를 맞춘다
- test(i18n): 두 언어 테이블의 정합을 테스트로 잠근다
- refactor(i18n): 두 파일이 공유하는 키에 common_ 접두를 준다
- feat(i18n): notice 토스트 97건을 키로 옮긴다 (I3a 슬라이스 3)
- feat(mobile): Android 가 손가락 전부를 보내고 브리지가 소유자로 가른다 (T2)
- test(session-host): CR4b 상속 오라클을 보강한다
- feat(session-host): CR4b controller takeover를 봉인한다