2026-09-06
요약 (AI 작성)
hwpjs 가 하루에 117커밋을 쌓은 날입니다. hwp5 문서 구조를 전수로 검증합니다 — ViewText 프레이밍, 소유된 revision text 수집, connector 소유권을 문서·CFB 로 교차 검증, group 자식 개수와 순서 있는 identity, memo 도형과 마커 소유권·목록 짝, drawing 메타데이터 접미사(예약 바이트는 정규화하지 않는다), fill image 참조, arc payload(추론 없이), picture 크기와 effects 뒤 alpha, 색 효과(손실 기본값 없이), history 레코드, 인덱스 레코드 계층과 문단 소유권, 겹치지 않는 완전한 표 격자. README 는 사용법에 집중하도록 줄였습니다.
maru 는 원격 파일 트리를 하루에 세웠습니다 — 백엔드가 원격을 읽고 원격 워커·§5 게이트·실물 sshd 왕복(RF2b), 트리에 원격이 서는 v1(따라가기·표시·펜스, RF3a), 원격 변경의 하부(저쪽 한 프로세스가 신원을 다시 재고 비대체로 옮긴다, RF6a), 원격에서 지우기(되돌릴 수 없다고 말하면서, RF6c), 만들기·밴드 진실·미러 정리(RF6d·e·f). 적대적 검증 5회가 낸 넷을 고치고 실서버 캡처로 눈으로 확인했습니다. 모바일은 브리지가 접근성 서술자를 내고 iOS 가 스크린 리더에 넘기며(M9 첫·둘째 슬라이스), 이름 없는 세션 줄이 통째로 사라지던 것과 보는 글자·읽는 글자가 다르던 것을 고쳤습니다.
편집기는 ⌥클릭 으로 커서를 추가·제거하고(§3.2c) ⌥더블/트리플클릭이 마지막 커서를 낱말·줄로 넓힙니다(§3.2d). 테스트는 AppSession 스위트를 같은 바이너리의 인덱스 샤드 4개로 나눠 병렬로 돌리고, prefix 제외 필터로 session_host 중복 실행 2,594개를 건너뛰며, CI 는 main 의 진행 중인 run 을 취소하지 않고 캐시는 그룹마다 최신 1세대만 남깁니다.
커밋
ohah/hwpjs
- docs(hwp5): document verified ViewText validation gap
- feat(hwp5): decode bounded distribution ViewText envelopes
- feat(hwp5): validate track change envelopes and content counts
- feat(hwp5): validate ViewText framing with shared container limits
- fix(hwp5): recognize observed revision sign field identity
- feat(hwp5): validate track author levels and declared counts
- test(hwp5): compare merged cache and final text coordinate evidence
- test(hwp5): verify revision range projection against ordered BodyText
- feat(hwp5): index observed revision merges by paragraph flow
- feat(hwp5): collect owned revision text with shared budgets
- test(hwp5): investigate merged revision line cache coordinates
- feat(hwp5): add bounded observed revision range projection
- feat(hwp5): validate connector ownership through document and CFB checks
- feat(hwp5): parse memo shape fields with shared bounded borders
- feat(hwp5): parse group child lists and explicit instance extensions
- feat(hwp5): validate group child counts and ordered identities in documents
- feat(hwp5): parse bounded connector payloads and verify paired coordinates
- feat(hwp5): compose bounded picture effect blocks atomically
- feat(hwp5): validate memo shapes through DocInfo resources
- feat(hwp5): validate direct OLE ownership and expose pending references
- feat(hwp5): parse explicit shape borders with shared line attribute views
- feat(hwp5): parse explicit drawing metadata suffix without normalizing reserved bytes
- test(hwp5): preserve evidence of divergent OLE reference targets
- feat(hwp5): parse shape component geometry and preserve rendering matrices
- feat(hwp5): validate drawing fill image references through shared rules
- feat(hwp5): parse bounded polygon points and preserve opaque tails
- feat(hwp5): validate arc ownership with explicit document layouts
- feat(hwp5): parse explicit arc payload layouts without inference
- fix(hwp5): preserve inactive presentation gradient image references
- feat(hwp5): validate picture ownership and selected document extensions
- feat(hwp5): parse picture dimensions and optional alpha after effects
- feat(hwp5): collect memo range diagnostics across document sections
- feat(hwp5): decode observed memo end token indices
- docs(readme): simplify usage introduction
- feat(hwp5): inspect index mark keyword boundaries and diagnostics
- feat(hwp5): parse bounded summary properties with deferred diagnostics
- feat(hwp5): validate decoded history records with explicit layouts
- feat(hwp5): decode document and layout compatibility records
- feat(hwp5): validate bounded script streams without execution
- test(hwp5): validate real index marks and allow preserved object extensions
- feat(hwp5): inspect page hiding and parity with explicit widths
- feat(hwp5): validate bookmark names through shared parameter fields
- feat(hwp5): index record hierarchy and validate paragraph ownership
- feat(hwp5): preserve control and explicit list header layouts
- feat(hwp5): parse column layouts and validate variable width pairs
- feat(hwp5): validate complete non-overlapping table grids
- feat(hwp5): parse optional memo field indices with shared identity rules
- feat(hwp5): validate document-global memo references
- feat(hwp5): validate memo marker ownership and list pairing
- feat(hwp5): decode memo list indices in body records
- fix(hwp5): validate full memo list paragraph counts
- feat(hwp5): parse bounded picture color effects without lossy defaults
- feat(hwp5): validate picture BinData ordinals and absent references
- feat(hwp5): validate ellipse ownership in documents and containers
- feat(hwp5): validate rectangle ownership with shared document mutation checks
- feat(hwp5): parse ellipse fields and preserve inactive interval coordinates
- feat(hwp5): parse explicit rectangle layouts with paired HWPX validation
- feat(hwp5): compose observed drawing styles from shared fill parsing
- feat(hwp5): connect explicit drawing style checks to document validation
- test(hwp5): verify shape style version correlations and selection limits
- test(hwp5): survey drawing styles and pin older layout incompatibilities
- feat(hwp5): support explicit fill-only drawing style layout
- feat(hwp5): parse explicit note control payload layouts
- feat(hwp5): integrate note list ownership and explicit earlier payloads
- feat(hwp5): parse observed equation payload layouts
- feat(hwp5): parse explicit OLE property layouts without ID overlap
- fix(hwp5): resolve observed storage extensions through shared BinData targets
- feat(hwp5): parse video payload views with explicit web string boundaries
- feat(hwp5): validate memo end targets across document sections
- feat(hwp5): add flow-scoped memo range diagnostics
- feat(hwp5): parse ordinary line payloads with lossless attributes
- feat(hwp5): validate ordinary line ownership through document and container paths
- fix(hwp5): reject layout compatibility outside its owner group
- test(hwp5): verify header footer diagnostics through document containers
- feat(hwp5): inspect header footer properties and owned list areas
- test(hwp5): centralize report offsets and verify distinct section ordering
- feat(hwp5): inspect page number position and preserve observed dash values
- feat(hwp5): validate equation ownership through document inspection
- feat(hwp5): validate hidden comment list ownership through shared groups
- fix(hwp5): recognize observed hidden comment codes without normalization
- test(hwp5): exhaustively cover formatting payload bit positions
- feat(hwp5): parse border fills character and paragraph shapes
- feat(hwp5): validate DocInfo resource counts and active references
- feat(hwp5): inspect ruby text and preserve full-width properties
- feat(hwp5): validate shape hierarchy and integrate geometry diagnostics
- feat(hwp5): validate curve ownership through document containers
- feat(hwp5): parse bounded curve segments and preserve raw tails
- feat(hwp5): parse explicit picture prefixes and verify paired fields
- feat(hwp5): validate polygon ownership and document count boundaries
- docs: split agent guide into topic-owned documents
- feat(hwp5): map paragraph flow ownership from validated lists
- docs(hwp5): align documentation routes with topic ownership
- feat(hwp5): add explicit observed forbidden character lists view
- feat(hwp5): expose explicit forbidden list document policy
- docs(readme): focus on build and API usage
- test(hwp5): verify forbidden list policy through CFB input
- feat(hwp5): expose cell flags and observed extension prefix
- feat(hwp5): parse bounded parameter sets and typed cell names
- feat(hwp5): parse note shapes with verified 32-bit separator layout
- feat(hwp5): link extended text controls within owning paragraphs
- feat(hwp5): group sibling paragraph lists and verify declared counts
- feat(hwp5): parse section and page properties with ownership checks
- feat(hwp5): validate control code and ID compatibility
- feat(hwp5): parse and validate table cell and caption structure
- feat(hwp5): parse common object properties with bounded descriptions
- feat(hwp5): validate parameter sources and report deferred data
- feat(hwp5): parse and validate paragraph metadata arrays
- feat(hwp5): parse paragraph headers and lossless text tokens
- feat(hwp5): inspect explicit character overlap layouts and references
- feat(hwp5): resolve summary codepages and validate dictionary structure
- feat(hwp5): parse decoded XML template strings with shared bounds
- feat(hwp5): inspect automatic and restart numbering controls
- feat(hwp5): validate common field envelopes and attribute diagnostics
- fix(hwp5): preserve observed memo token and header identities
- feat(hwp5): inspect preview UTF-16 text and preserve diagnostics
- feat(hwp5): validate CFB document streams and internal binary data
- feat(hwp5): compose decoded document validation with global limits
ohah/maru
- fix(mobile): 흐르는 목록의 서술자가 고정 헤더 밑까지 뻗었다
- feat(mobile): 세션 목록이 읽힌다 — M9 넷째 슬라이스
- test(remote-file-tree): 감시·이름 변경·삭제를 실서버 캡처로 눈으로 확인한다
- feat(mobile): 안 바뀐 프레임은 GPU 를 안 쓴다 — 정지 8초에 3,901 tick 을 쉰다
- feat(file-tree): 원격 트리가 스스로 갱신된다 — 채널 하나를 두 뷰가 나눠 쓴다 (RF5a)
- refactor(session-host): share candidate publication suffix
- test(session-host): specify shared publication suffix policy
- docs(session-host): define shared publication suffix authority
- perf(test): 러너에 keep-only prefix 를 더해 rx_read_test_support 바이너리의 session_host 중복 실행 1,555개를 끊는다
- fix(mobile): 훑는 사람만 겪는 셋 — 순서·알림·커서
- feat(mobile): iOS 가 서술자를 스크린 리더에게 넘긴다 — M9 둘째 슬라이스
- feat(editor):
⌥클릭으로 커서 추가·제거 (§3.2c) - fix(session-host): cross-bind stage5 semantic graph
- test(session-host): reject stage5 semantic mix-and-match
- docs(session-host): require stage5 semantic cross-binding
- test(session-host): openpty 판정자가 자식을 기다리는 동안 master 를 비운다 — p5c3c-3b TestTimedOut 데드락
- docs(mobile): 적대적 검증이 낸 셋을 계약과 계획에 싣는다
- fix(mobile): 서술자가 반쪽 글자를 내고, 눌리는 복사 버튼을 빠뜨렸다
- fix(mobile): 덮인 버튼을 읽어 주던 서술자를 «누르는 조건» 에 묶는다
- feat(mobile): 브리지가 접근성 서술자를 낸다 — M9 첫 슬라이스
- feat(file-tree): 원격 파일이 열린다 — 임시 미러·read_only·안내 3종 (RF4)
- build: test-session-host 는 잡의 -Doptimize 모드 하나만 컴파일한다 — 하위 스텝 스텝째 의존이 두 모드를 물려받았다
- fix(session-host): fd 슬롯 예약을 준비 작업보다 앞으로 옮긴다 — 디렉토리 fd 가 59 를 채갔다
- test(remote-file-tree): 실서버 캡처로 원격 트리와 읽기 전용 열기를 눈으로 확인한다
- feat(session-host): fd 슬롯 점유자를 «몇 개, 무슨 종류»까지 남긴다 — 하나로는 여는 주체가 안 갈렸다
- feat(session-host): 업그레이드 스캔을 건너뛴 순간을 남긴다 — 무음이라 사후 재구성이 안 됐다
- perf(test): 샤드 넷을 래퍼 한 스텝 안에서 동시에 돌린다 — zig build 는 inherit run 스텝을 직렬로 돈다
- test(editor): OW 판정자가 방향·막대·undo·비교뷰·제품 배선까지 잰다 (§3.2d)
- test(editor): OW 판정자로 ⌥더블/트리플클릭을 고정하고 죽은 조건을 뺀다 (§3.2d)
- feat(editor): ⌥더블/트리플클릭이 마지막 커서를 낱말·줄로 넓힌다 (§3.2d)
- feat(session-host): compose resumed publication
- test(session-host): specify resumed publication composition
- docs(session-host): define resumed publication composition
- docs(remote-file-tree): 남은 후속 둘을 조건 대기로 닫고, 슬롯 상한을 실측으로 뒷받침한다
- feat(file-tree): 원격 만들기·밴드 진실·미러 정리 (RF6d·RF6e·RF6f)
- feat(session-host): execute resumed publication command
- test(session-host): specify resumed publication command
- docs(session-host): define resumed publication command
- feat(agent-activity): 도구 호출이 화면에 뜬다 — 활동 뷰 AV1-b
- feat(session-host): close aggregate command outcomes
- test(session-host): specify aggregate command outcomes
- docs(session-host): close aggregate command outcomes
- feat(session-host): bind aggregate process events
- test(session-host): specify aggregate workflow events
- docs(session-host): bind aggregate outcomes to reducer events
- feat(agent): 주인 없는 nonce 를 알린다 — 마지막 한 칸이 조용했다
- feat(session-host): own aggregate child observations
- test(session-host): specify aggregate child ownership
- docs(session-host): define aggregate child ownership
- fix(input): 편집기 컨텍스트 chord 가 메뉴 keyEquivalent 를 이긴다
- docs(key-input): 마지막 가설을 코드로 죽인다 — 실험이 필요 없었다 (24~26회차)
- docs(key-input): 가설 셋을 가르고 남은 하나의 실험을 적는다 (21~23회차)
- docs(key-input): 검증 계획의 약점과 Swift 선-가로채기 경계 (18~20회차)
- docs(key-input): 진단을 반증 시도로 확증한다 (15~17회차)
- docs(key-input): 표시 수정의 안전성과 오버레이 조건을 적는다 (12~14회차)
- docs(key-input): 인용한 선례를 실제로 읽고 정정한다 (9~11회차)
- docs(key-input): 질의 설계의 함정 셋을 계약에 적는다 (provenance·rebind·판정자)
- docs(key-input): 메뉴 keyEquivalent 층이 편집기 chord 셋을 가로챈다
- perf(test): AppSession 스위트 샤드를 4 로 되돌린다 — 반복 횟수 대기는 #3327 이 고쳤다
- feat(session-host): observe bounded child outcomes
- test(session-host): specify dual stream child observation
- docs(session-host): define bounded child observations
- ci(cache): 캐시 청소가 main 그룹마다 최신 1세대만 남긴다 — 복원은 전부 접두 폴백이라 2세대가 필요 없다
- feat(session-host): recover aggregate cleanup after crashes
- test(session-host): specify crash-safe aggregate recovery
- docs(session-host): define crash-safe aggregate cleanup
- ci: main 의 진행 중인 run 은 취소하지 않는다 — PR ref 만 취소한다
- fix(mobile): 본문에서 보는 글자와 읽는 글자가 달랐다 — 결합·자리·커서
- feat(mobile): 터미널 본문이 줄마다 읽힌다 — M9 여섯째 슬라이스
- docs(remote-watch): 폴링 비용은 결함이 아니라 튜닝이다 — 범위와 착수 조건을 못박는다
- fix(test): 파일 열기 훑기의 조기 종료는 성공한 스텝에서만 정한다 — #3296 의 새 실패 모드를 닫는다
- docs(mobile): 접근성이 닫힌 뒤에도 «없다» 고 적혀 있던 넷을 고친다
- feat(file-tree): 트리에 원격이 선다 — 원격 탐색기 v1(따라가기·표시·펜스) (RF3a)
- feat(file-tree): 백엔드가 원격을 읽는다 — 원격 워커·§5 게이트·실물 sshd 왕복 (RF2b)
- build: test-session-host 도 release adapter 판정자를 집계 둘로 묶는다 — 개별 82 바이너리 → 2
- fix(file-tree): 원격 탐색기 리메디에이션 — 실패는 비활성으로·펜스 키는 발행 출처로 (적대적 검증 3회)
- feat(session-host): rebuild stage5 resume authority
- test(session-host): require stage5 resume authority
- docs(session-host): define stage5 resume authority
- feat(session-host): attest stage4 authored pair
- test(session-host): require stage4 authored action
- docs(session-host): define stage4 authored action
- fix(smoke): 상한이 조용하면 거짓 초록, 가로로 굴러간 프레임을 재면 거짓 빨강
- fix(smoke): 판정이 다른 호스트의 컴파일을 죽였다 — 그리고 게이트가 그것을 볼 수 없었다
- test(smoke): 굴린 편집기의 색을 잰다 — 판정이 보고도 안 잡던 자리 (§2m.114)
- feat(session-host): expose stage3 preparation command
- test(session-host): require stage3 preparation command
- docs(session-host): define stage3 preparation command
- feat(editor): 열/블록 선택 —
⌥드래그·⇧⌥드래그와⇧⌥⌘방향키 (§3.2a) - test(agent): 뺐던 분배 판정자를 되살린다 — mutation 설계가 틀렸던 것이다
- feat(agent): 원격 이벤트가 어느 조건에서 안 붙는지 남긴다
- feat(session-host): execute published aggregate cleanup
- test(session-host): specify published cleanup command
- docs(session-host): define published cleanup command
- style(agent-activity): zig fmt — 삽입한 절 앞 빈 줄 하나
- feat(agent-activity): 인덱스가 도구 호출도 담는다 — 활동 뷰 AV1-a
- fix(image-gallery): 크게 본 채 도크를 접으면 그림이 사라졌다 — 회수 규율이 그 한 장을 빼먹었다
- fix(mobile): 스크린 리더만 겪는 여덟 — 자리·상태·겹침·나갈 길·수·문구
- feat(mobile): 남은 화면 넷이 읽힌다 — 서버 목록·설정·편집·물어보는 화면들
- ci(check-boundaries): 경계 게이트를 인덱스 샤드 넷으로 나누고 imports.zig 를 ReleaseSafe 로 돈다
- feat(session-host): delete published aggregate safely
- test(session-host): specify post-publish aggregate deletion
- docs(session-host): define post-publish aggregate deletion
- fix(mobile): 스크린 리더만 겪는 다섯 — id·뒷정리·프레임 섞임·엉뚱한 버튼·이모지
- feat(mobile): Android 가 서술자를 TalkBack 에게 넘긴다 — M9 셋째 슬라이스
- feat(file-tree): 원격에서 지운다 — 되돌릴 수 없다고 말하면서 (RF6c)
- feat(session-host): project resumed publication assets
- test(session-host): specify resumed publication asset graph
- docs(session-host): define resumed publication asset graph
- perf(session-host): ledger 해제 1건의 재계산을 정책 변경 없이 5분의 1로 줄인다
- refactor(mobile): 읽는 순서를 브리지가 정한다 — host 가 다시 세우지 않는다
- feat(file-tree): 원격 변경의 하부를 연다 — 저쪽 한 프로세스가 신원을 다시 재고 비대체로 옮긴다 (RF6a)
- perf(test): 훑기 셋에 조기 종료를 두고 ledger 상한 판정자의 뒷정리를 drainAll 로 바꾼다
- feat(file-tree): 원격 트리에서 이름을 바꾼다 — 펜스를 여는 대신 문을 하나 더 낸다 (RF6b)
- docs(test): 러너 문서에 prefix 제외 필터 예외를 적는다 — «전체를 실행한다» 서술 정합
- perf(test): 러너에 prefix 제외 필터를 더해 app-host-abi 의 session_host 중복 실행 2,594개를 건너뛴다
- perf(test): AppSession 스위트를 같은 바이너리의 인덱스 샤드 4개로 나눠 병렬로 돈다
- docs(agent): RA5 후속의 사각지대를 적는다 — 반개방 TCP 와 그 수정
- fix(agent): ssh 에 ServerAlive 를 붙인다 — 반개방 TCP 가 원격 이벤트 채널을 5 시간 36 분 매달았다
- feat(session-host): bind live workflow steps
- test(session-host): specify live workflow step bindings
- docs(session-host): define live workflow step bindings
- feat(session-host): reauthenticate published cleanup assets
- test(session-host): specify published cleanup authority
- docs(session-host): define published cleanup reauthentication
- fix(mobile): 이름 없는 세션 줄이 스크린 리더에서 통째로 사라졌다
- docs(agent-activity-view): 적대적 검증 3회가 찾은 결함 다섯을 반영한다
- docs(agent-activity-view): 갤러리를 「에이전트 활동 뷰」로 넓히는 계약과 계획을 세운다
- feat(session-host): own live workflow invocations
- test(session-host): specify live workflow invocation owner
- docs(session-host): define live workflow invocation owner
- fix(test): 이미지 갤러리 판정자의 워커 대기를 반복 횟수 대신 벽시계 마감으로 — 부하에서 안 흔들리게
- fix(file-tree): 적대적 검증 5 회가 낸 넷을 고친다 — 정리·스탬프·비용·픽스처·목적지
- perf(test): AppSession 스위트 샤드를 4 → 3 으로 — 러너의 코어당 프로세스 하나
- feat(mobile): 줄이 «전체 중 몇째» 인지 말한다 — 그 길이 아예 없었다
- feat(session-host): hand off fixed workflow checkpoints
- test(session-host): specify process checkpoint handoff
- docs(session-host): define process checkpoint handoff
- feat(session-host): persist workflow reducer state
- test(session-host): specify durable workflow state handoff
- docs(session-host): define durable workflow state handoff
ohah/pdf
- fix: 그림자 마디를 8에서 32로 늘린다
- fix: 1형 셰이딩을 띠가 아니라 이어진 색으로 그린다
- fix: 시험이 조용히 적게 돌아도 통과했다
- refactor: /Annots 배열 찾기를 한 군데로 모은다
- test: 느림을 벽시계 말고 CPU 시간으로 가른다
- test: 어댑터 셋을 타입 그물 안으로 넣는다
- test: 고장 내기 10갈래 — 안 걸린 둘을 메운다
- test: 우리가 쓴 파일의 머리를 못 박는다
- test: 뽑아낸 값이 조용히 달라지지 않게 못 박는다 (손자국)
- test: 고장 내기로 찾은 빈 곳 셋을 메운다
- fix: 견본이 조용히 줄어도 그림 맞대기가 통과했다
- fix: 터진 시험을 통과로 세고 있었다
- fix: '실패 표시가 없으면 통과' 가 터진 시험을 통과시켰다