Files
document-haness/.agents/skills/writing-tech-log-records/references/record-kinds.md
T

13 KiB

다섯 종류의 칸과 게시 조건

칸 이름은 Studio 편집 화면 그대로, 상한과 필수 여부는 studio-api.openapi.yaml 그대로다. 계약 필드명을 괄호에 적는다. 계약은 tech-log-frontend/src/features/tech-log/contracts/studio/ 에 있고, 이 파일과 계약이 어긋나면 계약이 맞다.

RecordKind 는 다섯이다 — CASE · REFERENCE · QUESTION · CONCEPT · PROJECT_DECISION.

종류별 칸 (새 문서 화면이 적어 주는 그대로)

화면 이름 계약 kind 그 종류만의 칸
Case CASE 문제 · 결론 · 환경 · 재현 · 본문
Reference REFERENCE 목적 · 규칙 · 적용 조건 · 예외 · 예시
개념 CONCEPT 기준 버전 · 본문
Question QUESTION 상태 · 사실 · 가정 · 미지수 · 선택지
Decision PROJECT_DECISION 상태 · 결정일 · 결정문 · 판단 이유 · 영향 · 근거

여기에 아래 공통 칸이 더해진다.

공통 (다섯 종류 모두 — WorkingCopyInputBase)

필드 상한 게시 조건
제목 title 120자 필수 — 없으면 게시 거절
slug slug 3~100자, ^[a-z0-9]+(?:-[a-z0-9]+)*$ 필수 — 비우면 제목에서 만든다
요약 summary 2,000자 경고. 목록 카드에는 약 90자까지 보인다
Topic topicId 경고
variantIds 8개 선택. 고르지 않으면 그 주제의 공통 기록이 된다
Project projectId PROJECT_DECISION은 게시 시 필수
관계 relations 20개 PROJECT_DECISION1개 이상 필수. 그 종류에서는 절 이름이 「근거」다

편집 화면에서 축은 체크박스 묶음으로 나오고 묶음 이름이 「축 — 고르지 않으면 이 주제의 공통 기록이 됩니다」다. 보이는 축은 고른 Topic 이 정한다 — OAuth/OIDC 인증 경계를 고르면 SPA·Mediator·BFF·Forward-Auth 가 나온다.

축(variantIds)은 주제 안의 접근·구조다. 인증 경계 주제의 축은 SPA·Mediator·BFF·Forward-Auth, 조회 성능 주제의 축은 조회 전략이다. 한 기록이 여러 축에 걸릴 수 있다 — PKCE 는 SPA 와 BFF 양쪽에 관계된다. 아무 축도 고르지 않으면 「공통」 축이 따로 있는 것이 아니라 그 주제의 공통 기록으로 읽힌다.

slug를 비우면 제목에서 만든다. 한글 제목도 로마자로 옮겨 유효한 slug가 된다. 직접 쓸 때는 영문 소문자·숫자·하이픈만 쓴다.

Project에 slug가 없으면 공개 화면에 프로젝트가 표시되지 않는다. 공개 계약의 ProjectSummaryslugpath를 요구하기 때문이다. 주제·프로젝트 화면에서 확인한다.

frontmatter 의 topic

폴더 이름과 같은 slug 를 적는다. 화면에 보이는 한글 주제 이름은 topicName 에 따로 둔다. topic 이 표시 이름이면 폴더와 대조할 수 없다.

topic: oauth-oidc-auth-boundary
topicName: OAuth/OIDC 인증 경계

기록이 가리키는 로컬 파일

기록은 docs/<프로젝트>/tech-log-studio/<주제>/<종류>/ 에 있고, 그림과 증거는 같은 프로젝트의 final/ 에 있다. 같은 파일을 양쪽에 두지 않고 frontmatter 로 잇는다.

assets:
  - key: eager-lazy-query-sequence          # 본문의 :::evidence key 와 같은 값
    file: ../../../final/assets/diagrams/eager-lazy-query-sequence/eager-lazy-query-sequence.svg
evidence:
  - ../../../final/evidence/explain/highlights-child-plan-A.txt

assets 는 본문이 있는 Case 와 Concept 에만 둔다. 나머지 세 종류는 칸이 평문으로 렌더링돼 그림을 표시할 자리가 없다. 그림이 필요한 내용은 Case 나 Concept 에 담고 관계로 가리킨다.

assets 는 Studio 에 올릴 파일이다. 아직 안 올렸으면 key 가 파일 이름과 같고, 올린 뒤에는 서버가 준 <이름>-<해시8> 로 바뀐다. Studio 에 넣을 때 이 목록을 보고 Asset 을 올리고, 본문의 :::evidence key 를 서버가 준 키로 바꾼다.

evidence 는 그 기록이 인용한 측정 자료다. 실행계획·csv·터미널 기록·스크린샷이 여기 온다. 본문에 값을 옮겨 적었으면 그 값이 어느 파일에서 나왔는지 이 줄이 말해 준다.

평문 칸 쓰는 법

본문(bodyMarkdown)을 뺀 모든 칸은 평문이다. 백틱·파이프·#는 글자 그대로 보이고 줄바꿈만 살아난다. 그 줄바꿈이 유일한 서식이므로 아끼지 않는다.

무엇을 지우나. 백틱·별표·코드펜스는 글자 그대로 보인다. 식별자는 남기고 표시 문자만 뺀다. InboxCleanupJob:56 은 InboxCleanupJob:56 으로, **this is the parameter** 는 그 문장만 남긴다. 코드펜스 안이 이름 : 값 꼴이면 펜스 줄만 지우면 그대로 읽힌다. 줄바꿈이 유일한 서식이므로 문단 사이 빈 줄은 지킨다.

관계(근거) 절은 평문 칸이 아니다. 기록을 거는 목록이라 - **제목** 표기를 그대로 둔다.

나열은 이름 : 값으로 끊는다. 쉼표로 이으면 읽는 사람이 항목을 세어야 한다.

쓰지 않는다
access token 300초, refresh token rotation과 재사용 허용 0회, 그리고 issuer·audience 검증이다

쓴다
access token : 300초
refresh token rotation, 재사용 허용 : x
issuer · audience : 검증

있음·없음은 o·x로 적는다. 확인함·확인 안 함보다 훑을 때 빨리 잡힌다.

한 문장이 화면에서 두 줄을 넘으면 끊는다. 편집 화면의 칸은 좁고 공개 화면은 넓다. 여기서 한 줄로 보이는 문장이 저기서는 덩어리가 된다. 절차·조건을 한 문단에 이어 쓰지 않는다.

Case — 문제를 재현하고 검증한 결론

필드 비고
문제 problem 무엇이 왜 문제였나
결론 conclusion 검증으로 확정한 것
검증 환경 environment 런타임·버전·DB·도구
재현 조건 reproduction 다른 사람이 같은 결과를 얻는 방법
마지막 검증일 lastVerifiedOn 실제로 확인한 날. 30일 지나면 경고
본문 Markdown bodyMarkdown 10만 자. 본문을 갖는 두 종류 중 하나

공개 화면에서 검증 환경재현 조건environmentSummary 배열에 그 순서로 실린다.

Concept — 남의 것이 어떻게 동작하는지

새 문서 화면에서 이 종류만 이름이 한글이다. 「개념」을 고른다. 나머지 넷은 Case·Reference· Question·Decision 으로 적혀 있다. 화면 설명은 「개념의 내부 동작과 아키텍처를 처음부터 풀어 씁니다」다.

필드 비고
본문 Markdown bodyMarkdown 10만 자. Case 와 함께 본문을 갖는 두 종류 중 하나
기준 버전 basisVersion 120자. 무엇을 보고 쓴 글인지 한 줄

칸이 둘뿐이다. 문제도 결론도 재현 조건도 없다. 내가 재현한 결과가 아니라 이미 그렇게 동작하는 것을 적기 때문이다. Authorization Code Flow 가 code 를 한 번 더 교환하는 이유, Forward-Auth subrequest 가 실어 보내는 것 같은 것이 여기 온다.

lastVerifiedOn 이 없고 basisVersion 이 그 자리를 대신한다. 개념은 날짜로 낡지 않고 버전으로 낡기 때문이다. Keycloak 26.7.0 identity brokering, Kubernetes 1.31 처럼 적는다. 비워도 게시된다.

공개 주소는 /concepts/{slug} 다.

기준 버전을 비워도 게시된다. 계약의 required 에 들어 있지만 빈 문자열을 허용하고, 게시 검증도 막지 않는다(2026-09-04 에 임시 개념 기록을 만들어 비운 채로 게시해 확인했다). 그래도 채우는 편이 낫다 — 개념이 언제 낡았는지 읽는 사람이 알 방법이 이 칸뿐이다.

편집 화면 오른쪽 작업 상태 는 이 종류를 「동작 원리」라고 부른다. 새 문서 의 「개념」과 같은 것이다.

Case 와 헷갈리면 내가 무엇을 했는지를 묻는다. 내가 돌려 보고 수치를 얻었으면 Case, 남의 문서와 코드를 읽고 동작을 정리했으면 Concept 이다.

Concept 이 아닌 것

Concept 은 어떤 Case 를 이해하려면 먼저 알아야 하는 구조다. 그 Case 가 없으면 Concept 도 없다. 분석하면서 알게 된 사실을 종류가 마땅치 않아 여기 넣지 않는다.

이런 제목 실제로는
호출자가 없다 · 프로덕션에서 실행되지 않는다 부재는 Case 의 관측이다
구현 클래스 51개를 전부 읽었다 · 재현에 쓴 레인 분석 범위·방법. SSOT 의 coverage 원장에 남는다
보류한 항목과 보류한 이유 분석 진행 기록. 같은 곳에 남는다
grep refs=0 은 시작점이지 결론이 아니다 분석 방법론. Reference 로 쓸 수 있으면 Reference 다
(8.4) 문서/구현 드리프트 — … · Confirmed — … 분석 문서의 절 제목을 그대로 옮긴 것

한두 문장으로 Case 안에서 설명되는 것도 Concept 이 아니다. 없애고 Case 의 한 절로 넣어도 이해가 그대로면 독립 기록으로 만들지 않는다.

Concept 이 되는 것은 이런 것들이다 — Spring 조립의 세 경로, @ConditionalOnBean 의 평가 시점, 커밋 증거 상태 전이, fenced lease 와 CAS, gRPC flow control 과 backpressure. 여러 Case 가 같은 선수 지식을 요구할 때 그것을 한 번만 설명하려고 만드는 자리다.

Reference — 반복 적용할 기준

필드 비고
목적 purpose 이 기준이 무엇을 막는가
규칙 rules[] 제목(120자) + 본문. 평문
적용 조건 applyWhen[] 언제 적용되는가
예외 exceptions[] 적용되지 않는 경우
예시 examples[] 짧은 문장. 코드가 아니다
마지막 검증일 verifiedOn

규칙 본문에 코드를 쓰고 싶으면 그 코드가 있는 Case를 만들고 관계로 가리킨다.

Question — 아직 닫히지 않은 판단

필드 비고
질문 상태 questionStatus OPEN / RESOLVED / 미정
사실 facts[] 확인된 것
가정 assumptions[] 확인하지 않고 전제한 것
미지수 unknowns[] OPEN이면 1개 이상 필수
제약 constraints[] 선택을 좁히는 조건
선택지 options[] 제목(120자) + 설명. 50개까지
다음 검증 nextValidation 무엇을 하면 판단이 끝나는가

OPEN인데 해결 내용을 채우면 게시가 거절된다. 상태와 내용이 어긋나기 때문이다.

사실과 가정을 섞지 않는다. 확인했으면 사실, 아니면 가정이다. 그 구분이 이 종류의 존재 이유다.

Decision — 프로젝트가 정한 방향 (PROJECT_DECISION)

필드 비고
결정 상태 decisionStatus PROPOSED / ADOPTED / 미정
결정일 decidedOn
결정문 statement 무엇을 정했는가. 한 문장
판단 이유 rationale 왜 그렇게 정했는가
영향 consequences[] 이 결정으로 감수하는 것
근거 기록 relations 1개 이상 필수

근거가 없는 Decision은 게시되지 않는다(DECISION_EVIDENCE_REQUIRED). 무엇을 보고 정했는지 가리키지 못하면 그것은 결정이 아니라 선언이다.

영향에는 좋은 것만 적지 않는다. 감수한 비용이 빠지면 다음 사람이 같은 판단을 다시 못 한다.

종류 고르기

내가 직접 돌려 보고 결과를 얻었나 ── 예 ──→ Case
        │
        아니오
        │
남의 것이 어떻게 동작하는지 적나 ── 예 ──→ Concept
        │
        아니오
        │
판단이 끝났나 ──── 아니오 ──→ Question
        │
        예
        │
프로젝트의 방향인가 ── 예 ──→ Decision
        │
        아니오
        │
        └──→ Reference

Case 와 Concept 이 가장 자주 헷갈린다. 수치와 재현 조건이 있으면 Case, 읽고 정리한 동작이면 Concept 이다. Concept 과 Reference 는 「무엇이 그런가」와 「우리가 어떻게 할 것인가」로 갈린다 — PKCE 가 code 가로채기를 막는 방식은 Concept, 우리는 public client 에 PKCE 를 필수로 쓴다는 Reference 다.

한 자료가 여러 종류에 걸치면 나눈다. 예를 들어 N+1을 재현해 고쳤고 그 과정에서 조회 기준을 굳혔다면, Case 하나와 Reference 하나를 만들고 서로 관계로 잇는다. 한 기록에 몰아넣으면 Case의 칸도 Reference의 칸도 반쯤만 맞는다.