2026-09-05
날짜는 UTC 기준으로 나눴습니다(9월 22일부터는 한국 시간 기준). 커밋은 커미터 시각(committer date), PR은 생성·병합 시각으로 분류했습니다. 목록은 2026-10-06 KST에 GitHub에서 다시 조회해 보강했습니다. 공개 저장소의 기본 브랜치 활동만 포함합니다.
요약 (AI 작성)
hwpjs가 Zig로 다시 시작한 날입니다. Rust 코드를 보관하고 Zig 워크스페이스를 초기화한 뒤, CFB 컨테이너의 모듈러 Zig 리더를 세우고 검색·검증 계약을 통일하며 리더 경계를 반복 감사로 굳혔고, 엄격 검증과 편집 가능한 v3/v4 writer까지 넣었습니다. HWP5 쪽은 헤더와 레코드 파싱 기반을 놓고 DocInfo 속성과 버전별 ID 매핑, 바이너리·폰트 리소스, 탭·번호·글머리표·스타일을 개수 검증과 함께 파싱했습니다. @ohah/pdf는 pdf.zig에서 덩이들을 떼어 14,549줄을 7,489줄로 줄이고 전역 묶음을 구조체로 접었으며, pdf.js 맞대기로 DeviceCMYK 색·타일 무늬 간격·그림 확대 뭉개기를 잡았습니다. 문서를 잇달아 열면 앞 문서의 마스크 그림이 나오던 것, /CalRGB와 16비트 그림, 무색 무늬(/PaintType 2)의 색, 내보낸 PDF에 모듈 이름이 새던 것도 고쳤습니다. zerolist에는 ZeroList 통합과 Android 배치 최적화 검증 PR #1이 열려 있습니다.
maru는 소스 컨트롤 감시자를 실제로 심고(RW2c, #3212) 적대적 검증 13회에서 결함 열을 잡았으며(#3218), 전면 TUI 구간에 도크가 홈을 보던 원격 pane cwd를 한 규칙으로 모았습니다(#3247). 원격 파일 트리 설계를 열고 목록 wire와 (host, path) root 키의 RF1 순수 층을 놓았고(#3260), 감시 헬퍼가 목록을 말하는 list 서브커맨드를 붙였습니다(RF2a, #3271). Windows 원격 업로드 설계 초안 #3241은 열린 채 남아 있습니다. 편집기는 괄호 짝 점프(⇧⌘\, #3219)와 위/아래로 커서 추가(⌥⌘↑/⌥⌘↓, #3240)를 얻었고, 글자를 한 색으로 그리던 호스트가 중립 규칙을 쓰게 했습니다(#3233). 열/블록 선택 #3270은 이날 PR이 열렸습니다. 에이전트 쪽은 esc to interrupt가 사라진 claude 진행 상태줄을 화면에서 다시 읽고(#3222), codex의 Waiting을 놓치던 것을 고치며, 종류를 모르는 running 에이전트를 claude로 그리지 않게 했습니다(#3234). 이미지 갤러리 라벨은 「누가 넣었나」부터 말하게 했습니다(#3217).
테스트 인프라도 크게 손봤습니다. 시간을 태우던 픽스처 넷을 189초에서 2.7초로 줄이고(#3252), imports.zig 판정자의 되풀이 파싱을 기억하게 했으며(#3246), release adapter 판정자 84개를 모드당 두 바이너리로 모아 CI 컴파일 횟수를 크게 줄였습니다(#3262). 세션을 닫을 때 안 읽힌 master 출력을 버려 바쁜 자식의 exit가 막히지 않게 했습니다(#3266). session-host는 복원이 죽은 단계, fd 슬롯 예약 실패 이유와 점유자, 창이 안 돌아온 이유와 poison 위치를 남기게 했고(#3215), same-run attestation bundle 검증, durable evidence 승격과 인계, release aggregate 원자적 인계와 재개방, live release 단계 순서 강제, candidate attestation bundle 채택, stage 3 preparation 커밋까지 이었습니다. 모바일은 세션 목록이 흐르게 하고 스크롤바를 달았으며(#3214), 회전 시 격자를 다시 잡고(#3221) 시스템 다크/라이트를 따라가게 했습니다(#3255).
공개 커밋 154개, 해당일 생성 또는 병합된 PR 65개를 정리했습니다. PR 생성 64개·병합 59개는 같은 PR이 양쪽에 포함될 수 있습니다.
커밋
ohah/hwpjs
- feat(hwp5): parse DocInfo tabs numbering bullets and styles
- feat(hwp5): parse binary and font resources with count validation
- feat(hwp5): parse DocInfo properties and version-aware ID mappings
- feat(hwp5): add bounded header and record parsing foundation
- fix(cfb): align writer budgets and parse failure state
- feat(cfb): add strict validation and editable v3/v4 writer
- test(cfb): correct reproduction fixtures and document spec gaps
- fix(cfb): match legacy result shapes and header diagnostics
- test(cfb): close boundary coverage gaps and centralize storage rules
- fix(cfb): harden reader boundaries with repeatable audits
- fix(cfb): enforce shared search and validation contracts
- feat(cfb): implement modular Zig reader
- docs: replace agent persona files with Zig guidance
- docs: remove unused agent setup templates
- chore: archive Rust and initialize Zig workspace
ohah/maru
- feat(remote-watch): 헬퍼가 목록을 말한다 — list 서브커맨드(판 3)와 실물 왕복 게이트 (RF2a)
- feat(session-host): own stage3 preparation commit
- test(session-host): require stage3 preparation product
- docs(session-host): define stage3 preparation ownership
- build: test-macos-only 는 두 모드 루프 안의 판정자를 Debug 로만 돈다 — check-boundaries 와 같은 규칙
- fix(pty): 세션을 닫을 때 안 읽힌 master 출력을 버려 바쁜 자식의 exit 가 막히지 않게 한다 — teardown 4,077ms → 15ms
- build: release adapter 판정자 84개를 모드당 두 바이너리로 모은다 — CI 컴파일 45·129회 → 2·4회
- feat(session-host): adopt reauthenticated current drafts
- test(session-host): require current draft adoption
- docs(session-host): define current draft adoption
- fix(agent): fixture 와 판정자 진단에서 한글 리터럴을 뺀다 — i18n 원장이 잡았다
- test(agent): 실제 화면 fixture 로 규칙을 전수 잠근다 — 손으로 쓴 문자열은 실측과 어긋난다
- feat(session-host): reopen durable preparation semantics
- test(session-host): require preparation semantic reopen
- docs(session-host): define preparation semantic reopen
- perf(test): 느린 판정자 셋의 시간을 줄인다 — 실패 주입 조기 종료·fail-stop 병렬 대기
- feat(file-tree): 원격 파일 트리 설계를 열고 RF1 순수 층을 놓는다 — 목록 wire 와 (host, path) root 키
- feat(session-host): retain durable preparation outputs
- test(session-host): require durable preparation handoff
- docs(session-host): define durable preparation handoff
- feat(session-host): wire candidate attestation bundles
- test(session-host): require candidate bundle command wiring
- docs(session-host): define candidate bundle command wiring
- feat(agent): 화면이 provider 를 못 읽으면 스스로 말한다 — §1.2 의 화면 쪽 대칭
- feat(session-host): adopt candidate attestation bundles
- test(session-host): require candidate bundle adoption
- docs(session-host): define candidate bundle adoption
- feat(mobile): 시스템 다크/라이트를 따라간다 — 데스크톱 F2-9 를 잇는다
- test(agent): 종류 전환에서 리셋 호출을 잠근다 — AK1 이 남긴 마지막 공백
- feat(smoke): 편집기 판을 찍을 수 있게 한다 —
--hold-editor-ms(§2m.113) - test(app-session): 시간을 태우던 픽스처 넷을 고친다 — IG2-a·IG2 적대적·ES21·ES22
- fix(scm): 원격 pane 의 cwd 를 한 규칙으로 모은다 — 전면 TUI 구간에 도크가 홈을 봤다 (RS6)
- ci: check-boundaries 를 자기 러너로 갈라 잰다
- docs(agent): 레퍼런스 소스 실측을 남긴다 — 규칙의 데이터화·region 어휘·ASCII 프레임
- test(agent): C2 의 제품 배선을 판정자로 잠근다 — 두 줄이 끊겨도 아무도 몰랐다
- feat(session-host): enforce live release phase order
- test(session-host): require live release phase order
- docs(session-host): define live release phase order
- perf(boundary): imports.zig 판정자가 같은 소스를 되풀이해 파싱·토큰화·읽던 것을 기억한다
- docs(agent): 오늘 바뀐 계약과 판정자를 문서에 맞춘다
- fix(session-host): raise 3b source scan budget
- test(session-host): require durable 3b source scan
- docs(session-host): define 3b scanner budget
- feat(editor): 위/아래로 커서 추가 —
⌥⌘↑/⌥⌘↓(§3.2b) - fix(agent): C2 의 chrome 근거에 출력 조건을 건다 — 정반대를 요구하는 두 사고를 가른다
- fix(agent): C2 의 「무거운 조건」을 시간에서 근거의 질로 바꾼다
- feat(mobile): 키바 줄 수를 «폭이» 정한다 — 가로에서 한 줄, 본문 9줄→11줄
- feat(session-host): fd 슬롯을 «누가» 쥐고 있는지 남긴다 — 비었다던 자리가 점유였다
- fix(status-bar): 종류를 모르는 running 에이전트를 claude 로 그리지 않는다
- docs(scm): ②c 완료 표기와 감시자 시한 주석을 실측에 맞춘다
- feat(editor): 편집기가 글자를 한 색으로 그렸다 — 규칙을 중립으로 올려 두 호스트가 같은 것을 쓴다 (§2m.112)
- test(agent): 종류 전이 리셋을 판정자로 잠근다 — 열셋 중 하나만 잠겨 있었다
- docs(agent): 스피너 프레임 근거를 900 회 관측으로 갱신한다 — 표본이 결론을 바꿨다
- feat(session-host): execute aggregate process phases
- test(session-host): require aggregate process boundary
- docs(session-host): define aggregate process boundary
- docs(scm): §11.9 열린 질문 넷을 실측으로 닫는다
- feat(session-host): 창이 왜 안 돌아왔는지, poison 이 어디서 났는지 남긴다
- fix(agent): codex 진행 줄에서
working요구를 뺀다 —Waiting을 놓쳤다 - feat(session-host): reopen release aggregate safely
- test(session-host): require aggregate reopen binding
- docs(session-host): define aggregate reopen binding
- feat(session-host): fd 슬롯 예약이 왜 실패했는지 남긴다 — 단계 이름만으론 다섯 갈래였다
- docs(scm): 원격 트랙 진행 서술을 실제 그물에 맞춘다
- fix(app-session): 원격 SCM 픽스처를 호스트 PTY 로 보낸다
- docs(mobile): 적대적 검증이 열을 찾았다 — 넷은 방금 내가 만든 것이다
- docs(mobile): 오늘 붙인 것 셋과 «없어진 일» 하나를 문서에 맞춘다
- style(agent):
zig fmt를 적용한다 — CI 의 fmt-check 가 잡았다 - fix(agent): 스피너 프레임에
·를 더한다 — 목록은 원리상 불완전하다 - fix(agent): 스피너 프레임을 실측 다섯으로 좁힌다 — 추정과
⏺를 뺀다 - fix(agent): claude 진행 상태줄을 화면에서 다시 읽는다 —
esc to interrupt가 사라졌다 - feat(session-host): 복원이 어느 단계에서 죽었는지 남긴다 — 이름만으론 후보가 여럿이었다
- feat(session-host): handoff 디코드가 어디서 깨졌는지 남긴다
- feat(session-host): hand off release aggregate atomically
- test(session-host): require atomic aggregate handoff
- docs(session-host): define atomic aggregate handoff
- fix(mobile): 가로에서 키보드를 올리면 격자가 키바 밑에 깔렸다
- feat(mobile): 세로 잠금을 풀고 회전하면 격자를 다시 잡는다
- test(image-gallery): 크게 보기의 「빈 띠」 단언을 출처 줄까지 포함해 다시 쓴다
- feat(image-gallery): 격자와 크게 보기에 이미지 출처를 표시한다
- feat(image-gallery): 같은 메시지에 붙은 여러 장에 순번을 매긴다
- feat(image-gallery): 라벨 접두와 자리 나누기를 순수 계산으로 둔다
- docs(image-gallery): 라벨이 «누가 넣었나»부터 말하도록 계약을 정한다
- feat(mobile): 세션 목록에 스크롤바 — 흐르게 됐으니 어디쯤인지 말한다
- fix(mobile): 스크롤이 드러낸 결함 넷을 고치고 판정자를 아홉으로
- fix(mobile): 세션 목록이 안 흘렀다 — 창에 안 들어가는 세션에 닿을 수가 없었다
- feat(editor): 괄호 짝으로 점프 —
⇧⌘\(§3.9c) - fix(scm): RW2c 의 설치 경로를 굳힌다 — 적대적 검증 13 회에서 결함 열
- docs(editor): 대소문자 변환과 캡처 훅을 계획에 기록한다 — 「계약 안」 편집 보조 여섯이 닫혔다
- fix(session-host): retain durable evidence on close
- test(session-host): require retained evidence close
- docs(session-host): separate retained evidence close
- feat(session-host): promote baseline evidence durably
- test(session-host): require durable evidence handoff
- docs(session-host): define durable evidence handoff
- feat(scm): 실은 감시자를 «실제로 심는다» (RW2c)
- feat(session-host): verify same-run attestation bundles
- test(session-host): require local attestation bundle verification
- docs(session-host): define local attestation bundle verification
- refactor(mobile): 「키보드 겹침은 두 번 빼지 않는다」를 코어 한 곳으로
- fix(scm): 감시자의 rev-list 는 군더더기였다 — for-each-ref 가 이미 덮는다
ohah/pdf
- test: 아직 없는 기능을 미리 못 박는다 (빈틈 견본 6개)
- fix: /CalRGB 를 옮기지 않았고 16비트 그림을 안 그렸다
- fix: 그림자 /Extend 와 인라인 그림의 줄임 필터
- test: enc-aes256 견본을 우리 writer 로 다시 만든다
- test: 규격의 빈 곳을 겨눈 견본 열둘과 그 생성기
- fix: 혼합 모드 이름을 앞머리만 보고 골라 ColorDodge·ColorBurn 이 죽었다
- fix: 무색 무늬(/PaintType 2)가 준 색을 무시했다
- fix: 새 견본으로 잡은 셋 — /Decode·2·4비트 그림·Separation
- fix: JBIG2 — 아무것도 안 가리키는 글자 사전이 앞 글자를 물려받았다
- fix: 글꼴 캐시 열쇠가 바이트의 1%만 보고 있었다
- fix: 문서를 잇달아 열면 앞 문서의 마스크 그림이 나왔다
- test: 쓰는 쪽 타입 추론을 React·Vue·Svelte 까지 못 박는다
- test: pdf.js 에게도 제 연장을 준다 — JPX·JBIG2·ICC wasm
- refactor: 가장 깊던 두 조각을 함수로 — 깊이 11 → 9·8
- refactor: scanResources 를 자원 갈래 여섯으로 가름
- chore: 죽은 것 셋 치움
- fix: 내보낼 이름을 소스에서 뽑는다 — 손목록과 어긋나 있었다 (SSOT)
- refactor: 표의 처음 크기를 선언 한 곳으로 (SSOT)
- fix: 목차를 담을 자리를 잡고 쓴다 — 메모리 앞자리를 밟고 있었다
- refactor: 2~3개짜리 묶음 17개도 구조체로
- refactor: 남은 전역 17묶음도 구조체로 — 최상위 이름 371 → 207
- docs: 묶으면서 잃은 주석 두 덩이 되살림
- refactor: 앞머리가 같던 전역 15묶음을 구조체로
- refactor: 접근 함수 이름이 제각각이던 표 22벌도 Table(T) 로
- refactor: 늘어나는 표를 Table(T) 하나로 접다
- test: 만든 PDF 의 구조를 스스로 검사하는 상시 시험 추가
- refactor: 남은 여덟 덩이를 떼어 낸다 (10,859 → 7,489줄)
- test: 우리가 만든 PDF 를 pdf.js 로 열어 본다
- fix: 내보낸 PDF 에 모듈 이름이 새어 나갔다 — /Subtype /core.Form
- refactor: 문서 다시 쓰기(apply)를 떼어 낸다 (12,525 → 10,859줄)
- refactor: pdf.zig 에서 네 덩이를 떼어 낸다 (14,549 → 12,525줄)
- docs: 폼 XObject 설명이 낡았다 — 그리지 않는다고 적혀 있었다
- fix: 쪽 크기를 쓰레기 값만 걸러 내고 문서대로 쓴다
- fix: Type3 글꼴의 제 자원을 훑는다 — 글리프 안 그림·투명도
- fix: 타일 무늬 간격과 그림 키울 때 뭉개기 — pdf.js 맞대기로 잡은 둘
- fix: DeviceCMYK 색과 표본 함수 사이값 — pdf.js 맞대기로 잡은 둘
- test: pdf.js 와 그림을 맞대는 시험을 더한다
- perf: JPEG IDCT 를 정수로, DC 만 남은 칸은 건너뛴다
PR (해당일 생성/머지)
상태는 조회 시점 기준입니다. merged는 아래 대상 브랜치에 병합됐다는 뜻이며, 기능 브랜치 병합과 main 반영을 구분합니다. 같은 PR이 생성일과 병합일 양쪽 기록에 나타날 수 있습니다.