--- id: coding-conventions-comment-philosophy title: "코딩 컨벤션과 주석 철학" category: "Software_Engineering" status: "draft" verification_status: "applied" canonical_id: "" aliases: ["코딩 스타일", "주석 철학", "why comment", "post-mortem comment", "naming", "graceful degradation", "코드 컨벤션"] duplicate_of: "" source_trust_level: "A" confidence_score: 0.93 created_at: 2026-06-13 updated_at: 2026-06-13 review_reason: "" merge_history: [] tags: ["conventions", "style", "comments", "readability", "astraai"] raw_sources: ["AstraAI/src/core/lock.ts", "AstraAI/src/retrieval/index.ts", "AstraAI/src/features/company/dispatcher.ts", "AstraAI/src/extension.ts"] applied_in: ["AstraAI"] github_commit: "" --- # [[코딩 컨벤션과 주석 철학]] ## 🎯 한 줄 통찰 (One-line insight) AstraAI 코드의 가장 큰 특징은 "**주석이 '무엇'이 아니라 '왜'와 '왜 다른 방법이 아니었는지'를 적고, 버그 사후기록(post-mortem)을 코드 옆에 남긴다**"는 점이며, 이것이 작은 LLM 이 *의도까지* 학습하게 하는 핵심 자료다 [S1][S3]. ## 🧠 핵심 개념 (Core concepts) 1. **Why 주석:** 코드가 '무엇을 하는지'는 코드로 읽고, 주석은 '왜 이렇게 했는지'·제약·트레이드오프를 적는다 [S1]. 2. **Post-mortem 주석:** 과거 버그의 원인과 수정 근거를 코드 옆에 남겨 같은 실수를 막는다 [S1]. 3. **모듈 헤더 docstring:** 각 파일 상단에 그 모듈의 책임·배경·다른 모듈과의 분업을 설명 [S1][S4]. 4. **결정 근거 주석:** "왜 순차인가", "왜 handlePrompt 를 안 쓰나" 같은 설계 결정을 인라인으로 [S3]. 5. **방어적 기본값/널 처리 + 의도 명시:** `??` vs `||`, `void` fire-and-forget, 의도적 빈 catch 를 주석으로 [S2][S4]. ## 🧩 추출된 패턴 (Extracted patterns) - **named export 일관:** default export 를 배제하고 named export 만 — 자동완성·리네이밍 안전 [S4]. - **단일 진입점 헬퍼:** 설정은 `getConfig()`, 경로는 path resolver 처럼 한 곳을 통해 — 파싱/coercion 중복 방지 [S4]. - **`??` 로 의미 있는 0/'' 보존:** `brainFileLimit ?? 8` (0 이 유효), `req.timeoutMs ?? config.timeout` [S2]. - **의도된 graceful degradation:** 부가 작업 실패를 `catch { /* should never break main flow */ }` 로 — 빈 catch 에 *반드시* 이유 주석 [S2]. - **단계 로그(추적성):** 복잡 로직은 `fusionLog.push(...)` 처럼 단계별 기록을 남겨 디버깅 [S2]. - **상수 중앙화:** 가중치/임계값/불용어를 설정 객체 한 곳에(`SCORING_CONFIG`) [S2]. - **한국어 주석 + 영어 식별자:** 식별자·타입은 영어, 설명 주석은 한국어 — 팀 가독성 우선 [S1]. ## 📖 세부 내용 (Details) ### 주석이 의도를 가르친다 (이 위키의 핵심 가치) `lock.ts` 의 주석은 옛 구현이 왜 틀렸는지를 적는다: "`.then(...)` 은 매 호출마다 새 Promise instance 를 반환해서 사실상 항상 false — cleanup 이 안 됨." 이런 주석은 *코드만 봐서는 절대 알 수 없는* 함정을 전수한다. 작은 LLM 이 비슷한 코드를 쓸 때 같은 함정을 피하게 만드는 최고의 학습 신호다 [S1]. ### "왜 다른 방법이 아니었나" 를 적는다 `dispatcher.ts` 헤더는 "Why sequential?", "Why not use handlePrompt?" 를 명시한다. 대안을 검토하고 *기각한 이유* 까지 적어, 미래의 개발자(또는 LLM)가 같은 고민을 반복하지 않게 한다 [S3]. ### 방어적이되 명시적 ```typescript const brainFileLimit = options.brainFileLimit ?? 8; // 0 이 의미 있음 → || 아님 void ensureEmbeddingConfigured(context); // 비차단 의도를 void 로 명시 try { extract(); } catch { /* memory extraction should never break the main flow */ } ``` 빈 catch·fire-and-forget 같은 "위험해 보이는" 패턴에는 *왜 안전한지* 를 항상 주석으로 정당화한다 [S2][S4]. ### 네이밍 - 함수는 동사구(`buildContext`, `searchBrainFiles`, `parseModelPrefix`), boolean 은 `is*`/`should*`/`has*`(`isOperationalPath`, `shouldUseMultiAgentWorkflow`). - 내부 전용은 `_` 접두사(`_ensureBrainDir`, `_getBrainDir`). - 타입은 PascalCase 인터페이스(`RetrievalChunk`, `ConfidenceResult`), 상수는 UPPER_SNAKE(`PEER_OUTPUT_BUDGET`). ## ⚖️ 모순 및 업데이트 (Contradictions & updates) - **주석 과다 vs 적정:** "코드가 자명하면 주석 불필요" 라는 원칙과 충돌할 수 있다. AstraAI 의 기준은 *비자명한 why/제약/함정만* 적는 것 — "다음 줄이 무엇을 하는지" 류의 노이즈 주석은 피한다. - **주석의 노후화:** 코드가 바뀌면 주석이 거짓이 될 위험. post-mortem 주석은 역사적 사실이라 비교적 안전하나, "현재 동작" 주석은 변경 시 함께 갱신해야 한다. ## 🛠️ 적용 사례 (Applied in summary) - `AstraAI/src/core/lock.ts` — 버그 post-mortem 주석의 모범 [S1]. - `AstraAI/src/features/company/dispatcher.ts` — 결정 근거(왜 순차/왜 분리) 주석 [S3]. - `AstraAI/src/retrieval/index.ts` — 단계 로그, 상수 중앙화, `??` 보존 [S2]. ## 💻 코드 패턴 (Code patterns) ```typescript // 1) Post-mortem 주석 — 코드로 알 수 없는 함정 전수 (src/core/lock.ts) // 옛 구현은 `this.locks.get(id) === prev.then(() => next)` 로 Promise 동일성을 비교했는데, // `.then(...)` 은 매번 새 Promise 를 반환 → 항상 false → cleanup 실패. 그래서 고유 symbol // 토큰을 부여하고 "내 토큰이 최신일 때만" 정리한다. // 2) 의도적 graceful degradation — 빈 catch 에 이유 명시 (src/memory/index.ts) try { this.extractor.extractFromSession(...); } catch { /* memory extraction should never break the main flow */ } // 3) ?? 로 의미 있는 0 보존 (src/retrieval/index.ts) const brainFileLimit = options.brainFileLimit ?? 8; // 명시적 0 = "검색 끔" // 4) 단계 로그로 추적성 (src/retrieval/index.ts) fusionLog.push(`Brain search: ${brainChunks.length} chunks found`); fusionLog.push(`Selected: ${selectedChunks.length}, Dropped: ${dropped.length}, Tokens: ${tokensUsed}`); ``` ## ✅ 검증 상태 및 신뢰도 - **상태:** draft - **검증 단계:** applied - **출처 신뢰도:** A - **신뢰 점수:** 0.93 - **중복 검사 결과:** 신규 생성 (New discovery) ## 🔗 지식 그래프 (Knowledge Graph) - **상위/루트:** [[AstraAI 아키텍처 개요]] - **관련 개념:** [[에러 처리와 커스텀 에러]], [[모듈 시스템과 프로젝트 구성]], [[프롬프트 엔지니어링 패턴]] - **참조 맥락:** 로컬 LLM 이 코드를 작성할 때 네이밍·주석·방어 코드의 스타일을 AstraAI 와 일치시키도록 참조. ## 📚 출처 (Sources) - [S1] AstraAI/src/core/lock.ts — post-mortem 주석, 모듈 헤더 - [S2] AstraAI/src/retrieval/index.ts — ?? 보존, 단계 로그, 상수 중앙화 - [S3] AstraAI/src/features/company/dispatcher.ts — 결정 근거 주석 - [S4] AstraAI/src/extension.ts — named export, 단일 진입점, void/getter 패턴 ## 📝 변경 이력 (Change history) - 2026-06-13: AstraAI 코드 분석 기반 초안 생성.