2026-09-14
날짜는 UTC 기준으로 나눴습니다(9월 22일부터는 한국 시간 기준). 커밋은 커미터 시각(committer date), PR은 생성·병합 시각으로 분류했습니다. 목록은 2026-10-06 KST에 GitHub에서 다시 조회해 보강했습니다. 공개 저장소의 기본 브랜치 활동만 포함합니다.
요약 (AI 작성)
maru에서 에이전트 이미지가 터미널 안에서 열리게 된 날입니다. 마커 프리뷰를 설계하며 적대적 검증으로 초안을 여러 번 고친 뒤, 전송 전 스테이징 코어가 번호를 추측하지 않고 관찰하게 하고(MP1), 터미널의 [Image #N] 마커를 Cmd+클릭하면 그 자리에서 팝오버로 보게 했습니다(#3721). 원격 전송 후 프리뷰는 wire를 판 5로 올려 픽셀을 저쪽에서 당겨오고(P3, #3731), 프리뷰에서 「도크에서 보기」로 갤러리 크게 보기로 가게 했습니다(#3740). 디코드 결과가 남의 프리뷰에 붙고 죽은 surface가 픽셀을 들고 있던 것도 고쳤습니다(#3723). 에이전트 이어하기는 권한 모드와 끝난 뒤의 셸까지 그 세션의 모양을 되살리고(#3733), 원격 훅 설치를 못 띄워도 굳히지 않게 했습니다(#3709).
소스 컨트롤은 병합 충돌의 세 판(:1:·:2:·:3:)을 읽고(#3706), 충돌 파일을 세 판을 든 「병합 모드」 편집기로 열며(#3715), 3-way 병합을 pane 넷으로 그린 뒤(#3720) S2의 「고르기」 줄을 병합 pane에 되살렸습니다(#3741). 세 판의 스크롤 관례는 실측해서 §7 ⑥에 적었습니다. 원격 pane의 에이전트 탭은 「아직 지원하지 않습니다」 한 줄로 끝나게 하고, 연결이 끊긴 원격 pane이 「저장소를 확인할 수 없다」고 말하던 것을 고쳤습니다(#3703). 파일 탐색기는 .gitignore 흐림을 막던 세 자리를 고치고(#3708) 흐림 질의를 트리에서 읽게 했습니다(#3727).
terminal-core는 전날 열린 kitty delete 타깃 여섯 #3693을 병합하고, d=a가 화면에 보이는 배치만 지워 스크롤백 이미지를 살리게 했으며(#3705), wuffs로 PNG 여덟 변종을 열고 PNG 프레임과 o=z를 받게 했습니다(#3716, #3718). 매체 전송 설계는 실측으로 (A)에서 (B)로 다시 골랐습니다. 렌더러는 글리프 캐시 조회가 캐시 크기만큼 훑던 것(#3701)과 터미널 브라우저 스크롤이 60Hz를 무너뜨리던 세 곳(#3735)을 고쳤습니다. session-host는 화면 스트림 바이트를 재고, 화면이 큰 pane 하나가 세션 전부의 연결을 끊던 것(#3732)과 spawn이 셀 픽셀을 안 실어 이미지 자식이 기본 크기로 굳던 것을 고쳤으며, 실제 cross-uid 거부와 IME 조합 픽셀의 복구 surface 결속을 검증했습니다. Chrome Lab은 넓은 창 모서리와 드롭다운 시나리오 골든을 얻었고, 아카이브 스모크를 CI가 돌리게 하는 #3743은 이날 PR이 열렸습니다.
hwpjs는 EMF로 갔습니다(30커밋). 헤더 확장과 eof palette, pixel format descriptor, path bracket, world transform, mode·color·mapper·miter 상태, device context 스택, logical palette와 객체 테이블 상태, 색 공간·pen·brush·확장 font 객체, 16·32비트 poly와 point·shape 그리기 레코드를 검증합니다. @ohah/pdf는 파일 묶음(포트폴리오)을 알려 주고, 거듭 열어도 메모리가 안 자라는지 확인하며, pdf.js 맞대기를 나눠 돌려 18.9초를 4.4초로 줄였습니다. ohah.github.io에는 8월 18일부터 9월 14일까지의 오늘의 커밋 백필과 월간 오픈소스 갱신이 올라갔습니다.
공개 커밋 168개, 해당일 생성 또는 병합된 PR 52개를 정리했습니다. PR 생성 47개·병합 51개는 같은 PR이 양쪽에 포함될 수 있습니다.
커밋
ohah/hwpjs
- fix(emf): accept trailing handle record data
- fix(emf): accept trailing fixed-record data
- feat(emf): validate basic shape records
- feat(emf): validate basic point drawing records
- feat(emf): validate poly draw records
- feat(emf): validate 16-bit poly records
- feat(emf): validate 32-bit poly records
- feat(emf): validate extended font objects
- feat(emf): validate bitmap brush objects
- feat(emf): validate extended pen objects
- feat(emf): validate basic pen and brush objects
- feat(emf): validate color space creation payloads
- feat(emf): validate color space object state
- feat(emf): track selected graphics objects
- test(emf): validate HWP BinData corpus path
- feat(emf): validate object table state
- feat(emf): parse logical palette records
- feat(emf): validate device context stack
- feat(emf): parse justification and extent scaling
- feat(emf): parse text alignment state
- feat(emf): parse mapper and miter state
- feat(emf): parse color state records
- feat(emf): parse mode state records
- feat(emf): parse fixed point state records
- feat(emf): parse world transform records
- feat(emf): validate path bracket records
- feat(emf): validate record type enumeration
- feat(emf): parse pixel format descriptors
- feat(emf): validate eof palettes
- feat(emf): parse header extensions
ohah/maru
- ci(check): perf 하네스를 ReleaseFast 로 컴파일만 하는 게이트를 check 에 건다
- fix(render): /code-review 가 잡은 셋 — 반전 화면 trim·승격 실패 뒤 free·replace 원자성
- perf(render): 줄끝 trim 과 이미지 버퍼 재사용을 제품 동작으로 올린다
- fix(render): 선택·검색 하이라이트를 격자 기반으로 옮겨 빈 칸에서도 칠한다
- docs(io-render): 브라우저 스크롤 진단을 §10.6 으로 남기고 「근본은 CVDisplayLink」를 정정한다
- perf(render): 브라우저 스크롤이 60Hz 를 무너뜨리던 세 곳을 실험 플래그 뒤에서 없앤다
- feat(editor): 병합 pane 에 S2 의 «고르기» 줄을 되살린다 (S3b-3a)
- docs(editor): S3b-3 을 «공격해» 보고 다시 셋으로 가른다
- docs(agent-image): 「도크에서 보기」를 미구현에서 구현으로 — 네 자리를 전수로 고친다
- test(boundary): 순수 판정자가 못 보는 두 자리를 센다(적대적 4·8회차)
- feat(agent-image): 프리뷰에서 「도크에서 보기」 — 누르면 갤러리 크게 보기로 간다
- docs(chrome): below_clamp 을 「어느 그림이 증언하는가」로 잇고, 랩이 못 보는 것을 적는다
- test(chrome-lab): 골든이 못 보는 것을 본다고 적어 뒀다(적대적 2·7·10회차)
- test(chrome-lab): 드롭다운에 시나리오가 하나도 없었다 — below_clamp 를 그림으로 고정한다
- fix(chrome): 큰 폰트에서 도크 뷰 스위처가 사라졌다 — 슬롯 폭을 pt 로 옮긴다
- docs(chrome): 네 방향 edge_gap 을 「어느 그림이 증언하는가」로 잇는다
- fix(chrome-lab): 산출물이 창 크기를 거짓말하고 있었다(적대적 5·6회차)
- test(chrome-lab): 우·하 edge_gap 에 그림이 없었다 — 넓은 창 모서리 시나리오
- test(editor): 병합 pane 판정자를 «빈틈없이» 조인다 — 적대적 12~18회차
- fix(app-session): 판정자가 앵커를 찍어 메뉴 밖을 눌렀다(적대적 A51)
- fix(chrome): fmt 와 도크 시각 골든 — 「골든 없음」이 틀렸다
- fix(chrome): 프리미티브만 안전하게 만들고 호출자를 안 봤다(적대적 A41~A50)
- fix(chrome): popup_box 를 i64 도메인으로 — 캐스팅 여덟 곳이 방어 없이 남아 있었다(A36~A40)
- fix(chrome): 양쪽 gap 이 경계를 뒤집고 곱셈이 터질 수 있었다(적대적 A32·A34·A35)
- fix(chrome): 드롭다운이 창 가장자리에 붙던 것 — 낡은 복사본을 걷고 edge_gap 을 네 방향으로
- feat(agent): 이어하기가 «그 세션의 모양» 을 되살린다 — 권한 모드와, 끝난 뒤의 셸
- fix(session-host): 화면이 큰 pane 하나가 세션 전부의 연결을 끊던 것
- fix(agent-image): 판 5 가 오염 줄의 자리를 밀어 판정자 넷을 깼다 — CI 가 잡았다
- feat(agent-image): P3 원격 전송 후 프리뷰 — wire 를 판 5 로 올리고 픽셀을 저쪽에서 당겨온다
- fix(session-host): 계측 이름이 거짓말하고 있었다 — sent 가 아니라 made 다
- fix(editor): 병합 pane 에서 클릭과 가로 스크롤이 «Result 를 기준으로» 잰다
- docs(file-explorer): 지운 이름의 잔재를 걷고, 이어 묻기의 비용을 수치로 적는다
- feat(file-explorer): 흐림 질의를 «트리에서» 읽는다 — 그러면 이어 묻기가 성립한다
- docs(editor): 세 판의 스크롤 관례를 «실측» 해서 §7 ⑥ 에 적는다
- docs(agent-image): 마커 래핑을 쟀다 — 현실에서는 안 갈라지고, 갈라지는 경우는 안 고친다(§10.2)
- feat(session-host): 화면 스트림 바이트를 잰다 — 고치기 전에 계측부터
- diag(session-host): 닫기 30자리가 «어느 줄인지» 를 안 실어 보내던 것
- fix(agent-image): 아래로 잘린 화면에서 순번 매칭이 무너졌다(적대적 A31)
- fix(agent-image): 남의 그림이 붙고 죽은 surface 가 픽셀을 들고 있었다(적대적 A29·A30)
- fix(file-explorer): 안 보는 동안에는 묻지 않는다 — 그리고 나중에 열면 그제야 묻는다
- fix(file-explorer): 흐림 재시도가 «아무도 안 보는 동안에도» 디스크를 건드렸다
- fix(scm): 골든 crop 이 «도크가 아닌 한 열»을 물고 있었다 — 그리고 무시된 자리의 규칙은 건너뛴다
- fix(file-explorer): 규칙이 바뀌어도 이미 읽어 둔 흐림은 낡은 채로 남았다
- fix(scm): 한 배치는 «개수»가 아니라 «보낼 수 있는 바이트»가 정한다
- fix(file-explorer): 되살린 재시도가 «같은 모양으로» 다시 지고 있었다
- fix(file-explorer): 자리가 차서 거절된 흐림 질의가 잊히고 있었다
- test(scm): 실-git 판정자가 «그 기계의 전역 git 설정»에 매여 있었다
- test(file-explorer): 흐림을 «진짜 git 으로 물어 화면까지» 태우는 판정자를 세운다
- fix(scm): 부분 복사가 «할당한 것과 다른 길이»로 반납되고 있었다
- fix(file-explorer): 앞 디렉터리의 답이 뒤 디렉터리의 흐림을 지우고 있었다
- fix(file-explorer): 자라는 버퍼를 가리키는 슬라이스가 자식 stdin 으로 나가고 있었다
- fix(scm):
check-ignore가 원격 길로 새면 «틀린 성공»이 된다 — 그 길을 막는다 - fix(file-explorer): 흐림을 막던 셋째 자리 — git 이 이 명령을 아예 실행한 적이 없다
- fix(file-explorer): 흐림 판정이 «다른 축»을 대리로 묻고 있었다 — 그리고 아직 안 뜬다
- docs(agent-image): 적대적 검증 — 문서가 없는 방어를 있다고 하고, 안 쓰는 API 를 가리켰다
- docs(agent-image): 본문 계약을 코드에 맞춘다 — 회귀 수정이 §11.2 에만 적혀 있었다
- feat(editor): 3-way 병합을 pane 넷으로 그린다 (S3b-2)
- docs(editor): pane 넷을 «어떻게» 놓을지 적는다 (S3b-2)
- build: MP1 테스트 스텝에 png_codec 을 매단다 — 리베이스가 가져온 요구
- fix(agent-image): 적대적 3회 — 틀린 그림·자리 밀림·중복 픽셀·60Hz 화면 스캔(A21~A24)
- fix(agent-image): 배경을 깔 자리가 렌더 순서에 없다 — 테두리만 네 변으로 그린다(액자)
- fix(agent-image): 프리뷰 배경 위로 터미널 글자가 그려지던 것 — quad 레이어를 over 로
- fix(agent-image): 프리뷰 배경으로 뒤가 비치던 것 — 팝업은 창 투명도를 따르지 않는다
- fix(agent-image): 전송된 마커가 열리자마자 닫히던 것 — 여는 범위와 유지하는 범위가 달랐다
- fix(agent-image): P2 가 전송 전까지 막았다 — 범위는 게이트가 아니라 동점 규칙이다
- feat(agent-image): P2 전송 후 프리뷰 — 트랜스크립트가
\[Image #N\] → 이미지를 이미 들고 있었다 - fix(agent-image): 테두리가 Cmd 를 떼면 사라지던 것 — 매 프레임 도는 자리로 옮긴다
- fix(agent-image): 프리뷰 테두리가 셀 격자에서 사라지고 있었다 — GPU quad 로 직접 그린다
- fix(agent-image): 드롭과 원격에서 프리뷰가 안 열리던 두 구멍 — 실사용 경로가 거기였다
- docs(agent-image): P1 구현 현황과 «아직 눈으로 못 봤다» 를 §11.1 에 적는다
- feat(chrome): MP1 프리뷰 테두리와 실패 안내 — 문구는 i18n 이 고른다
- feat(app-session): MP1 클릭 토글과 화면 렌더 — P1 의 데이터 경로가 화면까지 닿는다
- feat(agent-image): MP1 디코드 경로 — 갤러리 워커에 raw 파일 잡을 더한다
- refactor(chrome): 앵커 팝업 기하를 공유 프리미티브로 뽑는다 — 세 번째 복사본을 만들려다 멈췄다
- feat(app-session): MP1 붙여넣기 관찰 배선 — 바이트가 우리를 거치는 유일한 자리에 건다
- feat(chrome): MP1 프리뷰 팝오버의 자리·크기 — pane rect 를 입력으로 받지 않는다
- docs(agent-image): 프리뷰는 pane 의 자식이 아니라 팝오버다 — M7 이 틀린 프레임이었다
- feat(agent-image): MP1 화면 마커 스캐너 — 셀 열로 답하고, 커서 블록 밖은 안 본다
- feat(agent-image): MP1 전송 전 스테이징 코어 — 번호를 추측하지 않고 관찰한다
- docs(agent-image): maru 안 재대조를 시도했고 막혔다 — 숨기지 않고 §10.1 에 적는다
- docs(agent-image): 좁은 pane + 전송 전이 갈 곳 없이 무반응이 되는 모순을 미결로 세운다(M7)
- docs(agent-image): 적대적 4회차 — Codex 는 alt 화면이 아니고, 원격은 관찰 자체가 안 된다(A15~A19)
- docs(agent-image): 적대적 3회차 — 전송이 「입력창 비우기」와 구분되지 않아 초안이 또 틀렸다(A11~A14)
- docs(agent-image): 마커에는 아무 표시가 없다 — 패턴으로는 구분이 불가능하다(적대적 A10)
- docs(agent-image): 터미널
\[Image #N\]마커 Cmd+클릭 프리뷰 설계 — 실측이 순서 규칙을 뒤집었다 - docs(terminal-core): 매체 전송 설계를 실측으로 다시 고른다 — (A)에서 (B)로
- feat(terminal-core): 명세가 요구하는데 거절하던 둘 — PNG 프레임과 o=z
- test(scm): 병합 모드를 «화면 셀» 까지 재고, 세 판의 주인을 상태가 든다 (S3b-1)
- feat(scm): 충돌 파일을 «병합 모드» 로 연다 — 세 판을 든 편집기 (S3b-1)
- docs(editor): 3-way 는 «편집기 Term 의 모드» 다 — 수치를 고쳐 적는다
- feat(terminal-core): PNG 이 여덟 변종을 거절하고 있었다 — wuffs 로 전부 연다
- test(session-host): complete IME pixel product gate
- test(session-host): revalidate IME capture runtime
- docs(session-host): record CR6d pixel gate status
- test(session-host): capture IME preedit pixel evidence
- test(session-host): validate IME preedit pixel evidence
- docs(session-host): define IME pixel evidence gates
- test(app-session): OSC 왕복에 이웃과 같은 시한을 준다 — 그리고 말없이 죽지 않는다
- fix(session-host): spawn 이 셀 픽셀을 안 실어 이미지 자식이 기본 크기로 굳던 것
- test(session-host): verify real cross-uid denial
- fix(workspace): 복원 뒤 체크포인트 백업을 다시 무장한다
- docs(agent): 설치 spawn 실패가 더는 안 굳는다 — 사유표를 갱신한다
- fix(agent): 원격 훅 설치를 못 띄워도 굳히지 않는다 — 마지막 「지금만」 실패
- docs(editor): 3-way 를 «새 Term 종류» 에 둔다 — §7 ④ 를 닫는다
- feat(scm): 병합 충돌의 세 판을 읽는다 —
:1:·:2:·:3:(S3a) - fix(scm): 상한에서 «우리가» 끊은 읽기를 실패로 읽지 않는다
- docs(editor): 3-way 병합을 두 조각으로 가른다 — 데이터가 화면보다 앞선다
- fix(terminal-core): 자리로 겨누는 delete 가 화면 격리를 뚫고 있었다 — 적대적 검증
- fix(terminal-core): d=a 는 화면에 보이는 배치만 지운다 — 스크롤백 이미지를 살린다
- perf(renderer): 글리프 캐시 조회가 캐시 크기만큼 훑던 것
- docs(verification-matrix): 소스 컨트롤 도크가 «설계만 있다»고 적혀 있었다
- fix(scm): 연결이 끊긴 원격 pane 이 «저장소를 확인할 수 없다»고 말하고 있었다
- test(session-host): 실제 자식을 띄우는 판정자들의 1초 예산 — 부하에서 3.0초를 재 놓고 1초를 줬다
- docs(terminal-core): delete 타깃이 구현돼 낡은 문단을 「구현 전 기록」으로 표시한다
- docs(terminal-core): 매체 전송 백로그에 빠진 키(S/O/N)와 침묵하는 delete 타깃을 적는다
- test(terminal-core): fuzz 가 새 delete 타깃을 한 번도 안 밟고 있었다 — 적대적 검증 3회차
- fix(terminal-core): d=Z 와 d=I/N+p= 가 명세보다 많이 지우고 있었다 — 적대적 검증 2회차
- fix(terminal-core): 대문자 delete 의 free 는 조건부다 — 적대적 검증
- feat(terminal-core): kitty delete 타깃 여섯 — 셀·열·행·id 범위·프레임 (11/11 완성)
- docs(ssot): 구현 계획 소유권 정리
- test(chrome): 커서 깜빡임 판정자가 «보이는 뒤집힘» 을 세던 것 — 소비한 반주기를 센다
- feat(scm): 원격 pane 의 에이전트 탭은 «아직 지원하지 않습니다» 한 줄로 끝난다
- test(session-host): 관측 예산 1초가 부하에서 터지던 것 — 시간 축을 판정자에서 걷는다
- diag(session-host): 닫는 자리가 «그 자리를 만든 오류» 를 버리던 것
- docs: align implementation status ownership
- test(editor): MAXC2 가 「몇 번째 할당인지」를 숫자로 쫓던 것 — 세어서 그만큼만 훑는다
ohah/ohah.github.io
- fix(docs): 3차 적대적 검증 후속
- fix(docs): 적대적 검증 후속 — 렌더 결함 3건·수치/추론 문장 교정
- docs(monthly-opensource): 8/18~9/14 최신화 — 타임라인·maru 3-6·hwpjs 3-9·pdf 신설·zts 후속
- docs(today-commit): 2026-08-18~09-14 백필 (28일) + 목차·메타 등재
ohah/pdf
- docs: 맞대기 표에 파일 묶음을 적는다
- feat: 파일 묶음(포트폴리오)을 알려 준다
- docs: 문서를 실제와 맞춘다 — 안 된다고 적힌 것 넷이 이미 된다
- test: 적대적 일곱 갈래를 나란히 돌린다 (3.7초 → 2.2초)
- test: 거듭 열어도 메모리가 안 자라는지 본다
- test: 미뤄 뒀던 셋을 가려 까닭을 제대로 적는다
- test: pdf.js 맞대기를 나눠 돌린다 (18.9초 → 4.4초)
- build: 안 바뀌었으면 JS 를 다시 굽지 않는다 (4.1초 → 17ms)
PR (해당일 생성/머지)
상태는 조회 시점 기준입니다. merged는 아래 대상 브랜치에 병합됐다는 뜻이며, 기능 브랜치 병합과 main 반영을 구분합니다. 같은 PR이 생성일과 병합일 양쪽 기록에 나타날 수 있습니다.