사용자가 열려 있던 마지막 자리를 제3안으로 닫음. 판정 기준을 둘로 나눈다 —
sourceCountMap(값 유효성)은 순회가 앞당겨 올리고, sourceEmitMap(전파 dedup)은
상류의 진짜 emit을 기다린다. emit 수신 규칙은 셋: count가 다르면 둘 다 갱신 +
rawInvalid + 전파 / count는 같은데 emit 기록이 다르면 전파만(순회가 앞질러
흡수한 경우) / 둘 다 같으면 삼킨다. 순회는 emit을 하지 않는다.
효과 — 통지가 죽는 "영구 침묵"이 사라지고, 순회가 emit을 안 하므로 게이트
누출 경로 자체가 없어져 source = nil 규약도 "게이트를 에포크 경계로" 같은
계약 반전도 불필요해진다. 직전 라운드에서 에이전트가 냈던 (c)안의 약점
(emit 도착 전까지 Get마다 재계산)도 sourceCountMap을 실제로 올리므로 없다.
같이 검토된 rawEmit+nil 안은 구조 위생(상류 emit과 내부 발생 emit의 진입점
통일)만 살리고 해법으로는 안 씀 — 막는 게이트는 보통 순회하는 노드 자신이
아니라 상류에 있어 자기 rawEmit을 태워도 누출이 남고, nil emit은 하류마다
전체 순회를 강제해 같은 문제를 연쇄시킨다.
M절에서 철회했던 seen/computedAt 분리가 다른 근거(순회가 값과 통지를
비대칭으로 앞당김)로 되살아난 것이라는 점도 명시. 이제 기제는 다 정해졌고
남은 건 채택 여부 자체 — README/question.md/ROADMAP 동기화.
doc-check.py ERROR 0.
Co-authored-by: qwreey <me@qwreey.moe>
Claude-Session: https://claude.ai/code/session_01TiW21rnti9SbLgF6twtn6D