2026-09-08
날짜는 UTC 기준으로 나눴습니다(9월 22일부터는 한국 시간 기준). 커밋은 커미터 시각(committer date), PR은 생성·병합 시각으로 분류했습니다. 목록은 2026-10-06 KST에 GitHub에서 다시 조회해 보강했습니다. 공개 저장소의 기본 브랜치 활동만 포함합니다.
요약 (AI 작성)
hwpjs가 ICC 역함수와 JPEG 헤더에 들어간 날입니다(68커밋). ICC는 chromatic adaptation 행렬과 고정 행렬을 정확한 유리수로 평가해 matrix TRC 모델을 조립하고, power level root를 활성 구간에서 찾고, clipped parametric branch jump를 분류하며, preimage 경계와 도달 가능성을 정확히 보존하고, full-width rational XYZ 행렬을 뒤집고, 넓은 gamma 역을 기호로 보존하는 데까지 갔습니다. PNG에 내장된 ICC 프로파일과 필수 태그·v2 텍스트 태그를 검사하고 이를 HWP5 BinData에 연결했으며, JPEG은 마커와 엔트로피 경계, frame·scan 헤더, quantization·Huffman 테이블을 파싱했습니다. @ohah/pdf는 표준 글꼴을 밖에서 받아 실을 수 있게 하고, CMap 표를 델타로 줄여 7.3MB를 3.8MB로, 엔진은 wasm-opt로 13% 줄였습니다.
maru 편집기는 전날 열린 #3370으로 비교 뷰에 caret을 세워 키보드로 읽게 했고, 열을 ⌃⇧Tab으로 넘기며(#3381), 가로도 caret을 따라가게 했습니다(두 뷰 공통, #3391). 편집과 접힘이 가로 위치·상한을 버리던 것을 고치고(#3404, #3407), 상태바가 비교 뷰에도 L/R 줄:열을 내게 했습니다(#3389). 활동 뷰는 결과가 이미지인 호출을 한 줄로 접고(AV4b, #3376), 펼쳐도 명령이 안 보이던 것을 고쳤으며(#3377), 접힌 줄에 썸네일을 보이고(AV5, #3388) 적대적 검증을 여러 회 기록했습니다. 이름도 image_gallery에서 활동 뷰에 맞게 바꿨습니다. Enter가 본문까지 넓히는 #3415는 이날 PR이 열렸습니다.
터미널은 kitty U=1 유니코드 placeholder를 받아 tmux 경유 이미지가 제자리에 뜨게 하고, kitty a=q·XTWINOPS·DECRQM·winsize 픽셀 같은 응답을 메웠으며(#3398), TERM_PROGRAM 위장을 걷어 maru가 자기 이름을 말하게 했습니다. 워크트리에서 남의 브랜치를 말하던 git 판정도 고쳤습니다(#3382). file-tree 워커를 거두고 나가게 한 #3399는 병합됐다가 deinit이 워커를 기다리지 않게 하는 #3402로 되돌려졌습니다. PR 체크리스트에는 각자는 초록인데 합치면 깨지는 경우를 다루는 합류 규율이 들어갔습니다(#3383).
모바일은 아틀라스를 그리는 배율에 맞춰 굽고 Android도 셀이 바뀌면 다시 굽게 했으며(#3390, #3392), OS 접근성 글자 크기를 따라가고(M13c, #3393), 새 출력을 소리로 알리고(M9a, #3395), 스크롤백을 낭독기로 훑고(M9b), 선택을 줄 단위 동작으로 만들었습니다(M9c, #3401). 저전력 모드면 그리는 주기를 반으로 하고(M14a) 배경에서는 아예 깨어나지 않게 했으며(M14b), 첫 실행이 빈 검은 화면이던 것도 고쳤습니다(#3416). session-host는 전날 열린 upgrade stage3 preparation #3371을 병합하고, profile stage3 명령과 live checkpoint 결속, authored profile subject 선택, profile별 attestation payload와 최종 fence, profile-aware aggregate 완성(#3414)까지 이었으며, 닫은 사유와 활성화 거부 조건을 로그에 남기게 했습니다.
공개 커밋 225개, 해당일 생성 또는 병합된 PR 45개를 정리했습니다. PR 생성 42개·병합 43개는 같은 PR이 양쪽에 포함될 수 있습니다.
커밋
ohah/hwpjs
- feat(image): resolve active JPEG tables for each scan
- feat(image): parse JPEG quantization and Huffman tables
- feat(image): inspect JPEG frame and scan header fields
- feat(image): parse JPEG marker and entropy byte boundaries
- feat(hwp5): connect bounded PNG inspection to BinData
- feat(image): inspect v2 profile Unicode with explicit UTF16BE policy
- feat(image): parse ICC v2 text tags in PNG inspection
- feat(image): inspect ICC tag payloads in PNG profiles
- feat(image): connect ICC required tags to PNG inspection
- feat(image): inspect embedded ICC profiles in PNG pixels
- feat(image): connect fraction matrix and TRC inverses
- feat(image): dispatch TRC inverses for full-width targets
- feat(image): compose parametric inverses for full-width targets
- feat(image): select nearest ordinates for full-width targets
- feat(image): compare ordinate distances for full-width targets
- feat(image): compare ordinates against full-width targets
- feat(image): select attained inverse values for full-width targets
- feat(image): preserve extended preimage bounds and exact root order
- feat(image): assemble full-width parametric preimage unions
- feat(image): preserve extended linear preimages and safe float conversion
- feat(image): preserve clipped preimages for full-width targets
- feat(image): locate full-width roots on active power branches
- feat(image): compare extended symbolic roots without narrowing
- feat(image): generate power roots for full-width targets
- feat(image): preserve wide gamma inverses symbolically
- feat(image): invert sampled curves with full-width targets
- feat(image): preserve wide linear RGB targets exactly
- feat(image): invert full-width rational XYZ matrices
- feat(image): connect fixed XYZ matrix TRC inversion
- feat(image): unify exact TRC inverse dispatch
- feat(image): compose parametric nearest-output inversion
- feat(image): select attained nearest parametric outputs
- feat(image): compare symbolic and rational ordinate distances
- feat(image): select nearest power branch ordinates
- feat(image): compare exact ordinates with rational targets
- feat(image): assemble exact parametric output ranges
- feat(image): preserve exact clipped power output ranges
- feat(image): preserve exact clipped linear output ranges
- feat(image): select nearest attained rational ordinates
- feat(image): select attained parametric inverse values
- feat(image): preserve exact preimage bounds and attainment
- feat(image): compare wide ICC roots with shared exact ordering
- feat(image): assemble complete parametric preimage sets
- feat(image): preserve complete clipped power preimages
- feat(image): locate normalized ICC roots in active branches
- feat(image): compare normalized ICC roots exactly
- feat(image): bound wide ICC rational inputs exactly
- feat(image): preserve normalized ICC power level roots
- feat(image): preserve exact affine preimages and attained choices
- feat(image): classify whole clipped ICC parametric curves
- feat(image): classify clipped ICC parametric branch jumps
- feat(image): compare ICC powers against exact rational values
- feat(image): partition active ICC power branches after clipping
- feat(image): locate ICC power level roots in active intervals
- feat(image): compare ICC power roots with certified integer bounds
- feat(image): preserve exact symbolic ICC power level roots
- feat(image): partition ICC curves at exact affine critical points
- feat(image): preserve exact open intervals in ICC parametric branch plans
- test(image): pin ICC parametric inverse topology counterexamples
- feat(image): validate entire ICC parametric curve real domains exactly
- feat(image): evaluate inverse ICC gamma curves with bounded numeric checks
- feat(image): invert sampled ICC curves at exact normalized coordinates
- feat(image): connect matrix TRC forward evaluation with exact and approximate paths
- feat(image): assemble ICC matrix TRC models from validated tag tables
- feat(image): evaluate fixed ICC matrices with exact rational results
- feat(image): validate ICC chromatic adaptation matrices exactly
- feat(image): add opt-in IANA locale matching and tighten history validation
- feat(text): preserve IANA alpha2 history and validate registry dates
ohah/maru
- feat(mobile): 첫 실행이 빈 검은 화면이었다 — 갈 곳에서 서게 한다 (M16a)
- test(session-host): CR2a 경계 상수를 다시 맞춘다 — rebase 가 병합 커밋과 함께 버린 수정
- chore(wasm): 커밋된 wasm 을 현재 소스로 재빌드한다
- style: zig fmt — 손으로 넣은 U=1 코드의 포맷을 맞춘다
- test(session-host): CR2e-e3a1 경계가 무는 크기 상수를 새 실측값에 맞춘다
- fix(perf): buildGpuImages 호출부를 새 시그니처에 맞춘다 — perf 게이트 복구
- feat(session-host): U=1 격자를 원격 wire 로 보내고, 이미지 패스 가드를 고친다
- feat(terminal): kitty U=1 유니코드 placeholder — tmux 경유 이미지가 제자리에 뜬다
- docs(ssh): 절 참조를 «자기 신원» 으로 맞춘다 — check-doc-links 복구
- fix(pty): TERM_PROGRAM 위장을 걷는다 — maru 는 자기 이름을 말한다
- fix(terminal): 대답하는 쪽을 메운다 — kitty a=q·XTWINOPS·DECRQM·winsize 픽셀
- feat(session-host): profile-aware aggregate를 완성한다
- docs(session-host): profile-aware aggregate를 정의한다
- feat(agent): orphan 에 «내가 뭘 들고 있었나» 를 함께 남긴다
- feat(session-host): profile authored checkpoint를 live 배선한다
- docs(session-host): profile authored live checkpoint를 정의한다
- feat(session-host): authored attestation 최종 fence를 고정한다
- feat(session-host): profile별 attestation payload를 고정한다
- docs(session-host): track authored selector process gate
- feat(session-host): serialize authored subject selection
- docs(session-host): define authored selector process
- docs(mobile): 데이터 절약 — 줄일 것이 없다는 것을 재서 적는다 (M14c)
- test(capture): 민 뒤에 접는 캡처 훅 (MARU_FOLD_AFTER)
- fix(editor): 접힘도 가로 위치·상한을 안 버린다 — 막대가 사라지던 자리
- perf(mobile): 배경에서는 아예 안 깨어난다 (M14b)
- feat(mobile): 저전력 모드면 그리는 주기를 반으로 (M14a)
- docs(boundary): 정지 축 밖의 워커는 누가 지키나 — 감사 결과를 적는다
- Revert "fix(file-tree): 워커를 거두고 나간다 — CI 간헐 누수의 원인"
- test(capture): 하니스가 알림을 닫고, 태운 키를 되돌리지 않는다
- fix(editor): 편집이 가로 상한도 안 버린다 — 그리기 직전 clamp 가 되감던 자리
- test(editor): 상한만 없는 갈래도 잰다 — 변이 2회차 I5
- test(editor): 상한을 모를 때 왼쪽으로 안 튀는지 잰다 — 변이 1회차 I5
- test(editor): 캡처 훅이 caret 이 설 때까지 기다린다
- feat(editor): 타이핑도 가로로 caret 을 따라간다 — 그리고 가로 위치를 편집이 안 버린다
- docs: 낡은 문장 셋을 고치고, 가로 추적의 편집 경로 구멍을 계약에 적는다
- feat(mobile): 선택을 «줄 단위 동작» 으로 만든다 (M9c)
- style(session-host): format selector measurement
- test(session-host): measure profile subject selection
- docs(session-host): track authored selector gate
- feat(session-host): select authored profile subjects
- docs(session-host): define profiled authored attestation
- feat(mobile): 스크롤백을 낭독기로 훑는다 (M9b)
- fix(file-tree): 워커를 거두고 나간다 — CI 간헐 누수의 원인
- fix(mobile): 낭독이 스크롤·회전에 끼어들던 것과, 자리가 모자라면 영영 막히던 것 (M9a)
- feat(mobile): 새 출력을 소리로 알린다 (M9a)
- docs(agent-activity): AV6 적대적 검증 — 판정자 이름이 두 벌인 이유를 적는다
- refactor(agent-activity): 이름이 거짓이 아니게 한다 — image_gallery → agent_activity (AV6)
- test(release): pin profile-selected live stage
- feat(session-host): dispatch live stage3 by profile
- docs(session-host): define live profile stage3 dispatch
- docs(agent-activity): 낡은 주석이 CI 누수 진단을 잘못 이끌었다
- fix(agent-activity): 읽기·명령을 거쳐도 그림이 산다 — 사용자 지적
- fix(agent-activity): 필터를 오가도 그림이 안 사라진다 — 사용자 지적
- test(agent-activity): 펼침의 「이미지」를 못박고 계약 표를 고친다 — 적대적 9~13 회차
- docs(agent-activity): 적대적 6·7·8 회차 — 계약이 코드를 못 따라간 자리와 실측
- test(agent-activity): 여럿 × 재연결의 교집합을 메운다 — AV5 적대적 6회차
- docs(agent-activity): 적대적 4·5 회차를 기록한다 — 규율을 잘못 옮긴 것도 함께
- test(agent-activity): 접기 회귀를 못박는다 — AV5 적대적 검증 5회차
- fix(agent-activity): 좁아지면 썸네일부터 버린다 — 이름이 먼저다 (적대적 4회차)
- docs(agent-activity): AV5 적대적 검증 3회를 기록한다 — 증상이 같아도 고칠 곳은 둘일 수 있다
- test(agent-activity): 파일 번호의 결합을 못박는다 — AV5 적대적 검증 2회차
- fix(agent-activity): 썸네일의 정체·게이트·잔값 — AV5 적대적 검증 1회차
- feat(agent-activity): 접힌 줄이 그림도 보여 준다 — 「전체」의 썸네일 (AV5)
- test(editor): max_first_col 상한을 잰다 — 변이 2회차 H10·H19
- test(editor): 가로 추적 판정자 둘을 더한다 — 변이 1회차
- test(editor): 캡처 훅이 행 끝으로도 보낸다 (MARU_DIFF_LINE_END)
- feat(editor): 가로도 caret 을 따라간다 — 두 뷰 공통
- docs(visual-mapping): 가로도 caret 을 따라간다
- docs(editor): 가로 추적에서 살아남은 변이 다섯의 근거를 적는다
- test(editor): DHS3 의 긴 줄을 첫 줄에서 내린다 — 변이 3회차 H24
- fix(mobile): 시작할 때 한 번 더 굽던 것을 없애고, 헛방어 하나를 되돌린다
- feat(mobile): OS 접근성 글자 크기를 따라간다 (M13c)
- docs(mobile): M13b 를 계약·계획에 적고, 컬러 원본 주장을 «자리» 로 좁힌다
- feat(mobile): Android 도 셀이 바뀌면 아틀라스를 다시 굽는다 (M13b)
- refactor(mobile): 소비처가 0 이 된 옛 셀 상수를 지우고, 그 상수를 쓰던 수식을 고친다
- fix(mobile): 다시 굽는 길을 열었더니 그 길의 결함 넷이 나왔다
- feat(mobile): 아틀라스를 «그리는 배율» 에 맞춰 굽는다 — 확대가 아니라 그린다
- test(git): 워크트리 판정자에 갈래 둘을 더한다 — 적대적 검증 3·4 회차
- fix(git): 워크트리에서 남의 브랜치를 말하고 있었다
- test(session-host): measure profile stage3 process path
- docs(session-host): define profile command process measurement
- feat(session-host): bind profile stage3 to live checkpoint
- docs(session-host): define profile stage3 checkpoint bridge
- test(status-bar): 결합 문자와 빈 행 갈래를 잰다 — 변이 4회차
- test(status-bar): 긴 행 상한과 버퍼 부족을 잰다 — 변이 3회차
- test(status-bar): 폭 가드를 잰다 — 변이 2회차 V14
- test(status-bar): 상태바 글자를 판정 가능하게 꺼내고 판정자 둘을 더한다
- style: zig fmt
- feat(status-bar): 비교 뷰에도 커서 위치를 낸다 — L/R 줄:열
- docs(status-bar): 비교 뷰의 커서 위치를 정한다 — L/R 줄:열
- fix(agent-activity): 펼쳐도 명령이 안 보였다 — 계약이 갚기로 한 대가를 갚는다
- docs(pr-checklist): 각자는 초록인데 합치면 깨지는 것 — 합류 규율
- fix(app-session): 거둠을 취소 뒤로 옮기고 정지 축을 게이트로 못 박는다
- fix(app-session): 판정자가 detached worker 보다 먼저 끝나지 않게 한다
- test(editor): DCOL3 픽스처가 선택 단위를 실제로 가르게 한다
- test(editor): 열 넘기기가 단위와 목표 열을 둘 다 푸는지 잰다 — 변이 19회차
- test(editor): 열 넘기기가 선택 단위도 푸는지 잰다 — 변이 18회차 U14
- fix(editor): 오버레이를 닫아도(⌘G 항해 중) 열 전환이 목록을 다시 센다
- docs(editor): 16회차까지 살아남은 변이 넷의 근거를 적는다
- test(editor): 더블클릭 경로도 검색을 따라오게 잰다 — 변이 15회차 T2
- test(editor): 마우스 경로와 검색 대상 가드를 잰다 — 변이 14회차
- fix(editor): 비교 뷰 열이 바뀌면 검색 목록도 다시 센다
- test(editor): 캡처 훅이 열 넘기기도 키로 태운다 (MARU_DIFF_SWITCH_SIDE)
- docs(editor): 열 넘기기에서 살아남은 변이 셋의 근거를 적는다
- test(editor): 열 넘기기가 범위 밖 자리에서도 안 죽는지 잰다 — 변이 12회차 S18
- test(editor): 열 넘기기가 키를 삼키는지 잰다 — 변이 11회차 S14
- feat(editor): 비교 뷰의 열을 ⌃⇧Tab 으로 넘긴다
- docs(key-input): 비교 뷰의 열을 키로 넘긴다 — ⌃⇧Tab
- docs: 랩 켠 비교를 「할 일」이 아니라 닫힌 결정으로 다시 적는다
- docs: 비교 caret 조각이 남긴 거짓 인용 둘을 고친다
- test(agent-index): 중복 판정자를 지운다 — 진짜 수정은 표본을 만든 것이었다
- test(agent-index): 이미지 없는 체인에도 표본을 둔다 — 적대적 검증 2회차
- fix(agent-index): 파일 번호는 스캐너가 찍는다 — 퇴출이 배열을 당겨도 안 어긋난다
- feat(session-host): drive profile stage3 preparation
- feat(session-host): define profile stage3 command transaction
- feat(session-host): retain profile timing artifact
- docs(session-host): define profile stage3 driver
- feat(session-host): 활성화 단계 거부가 어느 조건이었는지 말한다
- feat(session-host): 봉인을 못 읽은 것을 신원이 달라진 것과 가른다
- feat(session-host): 닫은 지점까지 남긴다
- feat(session-host): 닫은 사유를 안쪽까지 찍는다
- docs(agent-activity): 적대적 검증 3회를 기록한다 — 재 봤더니 없는 위험도 값이다
- fix(agent-activity): 「전체」는 이미지가 잘린 것도 말한다 — 적대적 검증 2회차
- test(agent-activity): 낡은 전제를 성질로 바꾼다 — 「0 줄이라고 적지 않는다」는 그대로
- feat(agent-activity): 결과가 이미지인 호출은 한 줄이다 — 「전체」의 중복 접기 (AV4b)
- feat(session-host): bootstrap profile stage3 command
- docs(session-host): define profile stage3 bootstrap
- fix(agent): 적대적 검증 5 회 — else 가 미래를 삼켰고, 판정자가 호출부를 안 잠갔다
- chore(i18n): 원장을 31→33 으로 올린다 — 갈라진 진단 둘
- fix(agent): 메모리가 잠깐 모자랐다고 그 목적지를 영영 죽이지 않는다
- feat(session-host): publish profile timing artifact
- test(session-host): require profile timing artifact
- docs(session-host): define profile timing artifact
- docs(editor): 10회차까지 살아남은 변이 둘의 근거와 가로 빚을 적는다
- test(editor): 거울 경우를 마저 잰다 — 변이 9회차가 연 구멍 셋
- test(editor): 열 판정을 조인다 — 변이 8회차가 연 구멍 둘
- test(editor): 비교 caret 판정자 셋을 더한다 — 상호작용 면
- test(editor): 비교 caret 판정자 다섯을 더한다 — 변이 6회차가 연 구멍
- docs(editor): 살아남은 변이 다섯이 왜 원리상 동치인지 적는다
- test(editor): 비교 caret 판정자 넷을 더 조인다 — 변이 4회차
- test(editor): 비교 caret 판정자 둘을 더한다 — 변이 3회차가 연 구멍 둘
- test(editor): 비교 caret 판정자 셋을 더한다 — 변이 2회차가 연 구멍 여섯
- test(editor): 비교 caret 판정자를 보강한다 — 변이 1회차가 연 구멍 다섯
- feat(editor): 비교 뷰에 caret 이 선다 — 키보드로 읽는다
- docs(key-input): 비교 뷰에 caret 을 세운다 — 「스크롤만」 결정을 뒤집는다
- docs(key-input): 비교 뷰에서 Page·⌘↑↓ 가 뷰를 굴린다
- feat(session-host): compose upgrade stage3 preparation
- test(session-host): require upgrade stage3 product
- docs(session-host): define upgrade stage3 product
ohah/pdf
- perf: CID→유니코드 표도 델타로 줄인다 (244KB → 151KB)
- perf: CMap 표를 델타로 줄인다 (7.3MB → 3.8MB)
- build: wasm-opt 을 엔진에도 걸어 13% 줄인다
- test: 적대적 검증 실행기를 저장소로 옮기고, 터진 자취를 남긴다
- test: 글꼴 열쇠 시간도 CPU 로 잰다
- fix: xref 정렬을 한 군데로 모으고, 구역 순서를 검사한다
- test: pdf.js 와 다른 15개를 가려 까닭과 함께 못 박는다
- feat: 표준 글꼴을 밖에서 받아 실을 수 있게 한다
PR (해당일 생성/머지)
상태는 조회 시점 기준입니다. merged는 아래 대상 브랜치에 병합됐다는 뜻이며, 기능 브랜치 병합과 main 반영을 구분합니다. 같은 PR이 생성일과 병합일 양쪽 기록에 나타날 수 있습니다.