내가 왜 내 backlog.md를 읽는 것을 그만두었는지 (그리고 대신 무엇을 읽는지)
요약
에이전트가 업데이트되지 않은 마크다운 파일을 기반으로 잘못된 정보를 제공한 사례를 통해, 유지보수되지 않는 기록물(backlog.md)의 위험성을 경고합니다. 작성자는 기록을 단순한 요약이 아닌, 데이터베이스의 캐시처럼 관리해야 함을 강조합니다.
핵심 포인트
- 업데이트되지 않은 기록물은 신뢰할 수 없는 캐시와 같다
- 데이터에서 유도되는 정보는 반드시 갱신 메커니즘을 포함해야 한다
- 기록(Markdown)은 사고의 초안일 뿐, 시스템의 소스(Source)가 되어서는 안 된다
- 상태 보고 시 파일 시스템을 우선시하는 워크플로우 권장
내 파일이 나에게 거짓말을 했던 그날 아침
5월 21일 수요일, 세션 시작 전, 키보드 옆에는 커피가 놓여 있었습니다. 나는 에이전트(agent)에게 DEV.to 시리즈가 어디까지 진행되었는지 물었습니다. 답변은 깔끔하고 명확했습니다. "대기 중인 기사 4개가 있으며, 게시될 준비가 되었습니다." 나는 다시 읽었습니다. 0.5초 정도 민망함이 느껴졌는데, 지난주에 DEV.to에서 두세 개 정도 본 것 같았기 때문입니다. 하지만 그사이 잠을 자서 확실하지는 않았습니다. 나는 모든 것을 바꿔놓을 질문을 입력했습니다. "정말로 게시될 기사들이 남아 있는 게 확실해?" 에이전트는 동시에 DEV.to API를 다시 조회하고, scripts/devto/state.json을 열어 두 정보를 교차 검증했습니다. 네 개의 기사는 이미 2~3일 전에 게시된 상태였습니다.
내가 방금 읽은 것은 환각 (hallucination)이 아니었습니다. 에이전트는 우리가 기대한 대로 정확히 수행했습니다. 즉, articles/backlog.md를 열고, 표를 읽고, 그 내용을 그대로 전달한 것입니다. 문제는 내가 이 파일을 업데이트하는 것을 그만두었다는 점이었습니다. 이번 주 푸시 (push) 이후에 sync-backlog.ts가 실행되지 않았던 것입니다. 프로덕션 (prod) 환경에서는 _"published"_라고 말하고 있었지만, 마크다운 (markdown) 파일은 _"en stand-by"_라고 말하고 있었습니다. 타이핑은 거짓말을 하지 않았습니다. 그것은 내가 직접 작성했고, 아무것도 유지 관리하지 않음에도 불구하고 권위 있는 정보로 취급했던 파일을 충실히 읽어준 것뿐이었습니다.
요약 (summary)은 갱신 기능이 없는 캐시 (Cache)와 같다
이것은 지속되는 1인 프로젝트에서 가장 흔히 발생하는 실패 모드입니다. 매일은 두 가지 흐름을 만들어냅니다. 한쪽에는 커밋 (commit), 배포 (deployment), 데이터베이스 (database)의 행, 전환되는 상태값들로 이루어진 움직이는 실체가 있습니다. 다른 한쪽에는 상황을 파악하기 위해 작성하는 기록들이 있습니다. 예를 들어 backlog.md, 루트 디렉토리의 MEMORY.md, 일요일 밤의 세션 노트, 혹은 전주에 리팩터링 (refactor)한 폴더의 README 등이 있습니다. 이러한 기록들은 스프린트 (sprint)를 마치는 동작 속에서 빠르게 작성되지만, 파이프라인 (pipeline) 내에서 이를 다시 닫아줄(업데이트할) 트리거가 아무것도 없기 때문에 느리게 유지되거나 아예 유지되지 않습니다.
R6는 SQL 컬럼에 대해 _Live / Snapshot / Cache mandatory (필수)_라고 말합니다. 다른 데이터로부터 유도될 수 있는 모든 컬럼은 해당 컬럼을 생성하는 커밋(commit)에서 자신의 카테고리를 선언해야 합니다. 만약 그것이 Cache(캐시)라면, 갱신 메커니즘 (GENERATED ALWAYS AS, SQL 트리거(trigger), 예약된 REFRESH 계획이 있는 구체화된 뷰(materialized view))이 동일한 커밋에 포함되어 제공되어야 합니다. 카테고리가 선언되지 않으면, 커밋되지 않습니다.
backlog.md도 정확히 동일한 논리적 객체입니다. 그 가치는 state.json에 몇 가지 편집 상의 상수(constants)를 더한 것에서 유도됩니다. sync-backlog.ts는 그것의 애플리케이션 트리거(trigger)입니다. 호출이 없다면, Cache(캐시)는 어긋나게 됩니다.
대신 내가 읽는 것
R2, Filesystem over summary (요약보다 파일 시스템),는 5월 15일부터 이 동작을 공식화했습니다. 모든 상태 보고(status report) 이전에, 다음의 네 가지 셸(shell) 명령어를 이 순서대로 실행합니다. 마크다운(markdown)은 마지막에 오며, 이는 사고의 초안(draft)으로서 오는 것이지, 결코 소스(source)로서 오는 것이 아닙니다.
git log --since='7d' --oneline
git status --porcelain
ls docs/adr/ | wc -l
...
결과는 3초 만에 읽힙니다. 내가 잊고 있었던 커밋이든, 기억하고 있던 것보다 하나 더 많은 ADR이든, 무언가 나를 놀라게 한다면 나는 backlog.md가 아니라 그 지점을 파고듭니다. 마크다운을 읽을 때, 나는 _"누가, 언제 이것을 업데이트했는가"_라는 암묵적인 질문을 던지며 읽습니다. 만약 15초 이내에 git log에서 답이 나오지 않는다면, 나는 그것을 상한(rotten) Cache(캐시)로 취급합니다.
Coda
언제, 어떤 메커니즘에 의해 생성되었는지 밝히지 않는 요약(sommaire)은 아무것도 말해주지 않습니다. 스크립트(script), 트리거(trigger), 또는 크론(cron)이든, 그것을 생성하는 커밋(commit)에 갱신 주기를 선언한다면 그것은 관리되는 캐시(Cache)로서 생존할 수 있습니다. 그렇지 않다면 그것을 소스(source)로 취급하는 것을 중단해야 하며, 다시 초안(brouillon)으로 돌아가게 됩니다. R6는 데이터베이스(database)에 대한 규칙을 말합니다. R2는 자기 자신에게 전달하는 기록(écritures)에 대해 동일한 규칙을 말합니다. git log를 확인하기 전에 backlog.md를 여는 에이전트(agent)는 나쁜 에이전트가 아닙니다. 그것은 사전에 금지했어야 할 인간의 동작을 충실히 수행하는 에이전트일 뿐입니다. 5월 21일 아침, 나에게 거짓말을 한 것은 에이전트가 아니라, 전날 저녁에 노트를 닫지 않았던 바로 나 자신의 타이핑(dactylo)이었습니다.
Counterpart Toolkit v0.7, 규칙 R2 — Filesystem over summary. v0.4.1의 R1에서 추출되어 독립적인 규칙으로 승격됨. toolkit의 현재 버전은 github.com/michelfaure/doctrine-counterpart 에서 CC-BY-4.0 라이선스로 제공됨.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기