넘겨받은 커머스는 여러 AI 에이전트 세션이 영역을 나눠 운영하고, 운영 변경은 사람이 승인한다. 그런데 한 번은 하루 전에 정한 고정 IP 관련 결정을, 다음 날 올라온 다른 허용 변경이 대조 없이 되돌렸다. 두 번째 안을 낸 쪽은 첫 번째 결정을 대조하지 않았다. 방화벽이나 허용 목록 같은 운영 설정이 넣었다 뺐다 흔들리면, 그 사이에 무엇이 열려 있었는지 아무도 모른다.
Table of contents
Open Table of contents
배경 — 빠져 있던 대조 단계
원인은 개별 안이 틀린 것이 아니라, 같은 대상에 대한 이전 결정을 찾는 단계가 절차에 없었다는 데 있었다. 그래서 운영 변경을 올리기 전의 절차를 세 단계로 정했다.
- 같은 대상의 마지막 결정·실행 기록을 찾는다
- 그 결정과 방향이 반대면, 반대인 사실과 그 근거를 안에 밝힌다
- 승인된 범위만 운영에 바꾼다
문제는 이 절차를 사람이나 세션이 기억하게 두면 똑같이 빠진다는 점이다. 그래서 절차가 빠지는 자리마다 장치를 걸기로 했다.
판단 — 한 장치가 아니라 세 층
장치를 하나로 할지 여러 층으로 할지를 먼저 정했다. 진행판 검사기 하나만 두는 대신 세 층으로 나눈 이유는, 한 군데에만 걸면 그 자리를 거치지 않는 변경은 빠져나가기 때문이다. 결정은 진행판에 기록되고, 안은 세션 사이 메시지로 오가고, 실제 변경은 명령으로 실행된다. 셋이 서로 다른 자리이므로 층을 셋으로 나눴다. 대가는 층마다 오탐 기준을 따로 맞춰야 한다는 점이다.
| # | 장치 | 걸리는 때 | 형태 |
|---|---|---|---|
| ① | 진행판 검사기(Python check.py)에 ops_change 검사 추가 | 결정 표의 제목·「고를 것」 칸에 운영 어휘가 있을 때, 설명 첫 줄이 마지막 결정: <번호·날짜> · 방향 같음/반대 또는 마지막 결정: 없음 이어야 통과 | 변경안 |
| ② | 메시지 훅 규칙 | 허브·조율·플랫폼 세션이 운영 어휘와 30자 안의 변경 동사가 든 안을 보낼 때 세 단계를 상기 | 규칙 후보 |
| ③ | 명령 훅 규칙(Bash·PowerShell) | gcloud … firewall-rules create·update·delete, *-iam-policy-binding·set-iam-policy, Cloudflare API 의 규칙·목록·WAF 변경 명령을 낼 때 한 번 막고 확인 | 미등록 |
①은 설정 파일(JSON)에 ops_change 의 어휘와 첫 줄 정규식이 있을 때만 검사한다. 설정이 없는 다른 워크스페이스는 동작이 그대로라, 같은 검사기를 공유하는 곳에 부작용이 없다.
검증 — 오탐을 좁힌 과정과 시험 사례
①의 트리거는 처음에 결정 표의 행 전체와 설명 본문으로 잡았다. 그러자 지금 진행판에서 3건이 걸렸는데 전부 오탐이었다. 서버 중계 함수를 언급한 행, Cloudflare 토큰을 언급한 행, 방화벽 일정이 적힌 기한 칸이었다. 반면 트리거를 제목과 선택지 칸으로 좁히자 오탐이 0이 됐다.
시험 사례는 걸려야 하는 것과 통과해야 하는 것을 함께 넣었다. 운영 어휘가 있는데 첫 줄이 없거나 둘째 줄에 있거나 방향 표기가 빠지면 실패해야 하고, 선택지 칸의 ⓑ IAM 바인딩 추가 도 실패해야 한다. 반대로 첫 줄이 맞거나, 어휘가 본문·기한 칸에만 있거나, 운영 변경이 아닌 결정이거나, 설정이 없는 판이면 통과해야 한다.
②는 스냅샷 382건에 돌려 실패 0, 걸림 4, 통과 9 였다. 시험 중 결함도 둘 잡았다. 시험에 쓴 세션 이름이 규칙 조건의 이름 꼴과 달라 걸려야 할 4건이 실패했고, 과거형 예외 글자에 되 만 있어 「추가된 항목은 없습니다」 같은 보고까지 걸렸다. 된·됐 을 더해 고쳤다. 「변경 없음」·「넣었다가 다시 뺐습니다」 같은 사고 보고는 통과하는 것이 맞다.
③은 읽기 명령이 걸리지 않는지를 대조군으로 봤다. firewall-rules list·describe, get-iam-policy, Cloudflare GET 과 GraphQL 조회, terraform plan, 그리고 dev 프로젝트의 방화벽 생성은 통과했다.
영향 범위 — 장치가 못 하는 것
세 장치 모두 한계가 있고, 그것을 숨기지 않았다. ①은 운영 어휘가 없는 제목(예: 「dev API 허용」)으로 올라온 변경을 잡지 못하고, 첫 줄의 형식만 볼 뿐 그 내용이 맞는지는 모른다. ②의 훅은 마지막 결정이 무엇인지 모르므로 상기만 하고 검증은 하지 못한다. 결국 장치는 「찾았는가」를 묻는 자리를 만들 뿐이고, 찾는 일 자체는 여전히 사람과 세션의 몫이다. 그래서 ①을 반영하면 운영 변경 결정마다 설명 첫 줄에 마지막 결정을 적는 습관이 생기는 것이 이 설계의 실제 효과라고 봤다.
결과 — 결정 대조를 거친 운영 변경
- 절차. 운영 변경을 올릴 때 「마지막 결정」을 첫 줄에 적게 해, 이전 결정과 반대 방향이면 그 사실이 안에 드러나게 했다
- 오탐. 진행판 검사기의 트리거를 제목·선택지 칸으로 좁혀 현재 진행판 오탐을 3건에서 0건으로 줄였다
- 남긴 한계. 장치는 상기와 형식까지만 한다. 마지막 결정의 내용이 맞는지 대조하는 일은 여전히 사람과 세션의 몫이다
정리
- 운영 변경의 흔들림은 승인이 없어서가 아니라 이전 결정을 대조하지 않아서 생긴다. 마지막 결정을 찾는 단계를 절차 맨 앞에 둔다
- 절차가 빠지는 자리마다 장치를 건다. 기록·메시지·명령이 서로 다른 자리라면 층도 따로 둔다
- 트리거는 오탐 0 이 될 때까지 좁히고, 걸려야 하는 사례와 통과해야 하는 사례를 함께 시험한다
- 장치는 상기와 형식까지만 한다. 내용의 대조는 남는다는 것을 한계로 적어 둔다