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>
This commit is contained in:
DongHyeonka
2026-09-07 15:29:33 +09:00
co-authored by Claude Opus 5
parent 6955611439
commit f6c825e858
62 changed files with 6381 additions and 186 deletions
@@ -0,0 +1,88 @@
---
kind: CASE
slug: a-list-item-had-to-carry-the-whole-document
title: 결정에는 상세 화면이 없어 목록 항목이 문서 전체를 실어야 했다
topic: values-lost-between-boundaries
topicName: 값이 경계에서 사라진다
project: TechLog
status: 게시 전
lastVerifiedOn: 2026-09-04
sourceRevision: tech-log@2026-09-02
source:
- final/document.md#§5.4
---
# 결정에는 상세 화면이 없어 목록 항목이 문서 전체를 실어야 했다
공개 결정 화면에서 제목 자리에 결정문 전문이 나오고, 요약이 없고, 줄바꿈이 전부 접히고, 영향과 근거가 늘 비어 있었다. 네 증상이 한 구조에서 나왔다 — 결정에는 상세 화면이 없고 공개 주소가 목록 위의 앵커다. 그래서 화면이 그리는 칸이 전부 목록 항목에 있어야 했다.
## 관계
- **Studio 에서는 보이는데 공개 쪽만 비면 그 사이에 계약이 있다**
이 사건이 그 신호의 예다.
- **계약은 앵커라고 적었고 만드는 쪽은 경로를 만들었다**
같은 앵커 구조에서 난 주소 쪽 사건이다.
- **관계의 요약이 경계 세 곳을 지나며 사라졌다**
같은 시기에 계약의 빈칸으로 난 다른 사건이다.
## 문제
결정은 상세 endpoint 가 없다. 공개 주소가 `/projects/{slug}/decisions#{slug}` 로 목록 위의 앵커다.
상세가 없으면 화면이 그리는 칸이 전부 목록 항목에 있어야 한다. 목록 항목에는 `title`·`summary`·`consequences`·`evidence` 가 빠져 있었다.
## 결론
네 증상이 전부 목록 항목의 빈칸에서 나왔다.
제목 자리 : statement 를 대신 썼다
요약 : 실을 칸이 없었다
줄바꿈 : 접혔다
영향과 근거 : 프론트가 빈 배열로 고정해 뒀다
DB 에는 작성자가 쓴 제목, 여러 줄 요약, 영향 4건이 그대로 있었다. 목록 항목이 화면이 그리는 칸을 전부 싣게 하고 네 곳을 이었다.
## 검증 환경
tech-log-design-package : 987c1b8 이후
tech-log-backend : 026460f 이후
tech-log-frontend : 31afb4d 이후
확인 방식 : DB 조회로 저장된 값을 확인하고 공개 화면과 대조
## 재현 조건
1. Studio 에서 결정을 작성하고 제목·요약·영향을 채운다
2. 게시한 뒤 프로젝트의 결정 목록을 공개 화면에서 연다
3. 저장된 값과 화면에 그려진 값을 대조한다
## 본문
<!-- body:start -->
## 상세가 없으면 목록이 전부 실어야 한다
결정은 자기 화면을 갖지 않는다. 공개 라우트는 `/projects/{slug}/decisions` 하나이고, 개별 결정은 그 목록 위의 앵커로 간다.
이 구조에서는 화면이 그리는 칸이 전부 목록 항목에 있어야 한다. 상세를 부를 곳이 없기 때문이다.
## 네 증상이 한 원인이었다
`ProjectDecisionItem``title` 이 없어서 프론트가 `statement` 를 제목 자리에 썼다. 결정문은 한 문장이 아니라 문단일 수 있으므로 제목 자리에 전문이 들어갔다.
`summary` 가 없어서 요약 줄이 비었다. `consequences``evidence` 가 없어서 프론트가 그 둘을 빈 배열로 고정해 뒀다.
줄바꿈은 다른 이유였다. 마크다운이 아닌 칸의 줄바꿈을 화면이 접고 있었다.
## 저장된 값은 그대로 있었다
DB 를 조회하면 작성자가 쓴 제목과 여러 줄 요약과 영향 4건이 있었다. 어느 것도 화면까지 오지 못했다.
## 화면 쪽에서 역으로 확인한다
이 부류는 응답에서 출발하면 보이지 않는다. 응답에 없는 칸을 찾는 일이기 때문이다. 화면이 그리는 칸을 먼저 적고 그 칸이 응답에 있는지 하나씩 맞춰야 한다.
## 확인하지 못한 것
저장된 값이 그대로였다는 것은 조회로 확인했다. 그 시점의 화면 캡처는 남기지 않았다.
<!-- body:end -->
@@ -0,0 +1,92 @@
---
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 -->
@@ -0,0 +1,95 @@
---
kind: CASE
slug: a-summary-vanished-at-three-boundaries
title: 관계의 요약이 경계 세 곳을 지나며 사라졌다
topic: values-lost-between-boundaries
topicName: 값이 경계에서 사라진다
project: TechLog
status: 게시 전
lastVerifiedOn: 2026-09-04
sourceRevision: tech-log@2026-09-02
source:
- final/document.md#§5.2
- final/document.md#§5.3
---
# 관계의 요약이 경계 세 곳을 지나며 사라졌다
관계 목록의 라벨을 고쳤는데 요약은 여전히 비어 있었다. 한 경계를 고치고 확인했더니 다음 경계가 버리고 있었고, 그것을 고치니 그다음이 버렸다. 세 번째는 계약에 담을 칸 자체가 없었다.
## 관계
- **공개 화면 한 줄이 그려지기까지 값이 지나는 경계 열한 개**
세 경계가 그중 어디인지가 그 개념에 있다.
- **한 경계를 고쳤으면 값의 여정 끝에서 확인한다**
이 사건에서 굳힌 규칙이다.
- **결정에는 상세 화면이 없어 목록 항목이 문서 전체를 실어야 했다**
같은 시기에 계약의 빈칸으로 난 다른 사건이다.
## 문제
관계 목록은 한 줄에 대상의 종류와 작성자가 쓴 이유와 대상의 요약을 보인다. 라벨은 고쳤는데 요약 자리가 계속 비어 있었다.
계약에는 요약이 있었다. DB 에도 값이 있었다. 화면까지 오지 못했다.
## 결론
값이 세 경계를 지나며 사라지고 있었다.
flattenRelations : 담지 않음 — 1차로 고침
렌더 모델로 변환 : 담을 칸 자체가 없었음
화면 목록으로 전달 : 또 버림
렌더 모델 계약(`ResolvedRelation`)에 요약 칸이 없었고 `additionalProperties: false` 라 실을 수도 없었다. 계약에 `summary` 를 더하고 — 이미 나가 있는 응답을 깨지 않으려고 required 에는 넣지 않고 — 세 경계를 모두 이었다.
그 과정에서 한 칸에 뭉쳐 있던 셋을 갈랐다. 대상의 종류는 `label`, 작성자가 쓴 이유는 `note`, 대상의 요약은 `summary` 다.
## 검증 환경
tech-log-frontend : a3ed23e 이후
tech-log-design-package : fa67a64 이후
tech-log-backend : 92679f5 이후
확인 방식 : 공개 화면의 관계 목록에서 세 값이 각각 나오는지 확인
## 재현 조건
1. 기록 둘을 관계로 잇고 이유를 적는다
2. 게시한 뒤 공개 화면에서 관계 목록을 본다
3. 라벨·이유·요약 세 값이 각각 나오는지 본다 — 하나라도 비면 그 값이 어느 경계에서 사라졌는지 역순으로 따라간다
## 본문
<!-- body:start -->
## 세 번 버려졌다
```text
계약(요약 있음)
└─ flattenRelations 가 담지 않음 ← 1차로 고침
└─ 렌더 모델로 바꿀 때 버림 ← 담을 칸 자체가 없었다
└─ 화면 목록으로 넘길 때 또 버림
```
첫 번째를 고치고 화면을 봤을 때도 요약은 비어 있었다. 두 번째를 고치려고 보니 렌더 모델 계약에 담을 칸이 없었고, `additionalProperties: false` 라 계약을 고치지 않고는 실을 수 없었다.
## 계약에 칸을 더할 때 required 를 따로 판단한다
`ResolvedRelation``summary` 를 더했다. required 에는 넣지 않았다. 이미 나가 있는 응답에는 그 칸이 없으므로, required 로 올리면 배포 순서에 따라 검증이 깨진다.
## 한 칸에 셋이 뭉쳐 있었다
값을 잇고 나서 다른 문제가 보였다. 관계 한 줄이 답해야 하는 것이 셋인데 `reason` 한 칸을 지나고 있었다.
| 무엇 | 뜻 | 경로별로 어떻게 나왔나 |
|---|---|---|
| 대상의 종류 | 「근거」「관련 기준」 같은 분류 | 렌더 모델 경로: 작성자의 문장이 이 자리에 눌려 나옴 |
| 작성자가 쓴 이유 | 「다음에 무엇을 읽을지」의 답 | 공개 조회 경로: **아예 버려짐** |
| 대상의 요약 | 대상이 무엇인지 | — |
셋을 `label` · `note` · `summary` 로 갈랐다. 설명 자리에는 문장이 있으면 문장을, 없으면 요약을 보인다. 요약은 대상이 무엇인지 말하고, 문장은 왜 지금 그것을 읽어야 하는지 말한다.
## 확인하지 못한 것
세 경로에서 무엇이 나오는지는 화면으로 확인했다. 세 경로 전부를 자동 검사로 고정하지는 않았다.
<!-- body:end -->
@@ -0,0 +1,79 @@
---
kind: CONCEPT
slug: eleven-boundaries-a-value-crosses
title: 공개 화면 한 줄이 그려지기까지 값이 지나는 경계 열한 개
topic: values-lost-between-boundaries
topicName: 값이 경계에서 사라진다
project: TechLog
status: 게시 전
basisVersion: tech-log-backend · tech-log-frontend 2026-09-02 · OpenAPI 3.1 계약 3종을 반입해 쓰는 구조
assets:
- key: value-boundaries
file: ../../../final/assets/tech-log-studio/value-boundaries.svg
sourceRevision: tech-log@2026-09-02
source:
- final/document.md#§1.2
- final/document.md#§17.1
---
# 공개 화면 한 줄이 그려지기까지 값이 지나는 경계 열한 개
공개 화면의 한 줄은 PostgreSQL 의 투영 테이블에서 출발해 열한 번 모양을 바꾼 뒤에 그려진다. 그 사이 어느 한 곳이 값을 담지 않아도 오류가 나지 않는다. `undefined` 는 빈 문자열로 그려지고 빈 배열은 「항목이 없습니다」로 그려진다.
## 관계
- **공개 Reference 가 통째로 비어 있었다 — 이름이 어긋났고 본문은 다른 테이블에 있었다**
이 경계 중 두 곳에서 값이 사라진 사건이다.
- **관계의 요약이 경계 세 곳을 지나며 사라졌다**
한 값이 연달아 세 경계에서 버려진 사건이다.
- **한 경계를 고쳤으면 값의 여정 끝에서 확인한다**
이 경계 수가 그 규칙의 근거다.
## 본문
<!-- body:start -->
## 열한 번 모양이 바뀐다
```text
PostgreSQL 테이블
└─ public_resource_projection (게시 시점에 굳어진 투영)
└─ JDBC 어댑터의 SQL (컬럼 이름을 컴파일러가 검사하지 않는다)
└─ *View 레코드 (application-core)
└─ *ResponseMapper (adapter/inbound/web)
└─ 생성된 DTO (계약이 만든 모양)
└─ HTTP envelope
└─ openapi-typescript 타입
└─ http-public-content-gateway 의 매퍼
└─ 포트 타입 (application/ports)
└─ 화면 컴포넌트
```
:::evidence key="value-boundaries" alt="저장·백엔드 조립·HTTP envelope·프론트엔드 조립·화면 다섯 묶음을 세 저장소 구역으로 나눠 이은 흐름도" caption=" " zoom="true"
:::
저장 쪽에 둘, 백엔드 조립에 넷, 전선에 하나, 프론트엔드 조립에 셋, 화면에 하나다.
## 어디서 검사가 끊기는가
경계마다 무엇이 값을 지키는지가 다르다.
JDBC 어댑터의 SQL 은 컬럼 이름을 문자열로 적는다. 컬럼이 없거나 이름이 다르면 실행할 때 알게 된다.
계약이 만든 DTO 와 생성된 타입 사이는 생성기가 지킨다. 다만 생성기가 보는 것은 스키마의 모양이고, 그 칸에 값이 담기는지는 보지 않는다.
게이트웨이의 매퍼는 계약의 타입을 읽는다. `as` 단언을 쓰면 그 확인이 사라진다.
포트 타입과 화면 컴포넌트 사이는 TypeScript 가 지킨다. 포트와 어댑터가 타입을 따로 들고 있으면 그 확인도 사라진다.
## 값을 버려도 오류가 나지 않는다
이 경계들은 값을 담지 않았다고 말하지 않는다. 담지 않은 채 다음으로 넘긴다.
`undefined` 는 화면에서 빈 문자열이 된다. 빈 배열은 「항목이 없습니다」가 된다. 그래서 화면만 보면 값이 없는 것과 값을 잃은 것이 같아 보인다.
## 두 화면이 같은 데이터를 볼 때
Studio 와 공개 화면은 같은 DB 를 보지만 계약이 다르다. Studio 는 작성 계약을, 공개 화면은 조회 계약을 지난다. 한쪽에만 값이 보이면 그 사이의 계약에 칸이 없다.
<!-- body:end -->
@@ -0,0 +1,65 @@
---
kind: REFERENCE
slug: a-missing-contract-field-has-a-signature
title: Studio 에서는 보이는데 공개 쪽만 비면 그 사이에 계약이 있다
topic: values-lost-between-boundaries
topicName: 값이 경계에서 사라진다
project: TechLog
status: 게시 전
verifiedOn: 2026-09-04
sourceRevision: tech-log@2026-09-02
source:
- final/document.md#§5.6
- final/document.md#§5.5
---
# Studio 에서는 보이는데 공개 쪽만 비면 그 사이에 계약이 있다
Studio 편집기에서는 값이 다 보이는데 공개 화면만 비어 있으면, 두 화면이 같은 DB 를 보고 있으므로 그 사이의 계약에 칸이 없다. 이 저장소에서 같은 신호가 여덟 번 같은 원인을 가리켰다.
## 관계
- **공개 Reference 가 통째로 비어 있었다 — 이름이 어긋났고 본문은 다른 테이블에 있었다**
이 신호가 처음 잡힌 사건이다.
- **결정에는 상세 화면이 없어 목록 항목이 문서 전체를 실어야 했다**
화면 쪽에서 역으로 확인해야 했던 사건이다.
- **한 경계를 고쳤으면 값의 여정 끝에서 확인한다**
칸을 더한 뒤 무엇을 확인할지가 그 기준에 있다.
## 목적
DB 에 값이 있는데 화면이 비어 있을 때, 어디를 먼저 볼지 정한다. 이 부류는 오류를 내지 않으므로 로그에서 출발하면 아무것도 나오지 않는다.
## 규칙
**Studio 에서는 보이고 공개 쪽만 비면 그 사이의 계약을 먼저 본다**
두 화면이 같은 DB 를 보는데 한쪽만 비면, 다른 것은 그 사이에 놓인 계약이다.
**화면이 그리는 칸을 먼저 적고 응답에 있는지 하나씩 맞춘다**
응답에서 출발하면 없는 칸은 보이지 않는다. 상세 endpoint 가 없는 종류에서 특히 그렇다 — 목록 항목이 문서 전체를 실어야 한다.
**칸을 더할 때 required 로 올릴지는 따로 판단한다**
이미 나가 있는 응답에는 그 칸이 없다. required 로 올리면 배포 순서에 따라 검증이 깨진다.
**값이 아니라 이름을 지키는 검사를 둔다**
게이트웨이가 읽는 이름이 계약의 타입에 있는지를 묻는다. 값을 비교하는 검사는 픽스처를 게이트웨이가 읽는 이름으로 만들면 그대로 통과한다.
## 적용 조건
같은 데이터를 두 표면이 각자의 계약으로 읽고, 한쪽만 비어 보이는 화면. 작성 계약과 조회 계약이 나뉜 구조에서 걸린다.
## 예외
두 표면이 같은 계약을 쓰면 이 신호는 성립하지 않는다. 그때는 매퍼나 질의를 먼저 본다.
저장 구조가 종류마다 다르면 계약이 아니라 조회가 원인일 수 있다. Reference 의 본문이 문서 본문 칸이 아니라 별도 테이블에 있던 것이 그 예다.
## 예시
공개 Reference 가 통째로 비었을 때 게이트웨이가 읽던 네 이름이 전부 계약에 없었다.
프로젝트의 「주요 주제」는 테이블도 조인도 가능했는데 응답에 실을 칸이 없었다.
질문 목록만 주제가 빠져 있어서 질문 줄의 맥락이 「· 프로젝트」로 시작했다. 지식 목록은 처음부터 그 칸을 싣고 있었다.
프로젝트 목록 행에 slug 가 없었다. 다른 목록이 프로젝트를 가리킬 때 쓰는 것은 id 가 아니라 slug 다.
@@ -0,0 +1,64 @@
---
kind: REFERENCE
slug: verify-at-the-end-of-the-value-journey
title: 한 경계를 고쳤으면 값의 여정 끝에서 확인한다
topic: values-lost-between-boundaries
topicName: 값이 경계에서 사라진다
project: TechLog
status: 게시 전
verifiedOn: 2026-09-04
sourceRevision: tech-log@2026-09-02
source:
- final/document.md#§17.1
- final/document.md#§5.2
- final/document.md#§6.6
---
# 한 경계를 고쳤으면 값의 여정 끝에서 확인한다
값이 여러 경계를 갈아타는 구조에서 한 경계를 고치고 「고쳤다」고 판단해 세 번 틀렸다. 타입 검사도 단위 테스트도 「코드를 읽어 보니 맞다」도 전부 중간 지점이다. 배포본에서 그 값이 실제로 그려지는 곳까지 가서 확인한다.
## 관계
- **관계의 요약이 경계 세 곳을 지나며 사라졌다**
한 경계를 고치고 판단해 두 번 틀린 사건이다.
- **공개 화면 한 줄이 그려지기까지 값이 지나는 경계 열한 개**
왜 중간 확인이 부족한지가 그 개념에 있다.
- **TypeScript 가 검사를 놓아 주는 네 곳**
타입 통과가 반영의 증거가 아닌 이유가 그 개념에 있다.
## 목적
「고쳤다」는 판단이 틀리는 것을 막는다. 값이 열한 경계를 지나는 구조에서 한 경계만 보고 판단하면, 다음 경계가 같은 값을 다시 버려도 알 수 없다.
## 규칙
**고친 값이 실제로 그려지는 곳까지 가서 본다**
배포본에서 그 화면을 열거나, 실제 요청을 보내 응답을 읽는다.
**타입 검사 통과를 반영의 증거로 쓰지 않는다**
메서드 매개변수의 bivariance, `as` 단언, 검사 대상이 없는 tsconfig 가 각각 통과시킨 사례가 있다.
**게이트웨이를 실제로 불러 어떤 연산이 나가는지 확인한다**
등록을 빠뜨린 연산은 옆 분기로 떨어지므로 서버는 정상 응답을 준다. 나가는 경로를 봐야 알 수 있다.
**여정이 끝나는 곳을 먼저 정하고 시작한다**
어디까지 가면 확인이 끝나는지 모르면 중간에서 멈추게 된다.
## 적용 조건
값이 계약·매퍼·포트를 여러 번 갈아타는 구조에서 「고쳤다」를 판단할 때. 계약을 소유한 저장소가 따로 있고 생성기를 지나 들어오면 특히 걸린다.
## 예외
경계가 하나뿐이거나 고친 그 곳이 여정의 끝이면 중간 확인으로 충분하다.
값이 아니라 이름을 지키는 검사를 이미 뒀으면 그 검사가 여정의 한 구간을 대신한다. 다만 검사가 덮는 구간이 어디까지인지 적어 둔다.
## 예시
관계 요약을 세 번 고쳤다. 매번 화면을 보고 나서야 다음 경계가 버리는 것을 알았다.
개념 삭제가 계속 질문 삭제 경로로 나갔다. 타입 검사가 통과해서 반영된 줄 알았고, 배포된 번들의 서버 로그에서 404 를 보고 알았다.
CONCEPT 을 `deleteQuestion` 으로 되돌려 가드가 깨지는 것을 확인했다.