2026-08-29
날짜는 UTC 기준으로 나눴습니다(9월 22일부터는 한국 시간 기준). 커밋은 커미터 시각(committer date), PR은 생성·병합 시각으로 분류했습니다. 목록은 2026-10-06 KST에 GitHub에서 다시 조회해 보강했습니다. 공개 저장소의 기본 브랜치 활동만 포함합니다.
요약 (AI 작성)
maru에 원격 에이전트 상태 축과 이미지 갤러리, 두 축이 열린 날입니다. 원격 상태 축은 훅 세트에 로컬/원격 스코프를 열고(RA1), maru ssh가 원격 pane 신원을 LC_MARU_PANE으로 보내며(RA2), 원격 훅 커맨드와 maru agent-events 스트리머를 만드는 토대(RA1부터 RA5, #2828)를 놓았습니다. 이어 원격 이벤트를 tick 루프에 붙여 배지가 ssh 너머에서 서게 했고(#2836), 원격 훅을 먼저 깔고 스트리머를 띄우며 로그 회전과 tmux 좌표를 남겼습니다(#2847). tmux 오배달을 역조회로 되찾는 RA6 작업도 이날 커밋됐고, 그 PR #2861의 병합은 다음 날입니다. 원격 SSH 알림은 훅 모드가 서지 않아 OSC가 담당한다는 점도 문서로 남겼습니다(#2823).
에이전트 이미지 갤러리는 계약과 계획을 세우고 뼈대와 인덱스(IG0·IG1, #2850), 격자(#2862), 크게 보기와 팬·줌(#2852), 중복 접기와 「무엇이었는지」 라벨(#2853)까지 하루에 섰습니다. 제품 스캔 실측 3.6초를 보고 동기 스캔을 기각해 스캔과 디코드를 워커로 옮겼고, 실제 세션이 드러낸 문제를 따라 최신 우선·스크롤·2:1 타일로 고쳤습니다(#2863). 기능 브랜치를 대상으로 열었던 #2851은 닫혔습니다.
편집기는 전날 열린 #2803으로 코드에 색을 입히기 시작했고, 구문 색을 theme.syntax 역할별로 정하게 했으며(#2811), 구문 파싱이 워커가 아니라 끊고 재개하는 방식으로 프레임 예산을 지키게 했습니다(§2.1a, #2824). 메이저 언어 열일곱을 더 칠해 grammar 18개가 됐고(#2840), 접힘이 구문 층으로 승격돼 언어별 종류 목록을 갖게 됐습니다(#2854). session-host는 자동 재접속을 bound jobs, worker issuer와 runtime, candidate adopt, admission coordinator와 settle을 거쳐 앱 전역으로 배선했고(#2864), cwd authority wire 토대를 놓았습니다(#2866). 읽을 주체가 없는 fd를 감시해 메인 스레드가 쉬지 않던 문제(#2831)와 복사가 자기 출력에 삼켜지던 문제도 고쳤습니다.
Windows는 전날 열린 실행 중 확인 모달 #2805를 병합하고, 창보다 긴 줄에 가로 스크롤과 막대를 붙였으며(W8.17c, #2812), 활성 카드가 화면 밖이면 사이드바가 따라가고 목록이 줄면 도크도 자기 범위로 돌아오게 했습니다(#2817, #2822). macOS 앱이 조용히 죽으면 흔적을 남기게 했고(#2818), 문서가 코드를 짚은 좌표를 게이트가 지키게 했습니다(#2814). 전날 열린 영속성 상태바 고지 #2798과 P4 게이트 현황 문서 #2802도 병합됐고, 모바일은 목록 줄을 눌러 그 세션 화면을 보게 했습니다(S11-6, #2832).
공개 커밋 150개, 해당일 생성 또는 병합된 PR 63개를 정리했습니다. PR 생성 59개·병합 58개는 같은 PR이 양쪽에 포함될 수 있습니다.
커밋
ohah/maru
- feat(session-host): add cwd authority wire foundation
- docs(session-host): reconcile completed P5 and E3b status
- feat(session-host): wire app-global automatic reconnect
- fix(image-gallery): 스크롤이 격자를 비우지 않는다 — 타일을 인덱스로 찾는다
- fix(image-gallery): 타일을 2:1 로 — 정사각은 실제 이미지와 안 맞는다
- fix(image-gallery): 최신을 먼저 보여주고 스크롤로 나머지에 닿는다 (IG7)
- docs(image-gallery): IG5 진행 상태와 세션 점프 취소 근거
- feat(image-gallery): 썸네일 아래에 「무엇이었는지」를 그린다 (IG5-c)
- feat(image-gallery): 격자 칸에 라벨 띠 (IG5-b)
- feat(image-gallery): 「이 이미지가 무엇이었는지」 순수 파서 (IG5-a)
- fix(image-gallery): 2중 저장을 접는다 — 계약이 약속했는데 구현이 없었다 (§4.3)
- feat(image-gallery): 훅이 없으면 자식 env 로 확정한 트랜스크립트로 메운다 (IG6-b)
- fix(image-gallery): 워커를 거두고 나간다 — detach 한 스레드가 메모리를 들고 살았다
- style(image-gallery): zig fmt
- fix(image-gallery): 문구가 첫 행 타일과 같은 띠를 쓰던 것 + 헤드리스 확인 게이트
- feat(image-gallery): 크게 보기에서 휠은 확대하고 드래그는 민다 (IG4-c)
- feat(image-gallery): 칸을 누르면 크게 열린다 (IG4-b)
- feat(image-gallery): 크게 보기의 팬·줌 순수 계산 (IG4-a)
- style(image-gallery): zig fmt — test 를 이어붙이며 생긴 빈 줄
- feat(image-gallery): 격자에 다 안 들어가면 말한다 (IG3-c3)
- test(image-gallery): 헤드리스로 실제 픽셀을 찍는 길을 연다
- docs(image-gallery): IG3 완료 — 격자에 이미지가 뜬다
- feat(image-gallery): 디코드를 워커로 옮긴다 (IG3-d)
- docs(image-gallery): IG3-a~c2 완료 상태를 적는다
- feat(image-gallery): 타일을 프레임 이미지 채널에 얹는다 (IG3-c2)
- feat(image-gallery): 격자 배치 순수 계산 (IG3-c1)
- feat(image-gallery): ImageIO 디코드를 붙인다 (IG3-b)
- feat(image-gallery): 텍스처 상한 clamp 계산 (IG3-a)
- feat(session-host): settle reconnect admission outcomes
- diag(session-host): 조용히 죽는 두 자리에 흔적을 남긴다
- fix(docs): 갤러리 계획을 인덱스에 넣고, 썩을 좌표를 뗀다
- feat(image-gallery): 스캔을 워커로 옮긴다 (IG1-e)
- docs(image-gallery): 제품 스캔 실측 3.6초 — 동기 스캔을 기각하고 워커를 앞당긴다
- docs(image-gallery): IG1 완료 상태와 계획과의 차이를 적는다
- feat(image-gallery): 갤러리 뷰가 활성 pane 의 이미지를 센다 (IG1-d)
- docs(image-gallery): 진행 상태와 검증 방법(베이스라인 대비 실패 수)을 적는다
- feat(image-gallery): 훅 payload 에서 갤러리 소스를 채택한다 (IG1-c)
- feat(image-gallery): 도크 네 번째 뷰 슬롯을 연다 (IG1-b)
- feat(image-gallery): 트랜스크립트 이미지 위치 스캐너 (IG1-a)
- refactor(dock): View 슬롯 순서의 손-미러를 지운다 (IG0)
- docs(image-gallery): 에이전트 이미지 갤러리 계약과 구현 계획을 세운다
- test(agent-hooks): CI 가 잡은 판정자 둘 — 내가 틀린 자리다
- fix(agent-hooks): POSIX 전용 설치 경로를 Windows 컴파일에서 가지친다
- feat(agent-hooks): 원격 훅이 tmux 좌표를 옆 파일에 남긴다 (RA6 선결)
- feat(agent-hooks): 원격 훅을 먼저 깔고 그 뒤에 스트리머를 띄운다 (RA3 배선)
- feat(agent-hooks):
maru agent-hooks로 원격 기계가 자기 훅을 심는다 (RA3) - feat(agent-events): 스트리머가 없던 동안 자란 로그를 시작할 때 거둔다 (RA3 상한)
- fix(agent-events): 1 MiB 를 넘긴 원격 로그가 영영 안 읽히고 안 줄었다 (RA3 회전)
- feat(session-host): reserve reconnect coordinator work
- feat(editor): 접힘이 구문 층으로 승격된다 — 언어별 종류 목록 (N4 §4)
- refactor(session-host): 검증에 안 쓰는 generation 을 Prepared 에서 뺀다
- fix(session-host): 복사가 자기 출력에 삼켜졌다 — 기준선은 한 번만 잡는다
- docs(layering): §3.4 계수 방식을 재현 가능한 명령으로 적는다
- docs(windows): 적대적 검증 — dock_scroll 판정이 오래 접혀 있었다(보고)
- docs(windows): 적대적 검증 — §2k 가 안 받는 메시지를 적고, 받는 넷을 빼먹었다
- docs(layering): §3.4 결정과 어긋난 표지 둘을 고친다
- fix(ssh): 쌓인 죽은 host 줄이 attach 를 막지 않는다 — 그리고 못 붙으면 말한다
- fix(mobile): 원격 화면이 창을 통째로 덮는다
- fix(control-plane): 앵커를 안 댄 연결은 세션 목록을 본다
- docs(plans): 전수 훑기가 남긴 낡은 헤딩 둘을 마저 고친다
- docs(plans): 계획 문서의 낡은 상태 여섯을 코드에 맞춘다
- feat(session-host): add reconnect worker runtime
- fix(agent-hooks): 게이트가 꺼져도 원격 축이 돌았다 — 한 Term 을 두 소스가 쓸 뻔했다
- fix(ssh):
$HOME을 작은따옴표에 가둔 자리를 고친다 — 축 전체가 죽는 한 글자 - docs(agent-hooks): §11.6 의 «RA1~RA5 배선» 을 정확히 고친다 — RA3 는 절반만이다
- chore(i18n): 원격 채널 진단 로그 둘을 원장에 올린다 — 표시가 아니라 사유다
- fix(agent-hooks): 적대적 검증이 잡은 둘 — 60fps 로 돌던 펌프와 안 놓아지던 채널
- feat(agent-hooks): 원격 이벤트를 tick 루프에 붙인다 — 배지가 ssh 너머에서 선다 (RA5)
- docs(status-bar): 「첫 Term 은 항상 in-process」 는 틀렸다 — 재실측으로 정정
- feat(editor): 새 언어들의 캡처를 표가 받는다 — property 가 열 개 언어에서 무색이었다
- feat(editor): 메이저 언어 열일곱을 더 칠한다 — grammar 18개 (N4 §5.3)
- feat(session-host): adopt automatic reconnect candidates
- docs(windows): 문서 감사 — 낡은 칸 둘, 없던 행 둘, 중복 절 하나를 고친다
- test(session-host): 감시 집합이 pump 집합을 벗어나면 잡는다
- feat(session-host): add automatic reconnect worker issuer
- feat(mobile): 목록 줄을 눌러 그 세션 화면을 본다 (S11-6)
- docs(windows): §2m.86 정정 — 제목 글리프 밀림은 "번들 폰트 없음" 에서만 난다
- fix(agent-hooks): sed 이 두 번 붙인
.local을 걷어낸다 — 그리고 왜 로컬이 못 봤나 - fix(agent-hooks): CI 가 잡은 둘을 고친다 — 놓친 호출부와 밀린 문서 좌표
- fix(agent-hooks): 「물어보지도 못했다」와 「진짜 detached」를 가른다 (RA6)
- feat(ssh): 원격 tmux 역조회를 실행한다 — 오염된 nonce 를 되찾는다 (RA6 배선)
- feat(ssh): 원격 이벤트 스트리머를 띄우고 끝내는 자리 (RA5 배선)
- test(agent-hooks): 원격 축이 로컬을 안 바꾼다는 것을 전수로 못박는다
- feat(agent-hooks): 원격 채널이 열리면 훅 모드가 선다 (RA5)
- test(agent-hooks): RA6 적대적 검증에서 나온 둘을 본 테스트로 올린다
- feat(agent-hooks): 원격 tmux 의 오배달을 역조회로 막는다 (RA6 절반)
- feat(agent-hooks): nonce 라우팅을 닫는다 — 어느 Term 의 이벤트인가 (RA5)
- test(agent-hooks): RA5 적대적 검증에서 나온 넷을 본 테스트로 올린다
- test(agent-hooks): RA4 가 실제로 뱉은 wire 를 RA5 회귀로 잠근다
- feat(agent-hooks): 원격 스트리머 wire 를 읽는 순수 소비자 (RA5 절반)
- feat(cli): maru agent-events — 원격 훅 로그를 exec 채널로 흘린다 (RA4)
- feat(agent-hooks): 원격 훅 커맨드를 만든다 — 칸 하나, 평평한 경로 (RA3)
- feat(ssh): maru ssh 가 원격 pane 신원을 LC_MARU_PANE 으로 보낸다 (RA2)
- fix(agent-hooks): planForSet 도 스코프를 받는다 — 안 그러면 원격 설치가 영영 refresh 다 (RA1)
- feat(agent-hooks): 훅 세트에 로컬/원격 스코프 축을 연다 (RA1)
- fix(session-host): 읽을 주체가 없는 fd 를 감시해 메인 스레드가 쉬지 않았다
- feat(windows): 에이전트 목록이 훑는 중이라고 말한다
- feat(session-host): bound automatic reconnect jobs
- docs(plans): 원격 에이전트 상태(배지·대화 줄) 단계 계획을 연다
- docs(agent-hooks): 원인이 밝혀진 관측을 §9-6 에서 뺀다
- docs(agent-hooks): PermissionRequest 는 대화형에서 온다 — 재실측으로 낡은 문장을 걷어낸다
- docs(agent-hooks): 낡은 절 참조 하나를 고친다 (§8-6 → §9-6)
- docs(agent-hooks): 적대적 검증 3회로 §11 의 과장·중복·틀린 서술을 걷어낸다
- docs(agent-hooks): 원격 SSH 알림은 훅 모드가 안 서서 OSC 가 산다
- fix(windows): 사이드바가 그리는 목록과 재는 목록을 갈라 놓고 있었다
- refactor(session-host): consolidate screen inbox ownership
- docs(editor): 파싱 예산을 실제 파일로 재고 근거를 실측으로 바꾼다 (§2.1a)
- feat(editor): 구문 파싱이 프레임 예산을 지킨다 — 끊고 재개한다 (§2.1a)
- ci: bundled CLI 게이트 예산을 20→35분으로 올린다 — 앱 재빌드가 들어갈 자리가 없었다
- fix(macos-app): 시그널 핸들러 안의 잠재 오버플로 패닉을 없앤다
- feat(macos-app): 종료 마커에 «누가 보냈는지» 를 남긴다 — signal 번호만으로는 못 좁힌다
- feat(macos-app): 앱이 조용히 죽으면 흔적을 남긴다 — 진단할 재료가 0이었다
- fix(windows): 목록이 줄면 도크도 자기 범위로 돌아온다 — 그리고 표면마다 휠 나머지
- test(config): 팔레트도 문서와 로더가 같은 범위를 말하는지 잰다 (PAL1)
- test(session-host): verify reconnect SSH isolation
- docs(editor): 구문 파싱은 끊고 재개한다 — 워커가 아니다 (§2.1a)
- docs(windows): 카드가 열여섯을 넘으면 기하가 갈린다 — 적대적 검증 보고
- feat(windows): 눈이 따라간다 — 활성 카드가 화면 밖이면 사이드바가 옮긴다
- fix(session-host): surface SSH upload failures
- feat(docs): 문서가 코드를 짚은 좌표를 게이트가 지킨다
- feat(control-plane): sessions.list 가 runtime_id 를 낸다
- style(app-session): 훅 턴 시각 상수 뒤 빈 줄이 두 개였다 — fmt 게이트가 잡았다
- docs(agent-session): 로그 필터링의 값을 실제로 재고, 하지 않기로 한 근거를 바꾼다
- feat(agent-hooks): 턴이 열린 시각을 남긴다 — payload 에 시각이 없어 «얼마나 오래» 를 못 답했다
- docs(agent-session): 시각을 어디서 찍을지 셋을 재고 «구간 기록» 을 고른다
- docs(agent-session): codex 실측과 로그 적재량을 함께 남기고, 시각을 어디서 찍어야 하는지 바로잡는다
- docs(agent-session): 중단된 턴이 «진행 중» 으로 남는 이유를 실측과 함께 남긴다
- docs: 좌표가 아니라 서술이 코드와 어긋나던 자리를 고친다
- docs: 코드 좌표가 가리키는 자리를 실제 위치로 되돌린다
- test(windows): 막대 트랙의 빈 자리 클릭 — 드래그와 다른 길이다
- fix(windows): 가로로 조금 민 것이 세로 한 줄로 튀었다 — 축마다 누적기
- test(windows): 터미널 위의 가로 휠 — 리포팅을 켜야 그 길에 닿는다
- feat(windows): 창보다 긴 줄에 축이 생겼다 — 가로 스크롤과 막대
- feat(config): 구문 색을 역할별로 정한다 — theme.syntax.<역할> (N4 §9.0)
- docs(editor): 구문 색 역할별 override 설계 (N4 §9.0)
- feat(session-host): make SSH action freshness asynchronous
- docs(windows): §2m.81 — 확인 모달 적대적 검증 4~6회
- test(windows): 적대적 검증 4~6회차 — 모달이 창을 따라오는가, 되풀이하면 쌓이는가
- docs(windows): §2m.80 — 확인 모달 적대적 검증 3회
- fix(windows): 적대적 검증 3회 — 모달이 창 버튼을 막고, 보류한 번호가 밀렸다
- docs(windows): §2m.79 — 확인 모달, 없던 것은 컴포넌트가 아니라 배선 셋이었다
- feat(windows): 실행 중이면 확인 모달을 띄운다 — W8.16 의 나머지
- docs(session-host): keep default-on migration in backlog
- docs(session-host): P4 게이트 현황을 코드·실측으로 다시 적는다
- fix(status-bar): 아이콘 충돌을 피하고 표를 실제 조립 순서로 맞춘다
- feat(status-bar): 영속성이 깨진 동안 그 사실을 화면에 남긴다
- test(syntax): 증분 파싱과 창 계약을 판정자가 지킨다 (N4 §5.3)
- fix(lab): 표시 폭 골든에서 색을 뺀다 — CI 에서만 깨졌다
- feat(editor): 편집기가 코드에 색을 입힌다 — 제품 배선과 캡처 (N4 §5.3)
- feat(editor): 구문 색의 순수 층과 provider — 캡처→색, 토큰, run 분할 (N4 §5.3)
PR (해당일 생성/머지)
상태는 조회 시점 기준입니다. merged는 아래 대상 브랜치에 병합됐다는 뜻이며, 기능 브랜치 병합과 main 반영을 구분합니다. 같은 PR이 생성일과 병합일 양쪽 기록에 나타날 수 있습니다.