5분

주간 개발일지 2026‑W36: 한국 공문서를 읽고, 새 로컬 모델에 맞추고, 보안 리뷰를 닫고, Bench를 띄우다

  • 주간 개발일지
  • 바이브코딩
  • 셀프호스팅 AI
  • 2026-W36
2026-09-04에 생성한 편집 일러스트입니다. W36 Git 이력으로 확인한 문서 추출, 모델 라우팅, 평가·보안 작업을 시각화했으며 실제 제품 화면은 아닙니다.

SHIPPED / EVIDENCE

이번 주 OpenMake

8월 31일부터 9월 6일까지 GitHub main에 95개 커밋이 쌓였고, 전주 마무리분인 1.35.0·1.35.1을 월요일 새벽에 자른 뒤 1.36.0부터 1.47.0까지 열아홉 개 릴리스가 나왔습니다. 세 갈래가 겹친 주간입니다. 받아만 두고 본문을 읽지 못하던 HWP·HWPX·HML 공문서를 읽게 만들었고, 그 과정에서 컨텍스트 초과를 일시 오류로 안내하던 문제와 토큰 과소추정이 드러나 함께 고쳤습니다. 로컬 기본 모델을 qwen3.8-27b로 바꾸면서 정적 카탈로그 대신 게이트웨이에서 모델을 자동 발견하게 했고, 새 모델 점검에서 나온 샘플링 기본값·추론 보존·이미지 총량 문제를 이어서 손봤습니다. 외부 모델 쪽에는 hasa와 B.AI를 BYOK provider로 붙이고, 무료 키의 분당 한도에 토론·딥리서치가 무너지지 않도록 provider별 동시성과 429 백오프를 두었으며, 추론 강도 3단이 외부 모델에도 실제로 전달되게 했습니다. 그 사이 apps/api 보안 리뷰에서 나온 high 3건·medium 1건·low 다수를 이틀에 걸쳐 닫았고, 라우팅 골든셋을 150건으로 늘려 라우팅 정확도를 77.5%에서 100%로 끌어올린 뒤 nightly 실모델 평가를 운영 Mac에 걸었습니다. 그리고 목요일 하루에 별도 저장소에서 OpenMake Bench를 만들어 bench.openmake.cc로 띄웠습니다. 같은 프롬프트를 여러 모델과 경로에 같은 조건으로 돌려 비교하는 측정 도구이고, chat 계정 SSO로 내 모델까지 잽니다. 목요일 저녁부터 토요일 자정까지는 성격이 다른 작업이 이어졌습니다. 딥리서치 정합성 결함 6건을 한 번에 닫고, 한국어 질문에 영어로 답이 나오던 언어 드리프트를 두 갈래로 잡았으며, 웹·iOS·Bench 세 곳에 같은 Instrument 디자인 토큰을 깔았습니다. 탭을 옮기면 응답을 잃던 소켓 문제를 스트림 detach/resume으로 고쳤고, 프롬프트를 줄이는 작업에서는 배포 첫 실측이 두 번 연속으로 설계를 되돌리게 만들었습니다. 사이트 쪽에는 간체 중국어 로케일을 올려 4개 언어가 되었습니다. 마지막 날인 일요일은 성격이 또 달랐습니다. 외부 리뷰가 짚은 메모리 결함을 닫는 것으로 시작해 하루에 네 번 릴리스했고(1.45.0~1.45.3), 30일 운영 실측으로 근거를 잡은 에이전트 작업 코딩 고도화와 승인 창 없이 도는 코드 탐색 도구를 얹어 1.46.0·1.47.0을 냈습니다.

기간
2026-08-31 – 2026-09-06
Git 커밋
95
근거
Git 이력

01

개발 현황

  • 한국 공문서를 읽습니다. .hwp·.hwpx는 업로드 허용 목록에 오래 있었지만 어느 추출기 목록에도 없어 받아만 두고 본문을 읽지 못하는 상태였습니다. 순수 JS 파서 kordoc으로 HWP 3.x/5.x·HWPX·HWPML을 추출하고, .hml 업로드를 열고, 에이전트 작업 샌드박스 이미지에 kordoc을 빌드타임에 넣어 공문서 생성·서식 채우기까지 가능하게 했습니다(1.36.0). 배포 직후 두 겹의 결함이 드러났습니다. 프론트 composer의 원본 전송 목록에 hwp 계열이 빠져 363KB 문서가 깨진 텍스트로 올라가 컨텍스트를 넘겼고, 그 실패가 "외부 LLM 제공자 일시 오류"로 안내돼 재시도해도 같은 결과였습니다. 전송 목록을 백엔드 추출 목록과 한 쌍으로 맞추고, 컨텍스트 초과는 CONTEXT_TOO_LARGE로 분리해 7개 로케일에서 첨부를 줄이라고 안내하며 재시도를 권하지 않게 했습니다.
  • 토큰 추정의 맹점을 실측으로 확인하고 좁혔습니다. 문자 기반 추정은 한국어 산문과 코드에는 보수적이지만 JSON 로그는 61%, base64는 36%, hex는 30%까지 과소추정해 context-fit 안전망을 그대로 통과시켰습니다. 가중치 조정으로는 덮이지 않는다는 것을 확인한 뒤, 추정치가 유효 컨텍스트의 절반을 넘는 요청에만 vLLM /tokenize로 정확히 재계산하고 보정 계수를 절단에도 같이 적용하게 했습니다. 평상시 대화는 임계에 닿지 않아 추가 호출이 없습니다. 턴 예산 판정에서 HWP 확장자가 빠져 있던 잠복 결함도 같은 점검에서 걷혔습니다.
  • 로컬 기본 모델이 qwen3.6-35b-a3b에서 qwen3.8-27b로 바뀌었습니다(1.38.0). DGX가 모델을 교체한 뒤에도 앱은 옛 이름에 묶여 UI·카탈로그·capability가 실체와 어긋났는데, 정적 카탈로그 한 줄이 목록의 유일한 출처였기 때문입니다. 이제 부팅과 주기 프로브가 LiteLLM /model/info를 읽어 로컬 모델을 발견하고, 정적 목록은 게이트웨이 불달 시 폴백으로만 남습니다. 새 모델 점검 후속으로 샘플링을 지정하지 않은 로컬 호출에 thinking ON/OFF별 공식 권장값을 채우고, 딥리서치 하위 호출·토론 참가자·구조화 답변 같은 메타 호출 10곳에 think:false를 명시했으며, 추론 레벨 미지정 폴백을 최대 추론에서 medium으로 낮췄습니다. 도구 루프에서는 assistant의 reasoning_content를 다음 턴에 보존해 도구 호출 5턴 동안 매 라운드 직전 추론을 잃고 다시 생각하던 낭비를 없앴고, vLLM이 발급한 tool_call id를 합성값으로 덮지 않으며, 요청당 프롬프트 이미지 총량을 vLLM 상한 8장에 맞춰 9장째에 400이 나던 경로를 막았습니다.
  • 외부 모델을 실제로 쓸 수 있게 했습니다. Open AI Service Hub(hasa)와 B.AI를 BYOK provider로 붙였고, B.AI는 45개 모델을 잔액 0인 키로 전부 호출해 무료 5종만 카탈로그에 실었습니다(1.38.0·1.39.0). 토론과 딥리서치에서 명시 선택한 외부 모델이 실행 불가일 때 조용히 로컬로 폴백하던 것을 오류로 드러내고, 외부 모델을 무시한다던 잘못된 프론트 안내를 정정했습니다. 그런데 전문가 5명 병렬 호출이 B.AI 무료 키에서 5/5, hasa 개발키에서 3/5 429로 끝났습니다. 외부 실행 클라이언트를 Proxy로 감싸 provider별 세마포어와 Retry-After를 존중하는 429 지수 백오프를 두고, 딥리서치 fan-out 동시성과 타임아웃을 provider 힌트에 맞추며, SDK의 맹목 재시도를 0으로 내리고 타임아웃에 배수를 적용했습니다(1.40.0). 입력창의 추론 강도 3단은 그동안 로컬과 ChatGPT OAuth에서만 유효했는데, OpenAI 호환 외부 provider에도 reasoning_effort로 전달되어 추론 토큰이 실측 264에서 61로 줄었습니다. 휴리스틱으로 추정한 capability 캐시가 config 실측값을 가려 vision·thinking을 거절하던 문제와 medium을 400으로 거절하는 glm-5.3의 강도 맵도 정정했습니다.
  • 9월 2일 apps/api 보안 리뷰의 결과를 이틀에 걸쳐 닫았습니다(1.39.0·1.40.0). high 3건은 시스템 스킬을 아무 인증 사용자가 덮어쓸 수 있던 저장형 프롬프트 인젝션, 자기 스킬을 공유 산업 에이전트에 배정할 수 있던 경로, 타인 userId로 push 구독을 등록해 알림 사본을 받을 수 있던 문제였습니다. push 소유자를 req.user로 고정하면서 웹 push가 사실은 한 번도 전달된 적 없던 결함도 함께 닫혔습니다. 이어서 번들 id만 알면 타인의 private 번들을 설치할 수 있던 IDOR, 노출 시점에만 걸리던 고위험 MCP 도구의 역할 게이트를 실행 경로에도 강제, CSV 수식 인젝션, 타인 MCP 서버 상태 조회 오라클, 소유권 검사 빈값 통과, 첫 실행 셋업의 관리자 경합을 처리했습니다. 심층방어로 {{env.KEY}} 위치 인자 비밀을 argv에 박는 대신 sh 변수 참조로 전달해 같은 호스트의 다른 계정이 ps로 읽을 수 없게 했고, REST 이미지 상한, push 엔드포인트 호스트 허용목록, 사용자 샌드박스의 realpath 기반 심링크 탈출 차단을 더했습니다.
  • 샌드박스와 MCP의 운영 자세를 다졌습니다. 외부 아키텍처 리뷰가 지적한 secure-by-default는 코드 기본값을 바꾸지 않고 부팅 자세 점검과 첫 실행 셋업 자동 활성화로 달성했습니다. docker 없는 배포에서 외부 MCP가 원인 표시 없이 전멸하지 않게 하기 위해서입니다. readonly rootfs 전환 라이브에서 uvx 기반 서버 2종만 전멸한 원인을 도구 venv 경로에서 찾아 캐시 볼륨으로 옮겼고, 앱 재시작 3회를 살아남은 고아 컨테이너에는 role·pid·serverId 라벨을 붙여 부팅 때 소유 프로세스가 죽은 것만 정리합니다(1.37.0). 재개용으로 살아 있어야 하는 작업 샌드박스는 라벨 스코프로 건드리지 않습니다. v2 이전을 마친 MCP v1 SDK는 배포 dist에 참조가 없음을 확인하고 제거했습니다.
  • 평가가 게이트가 됐습니다. 골든셋을 50건에서 150건으로 늘리고 운영 60일의 분포를 익명화해 반영하자 라우팅 정확도가 93.3%에서 77.5%로 내려갔는데, 이것이 라우터 개선 백로그였습니다. 실패 27건을 어휘 부재 17건과 토픽 부스트 오발동 10건으로 진단해 24개 에이전트에 키워드 70개를 보강하고 "짜줘"가 프로그래밍으로 새던 패턴을 좁혀 100%로 올렸고, 임계를 0.5에서 0.9까지 ratchet했습니다(1.37.1). nightly 실모델 평가를 운영 Mac에 걸자 정상 거절문이 금지어에 걸리고 한국어 거절이 영어 표지를 빗나가던 라벨 결함이 드러나 고쳤으며, 가짜 클링온으로 응하는 모델의 실패는 품질 신호로 남겼습니다(1.37.2). 라우팅·TTFT 일일 집계는 로그 경로 이전 뒤 매일 빈 리포트만 쌓던 것을 OMK_LOG_DIR로 되살렸고, CI 게이트 16단계가 전부 성공하고도 25분에 취소되던 job 상한을 35분으로 올렸으며, 릴리스 노트에서 빠진 항목을 수동 보정하고 그 교훈을 CLAUDE.md에 남겼습니다. 도구 루프 추론 보존과 로컬 provider responseFormat 전달은 1.40.1에 포함됐고, 그 뒤 로컬 모델 프로브의 demote 영구 고착과 외부 모델 캐시의 capabilitiesInferred 유실도 고쳤습니다(#729).
  • OpenMake Bench가 chat 옆에 섰습니다. 별도 저장소 openmake_bench에 9월 4일 하루 동안 커밋 네 개로 만들어졌습니다. 같은 프롬프트를 여러 모델과 세 경로(직접·게이트웨이·OpenMake)에 temperature 0, seed 고정, 반복 3회로 순차 실행하고 규칙·judge 채점과 TTFT·tps를 한 보고서로 묶는 측정 도구 위에, Bradley-Terry 블라인드 리더보드, 내 장비에서 돌아가는 모델의 Fit Score 추천, 고른 모델을 OpenMake 역할 설정에 적용하는 의사결정 엔진을 얹었습니다. 오전에 OpenMake Compare에서 Bench로 이름을 바꾸고 오후에 bench.openmake.cc로 운영 배포했습니다. 로그인은 OpenMake 리다이렉트 SSO로 하고, 로그인 시 사용자 JWT로 bench 이름의 API 키를 발급받아 AES-GCM으로 보관해 카탈로그와 런을 그 사용자의 계정(BYOK 포함)으로 호출합니다. 이를 위해 openmake_llm 쪽에는 SSO_CLIENTS에 등록된 클라이언트에 일회성 교환 코드를 넘기는 authorize 엔드포인트, 만료 시 provider를 라이브 조회하는 /api/v1/models 캐시, 그리고 에이전트 라우터·페르소나·도구·요약·로컬 폴백 없이 요청 모델만 호출하는 X-OpenMake-Raw 모드가 들어갔습니다(#732). Bench의 OpenMake 경로는 이 raw 모드가 기본이라 usage가 정확하고, 파이프라인 오버헤드는 옵션으로 따로 잽니다. 실행은 용량 도메인당 동시 1개로 로컬 엔진은 전부 직렬, 외부 provider는 provider별 병렬입니다. 저녁에는 chat과 같은 색·서체·파비콘의 디자인을 입히고 chat 사이드바 계정 메뉴와 로그인 화면에 bench 링크를 달아, 로그인 사용자는 SSO 경로로 로그인 상태 그대로 넘어갑니다.
  • 같은 날 B.AI glm-5.3-flash가 도구 루프 2턴째에 400을 내던 원인을 좇다 운영 결함 두 겹을 찾았습니다. 원인은 reasoning_effort: medium이었고(B.AI 재생: medium만 5회 중 2회 400), 앱은 이 모델의 medium을 high로 올리도록 돼 있었지만 LLM_REASONING_EFFORTS_JSON이 코드 기본값을 통째로 대체해 pm2가 물고 있던 옛 값이 그 항목을 지웠습니다. env는 이제 기본값 위에 항목 단위로 merge합니다. 그리고 .env 편집이 재시작에 반영되지 않았습니다. PM2는 최초 start의 env 스냅샷을 주입하고 --update-env는 셸 env만 보는데 deploy 셸은 .env를 source하지 않았기 때문입니다. deploy가 .env를 줄 단위로 파싱해 export한 뒤 재시작하게 했고(#731), 첫 배포에서 그 export가 스크립트의 readonly 상수 COMPOSE_FILE과 충돌해 set -e가 재시작 직전에 조용히 끝나던 것까지 잡았습니다(#733). #729부터 이 오후 커밋들까지는 이 스냅샷에서 아직 릴리스 전입니다.
  • 딥리서치 정합성 결함 6건을 한 번에 닫았습니다(1.41.0). depth 표가 두 곳에 따로 있어 서로 어긋나던 것을 하나로 합치고, needsMore 판정이 하드코딩 값 대신 config를 보게 했으며, REST 취소가 실제 실행에 연결되지 않던 배선을 잇고, CAPACITY 표기를 정정하고, configure_research가 사용자 격리를 지키게 하고, schema의 잘못된 default를 걷어냈습니다. 같은 흐름에서 분해 프롬프트에 현재 날짜를 주입하고 검색 연산자 사용을 금지했습니다. 모델이 오늘 날짜를 모른 채 "최신"을 물으면 검색어가 과거로 굳고, 연산자를 섞으면 검색 엔진이 결과를 0건으로 돌려주기 때문입니다. 유효 서브토픽 채택은 관용적으로 바꿔 분해 실패로 전체가 멈추는 경우를 줄였습니다(#739·#740). 이튿날 새벽에는 #740의 잔여 데드코드를 걷고, 배포가 빌드 전에 태그를 fetch하도록 해 build-info의 gitTag가 실제 태그와 어긋나던 것을 맞췄습니다(#742).
  • 한국어로 물었는데 영어로 답하는 드리프트를 두 갈래로 잡았습니다. 하나는 도구 결과가 영어로 돌아온 뒤 모델이 그 언어에 끌려가는 경우로, 도구 결과 뒤에 답변 언어 리마인더를 붙이고 답변 언어 가드를 관측 가능하게 만들었습니다(#743). 다른 하나는 감지 자체의 문제였습니다. 질문에 코드 식별자가 섞이면 라틴 문자 비중이 올라가 한국어 질문이 영어로 오판되고 있었습니다. 언어 감지 전처리에서 코드 식별자를 먼저 제거하도록 고쳤습니다(#745).
  • MCP 카탈로그에 Tavily(112)와 Context7(114)을 시드했습니다. 두 서버 모두 stdio로 버전을 고정해 등록했고, {{env.KEY}} 형태의 위치 인자 비밀은 argv에 박지 않고 sh 변수 참조로 전달하는 기존 방식을 그대로 씁니다(#737·#741).
  • 외부 provider 쪽 오류 분류를 두 번 손봤습니다. B.AI의 deepseek 2종을 무료로 열고 잔액 부족 응답을 INSUFFICIENT_CREDIT으로 분류했으며(#735), provider 정책에 의한 403을 MODEL_ACCESS_RESTRICTED로 나누고 폴백 배지에 사유 키가 비어 있던 것을 채웠습니다(#736). 금요일에는 NVIDIA NIM의 fallbackModels를 현재 서빙 중인 모델로 교체했습니다. 기존 4개 중 3개가 EOL로 410을 내거나 목록에서 사라진 상태였습니다(1.43.1).
  • 웹·iOS·Bench 세 곳에 Instrument 디자인 시스템을 깔았습니다. 코발트를 프라이머리, 시안을 보조로 두고 서체를 통일한 토큰 세트입니다(1.42.0·#753). 같은 날 모바일 대응도 함께 들어갔습니다. 입력 글꼴을 16px로 올려 iOS에서 포커스 시 화면이 확대되던 것을 막고, 터치 포인터에서 아이콘 버튼의 히트 영역을 36px로 넓혔습니다(#748). Bench 쪽에서는 카드가 내용 최소폭 때문에 화면 밖으로 나가던 그리드를 minmax(0,1fr)로 바꾸고, 탭 타깃 40px과 safe-area를 적용했습니다.
  • 탭을 옮기거나 앱이 백그라운드로 가면 소켓이 끊기면서 진행 중이던 응답을 잃던 문제를 고쳤습니다. 스트림을 detach했다가 재접속 시 resume하는 방식이라, 끊긴 사이에 생성된 부분도 돌아옵니다(1.44.0·#754). 에이전트 작업 쪽에서는 로컬 실행 시 사용자가 명시한 승인 정책이 'all'로 덮어써지던 결함을 고쳤습니다(#751). 승인 경계를 좁게 잡아 둔 설정이 조용히 넓어지는 종류의 결함입니다.
  • 프롬프트를 줄이는 작업에서 배포 첫 실측이 두 번 연속으로 설계를 되돌렸습니다. 1차로 참조되지 않은 MCP 서버를 프롬프트에 노출하지 않고, 저빈도 도구를 의도 기반으로 게이팅하고, 스킬 주입에 상한을 두었습니다(#755). 배포해서 재보니 큰 manifest 스킬 하나가 상한을 다 먹고 system 스킬을 밀어내고 있었습니다. 스킬 1개당 주입 상한을 8000자로 잡았고(#757), 그래도 합계 상한에서 밀리는 경우가 남아 system 스킬을 먼저 주입하도록 순서를 바꿨습니다(#758). 배포 전 추정과 배포 후 실측이 달랐던 사례입니다.
  • 사이트에 간체 중국어 로케일을 올렸습니다. 앱 UI는 이미 4개 언어였지만 사이트는 한국어·영어·일본어뿐이라 중국 쪽에서 열 페이지가 없었습니다. 페이지 카피 9종과 릴리스 노트 16건, 헤더·푸터·메타데이터를 번역하고 라우팅·hreflang·사이트맵을 연결했습니다. 개발일지는 한국어·영어·일본어로만 쓰므로 /zh/blog는 목차만 중국어이고 본문은 영어 원문을 그대로 보여 줍니다. 같은 날 저장소에도 중국어 README를 올리고, 공개 저장소의 테스트 픽스처에 남아 있던 개인 주소와 미사용 도메인을 openmake.cc 세 주소로 통일했습니다.
  • 마지막 날 아침은 메모리로 시작했습니다. 외부 리뷰가 짚은 P0 4건을 소스와 운영 DB로 대조해 닫았습니다(1.45.0). 설정에서 메모리 학습을 꺼도 세 경로 중 둘이 토글을 보지 않아 주입과 자동 저장이 계속되던 것을 서버 설정을 단일 권위로 두어 막았고, 클라이언트 플래그는 더 조일 수만 있고 켤 수는 없게 했습니다. 사용자가 지운 문장이 다음 발화에서 되살아나던 문제는 중복 판정이 비활성 행까지 보게 하는 tombstone으로 막았으며, explicit과 candidate이 뒤집혀 있던 출처 라벨을 정의대로 되돌리고 생성·삭제를 감사 기록에 남겼습니다. 운영 테이블이 0행이라 전부 잠복 상태에서 걷힌 결함입니다. 이어서 메모리가 왜 애초에 생기지 않는지를 실측으로 좁혔습니다. 90일 사용자 메시지 615건에 휴리스틱 패턴 적중이 0이었는데 패턴 결함이 아니라 그런 발화 자체가 없었고, LLM 추출 후보 11개 중 8개는 사용자 질문에 대한 답변이었습니다. 분석 대상 텍스트를 자기에게 온 질문으로 받은 것이라, 프롬프트에 경계 태그와 형식 요구를 넣고 결정적 줄 필터를 걸어 같은 18세션 재생에서 누출 12줄을 0으로 만들었습니다. 관측용 리포트를 일일 집계에 붙이고, 자동 감지·백필로 들어온 행에는 설정 화면에서 출처 배지를 달아 사용자가 보고 지우면 그대로 tombstone이 되게 했습니다. 별도 승인 큐 없이 검토가 되는 경량 해법입니다.
  • 근접 중복 판정은 배포한 뒤 두 번 다시 손봤습니다. 1.45.0 프롬프트로 백필을 재생하니 답변 누출은 0이었지만 "병렬로 업무를 처리하기를"과 "처리하는 방식을 선호한다"처럼 어미만 다른 같은 선호가 두 번 후보에 올랐습니다. 정규화 exact와 부분 포함만 보던 규칙에 조사·어미를 뗀 토큰 집합의 Jaccard 유사도를 더했습니다(임계 0.75). 문자 바이그램은 병렬과 직렬처럼 한 글자만 다른 대립 쌍을 0.87로 잡아 반려했습니다(#765). 배포해서 라이브에서 다시 재보니 어미를 한 번만 떼는 방식은 "받기를"과 "받는"을 같은 어간으로 모으지 못했고 "모든" 같은 수식어가 합집합만 키우고 있었습니다. 어미 제거를 최대 3회 반복하고 정도·빈도 부사를 불용어로 빼서 재캘리브레이션했습니다(#767·1.45.2). 두 번 다 배포 후 실측이 다음 수정을 지시한 경우입니다.
  • NVIDIA NIM이 요청 전체를 400으로 거절하던 원인이 MCP 도구 이름의 :: 네임스페이스였습니다. 내장 도구명은 전부 OpenAI 규약을 만족하므로 문제는 그것뿐이었는데, 그 400이 업스트림 오류로 분류돼 로컬 폴백을 타면서 사용자가 고른 모델이 조용히 바뀌고 배지도 그렇게 오안내했습니다. Codex 전용이던 도구 이름 코덱을 provider 중립 모듈로 빼서 openai-compat 경계에서만 인코딩하고 응답에서 원본을 복원하게 했고, 도구 정의 거절 400은 NOT_SUPPORTED로 분류해 조용한 폴백을 막았습니다. 내부 :: 규약은 역할 게이트와 병렬 판정이 전제하므로 그대로 둡니다(#769). 이어서 보안 리뷰 잔여 3건을 닫았습니다(1.45.3). 전역 registry 연결 경로가 {{env.KEY}} 자리표시자를 래핑하지 않아 리터럴이 그대로 argv로 내려가던 것, REST 히스토리의 images가 스키마에 없어 조용히 삭제되며 REST에서만 멀티턴 vision이 끊기던 것, 그리고 대상이 없는 심링크를 realpath 검사가 경로 없음과 구분하지 못해 통과시키던 갭을 링크 자체를 보는 fail-closed로 막았습니다.
  • 에이전트 작업의 코딩 능력을 30일 운영 실측 위에서 손봤습니다(1.46.0). 작업 70건·도구 호출 1,647건을 먼저 세어 착수 근거를 잡았습니다. 완료 작업 평균 43.5만 토큰인데 스텝 본문 총량은 그 1/18이라 병목은 결과 절단이 아니라 매 턴 전체 재전송이었고, bash 444건 중 34%가 grep·find·ls·cat 탐색이었으며, 파일을 편집한 작업 55건 중 테스트를 돌린 것은 2건이었습니다. 최근 4턴보다 오래된 긴 도구 결과를 앞 240자 스텁으로 접고(원문은 스텝 기록에 남아 증거 화면은 그대로), 탐색 전용 grep_code·repo_map을 넣고, 완료 관문에서 레포에 이미 있는 러너를 감지해 한 번 돌린 뒤 실패 출력을 수정 턴에 주입하는 테스트 게이트를 뒀습니다. 러너가 없으면 아무것도 하지 않아 리포트형 작업에는 영향이 없습니다. 반면 편집 실패율과 도구 반복 호출은 실측이 근거에 미달해 착수하지 않았습니다.
  • 그런데 새 탐색 도구가 로컬 브리지에서는 exec로 나가, 읽기 전용인데도 매 호출 승인 창을 띄웠습니다. 탐색 한 번에 승인이 뜨면 실사용이 불가능합니다. 진단 도구와 같은 취지로 code_nav 전용 kind를 만들어 외부 실행 파일과 셸 없이 디바이스에서 직접 돌게 했고, 승인 게이트가 없는 만큼 파일 4000·매치 400·15초 같은 캡으로 폭주를 막았습니다. 미구현이거나 구 버전인 디바이스는 전부 null을 돌려받아 기존 셸 경로로 폴백합니다(1.47.0). 승인 창이 다시 뜨는 회귀는 헬퍼 하네스가 실제 WebSocket으로 잡습니다. 배포 직후 라이브에서 repo_map이 .git을 파일로 나열한 것은 worktree가 걸린 폴더의 .git이 디렉토리가 아니라 포인터 파일이어서였고, 디렉토리에만 걸던 제외 규칙을 셸 폴백과 같은 이름 기준으로 통일했습니다(#776).

02

주간 기록을 재구성한 방법

이 기간과 일치하는 로컬 Claude Code 프로젝트 세션을 찾지 못했습니다. 따라서 Git 이력이 증명하는 개발 내용만 기록했습니다.

확인 가능한 Claude Code 메인 세션과 명시적으로 연결된 하위 세션, 저장소 Git 이력을 전수 점검했습니다. 세션은 의도와 조사 과정을 설명하고, 실제 반영된 코드는 Git을 최종 근거로 판단했습니다.

근거 자료

근거

OPENMAKE · MIT OPEN SOURCE

개발일지로 돌아가기