Files
document-haness/docs/TechLog/tech-log-studio/values-lost-between-boundaries/case/case-a-public-reference-was-entirely-empty.md
T
DongHyeonkaandClaude Opus 5 f6c825e858 docs(TechLog): 글감 56개를 기록으로 쓴다
주제 13개 · Case 28 · Concept 5 · Reference 15 · Question 4 · Decision 4.
계약의 노드마다 종류가 요구하는 칸을 채우고, 본문이 있는 두 종류에는 SSOT 가 이미
그려 둔 도식 셋(value-boundaries · decision-path-404 · topic-variant-model)을
tech-log-studio/ 로 옮겨 붙였다. 새로 그린 그림은 없다.

검사 셋 전부 통과한다.
  check_body.mjs      56 편 중 본문이 있는 33 편 PASS
  check_prose.mjs     56 편 error 0
  check_evidence.mjs  --repo 포함 문제 없음
  verify-tech-log-tree.py  프로젝트 5 · error 0 · warn 0

인용한 코드블록은 전부 SSOT 에서 찾아 대조했다. check_evidence.mjs 가 본문의 각 줄과
source 앵커와 계약 제목을 다시 확인한다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 15:29:33 +09:00

93 lines
4.6 KiB
Markdown

---
kind: CASE
slug: a-public-reference-was-entirely-empty
title: 공개 Reference 가 통째로 비어 있었다 — 이름이 어긋났고 본문은 다른 테이블에 있었다
topic: values-lost-between-boundaries
topicName: 값이 경계에서 사라진다
project: TechLog
status: 게시 전
lastVerifiedOn: 2026-09-04
sourceRevision: tech-log@2026-09-02
source:
- final/document.md#§5.1
- final/document.md#§6.2
---
# 공개 Reference 가 통째로 비어 있었다 — 이름이 어긋났고 본문은 다른 테이블에 있었다
Reference 를 게시했더니 Studio 에서는 모든 칸이 보이는데 공개 화면만 통째로 비어 있었다. 원인이 둘 겹쳐 있었다. 게이트웨이가 읽던 칸 이름이 계약에 없는 것들이었고, Reference 의 본문이 `body_markdown` 이 아니라 별도 테이블에 있었다. 타입 검사는 `as` 단언 때문에 아무 말도 하지 않았다.
## 관계
- **공개 화면 한 줄이 그려지기까지 값이 지나는 경계 열한 개**
이 사건이 그 경계 중 어디에서 났는지가 그 개념에 있다.
- **Studio 에서는 보이는데 공개 쪽만 비면 그 사이에 계약이 있다**
이 사건에서 굳힌 진단 규칙이다.
- **TypeScript 가 검사를 놓아 주는 네 곳**
`as` 단언이 어긋남을 가린 것을 그 개념이 설명한다.
## 문제
Reference 를 공개했다. Studio 편집기에서는 목적·규칙·적용 조건·예외·예시가 다 보이는데 공개 화면은 제목만 있고 아래가 비어 있었다.
DB 에는 작성자가 쓴 값이 그대로 있었다. 두 화면이 같은 데이터를 보는데 한쪽만 비었다.
## 결론
원인이 둘이었고 서로 다른 경계에 있었다.
게이트웨이가 읽던 이름 : purposeSummary · applyWhenMarkdown · exceptionsMarkdown · examplesMarkdown
계약이 주는 이름 : scopeSummary · appliesTo · excludedScope
결과 : 전부 undefined 로 떨어졌고, as string 단언 때문에 타입 검사가 통과했다
Reference 의 본문은 `body_markdown` 이 아니라 `reference_detail` 의 규칙과 예시에 있다. Studio 편집기가 규칙을 제목과 본문으로 나눠 받고 마크다운 본문은 비워 두기 때문이다. 공개 조회는 `body_markdown` 만 보고 빈 문자열을 내보냈다.
고친 뒤에는 값이 아니라 이름을 지키는 테스트를 뒀다. 계약에서 그 칸이 사라지면 `satisfies` 가 먼저 깨진다. 값을 검사하는 테스트로는 이 결함이 잡히지 않는다.
## 검증 환경
tech-log-frontend : 7211dd1 이후
tech-log-design-package : ff0c12a 이후
tech-log-backend : a5f93b9 이후
확인 방식 : 계약이 주는 이름과 게이트웨이가 읽는 이름을 대조
## 재현 조건
1. Studio 에서 Reference 를 작성하고 규칙과 예시를 채운 뒤 게시한다
2. 공개 화면에서 그 Reference 를 연다 — 제목만 보이고 아래가 비어 있다
3. 게이트웨이 매퍼에서 읽는 칸 이름을 계약의 스키마와 맞춰 본다
## 본문
<!-- body:start -->
## 계약에 없는 이름을 읽고 있었다
게이트웨이는 응답에서 네 칸을 꺼내고 있었다. 그중 계약에 있는 것은 하나도 없었다.
```ts
const summary = body.purposeSummary as string; // 계약에 그런 칸이 없다
```
`as string` 이 붙어 있으므로 컴파일러는 그 이름이 응답 타입에 있는지 묻지 않는다. 실행하면 `undefined` 가 나오고 화면은 빈 문자열을 그린다.
계약이 주는 이름은 `scopeSummary`, `appliesTo`, `excludedScope` 다.
## 본문이 다른 테이블에 있었다
두 번째 원인은 저장 구조였다. Reference 의 본문은 문서 본문 칸이 아니라 `reference_detail` 의 규칙과 예시에 들어 있다. Studio 편집기가 규칙을 제목과 본문으로 나눠 받고 마크다운 본문을 비워 두기 때문이다.
공개 조회는 문서 본문만 읽고 `content: ""` 를 내보냈다. 첫 번째 원인을 고쳐도 본문은 여전히 비어 있었다.
## 값이 아니라 이름을 지킨다
고친 뒤에 둔 테스트는 값을 비교하지 않는다. 게이트웨이가 읽는 이름이 계약의 타입에 있는지를 `satisfies` 로 묻는다. 계약에서 그 칸이 사라지면 컴파일이 먼저 멈춘다.
값을 비교하는 테스트로는 이 결함이 잡히지 않았을 것이다. 픽스처를 게이트웨이가 읽는 이름으로 만들면 값이 그대로 나오기 때문이다.
## 확인하지 못한 것
`as` 단언을 걷어낸 것은 이 매퍼 하나다. 같은 모양이 다른 매퍼에 남아 있는지 전수로 세지 않았다.
<!-- body:end -->