[{
      "title": "훅은 확정이고 프롬프트는 확률이라는데, 훅도 깨집니다",
      "description": "AI에게 지키라고 적어둔 규칙 하나를 프롬프트 대신 훅으로 강제하기로 한 결정, 그 훅이 같은 날 상대경로 때문에 깨진 일, 그리고 비교하지 않은 것",
      "url": "/portfolio/blog/2026/09/05/hooks-are-deterministic-until-they-break/",
      "category": "설계 결정"
    },{
      "title": "AI가 쓴 문장마다 근거가 살아 있는지 기계로 세기",
      "description": "위키의 사실 주장 30개가 소스 파일과 줄 번호로 지금도 추적되는지를 LLM 없이 채점하는 지표와, 비밀 값 필터 두 개를 같은 하네스에서 비교한 기록",
      "url": "/portfolio/blog/2026/09/02/grounding-metric-claims/",
      "category": "설계 결정"
    },{
      "title": "통계 캐시: \"스케줄러 필수\"라고 써놓고 cache-aside로 뒤집은 이유",
      "description": "이슈에 필수라고 적힌 스케줄러 대신 요청 시점 캐시를 고른 이유 넷과, 그 뒤에 남은 것",
      "url": "/portfolio/blog/2026/08/18/statistics-cache-aside/",
      "category": "설계 결정"
    },{
      "title": "우리 마스킹은 총합에만 조건이 걸려있는데",
      "description": "항목별로 가리면 뺄셈으로 복원된다. 지원자 3명 미만이면 분포를 통째로 감추기로 한 이유와 그 구현이 틀렸던 자리",
      "url": "/portfolio/blog/2026/08/10/statistics-reidentification/",
      "category": "설계 결정"
    },{
      "title": "RAG 서베이 논문 정독: 언제 도입할 가치가 있는가",
      "description": "RAG 서베이 논문을 읽고 언제 도입할 가치가 있는지 정리한 노트",
      "url": "/portfolio/blog/2026/07/08/rag-survey-notes/",
      "category": "공부 노트"
    },{
      "title": "라우트와 OpenAPI가 어긋나면 CI가 막게 한 이유, 그리고 경로만 보는 가드의 한계",
      "description": "API 문서를 유일한 기준이라 정해 놓고 사람이 눈으로 지키던 걸, 경로와 메서드만 대조하는 테스트로 CI에 넘긴 결정과 두 달 뒤 확인한 구멍",
      "url": "/portfolio/blog/2026/06/28/openapi-contract-guard-tests/",
      "category": "설계 결정"
    },{
      "title": "친구가 0명인 첫날, 누구를 추천할 것인가",
      "description": "친구가 0명인 첫날엔 공통 친구로 목록을 못 채운다. 초안을 버리고 프로필의 목표 유사도를 주력으로 둔 이유",
      "url": "/portfolio/blog/2026/06/26/friend-recommendation-cold-start/",
      "category": "설계 결정"
    },{
      "title": "DSC가 노이즈를 '품질 양호'로 읽었다: 데이터 품질 점수의 사각지대와 signal_integrity",
      "description": "데이터 품질 점수가 노이즈를 오히려 좋게 읽었다. 빼는 열화만 보던 지표 열 개에 노이즈 지표 하나를 더해 상관을 −0.16에서 +0.95로",
      "url": "/portfolio/blog/2026/06/03/dsc-blind-spot-signal-integrity/",
      "category": "문제 해결"
    },{
      "title": "GCP VM 위의 세 루프: proposer, reviewer, PR handler, 그리고 토큰 예산",
      "description": "코딩 에이전트가 제안하고 통계 게이트가 판정하는 자율 루프가 어떤 순서로 셋이 됐고, 첫 닷새 동안 왜 세 번 멈췄나",
      "url": "/portfolio/blog/2026/05/23/three-loops-on-a-gcp-vm/",
      "category": "설계 결정"
    },{
      "title": "팀빌딩을 LP로 푼 이유: 그리디 커버리지와 Nash 혼합전략, +111 ELO",
      "description": "상대를 모르는 상태에서 팀을 고르는 문제를 선형계획법으로 푼 이유와 실제 결과",
      "url": "/portfolio/blog/2026/05/15/teambuild-lp-minimax/",
      "category": "설계 결정"
    },{
      "title": "Tabular MC가 네 번 기각된 진짜 이유: 학습이 아니라 추론 코드 한 줄이었다",
      "description": "이틀 동안 네 번 학습시킨 몬테카를로 정책이 전부 게이트에 걸렸는데, 원인은 학습이 아니라 표에 없는 상황에서 random을 두던 한 줄이었다",
      "url": "/portfolio/blog/2026/05/14/tabular-mc-rejected-four-times/",
      "category": "문제 해결"
    },{
      "title": "n=200에서 이긴 정책이 n=500에서 떨어졌다: Wilson 신뢰구간 게이트가 걸러낸 16건",
      "description": "200판의 우위는 표본 오차였고 4%를 확인하는 데 2000판이 들었다. 통계 기준이 거른 16건의 수치 그대로",
      "url": "/portfolio/blog/2026/05/12/wilson-gate-16-verdicts/",
      "category": "문제 해결"
    },{
      "title": "가장 무거운 지표를 뺀 이유: value_accuracy 제거와 DSC 엔진 v4 (ADR-009)",
      "description": "상관을 올려 준 지표가 정작 원본 없이는 계산이 안 된다는 모순을 인정하고, 검증 조건을 먼저 적은 뒤 지표를 교체한 결정",
      "url": "/portfolio/blog/2026/04/27/dropping-a-weighted-metric-adr-009/",
      "category": "설계 결정"
    },{
      "title": "노이즈가 심할수록 점수가 올랐다: 자기 IQR로 이상치를 재던 지표",
      "description": "전체 상관이 0.08로 나온 원인을 오염 종류별로 쪼개 찾고, 이상치 지표의 기준을 원본 분포에 고정해 0.42까지 올린 기록",
      "url": "/portfolio/blog/2026/04/25/outlier-metric-self-reference/",
      "category": "문제 해결"
    },{
      "title": "RandomForest F1 0.99는 학습이 아니라 누수였다: split-first로 바꾼 기록",
      "description": "오염된 파일을 나누던 파이프라인이 test에 train 복제본을 흘리고 있어서, 먼저 나누고 train만 오염시키는 구조로 바꾼 기록",
      "url": "/portfolio/blog/2026/04/13/rf-f1-099-was-leakage/",
      "category": "문제 해결"
    },{
      "title": "오염을 넣어도 점수가 안 떨어졌다: DSC 엔진 첫 버전이 결측을 못 센 이유",
      "description": "데이터를 75%까지 오염시켜도 품질 점수가 2점도 안 움직이던 첫 엔진의 원인 세 가지와 같은 날 고친 기록",
      "url": "/portfolio/blog/2026/04/12/dsc-v1-could-not-see-pollution/",
      "category": "문제 해결"
    },{
      "title": "프로바이더 셋, 서킷 브레이커 셋: 401은 왜 장애로 세지 않나",
      "description": "LLM 세 곳을 연동하며 한 사용자의 잘못된 키가 전체를 막지 않게 한 규칙",
      "url": "/portfolio/blog/2026/03/31/three-providers-three-circuit-breakers/",
      "category": "설계 결정"
    },{
      "title": "@Async 리스너에서 터진 LazyInitializationException: 이메일이 조용히 안 나가던 이유",
      "description": "제출은 됐는데 이메일이 조용히 안 나가던 장애. 원인은 이틀 전 내가 되돌린 트랜잭션, 해법은 엔티티 대신 값 넘기기",
      "url": "/portfolio/blog/2025/10/16/async-listener-lazy-init/",
      "category": "문제 해결"
    },{
      "title": "페이지네이션 피드백을 받고도 못 고친 것",
      "description": "size=1000000을 막으라는 지적을 받고 미션 안에서는 적용하지 못했고, 석 달 뒤 팀 프로젝트에서야 상한을 둔 기록",
      "url": "/portfolio/blog/2025/07/23/pagination-feedback-not-applied/",
      "category": "공부 노트"
    },{
      "title": "예외를 던지는 책임은 어디에: Repository로 옮겼다가 Service로 되돌린 커밋 쌍",
      "description": "없는 데이터의 예외를 리포지토리로 옮겼다가 사흘 만에 서비스로 되돌린 이유. 리포지토리는 Optional만, 판단은 서비스가",
      "url": "/portfolio/blog/2025/07/21/where-exceptions-belong/",
      "category": "공부 노트"
    },{
      "title": "멘토의 질문 하나가 ID 발번 코드를 세 번 바꿨습니다: long++, AtomicLong, KeyHolder",
      "description": "long++에서 AtomicLong으로, 다시 KeyHolder로. 세 번 다 요구사항은 통과했고 차이는 요청이 겹칠 때만 드러났다",
      "url": "/portfolio/blog/2025/07/01/id-generation-three-times/",
      "category": "공부 노트"
    },{
      "title": "생활체조 원칙이 요구하는 줄 알았던 ProductName 클래스",
      "description": "첫 코드리뷰에서 '왜 이렇게 짰나요'를 받고 답하지 못해 지운 클래스, 그리고 지우는 김에 잘못 같이 지운 예외 처리",
      "url": "/portfolio/blog/2025/06/26/productname-object-calisthenics/",
      "category": "공부 노트"
    },{
      "title": "agent-research (분야 전문성이 있는 AI 에이전트 연구)",
      "description": "분야 전문성이 있는 AI 에이전트를 어떻게 만드나, 그 과정에서 AI의 산출물을 어떻게 검증하나",
      "url": "/portfolio/projects/agent-research/",
      "category": "프로젝트"
    },{
      "title": "capstone-dsc (데이터 품질 점수가 모델 성능을 예측하는가)",
      "description": "데이터 품질 점수가 모델 성능을 예측하는지 오염 실험으로 검증",
      "url": "/portfolio/projects/capstone-dsc/",
      "category": "프로젝트"
    },{
      "title": "diet-setlog (음식 사진으로 칼로리를 기록하는 식단 앱)",
      "description": "문서를 먼저 잠그고 코딩 에이전트로 11일 만에 만든 식단 기록 앱",
      "url": "/portfolio/projects/diet-setlog/",
      "category": "프로젝트"
    },{
      "title": "study-helper (PDF로 학습 노트와 퀴즈를 만드는 서비스)",
      "description": "혼자 만든 풀스택 3레포, LLM 3사 연동 API",
      "url": "/portfolio/projects/study-helper/",
      "category": "프로젝트"
    },{
      "title": "동아리움 (대학 동아리 지원 서비스)",
      "description": "대학 동아리 지원서 도메인, 이벤트로 쪼갠 이유",
      "url": "/portfolio/projects/team18-be/",
      "category": "프로젝트"
    },{
      "title": "vgc-ai (포켓몬 배틀 게임 AI)",
      "description": "코딩 에이전트의 제안, 신뢰구간으로 걸러내기",
      "url": "/portfolio/projects/vgc-ai/",
      "category": "프로젝트"
    }]
