quad/.claude/conventions.md
qwreey 0ec22fbe73
qa: 9라운드 후속 H-143~H-146 확정·반영 + 감사 8라운드·code-review — 잔여 셋은 10라운드 문항지로
- H-143 Rerun 꼬리: 실행 중 사망(wasAlive and not canExecute)이면 cleanup 즉시 소진
  (처음 쓴 not canExecute 판정은 생성자 최초 설치를 죽여 감사 2라운드가 정정)
- H-144 재구독 꼬리(Refresh 먼저) + 진입점은 EffectHandle 자기 것 (b)
  (Observer 함수 배정은 콜론 위임으로 꼬리 2회 — 감사 4라운드, luau 재현)
  → conventions.md 설계 원칙 신설: 하나의 무언가가 두 일을 하지 않는가
- H-145 bk.indexOfElement weak-key / H-146 루트 .Parent는 사용자 몫, Mount 없음
- 감사 1→1→1→1→1→1→1→0, /code-review high 10건 중 7 반영
- H-147~H-149는 qa-request/pre-implementation-handtrace-round10.md §4로 (배치 회신)
- round10 지시서(-brief.md) 신설, 광범위 탐사 예정

Co-authored-by: qwreey <me@qwreey.moe>
Claude-Session: https://claude.ai/code/session_01546hjsYNLSMZdHdPyTZaGb
2026-08-28 00:28:52 +09:00

32 KiB

관례와 작업 방식

이 파일은 루트 CLAUDE.md@import 하므로 매 세션 컨텍스트에 로드된다 — 늘리기 전에 "정말 매 세션 필요한가"를 따질 것. 세션마다 필요하진 않은 상세는 .claude/ 아래 개별 문서로.

언어/모델 관례 (기존 메모, 유지)

사용자는 한국 유저임을 유의해. 사용자가 보게 될 것은 한국어로 띄워주는 게 좋아. 너가 보는 것들(코드 주석 등)은 원하는 언어여도 되는 것(가장 성능이 좋을 영어를 쓰든 그래도 됨, 예를 들어 이 문서도 영어여도 무방하지만 지금은 한국어로 유지). 사용자가 검토해야 하는 것(plan, backlog 등)은 한국어로 써. 코드 안 주석은 공식성을 유지하기 위해 굳이 한국어일 필요 없음, 영어 가능.

또 토큰 맥싱에 유의해 — 아주 작은 테스크라 충분히 작은 모델이 쓸 수 있으면 haiku, 일반 작업은 sonnet. 특히 소스코드를 많이 읽어야 하는 리서치는 메인 컨텍스트를 부패시키니 Agent로 위임할 것(아래 "작업 방식" 참고).

설계 원칙

  • 드문 오용이나 가상의 미래 요구까지 방어/최적화하려고 구조를 복잡하게 만들지 않는다. 실제로 관측된 문제(실측된 병목, 실제로 밟은 함정)에만 구조를 쓴다. [2026-08-16 명문화] 이 원칙은 base/modifier-plan.mdApply 체인 fast-path를 미루는 근거 등으로 여러 문서가 이미 인용해왔지만 정작 어디에도 적혀 있지 않았다 — 코퍼스 전체 grep과 git log -S로 확인됨. 사용자가 세션 중 구두로 말한 게 옮겨적히지 않았을 가능성이 크다는 사용자 본인 추정에 따라 여기 정식 관례로 승격(선택지 (a) 채택). 이 누락이 아래 "사용자 발언을 인용할 때" 관례가 생긴 계기이기도 함.
  • [2026-08-27 명문화] 하나의 무언가가 두 일을 하고 있지 않은지 유의한다 — 이질적인 타입끼리 구현 본문을 공유하지 않는다. 사용자 원문: "항상 언급되는 말이지만, '하나의 무언가가 두 일을 동작하지 않는가에 유의하자'" (session/2026-08-27-03-handtrace-round9-h143-h146.md). 첫 사례는 하루 전의 invalidAfter — 사용자 확인(2026-08-27): "그게 정확히 invalid after 문제에서 났던 이야기였어". 한 필드가 "캐시가 여기까지 유효"와 "여기까지 :Set을 마쳤다"라는 다른 목적의 값을 같이 쥐고 있어서 getOffsetAt의 꼬리가 splice의 되감기 신호를 지웠고(사용자 진단 "Set을 해줬느냐와 캐시가 유효하지 않느냐라는 다른 목적의 값을 같은 값이 쥐고 있음"), offsetCacheValidUpTo/offsetSetUpTo 둘로 갈라졌다(base/dispatch-core-plan.md의 "두 필드" 절, session/2026-08-26-01-handtrace-round8-resolution.md가 *"두 뜻이 실제로 같다는 확정은 의심할 것"*으로 남긴 교훈). 이번 계기: Observer의 네 진입점 함수 객체를 EffectHandle 메소드 테이블에 그대로 배정해 두 타입이 한 본문을 쓰게 했더니, 그 본문의 콜론 위임(self:WeakSubscribe())이 EffectHandle의 오버라이드로 가서 재구독 꼬리가 두 번 돌고 강한 킵 전에 Rerun하는 결함이 났다(감사 4라운드, base/effect-plan.mdEffectHandle 블록). 공유해도 되는 건 데이터(레지스트리)와 순수 술어(canBound)이고, 타입별로 다른 후처리가 붙는 본문은 각자 가진다. 위 첫 원칙과 짝 — "구조를 늘리지 않는다"가 "본문을 억지로 합친다"로 읽히면 안 된다.

문서 표기 규약

doc-check.py는 정규식으로 정적·결정론적으로 판정한다 — 표기가 흔들리면 검사가 열거형으로 비대해지거나 아예 무력화된다. "예상 가능한 범위"를 컨벤션으로 미리 좁혀두는 게 정규식을 늘리는 것보다 싸다는 게 사용자 판단(2026-08-16, "형식이 많이 왔다 갔다 하면 문제가 커져", "가장 비용이 쌈"). 근거가 된 실측과 논의 원문은 session/2026-08-16-03-doc-check-section-convention.md.

컨벤션이 규정으로 값을 하는 범위는 "도구가 잡은 걸 표준 마커로 잠재우는" 검사뿐이다. "위험한 문장을 먼저 찾아내야 하는" 검사(시한부 주장 탐지 등)는 표현을 열거하는 수밖에 없다 — 정규식은 날짜를 안 붙인 문장을 찾을 수 없기 때문. 그 잔여가 quad-doc-auditor의 몫이고 앞으로도 그렇다.

  • [2026-08-16 신설] 절 인용 규약 — 절 제목은 의역하지 말고 원문에서 잘라 쓸 것. `<파일>.md`의 "절 제목" 형태로 인용할 때(예시의 <파일>은 자리표시자 — 실제 파일명처럼 적으면 doc-check.py가 깨진 참조로 잡는다):
    • # 헤딩: 제목의 연속된 부분문자열이면 됨(줄여 쓰기 허용, 말 바꾸기 금지).
    • **볼드**: 이 코퍼스가 하위 절로 쓰는 형태. 절로 인정되는 건 빈 줄 다음에 오는 볼드리스트 항목(- /1. /> ) 머리의 볼드뿐이다 — 문단이 줄바꿈되며 우연히 줄머리에 걸린 강조는 절이 아니다. 인용은 제목 앞부분부터 잘라 쓸 것. 볼드는 단순 강조와 구분이 안 되고 # 헤딩보다 압도적으로 흔해서(실측 수치는 session/2026-08-16-03-doc-check-section-convention.md), 중간 조각 인용까지 허용하면 무관한 강조에 우연히 걸려 검사가 조용히 통과하는 쪽으로 무력화된다.
    • 큰따옴표가 든 제목은 앞부분만 인용할 것 — 인용 문법 자체가 "..."라 안쪽 따옴표가 문법을 깬다.
    • ⚠️ 태그로 닫히는 볼드는 절로 인식되지 않는다. - **[해소됨, …]** 실제 제목 — 본문…처럼 볼드가 상태 태그에서 끝나고 진짜 제목이 볼드 평문으로 나오면(archive/question-resolved.md가 이 형태), 검사기는 "[해소됨, …]"만 절 제목으로 본다. 그런 항목을 가리킬 땐 큰따옴표 인용을 쓰지 말고 백틱으로 쓸 것. 새로 쓸 땐 태그와 제목을 한 볼드 스팬 안에 넣을 것**[해소됨, …] 실제 제목**. 절 참조가 ERROR로 승격됐으므로, 이걸 모르고 규약대로 큰따옴표 인용을 하면 실재하는 서술인데도 커밋이 막힌다.
    • 선두 장식(⚠️/), 백틱, 선두 상태·날짜 태그([2026-08-16 신설], [해소됨, …])는 붙이든 빼든 무관(양쪽에서 똑같이 벗겨내고 비교). 태그는 제목의 일부가 아니다 — 시간이 지나면 내용이 바뀌는 메타 표시라 거기에 인용을 묶으면 태그가 갱신될 때마다 참조가 깨진다. 인용은 태그 뒤 실제 제목부터 잘라 쓰는 걸 권장.
    • 줄바꿈에 걸쳐 인용해도 무관(공백을 무시하고 비교). 다만 인용이 160자를 넘으면 검사 자체가 안 걸리니 길게 늘어뜨리지 말 것.
    • blockquote(> ) 안에서는 인용을 줄바꿈에 걸치지 말 것 — 다음 줄의 > 마커가 인용문 안으로 딸려 들어가 매칭이 깨진다. 실제로 이 세션에 ROADMAP.md에서 그 마커를 지우다 blockquote를 통째로 망가뜨릴 뻔했다.
    • 절 제목을 문장에 끼울 땐 "…" 뒤에 을 붙일 것("패키지 경계" 절이 세운 원칙처럼). 제목을 명사구 자리에 그대로 넣으면 원문에서 잘라 쓴 제목이 문장과 안 맞아 문법이 깨진다 — 이 세션에 실제로 여러 건 냈다.
    • 용어를 인용할 땐 이 형태를 쓰지 말 것`<파일>.md`의 "cleanup" 처럼 쓰면 절 인용과 문법이 같아서 구분이 안 된다(실제로 base/lifecycle-pattern.mdeffect-plan.md의 용어 cleanup을 이 형태로 인용해 오탐을 냈었고, 이 규약을 세우면서 같이 고쳤다). 용어는 따옴표 없이 쓰거나 문장을 바꿀 것.
    • 제외 대상: initreq/를 가리키는 인용(읽기 전용 외부 원본이라 절 구조가 없음 — raw-userinput.md는 스스로 "정리가 없는 생각의 흐름"이라 밝힘), 그리고 archive/·session-summary.md가 하는 인용(히스토리 문서).
    • 왜 지금 정하나: 예전엔 "절 제목을 의역해 인용하는 관례"가 있어서 이 검사가 영원히 WARN에 묶여 있었다. 의역을 금지하면 ERROR로 승격돼 절 참조 rot이 커밋 게이트에 걸린다 — bind-system-plan.md 분할 때 20곳이 이 사각지대로 샜던 실패 모드다. [2026-08-16] 불일치를 0으로 만들고 깨끗하게 도는 걸 확인한 뒤 ERROR로 승격 완료 — 이제 의역 인용은 커밋 게이트에서 막힌다.
  • [2026-08-16 신설] 세션은 산문 서수 말고 파일 ID로 지칭할 것. 지금 코퍼스엔 한글 서수("열세 번째 세션") / N차 / N번째가 다 섞여 있고(정확한 분포는 세는 범위에 따라 달라지므로 여기 숫자로 못 박지 않음), 같은 세션을 다른 이름으로 부르는 사례가 한 파일 안에도 있다 (base/tween-plan.md가 같은 2026-08-13 13차를 "13차 세션"과 "열세 번째 세션" 두 표기로). 이건 스타일 취향이 아니라 grep을 감사 도구로 못 쓰게 만드는 문제다 — "13차 세션에 뭘 정했나"를 찾으면 절반을 놓친다. 앞으로는 `session/YYYY-MM-DD-NN-slug.md` 형태의 파일 ID로 쓸 것. doc-check.py가 이 참조를 이미 검증하므로(없는 세션을 인용하면 깨진 파일 참조로 잡힘) 새 코드도 필요 없다. 기존 표기는 일괄 치환하지 말 것 — 그 파일을 만질 때 같이 고친다.
  • [2026-08-16 검토 후 보류] 날짜 마커 라벨([YYYY-MM-DD 신설/정정/기준…])의 어휘는 닫지 않는다. 날짜 리터럴 자체는 강제 장치 없이도 이미 100% 균일해서(실측은 세션 파일) 고칠 게 없고, 라벨 쪽은 사용자 판단대로 기계 검사 대상이 아니라 읽는 쪽 판단 재료다 — "에이전트가 순서 섞였을 때 최신의, 옳은 요소 선택에 도움이 되는 정보에 가깝지 이게 warn을 만들지는 못할듯". 어휘를 닫아도 검사가 하나도 안 생기므로 안 한다. 같이 묶여 있던 DATED 앵커 좁히기(±3줄 아무 날짜 → 같은 줄 마커)만은 유일하게 WARN을 만드는 항목이라 성격이 다르지만, 지금 그 위음성이 아프다는 증거가 없어 함께 보류 — 아프면 그때 한다("실제로 관측된 문제에만 구조를 쓴다" 원칙 그대로).

작업 방식

  • 소스코드를 많이 읽어야 하는 리서치는 Agent(Explore)로 위임 — 메인 컨텍스트 보호. 이미 완료된 v1/rbvm/tbox/Fusion/Vide 리서치 결과는 .claude/base/에 정리되어 있으니 중복 조사하지 말고 먼저 그걸 볼 것.
  • 병렬화 가능한 작업은 Agent 여러 개를 한 메시지에 동시 호출. 서로 독립적인 파일/주제를 다루는 리서치나 구현 조사, 또는 서로 다른 문서 파일을 고치는 문서 정리 작업이 여기 해당(단, 같은 파일을 동시에 고치는 에이전트를 병렬로 띄우지 말 것 — 충돌함).
  • 크리티컬한 설계 결정은 구현으로 밀어붙이지 말고 plan을 research/에 남긴 채 연기. 사용자는 Lua/Roblox 엔진을 깊이 아는 사람 — 근거와 선택지를 문서에 정리해두면 사용자가 깨어있을 때 훑어보고 답해줄 것. .claude/question.md에 반드시 반영.
  • 작업이 끝나면(또는 방향이 바뀌면) 항상 자기 문서화 — 완료된 걸 다시 조사하게 되는 재작업을 막기 위함. .claude/base/로 승격, .claude/qa-request/로 이동, 또는 문서 자체를 갱신. code-docker/webmanager의 .claude/ 관리 방식이 좋은 예시(.claude/initreq/code-docker/webmanager/.claude/README.md 참고).
  • [2026-08-19 신설] 설계 결정이 오간 세션은 끝나기 전에 session/YYYY-MM-DD-NN-slug.md 원문을 반드시 남길 것. 2026-08-19 세션이 점검해보니 2026-08-18(커밋 10개, QA 1~2라운드 포함)엔 session/ 파일이 1개뿐이었고 2026-08-19는 이 점검 전까지 0개였다 — 실제로 여러 세션이 이 규율을 빠뜨렸다는 뜻(경위는 session/2026-08-19-01-new-initxxx-composition-relate-guard.md). 사용자 판단(2026-08-19): 이미 지나간 공백은 재구성하지 말고 인정하고 넘어간다 (그 시점 대화 원문에 접근할 수 없는 채로 "원문"을 지어내면 그 자체가 허위 기록이 됨) — 대신 앞으로 같은 공백이 반복되지 않도록 이 항목을 명문화한다. base//research/에 실제로 반영되는 설계 결정이 있었던 세션은, 커밋 직전이 아니라 작업이 일단락되는 시점마다 session/ 파일을 쓸 것 — 핸드오버 체크리스트(바로 아래)가 요구하는 감사·커밋 절차와 별개로, 이건 그 이전에 지켜야 할 절차다.
  • 중대 변경 핸드오버 체크리스트 — 확정된 결정을 뒤집거나 문서를 쪼갤 때 반드시 이 순서를 밟을 것. 2026-08-13 일곱/여덟 번째 세션에 6+6라운드 수동 감사로 55건을 찾았는데, 거의 전부가 "변경한 세션이 그 자리에서 안 한 일"이 나중에 stale로 쌓인 것이었음. 감사로 뒤늦게 줍지 말고 바꾸는 그 순간에 닫을 것:
    1. python3 .claude/tools/doc-check.py를 돌릴 것(아래 항목 참고) — ERROR 0을 유지한 채로 커밋. 이게 규율 대부분을 기계가 대신함.
    2. 바꾼 주장을 부정당하는 본문 문장을 grep으로 전수 찾을 것(또는 .claude/agents/quad-doc-auditor.md로 위임 — 아래 항목 참고, 신선한 맥락에서 도는 서브에이전트가 이 항목을 실제로 더 잘 잡아왔음). 헤더에 정정 배너만 달고 본문 bullet을 안 고치는 게 가장 잦은 실패 — 실제로 CLAUDE.md가 "스파이크를 아직 안 돌려봄"이라고 서술한 채 한 라운드를 통과했음. 배너를 달았으면 그 배너가 부정하는 문장을 같은 커밋에서 고쳤는지 확인.
    3. 뒤집힌 원문은 archive/로 옮기고 포인터만 남길 것 — 본문에 "히스토리로만 보존"이라며 두면 구현자가 앞에서부터 읽다가 그 "확정"을 그대로 믿음(slot-plan.md에서 실제로 발생).
    4. 개수·목록·상태는 소스를 하나만 둘 것. "20개 중 19개", "4개 문서", "남은 건 X뿐" 류는 두 곳 이상에 적는 순간 반드시 갈라짐 — 한 곳(예: luau-test/STATUS.md, 폴더 구조)을 소스로 하고 나머지는 가리키기만.
    5. 시한부 주장엔 날짜를 붙일 것. "아직 안 돌려봄"이 아니라 "[2026-08-09 기준] 아직 안 돌려봄" — 날짜가 있으면 다음 세션이 의심할 수 있지만, 없으면 영원히 현재형으로 읽힘.
    6. 인덱스 레이어 3개를 같이 갱신: .claude/README.md(색인), question.md(사용자가 답할 것만), 루트 ROADMAP.md/HUMAN_TODO.md.
  • [2026-08-16 실측] @import로 로드되는 파일(이 문서/project-context.md/ todos.md)을 그 세션에 고쳐도 그 세션의 컨텍스트엔 반영되지 않는다. 세션 시작 시점 버전이 그대로 남는다 — session/2026-08-16-02-audit-tooling-verification-and-first-real-run.md 세션의 4라운드 감사가 받은 임포트 블록이 세션 시작 커밋과 정확히 일치했고(그 사이 7커밋), 메인 세션 자신의 컨텍스트도 마찬가지였다. 그래서 이 문서를 고친 세션은 자기가 방금 쓴 규칙을 컨텍스트에서 못 본다 — 고친 뒤에는 기억에 의존하지 말고 파일을 직접 Read해서 따를 것. 다음 세션부터는 정상적으로 새 버전이 로드된다.
  • 기계 점검 — python3 .claude/tools/doc-check.py. 깨진 파일/절 참조, README 색인 누락, 날짜 없는 시한부 주장, 미반영 배너를 한 번에 훑음. 커밋 전에 돌리는 게 기본 — 수동 감사에서 나온 발견의 대부분이 이걸로 잡히는 종류였고, 실제로 여덟 번째 세션에 문서를 쪼개면서 잘못 옮긴 참조를 이 스크립트가 잡아냈음. ERROR는 고치고, WARN은 판단이 필요한 것이라 늘 0일 필요는 없음. [2026-08-16 정정] 예전엔 여기 "절 제목을 의역해 인용한 관례"를 WARN이 0일 수 없는 대표 사유로 적어뒀는데, 위 "절 인용 규약"으로 의역 인용은 관례가 아니라 고칠 대상이 됐다 — 절 참조는 이제 WARN이 아니라 ERROR다(승격 완료).
  • [2026-08-16 도입] .claude/agents/quad-doc-auditor.md 서브에이전트 — 위 체크리스트 2~4번(본문 문장 grep, archive 이전, 개수/목록 단일화)을 신선한 맥락에서 대신 수행. 읽기 전용, 발견만 리포트(직접 수정 안 함). .claude/base/.claude/research/이 문서/.claude/todos.md 등 라이브 문서에 중대한 변경이 있은 뒤, 특히 커밋 전에 돌리는 게 기본 — 지난 세션들에서 "변경한 세션 자신의 self-audit은 자기가 뭘 안 건드렸는지 몰라서 놓친다"는 패턴이 반복 확인됐고(세션 히스토리 7·8·10·11차 등), 이걸 매번 즉흥적으로 프롬프트 짜는 대신 고정 정의로 옮긴 것. 아주 큰 변경(설계 반전 규모)엔 이걸로 대체하지 말고 /code-review(diff 기반)와 사용자의 직접 diff 검토를 병행할 것 — 이 서브에이전트는 diff가 아니라 코퍼스 전체의 정합성만 봄.
  • [2026-08-16 신설, 2026-08-18 재설계] "핸드오버 준비하고 커밋해" 류 요청엔 되묻지 말고 아래 감사 루프를 돌릴 것. 단일 quad-doc-auditor 패스는 비결정적이라 매번 다 잡는다는 보장이 없다 — 그래서 여러 번 돌린다. 다만 여러 개를 동시에 띄우지는 않는다(아래 1번). 처음엔 이걸 Workflow(quad-handover-audit.js)로 만들어 픽스까지 서브에이전트에 맡겼으나, 첫 실동에서 에이전트 67개·4.6M 토큰을 쓰고도 수렴하지 못해 2026-08-16에 폐기(원문은 archive/가 아니라 git 히스토리와 session/2026-08-16-02-*.md에 있음). 폐기 이유는 셋 — (1) 토큰이 과하게 갈림, (2) 파일별로 픽스 에이전트를 쪼개니 그 에이전트들이 또 부정확한 서술을 새로 만들어냄, (3) 서브에이전트는 사용자에게 물을 수가 없어서 판단이 필요한 항목이 그냥 임의 처리됨. 지금 절차:
    1. quad-doc-auditor는 한 턴에 하나만 호출한다 — 병렬 금지 (Agent 도구 직접 호출, Workflow 안 씀). 사용자 지침(2026-08-18): "시간이 걸려도 상관 없으니, 차라리 병렬 에이전트를 덜 써줘. 그냥 한 턴에 하나씩만 사용하고, 0 이 나올때 까지 턴 수를 늘리는게 나아보임. 토큰을 너무 많이 소비해서 다른 작업을 못 하고, 세션 한도에 닿더라고." 이건 2026-08-16의 "최소 2개 병렬, 변경이 많으면 3~4개로 늘림" 지침을 대체한다 — 커버리지를 병렬 폭이 아니라 턴 수로 얻는다. 근거가 된 실측(2026-08-18): 전 코퍼스 감사 한 패스가 서브에이전트 토큰 21만 / 툴 호출 82회였고, 계획대로 4개를 병렬로 돌렸으면 한 번에 80만 토큰대였다 — 세션 한도를 그 자리에서 태워 정작 본 작업을 못 하게 된다. 감사자 모델은 sonnet 유지 — haiku로 더 낮추지 말 것(사용자 판단, 2026-08-16). 실제로 이 감사가 잡아온 것들(재역전된 배너, 자기 메모리의 stale 서술)은 문맥 추론이 꽤 들어간 발견이었다.
    2. [2026-08-18 신설] 프롬프트로 감사 범위를 좁힐 것 — 기본은 diff 범위다. 감사자 정의 자체는 "코퍼스 전체를 신선한 맥락에서 다시 읽는다"인데(라이브 문서 90개 이상, base/만 1만 줄 이상), 대부분의 핸드오버에서 실제로 위험한 건 이번에 바뀐 파일과 그걸 인용하는 곳이다. 그래서 프롬프트에 (a) 바뀐 파일 목록, (b) 이번에 뒤집힌 결정 목록, (c) "그 파일들을 인용하는 곳까지만 확장해서 보라"를 명시할 것. 전 코퍼스 스윕은 오래 안 돌렸을 때 한 번씩만. 라운드마다 각도를 바꾸면(예: 1라운드는 base/ 정합성, 2라운드는 인덱스 레이어(README/ROADMAP/question/todos), 3라운드는 archive/luau-test/audit) 병렬로 폭을 넓히던 효과를 턴으로 얻을 수 있다.
    3. 리포트는 메인 세션이 검토하고, 수정도 메인이 한다. 픽스를 서브에이전트에 위임하지 말 것(위 (2)번 이유). 감사자는 읽기 전용이고 발견만 리포트한다.
    4. 애매하면 임의로 정하지 말고 그 자리에서 사용자에게 보고할 것. 메인 세션은 사용자에게 물을 수 있다는 게 서브에이전트 대비 유일한 강점이니 그걸 쓸 것(어떤 발견이 여기 해당하는지 판정 기준은 .claude/agents/quad-doc-auditor.md의 "출력 형식" 절이 소스 — 여기서 다시 나열하지 않음).
    5. 새 발견이 0건인 라운드가 나올 때까지 1~3을 반복(사용자 지침 2026-08-18의 "0 이 나올때 까지 턴 수를 늘리는게"). 옛 규칙이던 "무발견 2연속"은 병렬 다패스를 전제한 것이라 같이 완화됐다 — 대신 라운드마다 각도를 바꾸는 것(위 2번)이 그 역할을 대신한다. 수렴 안 하면 조용히 멈추지 말고 사용자에게 보고할 것 — 첫 실동이 실제로 6라운드를 소진하고도 수렴 못 했고(새 발견 28→15→16→7→11→6, 단조 감소가 아니었음), 그때 조용히 끊으면 "감사 통과"로 오독된다. 비용 때문에 중간에 멈출 때도 마찬가지로 "몇 라운드에서 왜 멈췄는지"를 반드시 보고할 것.
    6. python3 .claude/tools/doc-check.py로 ERROR 0을 최종 확인한 뒤 평소 커밋 절차(git status/diff 검토, 메시지 작성)로 넘어갈 것. git commit은 항상 메인 세션이 직접 함 — 커밋 전 diff 재검토는 대화형 맥락이 필요해서 위임하지 않는다.
  • [2026-08-18 실측] /code-review는 감사자를 대체하지 않는다 — 큰 변경에는 둘 다 필요하다. 2026-08-18 핸드오버에서 감사자 1패스가 1건을 잡은 뒤 사용자가 /code-review high를 직접 돌리자 10건이 더 나왔고 전부 유효했다. 둘이 보는 축이 다르기 때문 — 감사자는 코퍼스 전체의 의미론적 정합성(A 문서의 결정과 B 문서의 서술이 어긋나는가), code-review는 diff 자체의 결함(이번에 새로 쓴 서술 안의 모순, 새 API가 기존 계약과 충돌하는가). 실제로 그 10건엔 "새로 확정한 store:GetDynamic이 Store의 lazy __index와 충돌해 그대로 구현하면 런타임 에러"처럼 감사자 각도에선 안 보이는 것이 있었다.
    • **⚠️ [2026-08-26 사실 정정] "/code-review는 사용자만 호출할 수 있다"는 틀렸다 — 지금은 세션의 skill 목록에 있어 직접 호출된다(이 세션이 3차를 직접 돌려 확인). 이 문장을 그대로 믿고 두 번을 사용자에게 요청한 뒤에야 발견했다. 돌릴지 말지는 여전히 비용 판단이라(1회 20만 토큰 안팎) 자동 실행을 관례로 못 박지는 않는다 — 큰 변경 뒤엔 돌리는 걸 기본으로 하되, 세션 한도가 빠듯하면 사용자에게 상의할 것.
    • [2026-08-26 실측] 감사 루프가 수렴해도 code-review는 따로 필요하다. 8라운드 반영에서 quad-doc-auditor 11라운드가 44건을 잡고 0건으로 수렴한 직후, /code-review high 3회가 21건을 더 냈고 전부 유효했다(HIGH 1건 포함 — 그대로 두면 런타임 크래시). 그중 절반 이상이 직전 수정의 산물이었다. 두 도구가 못 보는 영역이 갈린다: 감사자는 문서 사이의 정합성(A의 결정 vs B의 서술), code-review는 방금 쓴 문단 의 논리(표에 행만 넣고 헤딩 개수는 그대로, 이름만 바꾸고 그 이름이 서술하던 동작은 그대로, 새 규칙의 근거를 잘못 적어 그 근거가 다른 불변식을 함의하게 만듦). 수정분 자체가 새 결함을 만든다는 게 반복 관측됐으니, 반영이 끝난 뒤 한 번 더 돌리는 걸 기본으로 할 것.
    • [2026-08-27 신설] /code-review(그리고 메인 세션 자신)가 내놓는 새 필드·인자·이름·메커니즘은 발견이지 결정이 아니다 — 사용자 결정 없이 base/에 넣지 말 것. code-review는 완전한 외부자라 이 코퍼스의 결정 이력(누가 그 책임을 갖는지, 어떤 모양이 이미 기각됐는지)을 모르고, 증상을 닫는 가장 가까운 코드를 제안한다. 실제 사고: 2026-08-25 /code-review"len은 자리마다 유일하지 않다"를 잡고 원래 키(요소)로 되돌아가는 대신 token = {}이라는 신원을 발명해 bk.tokens/indexOfToken 두 구조를 넣었고, 그게 사용자 인용문("dispatch 로 격상") 옆에 앉아 승인된 메커니즘처럼 하루를 살았다(9라운드 H-141, 사용자: "내가 등장시킨 적 없는 token 이 나와서 당황스러움"). 같은 날 메인 세션도 같은 실수를 세 번 했다(subject 인자 / Observer에 위치 필드 — 이미 기각된 Effect userdata의 재개방 / 조회 클로저). 규칙:
      1. 리뷰 발견을 반영하기 전에 (a) 그 책임의 현재 소유자와 (b) 그 모양이 과거에 기각된 적 있는지를 먼저 grep한다base/의 "검토 후 안 만들기로 한 것"류 목록과 archive/가 그 자리다.
      2. 발견이 새 필드·인자·이름·메커니즘을 요구하면 그건 사용자 문항이다question.md나 그 라운드의 followup에 갈래로 올리고 결정을 받는다. 증상만 확실하고 처방이 새 개념이면 "증상 확정, 처방 미정"으로 남긴다.
      3. 기존 사용자 인용문 옆에 새 메커니즘을 붙이지 않는다 — 인용문이 승인한 것과 다른 것을 그 옆에 적으면 다음 세션이 승인된 것으로 읽는다. 붙일 땐 *"이 인용은 X를 승인한 것이고 Y는 리뷰 제안"*이라고 갈라 적을 것.
  • 문서가 쌓이면서 모순/중복/stale 마커가 생기기 쉬움 — 주기적으로 감사할 것. 다만 위 체크리스트+doc-check.py+quad-doc-auditor가 자리잡으면 이 감사는 "기계도 서브에이전트도 못 보는 것"(설계 자체의 자기모순, 의사코드 손 트레이싱)에만 집중하면 됨. 2026-08-04 세션에 실제로 전체 .claude/ 코퍼스에서 이런 문제가 다수 발견되어 정리함(.claude/session-summary.md 참고) — 여러 라운드에 걸쳐 같은 문서를 계속 고치다 보면 "정정됨" 표시가 원래 문장에 안 반영되고 방치되는 패턴이 반복되니, 큰 방향 전환이 있을 때마다 관련 문서 전체를 훑어 확인할 것.
  • Roblox Studio MCP 연결 시 주의: Studio는 잘 죽는 편 — 죽었을 때 살리려고 위험한 명령을 반복 시도하지 말 것. 그런 상황이면 MCP 없이 할 수 있는 작업만 하거나 대기. 연결 방법은 HUMAN_TODO.md 1번 항목 참고(사용자가 Studio에서 베타 기능을 켜줘야 함).
  • [2026-08-16 신설] 사용자 발언을 근거로 인용할 때는 결론만 적지 말고 "사용자가 무슨 논거로 그렇게 말했는지"까지 남길 것. 문서에 사용자 확정이라고만 적어두면 다음 세션이 그 결정을 재검토할 수도, 인접한 새 문제에 적용할 수도 없다 — 근거가 없으면 그건 권위지 논거가 아니다.
    • 어디에 적나: 논거 원문·대화 흐름은 .claude/session/의 그 세션 파일에, 라이브 문서(base//research/)는 결론 + 짧은 논거 + 그 세션 파일 포인터를 적는다. 좋은 본보기는 base/component-composition-plan.md §1의 **사용자 확정**("마법 안쓴다 그것도 동의함") 패턴 — 사용자 어투 그대로 짧게 인용하면 나중에 진위와 맥락을 다 되짚을 수 있다.
    • 원칙·규칙을 새로 세우는 발언이면 그 자리에서 이 문서(conventions.md) 나 해당 base/ 문서에 명문화할 것. 안 그러면 나중 문서들이 출처 없는 원칙을 인용하게 된다 — 위 "설계 원칙" 절의 첫 항목이 그 사례다 (경위는 그 항목에만 적어둠, 여기서 반복하지 않음).
  • SAFETY.md 반드시 지킬 것 — (1) GitHub 등 외부 git 호스팅에 이 레포를 push하지 말 것, 모델의 git 작업 공간은 사용자가 별도로 마련해줄 제한 계정 (예: git.qwreey.moe) 전용으로 국한됨 — 그 계정/원격이 설정되기 전까지는 로컬 git 커밋까지만 하고 원격 추가/푸시는 하지 말 것. (2) Roblox Studio는 메인 계정이 아닌 별도 계정으로만 사용 — 로그인 계정 전환을 사용자가 안 해줬다면 Studio 관련 작업(MCP 연결 등)을 진행하지 말고 대기.
  • [2026-08-18 신설, 같은 날 정정] 이 레포의 모든 커밋에 사용자 GitHub 계정(github.com/qwreey)을 co-author로 추가할 것 — 커밋 메시지 끝에 Co-authored-by: qwreey <me@qwreey.moe>만 넣는다. 하네스 기본 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> 트레일러는 이 레포에 한해 넣지 말 것. 사용자 확정(2026-08-18) — 커밋 계정 자체가 qwreey-bot이라 이미 에이전트 커밋임이 드러나므로 Claude 트레일러까지 이중으로 밝힐 필요는 없고, 대신 해당 GitHub 계정 프로필에 Claude를 사용한다고 명시해둘 예정("어차피 qwreey-bot 자체가 에이전트가 커밋했다고 알려주는지라 큰 필요는 없어"). .claude/settings.json"includeCoAuthoredBy": false도 선언해뒀지만 [2026-08-18 확인] 하네스 버그로 무시됨(includeCoAuthoredBy/attribution.commit 둘 다 알려진 미해결 버그 — GitHub Issue #7543/#65657) — 그래서 실제 억제는 이 문장을 세션이 읽고 지키는 방식으로만 보장된다. qwreey 트레일러는 계속 추가한다 — 위 문단이 이미 그 근거(GitHub 기여 그래프 반영)를 서술함, 여기서 반복 안 함. github 리모트로 싱크되어 upstream(github.com/qwreey/quad, 사용자 본인 소유)에 PR이 merge될 때 GitHub 기여 그래프에 반영되게 하기 위함 — 관련 리모트 정책은 메모리 git-remote-push-policy 및 위 SAFETY.md 항목 참고.