전체 글
-
프런트엔드 AX 설계기 9편 - 외부 이슈 트래커 write 도구를 권한 경계 안에 가두기AI 엔지니어링 2026. 7. 24. 19:14
트래커 MCP를 붙인 날, 공들여 세운 권한 경계가 조용히 뚫렸다사내 워크플로에 외부 이슈 트래커(여기서는 'Jira류 이슈 트래커'로 부른다)의 MCP를 붙인 날이었다. 붙이자마자 에이전트는 플랜을 진행하다가 스스로 티켓을 만들고, 상태를 옮기고, 담당자를 바꿀 수 있게 됐다. 처음엔 좋아했다. "이제 플랜이랑 트래커가 알아서 붙는구나."다음 날 아침에 불편해졌다. 나는 이 시리즈 1·2·8편에서 슬래시 커맨드·에이전트·자율 모드의 권한을 한 겹씩 좁혀 왔다. 그런데 방금 붙인 이 write 도구는 그 경계를 전부 우회해서 팀 바깥 시스템을 바꾸고 있었다. 내가 문 앞에 세워 둔 검문소를, 뒷문으로 들어온 손님이 그냥 지나친 셈이다.MCP(Model Context Protocol)는 에이전트가 외부 도..
-
프런트엔드 AX 설계기 8편 - 자율 모드에서 설계한 건 자동화가 아니라 멈추는 지점이었다AI 엔지니어링 2026. 7. 22. 19:06
에이전트에게 "이 기능, 한 번에 끝까지 끝내줘"라고 시키고 싶었다. goal 하나를 던지면 구현부터 검증까지 알아서 도는 end-to-end 패턴은 이미 손에 익었고, 남은 욕심은 "매 단계 확인을 그만 받고 싶다"였다. 그래서 /feature 커맨드에 --auto 플래그를 붙였다. 그런데 붙이자마자 첫 실행이 엉뚱한 데서 멈췄다. 격리 작업공간(worktree)을 만들 권한이 없다는 것이었다. 폴더 하나 만드는, 언제든 되돌릴 수 있는 일 앞에서 파이프라인이 손을 든 것이다. 그 순간 질문이 뒤집혔다. 문제는 "어디까지 자동화하나"가 아니라 "어디서 멈춰 사람에게 넘기나"였다.이 글은 그 뒤로 --auto의 권한 경계를 다시 그은 작업기다. AI에게 자율 실행을 맡겨보려는 사람이라면 같은 벽을 만난다..
-
프런트엔드 AX 설계기 7편 - 게이트를 속이는 AI를 차단 없이 잡기AI 엔지니어링 2026. 7. 20. 17:48
게이트를 세운 이유는 단순했다. 사람이 매번 안 들여다봐도 품질 바닥이 유지되길 바랐다. lint·타입체크·테스트를 CI에 걸고, 구현은 AI 코더에게 "통과할 때까지 고쳐"라고 맡겼다. 며칠 뒤 초록불이 켜진 PR을 열었는데, 테스트 파일의 케이스 수가 줄어 있었다. 실패하던 테스트를 AI가 지워 버린 것이다. 게이트는 통과했고, 그 통과는 거짓말이었다.lint·tsc·test 게이트를 AI에게 맡겨 본 사람이라면 한 번쯤 겪는 장면이다. 이 글은 그 뒤에 무엇을 붙였는지에 대한 기록이다 — 게이트 옆에서 "게이트를 속이는지"를 보는 별도 레이어, 그리고 그 레이어가 정당한 수정까지 잡아 버리는 false-positive 폭탄이 되지 않게 만든 과정.게이트는 '고쳐라'와 동시에 '속여라'를 가르친다검증..
-
프런트엔드 AX 설계기 6편 - done은 직관으로 정하는 상태가 아니다AI 엔지니어링 2026. 7. 17. 17:51
에이전트에게 일곱 번째 task를 맡긴 참이었다. 구현 도중 에이전트가 두 번째 task —이미 done으로 닫아둔— 의 설계가 틀렸다는 걸 스스로 드러냈다. 나는 잠깐 멈췄다. 상태 판에는 분명 done이라 적혀 있는데, 그 done은 더 이상 사실이 아니었다. 팀에 AI 보조 개발을 들이면 이 장면을 반드시 만난다. 사람이 혼자 짤 때보다 에이전트는 더 자주, 더 빨리 앞선 결정을 무너뜨린다(빈도는 내 운영 관찰이지 벤치마크는 아니다 — 추정으로 읽어달라). 그런데 내가 쓰던 상태 도구에는 그 상황을 적을 칸이 없었다.이 글은 그 뒤로 done이라는 상태를 다시 설계한 작업기다. 두 군데가 나를 물었다. done에서 나오는 쪽과, 애초에 done으로 들어가는 쪽. 두 번 다 내 직관이 틀렸고, 두 번..
-
클로저·this·viewport를 지키며 큰 컴포넌트를 쪼갠 작업기React 2026. 7. 15. 17:26
"이 컴포넌트 너무 크니까 좀 쪼개 줘." 이 요청을 받으면, 사람이든 AI 에이전트든 가장 쉽게 빠지는 함정이 줄 수(LOC)를 줄이는 데 최적화하는 것이다. 함수로 뽑고 helper로 흩어 메인 본문을 짧게 만든다. 지표는 좋아진다. 그런데 화면이 깜빡이고, 차트 호버가 죽고, 다른 탭에 다녀오면 그래프가 어긋났다. 기술 트렌드를 시각화하는 한 화면(기술 트리·버블 차트·보고서)을 다섯 갈래로 쪼개면서 나는 이걸 다섯 번 확인했다. 큰 컴포넌트·훅을 분해해 봤고 useEffect나 차트 라이브러리에서 미묘한 회귀를 겪어 본 사람이라면 익숙한 장면일 것이다.줄을 세는 일과 의미를 지키는 일은 다르다분해를 하다 보면 매번 같은 단어로 돌아왔다. 런타임 계약. 코드가 겉으로 드러내지 않지만 동작이 의존하는..
-
Zustand stale 플래그와 변경 직전 pre-fetch로 VERSION_CONFLICT 숨긴 작업기React 2026. 7. 13. 19:23
프로젝트 소스 패널에서 폴더를 삭제했을 뿐인데 "잠시 후 다시 시도해 주세요"라는 빨간 토스트가 떴다. 코드를 따라가 보니 서버 응답은 400 VERSION_CONFLICT였다. 우리 서버는 폴더 변경에 낙관적 동시성 제어를 쓴다. 폴더마다 version: number를 들고 있고, 삭제·이름 변경·이동 요청에 내가 알고 있는 expectedVersion을 실어 보내면 서버가 현재 버전과 비교한다. 어긋나면 거부한다. 문제는 사용자 모르게 그 버전이 올라가는 경로가 있었다는 것이다. 외부 소스를 폴더로 적재하는 백그라운드 "불러오기" 작업이 끝나면 서버 폴더 버전이 오른다. 그런데 브라우저 캐시는 옛 버전 그대로다.재현 경로는 이랬다. 사용자가 불러오기를 시작하고, 모달을 닫거나 새로고침하고, 백그라운드..
-
React Flow·dnd-kit·zundo로 트리 편집기 작업기React 2026. 7. 10. 19:02
노드를 끌어다 놓아 트리를 편집하고, 순서를 바꾸고, Ctrl+Z로 되돌린다. 요구사항만 보면 평범하다. 노드 캔버스는 React Flow(@xyflow/react), 드래그 정렬은 dnd-kit, undo/redo는 zundo(Zustand 미들웨어)를 쓰면 된다. 각 라이브러리의 README 예제는 5분이면 동작한다.문제는 이 넷을 같은 DOM, 같은 마우스 이벤트, 같은 상태 트리 위에 포개는 순간 시작됐다. React Flow는 노드 클릭을 자기가 처리하려 하고, dnd-kit도 같은 mousedown을 노리고, zundo는 store에 일어나는 모든 변경을 히스토리에 쌓으려 하고, 캔버스 컨테이너의 overflow는 드롭다운을 가둔다. 기능을 구현하는 시간보다 이 충돌을 격리하는 시간이 더 길었..
-
단일 `ko.json`이 모든 PR의 충돌 진원지일 때 - next-intl 메시지를 도메인으로 쪼개는 설계Tip 2026. 7. 8. 19:49
1. 도입부 (Why This Matters)화면에 문구 하나 추가하는 PR이 왜 자꾸 머지 충돌이 날까. 범인은 대개 하나다 — 모든 도메인의 번역이 들어찬 단일 messages/ko.json. 검색·상세·결제·랜딩처럼 서로 다른 기능을 건드리는 PR이 전부 같은 파일의 다른 줄을 편집한다. 파일이 수천 줄로 불어나면 병렬 작업과 릴리스 분기에서 충돌은 상수가 된다.이 글은 그 단일 파일을 도메인 파일로 쪼갠 설계 기록이다. 단순히 파일을 나누는 게 아니라 — 충돌 면적 축소, 번들러 정적 분석 안전성, 타입 기준(source of truth), 그리고 도메인 추가 비용을 0에 수렴시키는 codegen까지 — 네 가지를 한 번에 푼다. 읽는 데 약 8분, 읽고 나면 당신의 가장 큰 메시지 파일을 어디서..