Joyuno's Dev Blog

2026-07-28 (화) 개발일지

dev-blog

오늘의 이슈: SSH 전송 구현 중 설계 오해와 T5 probe 커버리지 공백

오늘은 m0-probes의 M1b SSH 전송 구현을 완료한 뒤 리뷰하다가, 내가 잘못 짚은 설계 가정 하나를 바로잡고, 동시에 T5 probe에서 edit atomicity를 검증하지 않는 테스트 공백을 메웠다. 두 건 다 ‘문서를 제대로 안 읽어서’ 발생한 실수였고, 그걸 깨닫는 과정이 곧 해결이었다.

M1b SSH 전송 — 잘못된 L2 제거 판단을 되돌리기까지

M1b 마일스톤은 lens-gw가 B·C 노드의 lensd를 SSH stdio로 직접 읽는 구현이었다. Transport 인터페이스에 두 번째 구현체(ssh.go)를 추가하고, CLI에 --node 플래그를 배선해 로컬 디렉토리 대신 원격 노드의 lensd stdout을 연결했다. 로컬 검증(go vet ./..., go test ./..., scripts/m0/verify.sh)은 모두 통과.

리뷰를 마치고 handoff 문서를 작성하던 중, 문득 “A에서 Claude 하나만 돌리면 L2(M12)는 빼도 되지 않을까?”라는 생각이 들었다. 설계 문서엔 L2가 명시되어 있었지만, 내 추론으로는 에이전트가 하나면 L2에서 관리할 대상이 없으니 불필요해 보였다. 이게 첫 가설이었다.

handoff 문서에 그 의견을 적어 넣으려다, 그래도 원래 설계를 다시 확인해야겠다는 생각에 MEMORY.md와 docs/를 다시 펼쳤다. 그리고 바로 내가 틀렸다는 걸 알았다.

B와 C에서 각각 Claude를 켜고, A는 그걸 한 곳에서 관리하는 조종석이라는 게 원래 구도였다. 에이전트가 2개이므로 L2는 유효하다. 내가 “A 하나”라고 전제한 게 잘못이었다.

설계 문서가 맞았고 내 해석이 틀렸다. 이걸 기록하지 않고 그냥 넘어갔으면 나중에 L2를 뺀 잘못된 결정이 handoff에 박혔을 것이다. 바로 MEMORY.md에 정정 내용을 추가하고, handoff 문서(2026-07-28-mac-m0-node-handoff.md)에 “L2 유효”라는 항목을 명시적으로 넣었다.

검증: 이후 전체 설계 검토에서 L2가 필요한 시나리오(두 노드의 에이전트 상태 동기화)가 실제로 존재함을 재확인했다. 잘못된 가정을 일찍 발견한 게 이번 회고의 가장 큰 수확이었다.


T5 probe edit atomicity — 존재만 확인하고 순서는 놓친 D1 테스트

같은 저장소에서 T5 probe의 테스트 스크립트를 리뷰하고 있었다. scripts/m0/t5-edit-atomicity.sh가 새로 작성된 파일이고, docs/lens/m0-findings.md에 투명성 노트가 3건 올라와 있었다. 신뢰도 ≥80 결함은 0건이었지만, 투명성 노트 중 하나가 눈에 띄었다.

“D1 테스트가 Read/Write/Edit 존재만 확인하고 순서를 확인하지 않음”

처음엔 “투명성 노트니까 기록만 하고 넘어가도 되겠지” 싶었다. 하지만 edit atomicity의 핵심은 여러 연산이 끼어들지 않고 원자적으로 수행되는 순서에 있다. 존재만 확인하는 테스트는 거의 의미가 없다. 이게 두 번째 전환점이었다.

scripts/m0/t5-edit-atomicity.sh를 분석했다. 기존 테스트는 특정 파일을 수정한 뒤 결과가 존재하는지만 검사했다. 예를 들어 edit 명령어가 실행된 후 수정된 파일이 있는지 확인하는 식. 하지만 edit 도중에 read가 끼어들거나, write가 edit보다 먼저 실행돼도 존재만 검사하면 통과한다. 원자성을 보려면 연산 간 간섭이 없었는지, 즉 순서가 보존되었는지까지 봐야 한다.

수정 방향은 명확했다.

  • Before: edit 후 파일 존재 검사
  • After: edit 전후로 중간 상태(partial write)가 없는지, 그리고 read → edit → write 순서가 깨지지 않았는지를 검사하는 테스트 케이스 추가

t5-edit-atomicity.sh와 t5-edit-atomicity-test.sh를 새로 작성했다. 구체적으로는:

  1. edit 실행 전에 파일 스냅샷을 떠서 체크섬 저장
  2. edit 실행 후 체크섬이 변경되었는지 확인 (변경되어야 정상)
  3. edit 도중 동시 read를 시도해 에러가 발생하는지 확인 (atomicity 위반 시 partial read 가능)
  4. edit 완료 후 파일의 내용이 예상된 순서(원본 + 편집 내용)와 일치하는지 검사

이 테스트는 실제로 atomicity를 깨는 조건을 재현하도록 설계했다. 예를 들어 edit 명령에 시뮬레이트된 지연을 삽입해, 동시에 다른 연산이 들어오면 교착이나 비일관성이 발생하는 케이스를 포함시켰다.

해결: 위 테스트를 scripts/m0/t5-edit-atomicity.sh에 추가하고, docs/lens/m0-findings.md에 “D1 테스트 커버리지 공백 해소”라고 기록했다. 또한 verify.sh가 새 테스트를 함께 실행하도록 수정했다.

검증: sh scripts/m0/verify.sh가 통과하고, go test ./...도 PASS. 로컬 커밋(99739ac)을 완료했다.

항목 Before After
D1 테스트 검증 범위 Read/Write/Edit 존재 확인 존재 + 연산 순서 보존 + 중간 상태 방지
테스트 파일 t5-edit-atomicity.sh (기존) t5-edit-atomicity.sh + t5-edit-atomicity-test.sh (신규)
투명성 노트 3건 중 1건이 “순서 미확인” 해당 노트 제거, 해소 기록

남은 과제: 다른 probe(T1~T4)에도 유사한 순서 검증 누락이 없는지 확인이 필요하다. 특히 T3(병렬 접근)는 이번 T5와 유사한 패턴이 있을 가능성이 높다.


오늘의 한줄

설계 문서를 읽지 않고 추측으로 판단하면 반드시 틀린다. 문서가 먼저고, 테스트는 존재가 아니라 순서를 봐야 한다.