키오스크 도입 후 고용은 11% 줄고 주당 근로시간은 2시간 늘었다. AI 에이전트도 같은 자리에서 깨진다

어제 마트 계산 줄에 서서 앞사람 손을 보고 있었다. 예순쯤 되어 보이는 분이었는데 폰을 단말기에 툭 대고 삼성페이로 결제하는 데 3초도 안 걸렸다. 나는 거기서부터 머릿속으로 세대 이야기를 만들기 시작했다. 이분들이 인터넷 보급기를 통과한 세대니까 디지털 전환이 상대적으로 수월했던 거라고. 60대와 70대가 리니지 오토를 돌리는 것도 같은 맥락이라고. 꽤 그럴듯하게 조립됐다. 그리고 그날 저녁 나는 통신사 ARS에서 상담원을 못 찾아 같은 메뉴를 세 바퀴 돌았고, 그 가설은 필요가 없어졌다… 세대로 설명하려던 문제가 세대와 무관한 자리에서 나를 붙잡은 거다. 내가 헤맨 건 학습 부족이 아니었다. 그 시스템에는 내가 가려는 곳으로 가는 길이 아예 없었다. 세대는 변수가 아니었다 먼저 내가 틀린 부분을 정확히 해두자. 2026년 기준 X세대는 1965년에서 1980년 사이에 태어난 46세부터 61세까지다. 마트에서 본 예순 남짓한 분은 X세대 끝단이 아니라 베이비붐 세대에 더 가깝다. 리니지 오토를 돌리는 60대와 70대도 대부분 붐 세대다. 이 구분을 뭉개면 아무 얘기도 못 한다. 그런데 구분을 정확히 해도 설명이 안 되는 게 남는다. 젊은 사람도 키오스크에서 막힌다. 나는 하루의 절반을 터미널에서 보내는 사람인데, 처음 보는 무인 주문기 앞에서 뒷사람 눈치를 본 적이 여러 번 있다. 화면 어디를 눌러야 다음으로 가는지 몰라서다. 세대가 진짜 원인이라면 이런 일은 안 생겨야 한다. 그래서 시니어 얘기를 원인 자리에서 빼기로 했다. 시니어는 이 시스템의 결함이 가장 먼저, 가장 크게 드러나는 자리다. 증상이 제일 선명한 곳이 원인은 아니다. 번호가 매번 바뀌는 ARS 유튜브에 돌아다니는 ARS 풍자 영상 의 대본을 하나 읽었다. 가상의 에어컨 회사 고객센터에 전화해서 상담원을 찾아가는 코미디 스케치인데, 웃다가 중간에 등이 서늘해졌다. 과장은 됐지만 과장의 방향이 정확했다. 대본에서 벌어지는 일을 설계 결함으로 옮기면 이렇게 된다. 메뉴 번호가 ...

계획서대로 짰으면 그 버그는 그대로 나갔다

계획서대로 짰으면 그 버그는 그대로 나갔다 넉 달째 이 블로그를 에이전트로 굴리고 있고, 회사 코드도 상당 부분 AI와 짠다. 그래서 「계획 없이 코딩하면 토큰 낭비하는 이유」 라는 글이 조회 2만 3천에 추천 42를 받고 있는 걸 보고 한참 들여다봤다. 내가 매일 하는 일에 대한 얘기니까. 요지는 이렇다. research.md 로 코드베이스를 먼저 분석시키고, 그걸 바탕으로 plan.md 를 쓰고, 주석 달아가며 계획을 몇 번 다듬은 다음, "plan.md대로 모두 구현해"라고 지시한다. 그러면 "AI는 새로 판단할 필요 없이 계획 충실하게 코드를 쓰죠"라고 되어 있다. 읽고 나서 든 생각은 하나였다. 나는 정확히 반대로 일하고 있는데, 그럼 내가 토큰을 버리고 있는 건가. 그래서 지난주 내 커밋 로그를 열어봤다. 7월 29일 저녁, 회사에서 맡고 있는 데스크톱 오디오 앱의 버그를 다섯 개 고친 날이다. 커밋 시각이 18:05, 18:06, 19:06, 20:40, 21:52다. 네 시간이 안 걸렸다. 다섯 개는 이런 것들이었다. 자동 곡 전환 후 앨범 이미지가 이전 곡 것으로 남는다 자동 전환 시 바꾼 음소거 상태가 반영 안 된다 음질을 바꿔도 첫 전환에서는 이전 음질이 재생된다 자동 전환 후 볼륨이 이전 값으로 돌아간다 출력 장치를 바꿔도 다음 곡에 반영이 안 된다 지금 나열해놓고 보면 하나의 문제다. 재생 중에 바꾼 설정이, 자동으로 넘어간 다음 곡에 안 실린다. 미리 준비해둔 다음 곡 재생기가 설정 변경 대상에서 빠져 있었고, 그게 승격되는 순간 준비 시점의 옛 상태가 되살아난다. 원인은 같고, 증상만 다섯 가지로 갈라져 나온 것이다. 그런데 이걸 plan.md 에 미리 적을 수 있었을까. 못 적는다. 저 다섯 개를 관통하는 문장은 네 번째 커밋을 쓰면서 겨우 나왔다. 그 전까지는 그냥 앨범 이미지 버그였고, 그다음엔 음소거 버그였다. 마지막 커밋 메시지에 내가 직접 이렇게 써놨다. ...

AX는 회사 단위로 팔리는데 AI 격차는 옆자리 사이에서 벌어진다

앞 글을 다 쓰고 나서도 뭔가 계속 걸렸다. 기록을 남겨라, 찾을 수 있게 해라, 데이터를 어떻게 쌓았는지가 결국 승부처다 . 쓰면서도 맞는 말이라고 생각했고 지금도 그렇게 생각한다. 그런데 다 쓰고 읽어보니 이상했다. 이 얘기 어디서 많이 들어본 것 같은데. 회의록 쓰라는 말, 티켓 남기라는 말, 데이터를 한군데 모으라는 말. 새로 발견한 게 하나도 없었다. 최신 기술 이야기를 한다고 앉았는데 결론이 20년 된 잔소리로 끝난 셈이다. 그게 틀렸다는 게 아니라, 그렇다면 AX라는 새 단어는 대체 뭘 하고 있는 건가 싶었다. 그래서 이번엔 단어 쪽을 뒤져봤다. AX가 정확히 무슨 뜻이고 언제부터 이렇게 쓰였는지. 정의는 깔끔하게 나왔다. Artificial Intelligence Transformation. 인공지능 전환. 실체 없는 말도 아니었다. SK C&C는 2025년 5월 13일에 사명을 SK AX로 바꾸겠다고 발표하고 그해 6월 1일부터 적용했다. 회사 이름에 붙일 정도면 최소한 업계에서 통용되는 말은 맞다. 그런데 정의를 확인하고 나니까 오히려 더 헷갈렸다. 전환한다는 건 알겠는데 뭐가 전환된다는 건지가 안 잡혔다. 문장의 주어가 회사이기 때문이다. 회사가 전환한다. 조직이 전환한다. 그룹이 전환한다. 그런데 지난 두 달 동안 내가 실제로 본 변화는 전부 사람 한 명 단위였다. 주어가 안 맞는 것 같았다. 사명을 버즈워드로 바꾼다는 것 SK AX의 사명 해석은 이렇다. AI for Future, AI for Innovation, AI for Expansion, 그리고 AI for X. 마지막 X는 무한한 가능성이라고 붙였다. 2027년까지 전사 생산성을 30% 이상 올리고 10년 안에 글로벌 AX 서비스 톱10에 들겠다는 목표도 같이 냈다( 전자신문 , AI타임스 ). 이걸 조롱하고 싶진 않다. 오히려 정직한 축에 든다고 생각한다. 30%라는 숫자를 걸었기 때문이다. 2027년에 확인 가능한 약속이고, 못 지키면 지적당할 숫자다...

AX 도입 파일럿 95%가 실패하는 자리는 모델이 아니라 구두로 끝난 회의다

6월 첫 주에 조직 개편 공지가 올라왔다. 명분은 AI 대응이었다. 그리고 얼마 지나지 않아 사내 AI 업무 에이전트가 열렸다. 사내 문서와 위키, 이슈 트래커, 메신저, 코드 저장소를 한데 모아 지식 베이스를 만들었고 거기 붙어서 답한다고 했다. 나는 이걸 보고 좀 들떴다. 넉 달째 내 블로그를 에이전트로 굴리고 있었으니까, 이 정도면 나한테는 그냥 익숙한 물건이 하나 더 생긴 거라고 생각했다. 제일 먼저 시킨 게 주간보고였다. 한 주 동안 내가 남긴 것들을 수집해서 위클리를 쓰게 했다. 잘 됐다. 예상보다 잘 됐다. 화요일에 처리하고 완전히 잊어버린 이슈 하나가 목록에 올라와 있었다. 내가 손으로 썼으면 그건 100% 빠졌을 항목이다. 그런데 같은 도구를 받은 옆자리는 아무것도 못 뽑았다. 실패한 게 아니라 결과가 거의 비어 있었다. 처음엔 프롬프트를 잘못 넣었나 싶었는데 아니었다. 그 사람의 한 주가 어디에도 적혀 있지 않았을 뿐이다. 회의는 했고 결정도 났고 일도 돌아갔는데, 그게 전부 말로 끝나 있었다. 에이전트 입장에서는 수집할 대상 자체가 없었던 것이다. 그때부터 AX라는 단어가 좀 다르게 보이기 시작했다. 6월에 세 그룹이 동시에 같은 말을 했다 내 회사만의 일이 아니었다. 2026년 6월, 국내 주요 그룹들이 거의 같은 시기에 AX를 경영 전면에 내걸었다는 보도가 쏟아졌다. 삼성은 ChatGPT와 Gemini, Claude 같은 외부 생성형 AI를 계열사 전반에 공식 도입하고 임원 대상 집중 교육에 들어갔다. 자체 모델로 가두는 대신 성능 좋은 걸 그냥 쓰는 개방 노선이다. SK는 6월 11일부터 사흘간 이천에서 포럼을 열고 최태원 회장과 경영진이 AX 전략을 집중적으로 다뤘는데, 민감 데이터는 자체 모델과 사내 플랫폼으로 통제하고 범용 영역만 외부 모델을 쓰는 내재화 쪽에 무게를 뒀다. LG는 구광모 회장이 AX를 핵심 과제로 못박았고 자체 모델 ExaOne을 중심에 두되 일부 계열사가 글로벌 모델을 병용하는 하이브리드로 간다( ...

내 커밋 훅은 커밋되는 파일을 안 보고 있었다

내 커밋 훅은 커밋되는 파일을 안 보고 있었다 7월 8일 Wiz가 GhostApproval을 공개했다. 코딩 에이전트 6종이 공통으로 가진 신뢰 경계 결함이고, 그 목록에 Claude Code가 들어 있었다. 내가 매일 쓰는 도구다. 기사 제목만 보고 "샌드박스 우회 하나 더 나왔군" 하고 넘길 참이었는데, 원문의 작동 방식 설명을 읽다가 손이 멈췄다. 이건 샌드박스를 뚫는 얘기가 아니었다. 그래서 지난주에 손본 내 커밋 훅이 떠올랐다. 이 레포의 pre-commit-check.sh 는 커밋 직전에 시크릿을 스캔한다. 원래는 가짜 AWS 키를 여섯 줄 던졌더니 탐지가 0건이었던 물건 이다. 지난 세션에 탐지 패턴을 0/6에서 6/6으로 올리고, 값이 stdout에 찍히던 것도 막고, 공백 든 파일명으로 우회되던 것도 git diff -z 로 고쳐놨다. 회귀까지 돌려서 오탐 0건을 확인했다. 그러니까 GhostApproval과 같은 형태가 여기 있는지 찔러보는 건 30분이면 끝날 확인 작업이라고 생각했다. 찔러보니 심링크는 정말 차단됐다. 워크스페이스 밖을 가리키는 심링크를 스테이지하고 커밋을 시도했더니 훅이 exit=1로 차단했다. 여기까지는 의도한 결과였다. 그런데 차단된 이유 를 확인하려고 로그를 읽다가, 훅이 나에게 보고한 경로와 훅이 실제로 읽은 파일이 다르다는 걸 알았다. 그 사실을 따라가다 심링크와 무관한 훨씬 단순한 경로를 하나 찾았다. 그 경로로는 AWS 액세스 키가 커밋에 그대로 들어갔고, 훅은 exit=0으로 통과 신호를 냈다. 그리고 그걸 고친 패치를 다시 찔러봤을 때, 같은 병이 방향만 뒤집혀 남아 있었다. GhostApproval은 샌드박스 우회가 아니다 먼저 원문을 정확히 짚어야 한다. Wiz의 분류는 CWE-61(symlink following)과 CWE-451(UI misrepresentation)의 조합이다. 두 번째 항목이 핵심이다. 공격 순서는 이렇다. 악성 레포가 정상 설정 파일처럼 보이는 심링...

시크릿 스캔을 걸어뒀는데 AWS 키가 그냥 통과했다

회사에서 보안점검을 하자는 이야기가 내려왔다. 티빙 유출 건 때문이었다. 다니는 곳이 미디어 쪽이라 남의 일처럼 읽히지 않았고, 점검 항목이 돌기 시작하면서 사내 맥에는 MDM이 들어왔다. 소스가 회사 밖 클라우드로 나가는 경로를 통제하는 쪽이었다. 코드가 저장소에 들어가는 순간에도 검사를 거치게 만드는 작업도 같이 진행됐다. 나는 그 흐름을 보면서 개인 레포는 이미 대비가 돼 있다고 생각했다. 이 블로그를 굴리는 레포에는 커밋 직전에 도는 훅이 하나 있다. 시크릿이 스테이지되면 커밋을 막는다. 몇 달 전에 직접 짜서 붙였고, 그 뒤로 한 번도 의심해본 적이 없었다. 실제로 잘 돌긴 했다. scripts/credentials.json 을 실수로 git add 한 적이 있었는데 그때 정확히 막혔다. 막힌 경험이 있으니 신뢰가 생겼다. 그래서 이번엔 순서를 바꿔봤다. 훅이 있다는 걸 확인하는 게 아니라, 훅이 무엇을 잡는지 확인해봤다. 사내 보안 점검 스킬을 내 레포에 그대로 돌리고, 훅이 쓰는 정규식만 따로 떼어내 가짜 시크릿 여섯 개에 던졌다. 탐지 0건이었다. 훅은 자기가 아는 것만 알고 있었다 내 훅이 찾던 건 다섯 가지였다. GOOGLE_API_KEY 계열, OAuth JSON의 client_secret 과 refresh_token , 그리고 sk- 로 시작하는 OpenAI 키와 sk-ant- 로 시작하는 Anthropic 키. 이 목록을 짤 때의 나를 기억한다. 이 레포에서 실제로 쓰는 자격증명이 Google OAuth와 두 LLM API 키뿐이었으니까, 내가 가진 걸 기준으로 목록을 만든 것이다. 논리적으로는 틀린 데가 없다. 문제는 사고가 내가 가진 것 안에서만 나지 않는다는 데 있다. 던져본 여섯 개는 이런 것들이었다. AWS_ACCESS_KEY_ID = AKIAIOSFODNN7EXAMPLE aws_secret_access_key = wJalrXUtnFEMIK7MDENGbPxRfiCYEXAMPLEKEYxx GITHUB_TOKEN = ...