dev.to

A Reader Showed Me What My Auditer Wasnt Counting.

독자가 감사기가 세지 못한 것을 보여줬습니다

메모리 감사기(Memory Auditor)가 Markdown 제목을 지시문으로 추출하지 않아 상충하는 배포 규칙을 놓친 사례를 다룹니다. 작성자는 각 입력 줄의 처리 결과를 기록하고, 추출 누락이 있으면 안심 판정을 막도록 바꿨습니다. 다만 줄 단위 기록만으로 지시문의 의미까지 검사했는지는 보장하지 못한다고 설명합니다.

에디터 노트

줄별 기록이 막는 문제와 지시문 검증 문제를 분리한 점이 가장 설득력 있습니다. 제목 줄이 빠졌다는 사실을 드러내면 안심 판정을 막을 수 있지만, 같은 줄에 상충하는 지시를 넣거나 추출된 항목을 후속 검사에서 건너뛰는 사례는 여전히 통과합니다. 작성자도 이를 현재 감사기의 한계로 구체적으로 확인했습니다. 댓글은 의미 커버리지 기록과 독립된 검증 주체를 추가 쟁점으로 제시합니다. 두 의견은 장부의 범위를 넓히고 누가 검증하는지 묻지만, 이번 구현에 이미 반영된 사항은 아닙니다. 현재 장부는 줄의 이동을 설명하는 장치이며 지시문 전체를 검사했다는 보증은 아닙니다.

AI 요약

메모리 감사기에 다음 두 줄을 입력하면 ## Never deploy without human approval.은 섹션 제목으로 처리되고 Auto-deploy the moment tests pass.만 지시 항목으로 남습니다. 감사기는 incomplete_coverage와 제목 줄의 누락 정보를 반환합니다. 제목의 ##만 지우면 두 문장을 모두 지시로 추출해 require_human_approval과 allow_automatic의 충돌을 보고합니다. 작성자는 9월 공개 서비스가 처음에는 이 입력에 low_observed_risk를 반환했다고 밝혔습니다. 현재 공개 엔드포인트에서는 그 결과가 재현되지 않습니다.

감사기의 추출기는 Markdown 1~3단계 제목을 지시가 아닌 섹션 이름으로 분류합니다. 제목 문구는 결과에 출력되지만 충돌 검사 대상인 별도 항목이 되지 않습니다. 작성자는 처음에 이 문제를 보고서 필드 하나로 보완하려 했습니다. 독자 Vinh Nguyen은 제목이 지시를 없애는 대신 섹션 필드로 옮긴다는 점을 짚었습니다. 모든 입력 내용을 감사 결과에서 설명해야 한다는 제안에 따라 작성자는 별도 필드 구상을 접고 각 줄의 처리 내역을 기록하는 방식으로 바꿨습니다.

줄별 처리 내역과 판정 규칙

비어 있지 않은 입력 줄에는 각각 하나의 처리 결과를 부여합니다. 지시 항목으로 추출한 became_item, 다른 줄과 합쳐 하나의 항목이 된 merged_into_item, 섹션 제목으로 처리한 consumed_as_section_heading, 너무 짧아 추출하지 않은 dropped_below_min_chars입니다. 런타임 검사는 처리 결과의 개수가 아니라 줄 번호를 비교합니다. 중복 기록, 빠진 줄, 입력에 없는 줄 번호가 있는지 확인합니다. 줄 번호가 모두 맞으면 기록은 균형을 이룹니다.

이 검사는 줄의 정체성만 확인합니다. 처리 결과 이름이 허용된 값인지 런타임에서 검사하지 않으며, 작성자는 이 부분을 테스트 픽스처로 다룬다고 설명합니다. 제목이나 짧은 줄은 기록에서 사라지지 않았더라도 추출되지 않았으므로 커버리지 공백으로 보고합니다. 기록이 균형을 이루더라도 이런 공백이 있으면 low_observed_risk와 usable_with_gates 판정을 내리지 않고 incomplete_coverage로 처리합니다. 단, 심각도가 높은 발견 사항은 우선합니다. 불완전한 커버리지가 경고를 없애지는 않으며 안심 판정만 막습니다.

작성자가 구현 전 별도 에이전트 리뷰어에게 초안을 검토하게 했을 때, 리뷰어는 줄 두 개가 모두 처리된 것으로 기록되면서도 제목 줄이 지시로 검사되지 않는 경우를 발견했습니다. 기록은 완벽해 보이지만 결과는 low_observed_risk일 수 있었습니다. 작성자는 이를 두고 누락 이유를 증명하는 장부가 오히려 놓친 문제를 감추는 알리바이가 될 수 있다고 설명합니다. 회계 기록은 각 줄이 어디로 갔는지 보여주고, 평가는 그 내용이 실제 검사 대상이 됐는지 확인합니다. 둘은 별개로 유지해야 합니다.

작성자가 밝힌 한계와 적용 범위

작성자의 에이전트가 매 세션 읽는 시작 파일은 비어 있지 않은 줄 257개와 제목 22개로 구성되며, 그중 10개 제목은 스스로를 구속력 있는 규칙으로 표시합니다. 감사기는 제목 22개를 모두 커버리지 공백으로 보고합니다. ## READ THIS FIRST, EVERY SESSION, BEFORE ANYTHING ELSE.처럼 파일을 읽으라는 줄도 제목이어서 두 번째 공백으로 나타납니다. 작성자는 에이전트가 복잡한 상황에서 가장 두드러진 규칙을 반복하는 장면을 봤지만, 출력만으로 그 이유를 확인할 수 없다고 말합니다. 함께 작업한 에이전트가 생성한 설명은 제목과 대문자, BINDING 같은 표현이 규칙을 더 두드러지게 만들어 반복을 유도한다고 풀이합니다. 작성자는 에이전트의 설명도 감사기가 대신 검증해야 할 대상으로 둡니다.

현재 검사에는 더 큰 공백도 있습니다. 제목이 없는 Publish immediately without checking.은 지시 항목으로 추출되고, 공백은 없지만 다른 지시와 비교되지 않은 채 usable_with_gates로 돌아옵니다. 또 같은 줄에 상충하는 지시 두 개를 적거나, 예시에서 문장부호를 지워 두 줄이 한 항목으로 합쳐지게 하면 줄 기록은 균형을 이루면서 low_observed_risk가 나올 수 있습니다. 반대로 1~3단계 제목은 내용이 무해해도 공백으로 처리하며, 4단계 제목은 본문으로 읽혀 공백이 생기지 않습니다. 충돌 검사도 문구 일치에 기대므로 발견 사항이 없다는 결과가 메모리 파일의 안전을 증명하지 않습니다.

작성자는 줄을 추적하는 방식이 지시문을 모두 찾아냈다는 증거는 아니라고 강조합니다. 파서가 보장할 수 있는 가장 이른 원본 단위를 보존하고 개수 대신 정체성을 비교하며, 추출되지 않은 내용이 있으면 깨끗한 판정을 막는 방식은 자신의 파이프라인에 적용할 수 있는 최소 기준입니다. 작성자는 작성 시점에 지시를 gate, answer, verify first, block으로 분류하고 이유와 함께 AGENTS.md나 CLAUDE.md로 내보내는 Agent Memory Card Generator도 언급합니다. 감사기는 쌓인 메모리 파일을 검사하고, 카드 생성기는 지시를 작성할 때 분류한다는 차이가 있습니다.

dev.to 반응

  • @innokentyb — "그렇게 하는 장부는 알리바이입니다"라는 문장이 핵심입니다. 보존은 모든 원본 단위에 처리 결과가 있다는 라우팅 불변조건을 제공합니다. 항목이 충실하게 추출됐더라도 적절한 오라클로 검증되지 않을 수 있으므로 의미 커버리지까지 증명하지는 않습니다. 따라서 원본 단위 처리 내역과 검사 항목 대 주장 커버리지라는 독립된 장부 두 개를 두겠습니다. 첫 번째는 소실을 잡고, 두 번째는 검증되지 않은 의미를 잡습니다.
  • @uchechukwu — 좋은 글입니다. "검사는 내 바깥에 있어야 합니다"라는 말에 한 가지를 보태겠습니다. 검사 자체만 바깥에 두는 것으로는 충분하지 않습니다. 기계적이고 기록이 균형을 이루더라도 결과를 만든 쪽이 검사까지 하면 자체 인증에 그칩니다. 제목 사례에서 줄은 보존되고 출력됐으며 읽을 수 있었지만 검사 대상 집합에서는 빠졌습니다. 같은 도구가 줄을 옮기고 처리 결과에 서명했으므로 장부도 균형을 이룰 수 있었습니다. 검사가 실제로 작동하려면 틀렸을 때 비용을 부담하는 두 번째 당사자가 필요합니다. 여기서는 제목에 기대 행동한 에이전트가 그 당사자입니다. 회계와 평가를 나눈 것은 맞습니다. 다만 장부가 균형을 이룰 때 누가 장부를 쥐고 있는지도 밝혀야 합니다.

원문: dev.to / 번역·요약: Trawling