← 메모리

기억한 실수를 길목에 놓았다

규칙도 기억도 있었는데 에이전트는 같은 유형의 오판을 다시 저장했다. 기억이 꺼내야만 나오는 구조였기 때문이다. 그래서 실수가 나는 길목에서 기억을 자동으로 꺼내 붙이는 장치를 Hindsight-Crew에 만들었고, 그 장치의 완료 보고는 검증 표본이 운영과 달라 세 번 뒤집혔다.

목차
  1. 문제
  2. 58초 사이에 일어난 일
  3. 기억을 길목에 놓는 세 층
  4. 주입은 참고 자료로 붙인다
  5. 완료 보고가 세 번 뒤집혔다
  6. 3주 운영 숫자
  7. 결론
  8. 한계·재검토 트리거
  9. 참고

에이전트가 "퍼지 불가"라는 판정을 기억에 저장하고 58초 뒤, 내가 "왜못해 aside가 있는데"라고 물었다.
답은 이미 기억 뱅크에 있었다.
recall 한 번이면 나오는 기록이었고 막혔다고 말하기 전에 recall부터 하라는 규칙도 이미 지침에 있었다.

이런 장면은 그 전에도 있었다.
aside로 Cloudflare 2FA를 처리할 때마다 같은 실수가 되풀이됐고, 내가 "리콜해봐 너는 해답을알고있어"라고 해야 에이전트가 그제야 답이 recall에 있었다고 했다.

문제

"막혔다"고 선언하기 전에 recall을 하라는 조항은 8월 26일에 지침에 들어갔다.
그 조항이 생긴 경위는 블로커 오진을 다룬 글에 있다.
9월 21일의 실수는 그 조항이 있는 상태에서 같은 유형으로 다시 일어났다.

규칙을 한 줄 더 쓰는 것으로는 막을 수 없다고 봤다.
그날 설계를 적은 이슈의 진단은 이렇다.
"하인드사이트의 전 도구는 pull 방식이다. 호출되지 않은 기억은 존재하지 않는 것과 같다."
retain도 recall도 에이전트가 스스로 부를 때만 일한다.
부를 생각을 못 한 순간이 바로 실수가 나는 순간이라서 기억 쪽을 아무리 고쳐도 이 실패는 남는다.

58초 사이에 일어난 일

배포는 끝났는데 CSS만 Cloudflare 엣지 캐시에 옛 버전으로 남아 있어서 새로 넣은 표시 하나가 보이지 않았다.
에이전트는 캐시를 비우려다가, 가진 API 토큰으로는 보이는 zone이 0개라는 것을 확인했다.
그리고 토큰에 zone 퍼지 권한이 없다는 사실을 "퍼지는 내가 못 한다"는 결론으로 넓혔다.
대안으로는 대시보드에서 직접 비우거나 약 4시간 기다리라며 일을 내게 넘겼다.

그 판단은 대화로 끝나지 않고 기억에도 들어갔다.
배포 완료 기록 안에 "zone 0개 조회 = 퍼지 불가"라는 한 문장으로 들어갔고 라벨은 [완료+gotcha]였다.
다음 세션이 이 기록을 recall하면 퍼지는 원래 안 되는 일로 읽힌다.

내 지적을 받고 에이전트가 aside에 대시보드 로그인을 맡겼지만 작업은 2FA 화면에서 멈췄다.
"2fa 관련해서도 리콜해봐 내용있어"라고 한 줄 더 보내자, recall 한 번에 8월에 남긴 분담 기록이 나왔다.
Claude Code만 2FA 시드를 읽고, 계산한 6자리 코드만 aside에 넘기는 구조였다.
aside는 그 코드로 로그인한 뒤 CSS 파일 URL 하나만 골라 퍼지했다.
같은 zone에 다른 사이트가 붙어 있어서 전체 퍼지는 누르지 않았고 다시 조회한 응답은 age: 0이었다.

에이전트가 스스로 인정한 내용은 이랬다.
"토큰 권한만 보고 '퍼지 못 한다'고 단정해서 레인 전체를 닫았고, 막혔다고 말하기 전에 리콜을 안 돌렸다. 둘 다 규칙에 적힌 그대로인데 건너뛰었다."

recall은 낡은 절차도 함께 드러냈다.
8월 20일 기록에는 2FA 입력이 6칸으로 나뉘어 자동 제출된다고 적혀 있었는데, 그날 화면은 입력창 하나에 Verify를 직접 눌러야 했다.
에이전트는 "직전 retain의 '퍼지 불가' 판정은 틀렸다"로 시작하는 정정 기록을 다시 저장했다.

기억을 길목에 놓는 세 층

같은 날 설계를 이슈로 정리했다.
기억이 pull 방식이라면 push 배선은 기억 바깥, 즉 모든 호출이 지나가는 게이트웨이와 에이전트 하네스에 둘 수밖에 없다.
설계 커밋에는 이 전제가 제약 줄로 남아 있다.
"하인드사이트 전 도구가 pull 방식이라 push 배선은 게이트웨이·하네스 층에서만 가능."

에이전트의 첫 제안은 이 함정을 aside 호출 직전에 읽는 플레이북에 적어 두는 것이었다.
나는 플레이북은 임시 조치이고 같은 상황은 계속 반복될 텐데 Hindsight에 근본적으로 처리할 장치가 없냐고 되물었다.
설계를 들은 뒤에는 '배우는' 마지막 한 걸음이 아직 수동이지 않은지, 주입이 컨텍스트를 더럽히지 않는지, 적어 둔 gotcha가 나중에 맞지 않게 되면 어떻게 되는지, 현장의 판단이 틀렸을 때도 바로잡을 수 있는지를 차례로 물었다.

층무엇을 보나걸리면
길목 주입aside로 가는 호출의 과제 텍스트를 정책 테이블과 대조그 행에 적힌 쿼리로 라이브 recall을 돌려 과제 앞에 붙인다. LLM 0회
재발 탐지같은 함정이 다시 저장되거나, 늦은 recall 뒤 정정이 저장되는 패턴트리거 초안을 만들고 통지한다. 등록은 사람이 승인한다
retain 모순 게이트차단·불가 계열 라벨의 저장이 성공 전례와 충돌하는가저장은 하고 경고만 돌려준다

길목에서 붙는 텍스트는 테이블에 고정해 두지 않았다.
테이블에는 recall 쿼리만 적고, 트리거가 발화할 때마다 그 쿼리로 기억을 새로 꺼낸다.
그래서 정정 기록이 들어오면 테이블을 고치지 않아도 다음 주입부터 내용이 바뀐다.
2FA 입력창이 바뀐 일이 바로 이런 경우였다.

기각한 안은 설계 커밋에 기각 줄로 남겼다.
답 텍스트를 테이블에 적어 두는 안은 "정정 retain이 주입을 갱신하지 못해 낡은 지시가 남는다".
재발 신호를 트리거로 자동 등록하는 안은 "폭발 반경·오탐 비대칭·기억의 준지시화 - 사람 게이트가 방화벽".
모순 게이트가 저장을 반려하는 안은 "세상이 바뀌는 정상 사건"까지 지운다.
aside 샌드박스가 비밀 폴더 읽기를 막기 시작한 일처럼, 예전의 성공 경로가 정말로 막히는 경우도 있기 때문이다.

주입은 참고 자료로 붙인다

붙는 기억은 1~2건, 약 500토큰이 상한이다.
기억마다 [hindsight 참고, 날짜 관측, id] 꼴의 머리를 달고, 끝에 푸터 한 줄을 붙인다.
"이 기록은 그 시점의 관측이다. 현장이 기록과 다르면 현장이 우선이다."
낡은 기억이 지시처럼 읽히는 것을 막으려는 장치다.

구현 세션의 첫 실측에서 2FA 과제 텍스트에는 975자, 추정 496토큰이 붙었고 관계없는 텍스트에는 0바이트가 돌아왔다.
같은 날 구현 세션이 셰임(aside 호출을 감싸는 얇은 래퍼)을 거쳐 aside를 실제로 부른 검증 호출에서는, 프롬프트 첫 줄에 [hindsight 참고, 2026-09-21 관측 머리가 붙었다.
붙은 기억은 그날 앞서 저장된 정정 기록이었다.
정정 기록이 저장되고 2시간 38분 뒤의 일이었다.

완료 보고가 세 번 뒤집혔다

장치의 "완료"는 세 번 뒤집혔다.
이슈는 닫힘 세 번, 재오픈 두 번을 거쳤고 셋째 결함은 이슈가 열린 채로 "운영 반영 완료"가 보고된 뒤에 드러났다.

차례완료 근거다른 세션이 찾은 것검증 표본과 운영의 차이
첫 완료세 층 모두 실측 통과MCP recall 응답이 이중 인코딩이라 원장의 MCP 항목 97/97이 결과 id 없이 비어 있었다. 실제 원장 116줄 중 113줄이 테스트가 남긴 기록이었다라이브 검증의 구원 recall은 REST였고, 테스트 픽스처는 dict였다
둘째 완료324 passed결함 7건. 다른 서비스 2FA 문장에도 트리거가 발화했고, 추가 지연 8초 이하라던 판단도 통지 15초 타임아웃이 직렬로 붙어 틀렸다리뷰어가 넣은 시험 문장에서야 드러났다. 매치 쪽 실측 표본은 Cloudflare 문장뿐이었다
셋째 완료454 passed, 운영 반영게이트 recall이 retain 전문을 2,000자로 잘라 쿼리로 보냈고 위쪽 Hindsight의 쿼리 길이 한도 500토큰에 걸려 실사용 retain 12건이 전부 recall-failed9월 21일 검증은 짧은 probe였다

첫 결함 묶음에는 셰임이 실패 응답을 걸러내지 못해서 토큰이 무효하면 에러 JSON이 프롬프트 앞에 붙는 문제도 있었다.
이 문제는 검수 세션이 일부러 무효 토큰을 넣어 재현한 것이고 운영에서 실제로 붙은 적은 없다.
둘째 검수의 오발화도 리뷰어가 시험 문장 두 개로 얻어 낸 결과다.
그 리뷰어가 남긴 문장은 둘째 행의 사정을 정확히 짚었다.
"소수 점수 표본은 장기 정확도의 증거가 아니다."

셋째 결함이 가장 컸다.
고친 코드에 남은 주석을 옮기면 이렇다.
"실제 길이의 retain은 전부 recall-failed로 돌아왔고, 두 게이트는 운영에서 조용히 꺼져 있었다."
재발 탐지와 모순 게이트는 테스트와 probe를 전부 통과한 상태로, 실사용 retain에서는 recall 단계부터 실패하고 있었다.
쿼리를 한도 안으로 자르도록 수정한 뒤, 488 passed로 이슈를 최종 종료했다.
여기서 말하는 한도는 recall 쿼리의 길이 한도이고 recall이 돌려주는 결과의 토큰 예산과는 다른 값이다.

검수는 매번 내가 다른 세션에 맡겼다.
첫 완료 7분 뒤 검수 요청서를 새 세션에 넣었고, 둘째 완료 뒤에는 같은 요청서를 Codex에 넣어 다시 보게 했고, 셋째 "운영 반영 완료" 보고 약 4분 뒤에는 다른 세션에 "하인드사이트 이슈#12 도 전체적으로 검수해"라고 보냈다.

세 번 모두 구현이 틀린 지점은 달랐지만 검증이 놓친 이유는 같았다.
검증 표본이 운영 분포를 닮지 않았다.
차례대로 REST 경로와 dict 픽스처, Cloudflare 문장뿐인 표본, 짧은 probe였다.
그래서 수정의 방향도 같았다. 실제 응답을 캡처해 픽스처로 쓰고 실제 길이의 retain으로 회귀 테스트를 걸었다.

3주 운영 숫자

게이트웨이 로그에서 길목 주입 줄을 다시 셌다.
9월 21일부터 10월 14일까지(UTC 날짜 포함)는 match 59, miss 173, recall-failed 6이었다.
match는 전부 Cloudflare 대시보드 2FA 트리거에서 나왔다.
지금 등록된 트리거는 두 개이고, 둘 다 aside 호출에만 걸린다.

9월 30일부터 10월 7일까지 7일 구간의 감사 줄에서는 길목 주입 71줄, 재발 탐지 20줄, 모순 경고 12줄이 찍혔다.
10월 5일까지 재발 탐지가 쌓은 트리거 초안 12건을 따로 검토한 권고는 등록 1(병합 1), 보류 2, 기각 8이었다.
탐지 임계값 재평가가 아직 끝나지 않았으므로, 이 비율로 탐지 품질을 판단하지는 않는다.

장치를 설계한 9월 21일에는 지침에도 조항이 하나 더 들어갔다.
같은 조작이나 접근이 2회 연속 실패하면, 막혔다는 선언과 상관없이 막힘으로 보고 recall부터 한다.
8월의 조항은 에이전트가 "막혔다"고 말해야 걸렸다.
새 조항은 실패 횟수로 걸린다.
다만 에이전트가 읽고 따라야만 걸린다는 점은 새 조항도 8월 조항과 같다.
그래서 기억 쪽에서는 길목 주입이, 지침 쪽에서는 이 조항이 같은 빈틈을 함께 맡는다.

결론

규칙이 있는데도 실수가 재발한 것은, 기억을 꺼내는 호출이 에이전트의 판단에 달려 있었기 때문이다.
판단이 틀린 순간에는 기억도 함께 빠진다.
그래서 실수가 나는 호출 앞에 recall을 고정했고 그 장치의 완료는 운영과 닮은 표본으로 다시 검증할 때까지 세 번 미뤄졌다.

한계·재검토 트리거

match가 전부 트리거 하나에서 나왔으므로, 길목 주입이 다른 유형의 실수에도 효과가 있는지는 이 숫자로 말할 수 없다.

고친 뒤에도 10월 14일까지 게이트웨이 로그에는 모순 게이트의 recall 실패가 45줄 더 찍혔고, 원인은 로그에 남아 있지 않다.

발단이 된 오판 기록의 라벨은 앞에서 본 완료+gotcha였고 모순 게이트는 라벨만 읽기 때문에, 그 원사례는 이 게이트의 대상 밖이었다.
그 기록이 걸리는 쪽은 kind:gotcha 태그로 대상이 되는 재발 탐지다.

2026-10 기준 / 재검토 트리거: 재발 탐지 임계값 재평가가 끝나거나, 두 번째 트리거가 운영에서 match를 내면 이 글의 운영 숫자를 다시 센다.

참고