Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/_meta/editorial/semantic-pass-progress.md
T
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.

Follows the import procedure in README.md.

  source/     the originating repository verbatim — 78 documents, 28 SVGs,
              8 manifests, plus .source-revision recording the commit
  final/      the SSOT
    document.md   729 lines written from the 29 experiment documents, not
                  concatenated: what was predicted, what was measured, and
                  where the measurement itself was wrong
    evidence/raw    125 outputs, flattened to <experiment>__<file> because
                    the originals collided (01-baseline.txt appeared three
                    times) and the audit only globs the top level
    evidence/meta   one per raw file; command and exitCode are null and the
                    README says why rather than inventing them
    evidence/browser  22 captures
    assets/       three diagrams through techviz
    .techviz/     their VizSpecs

A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.

Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.

verify-pipeline.py passes. audit-records.py reports no issues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:51:59 +09:00

19 KiB

Semantic Editorial Pass — 진행 기록

현재 상태: COMPLETE

:::warning

이 문서는 작업 로그다. 아래 여러 절은 작업 당시의 incremental progress snapshot 이다. 진행 중 표기, 중간 count, 이전 audit 결과는 historical record 이며 현재 상태를 뜻하지 않는다. 예를 들어 state-machines-and-ownership — 78/119 (진행 중) 은 그 시점의 값이고, 그 topic 은 CONCEPT 386건 완료 시점에 끝났다.

정본은 두 곳이다.

  • 이 문서 하단의 Correction pass
  • _meta/editorial/final-editorial-validation-2026-09-01.md — 최종 검증 수치

:::

시작 2026-09-01. 대상 949 records. 우선순위 CONCEPT -> CASE -> REFERENCE/QUESTION/DECISION.

Historical progress snapshot — 이번 pass 에서 함께 고친 것

  • 생성 과정에서 문장이 절 경계에서 잘려 나간 body 를 원본 source anchor 로 복원한다. 말줄임(…)으로 끝난 문장, 목록이 한 줄로 뭉개진 문단, 코드 스팬 중간에서 끊긴 문장이 대상이다.
  • 절 제목을 그 문서가 실제로 설명하는 메커니즘·사건·경계 이름으로 바꾼다. 고정 목차를 새로 만들지 않는다.
  • 제목이 SSOT 절 머리글(모듈의 정체와 경계, 실패 경로와 복구/번역 등)이거나 분석 번호((8.2) 등)이거나 분석 과정형(Confirmed —)이면 그 문서의 메커니즘 이름으로 바꾼다.
  • 그림은 논지에 맞는 visual grammar 로 다시 그리거나, 논지와 무관하면 제거한다.

Historical progress snapshot — 완료 topic (CONCEPT)

  • result-and-failure-algebra — 10/10
  • query-and-pagination-models — 6/6
  • observability-models — 7/7
  • identity-and-value-contracts — 8/8
  • capability-and-disclosure-models — 11/11
  • security-and-trust-boundaries — 20/20

Historical progress snapshot — 그림 처리 기록

  • 재설계: adapter-inbound-graphql-c10, adapter-outbound-cache-redis-c03, adapter-outbound-support-c02, application-core-c01, messaging-testkit-c04, adapter-inbound-web-c01, adapter-outbound-objectstorage-c01, adapter-outbound-persistence-jpa-c24, grpc-advanced-diagnostics-c02, adapter-inbound-web-c03, adapter-inbound-web-c04, application-core-c02, grpc-advanced-diagnostics-c01, grpc-observability-c01, grpc-spring-boot-starter-c01
  • 제거: grpc-core-api-c01(기록의 논지와 다른 그림), app-bootstrap-c01(표로 읽는 것이 명확), adapter-outbound-notification-c04(같음), grpc-advanced-bootstrap-c03(같음)
  • admission-budget-and-backpressure — 21/21
  • composition-and-lifecycle-models — 26/26
  • transaction-and-consistency-models — 27/27
  • state-machines-and-ownership — 78/119 (진행 중)

CONCEPT 386건 완료 (2026-09-01)

  • 일반 heading(구조 / 명령이 보여 주는 것 / 어떻게 움직이는가 / 무엇이 불변식인가 / 어디까지가 경계인가 / 왜 그렇게 되나 / 무엇이 남는가 / 실패하면 어떤 상태가 되는가 / 근거 절 원문)을 남긴 CONCEPT body 0건.
  • audit_corpus_structure.py concept: bodies=386 findings=0.
  • state.json 과 frontmatter/H1 사이 title 불일치 132건을 state.json 쪽(보호 대상 식별자가 살아 있는 쪽)으로 정본화. 단 test-names-that-assert-what-their-bodies-do-not 은 본문이 네 사례를 열거하므로 "테스트 넷" 으로 확정하고 state.json 을 고쳤다.
  • diagram 217 → 181. 제거 36건은 (a) 내용이 목록/표라서 그림이 정보를 더하지 않는 경우, (b) alt 가 다른 기록의 주장을 그리고 있던 경우다.
  • CASE 402건은 ca0..ca30 청크로 진행한다.

CASE 402건 완료 (2026-09-01)

  • ca0..ca30 청크 전량 편집. 일반 heading 잔존 0건.
  • audit_corpus_structure.py case: bodies=402 findings=0.
  • CASE 구간에서 diagram 재설계 다수, 제거 다수. 최종 diagram 수는 pass 종료 시 재보고.
  • 다음: REFERENCE 105 / OPEN QUESTION 31 / DECISION 25 (본문 파일 없음, record .md 만 편집).

Semantic editorial pass — 1차 (2026-09-01, 이후 정정됨)

:::warning

아래는 1차 pass 당시의 스냅숏이다. 두 수치가 틀렸고 correction pass 에서 정정했다 — 20개 이상 문서에서 동일한 문단 = 0 은 body 만 센 것이고 main record 를 세지 않았으며, 테스트 수는 test_verify_pipeline 한 파일만 돈 결과다. 최신 상태는 이 문서 끝의 "Correction pass" 절을 본다.

:::

전체 949건 편집을 마쳤다. lastEditorialAt / lastValidationAt = 2026-09-01T10:39:26Z.

구조 다양성

지표 이전 이후
CONCEPT heading signature 18 / 386 (4.7%) 382 / 386 (99.0%)
CASE heading signature 12 / 402 (3.0%) 400 / 402 (99.5%)
CASE 서로 다른 ## heading 1,191
CONCEPT 서로 다른 ## heading 1,054
20개 이상 body 에서 동일한 문단 다수 0
20개 이상 main record 에서 동일한 문장 측정하지 않음 측정하지 않음 — correction pass 가 163건을 찾았다

## 출처 는 provenance 절이므로 전 기록이 공유한다. 그 다음으로 빈도가 높은 것은 CASE ## 수정 37건(9.2%), CONCEPT ## 이 기록이 다루는 파일 범위 34건(8.8%) 이다. audit_corpus_structure.py 의 FIRST_HEADING_DOMINANCE(80%) · LOW_HEADING_SIGNATURE_DIVERSITY(15%) · REPEATED_BOILERPLATE(20) 세 규칙 모두 findings=0.

이번 회차에 마지막으로 처리한 것

  • CASE ca29 · ca30 청크 25건. CASE 402건 전량 완료.
  • REFERENCE 40건: 목적/규칙/적용 조건/예외/근거 가 전부 boilerplate 였던 기록을 각 source anchor 의 SSOT finding(사실·근거·왜 문제인가·확인 방법)으로 다시 썼다.
  • QUESTION 13건: 미지수("현재 근거로는 답이 닫히지 않는다")와 다음 검증 boilerplate 를 각 기록의 실제 미지수와 확인 방법으로 바꾸고, SSOT 의 후보를 선택지 절로 옮겼다.
  • ## 원본 판정이 무엇을 적었나 206건(CASE 186 · CONCEPT 20)을 각 기록이 인용하는 근거가 무엇을 보여 주는지로 개별 명명했다. 편집 과정에서 이 heading 자체가 두 번째 template 이 된 것을 계측으로 발견해 되돌린 것이다.
  • 제목: LONG_TITLE 후보를 전수 검토했다. 9건을 줄였고 60건은 유지했다.

제목 판정

줄인 것 9건.

  • analysis-finding-a03-f003legacy compatibility surface의 제거 조건을 세 가지로 고정한다 (다른 두 기록의 ## 관계 가 이미 이 이름으로 이 규칙을 가리키고 있었다. 끊긴 링크가 붙었다)
  • a05-f003-capabilitysupport-constraintsCapabilitySupport.constraints 의 경계가 타입에 없다
  • analysis-finding-a04-f006cache-redis 와 httpclient 의 support 간선이 죽었는지 확정되지 않았다
  • a06-f003-change-streams-true(88자) → 두 절 중 중복(거부되지 않고/조용히 버려지며)을 뺐다
  • a13-f002-authentication-failed-resumehealthy(77자) → 한 절로 줄였다
  • analysis-finding-a19-f013(75자) → 인용 문장을 본문에 남기고 제목은 사건 이름으로 바꿨다
  • a14-f005-publicpaths-restrictedpathrule(73자) → 뒤 절이 앞 절을 일반어로 반복하고 있었다
  • messaging-nats-experimental-f03(72자) → 제목에 두 문장이 들어 있었다
  • messaging-kafka-f01(69자) → 세 절 중 사건을 이루는 두 절만 남겼다

유지한 60건은 길이가 (a) MessagingPublicSurfaceContractTest · GrpcSerializedStreamWriter 같은 보호 대상 식별자, (b) 사건 자체가 두 사실의 대조인 경우(문서 X · 코드 Y), (c) 열거가 실질인 경우 (연결 티켓·origin 정책·메시지 권한·연결 예산)에서 온다. 줄이면 사실이 빠진다.

시각 자료

  • diagram 217 → 181. 제거 36건은 내용이 목록/표라 그림이 정보를 더하지 않거나, alt 가 다른 기록의 주장을 그리고 있던 경우다.
  • terminal SVG 788건은 손대지 않았다.
  • validate_svg.py assets/svg --kind diagram PASS, assets/terminal --kind terminal PASS.

최종 검증

명령 결과
PYTHONPATH=tools python3 -m unittest tools.tests.test_verify_pipeline OK (38 tests — 한 파일만. 전체 discover 아님)
python3 tools/verify_pipeline.py /shared PASS
audit_korean_tech_writing.py concept scanned=772 findings=0
audit_korean_tech_writing.py case scanned=804 findings=60 (LONG_TITLE, 전건 검토 후 유지)
audit_korean_tech_writing.py reference scanned=105 findings=0
audit_korean_tech_writing.py openquestion scanned=31 findings=0
audit_korean_tech_writing.py decision scanned=25 findings=0
audit_corpus_structure.py concept bodies=386 findings=0
audit_corpus_structure.py case bodies=402 findings=0
validate_svg.py assets/svg --kind diagram PASS
validate_svg.py assets/terminal --kind terminal PASS
record/body SHA ↔ _meta/state.json 949건 전건 일치

남은 editorial warning

CASE LONG_TITLE 60건뿐이다. 위 판정대로 유지 결정이며, 규칙을 다시 적용할 때는 길이가 아니라 "제목이 사건을 이름 짓는가"로 판정한다.

편집 중 발견해 고친 사실 오류 하나

case-an-unselectable-broker-listed-with-features## 출처 가 존재하지 않는 절 analysis/messaging/messaging-rabbit.md §17 을 가리키고 있었다. SSOT 를 grep 해 analysis/19-messaging-platform.md §6.2 가 그 finding 의 실제 소유자임을 확인하고 고쳤다.


Correction pass (2026-09-01)

독립 재검증에서 나온 결함만 고치고, 같은 형태가 다시 완료 판정을 통과하지 못하도록 validation contract 를 보강한 회차다. 949건을 다시 쓰지 않았다. lastEditorialAt · lastValidationAt = 2026-09-01T11:32:12Z.

1. main record boilerplate 163건

1차 pass 의 audit 은 *.body.md 만 glob 했다. main record 는 대상 밖이었고, 그래서 다음 두 문장이 CASE 163건과 158건에 그대로 남아 있었다.

확인 방식 : 원본 분석 절의 판정을 옮겼고, 이 기록에 붙은 자산의 명령만 이번 회차에 실행했다
이 노드는 canonical SSOT 의 판정을 그대로 옮긴 것이다. 그 SSOT 의 §16 이 해당 finding 에 대해 실행하지 못한 검증을 소유한다.

둘 다 기록이 아니라 생성 파이프라인을 설명하는 문장이다. 163건 전부를 owning SSOT 43개의 §16 (확인하지 못한 것)과 각 기록에 붙은 자산으로 다시 썼다.

  • 확인 방식 — 그 기록을 실제로 무엇이 확정했는지. 예: GrpcAdmissionController 참조 16건 전수 검색과 두 클래스의 공개 표면 대조, HeaderValue 참조 26건 검색과 파서의 종료 지점 탐색 코드 확인. jshell 리플렉션으로 왕복 손상을 런타임 재현.
  • 확인하지 못한 것 — owning SSOT §16 이 그 finding 에 대해 소유한 실제 미검증 범위. SSOT 가 그 finding 을 닫아 둔 한 건(messaging-outbox-jdbc-postgresql-f03)만 없음 — … 으로 적었고, 읽지 않고 없음 을 쓴 기록은 없다.

고정 필드(## 요약 · ## 문제 · ## 결론 · ## 검증 환경 · ## 재현 조건 · ## 확인하지 못한 것)는 record contract 이므로 건드리지 않았다. 공통 환경값 (OpenJDK : 21.0.12 · Gradle : 9.0.0 · 소스 수정 : x)도 그대로 두었다.

덤으로 같은 형태 하나를 더 찾아 고쳤다 — CASE 5건과 그 body 5건이 가족 문서의 판정을 옮긴 것이다. 실행 확인은 그 문서의 §확인하지 못한 것이 소유한다. 를 갖고 있었는데, analysis/19-messaging-platform.md 에는 그런 절이 없다. 끊긴 포인터였다.

2. corpus audit 의 근본 원인

audit_corpus_structure.py 를 두 층으로 나눴다.

대상 검사
rich body *.body.md heading signature · 첫 heading 편중 · 반복 문단
main record *.md (body 제외) section 내부 설명형 prose 반복만

main record 층은 고정 schema heading 을 검사하지 않는다. CASE 의 여섯 절이 100% 같은 것은 계약이 동작하는 것이지 결함이 아니다. 대신 키 : 값 줄의 값이 값인지 설명인지를 가른다 — 한국어 종결형이 붙거나 문장이 둘 이상이면 설명으로 본다. 21.0.12 java -version 으로 확인 은 값이고, 원본 분석 절의 판정을 옮겼고 … 는 설명이다.

## 관계 · ## 근거 기록 · ## 출처 아래의 - 링크 줄은 대상에서 뺐다. 그 줄은 다른 기록의 제목을 그대로 반복해야 링크가 성립한다 — 참조이지 설명이 아니다. 링크 아래의 설명 줄은 그대로 검사한다.

regression test: tools/tests/test_main_record_boilerplate.py 8건.

  • 고정 CASE heading 이 100% 같아도 fail 하지 않는다
  • 공통 Java/Gradle 값만 같아도 fail 하지 않는다
  • 같은 설명 문장이 20개 이상 main record 에 반복되면 fail 한다
  • 19건이면 fail 하지 않는다 (threshold 경계)
  • 관계 링크 줄은 반복해도 fail 하지 않는다

3. 잘못된 evidence reference 4건

owning SSOT 를 다시 읽고 정본으로 고쳤다. 없는 파일을 새로 만들지 않았다.

기록 잘못된 참조 정본
a-resumed-redrive-skips-what-it-could-not-move 306-redrive-resume-skips-failed-items.txt 306-redrive-resume-skips-unmoved.txt (EVD-306)
an-authorization-denial-recorded-as-a-configuration-error 287-messaging-security-access-path.txt 287-messaging-security-duplicate-checks.txt §C (EVD-287)
blocking-means-startup-fails-and-nothing-runs-it 302-messaging-admin-service-unwired.txt 302-admin-api-topology-guarantee-unwired.txt (EVD-302)
the-forgeable-approval-survived-on-the-irreversible-half 307-destructive-approval-not-verified.txt 308-admin-runtime-api-and-dependency-defects.txt (EVD-308)

넷째는 접두사 정정이 아니다. ApprovedVerifiedApproval 이 아니라 AdminApproval 을 담는다는 사실은 analysis/messaging/messaging-admin-runtime.md 의 §14 표에서 EVD-308 에 귀속돼 있다 (EVD-307 이 소유하는 것은 구현 0건 쪽이다).

4. source/evidence reference validator

tools/validate_source_references.py 를 추가하고 verify_pipeline.py 의 REQUIRED_PATHS 에 등록했다.

참조 형태 규칙
analysis/foo.md 파일 존재
analysis/foo.md#L123 파일 존재 + line 범위 유효
evidence/raw/<full-name>.txt 정확히 그 파일 존재. 접두사가 같은 이웃으로 대체하지 않는다
evidence/raw/287 unique prefix 로 정확히 하나에 해석

두 evidence 형태를 비대칭으로 둔 것이 이 도구의 요점이다. 전체 파일명을 적은 것은 그 파일에 대한 단언이므로, 없으면 FAIL 이어야 한다. 번호만 적은 shorthand 는 evidence id 를 가리키므로 접두사 해석을 허용한다.

regression test: tools/tests/test_source_reference_validation.py 8건 — 이번 네 오류의 형태가 전부 포함돼 있다.

5. SVG semantic defect

정상 방향 화살표는 실재하는 관계를 뜻하고, 도착 상자를 빗금 치는 것으로 그 뜻이 뒤집히지 않는다. 33개 후보를 전수 검토해 3건을 재설계하고 30건을 유지했다. 상세는 _meta/editorial/svg-semantic-review-2026-09-01.md.

판정
재설계 3
유지 — 들어오는 전이는 실재하고 부재는 나가는 쪽 3
유지 — 빗금 상자에 화살표가 닿지 않음 2
유지 — 빗금 상자 없음, 화살표가 전부 실재 흐름 25

규칙을 designing-tech-log-visuals 의 SKILL hard gate · editorial rules · review checklist 세 곳에 명문화하고, 그 셋이 존재하는지 검사하는 테스트를 붙였다.

layout signature 수는 목표로 삼지 않았다. 재설계 3건은 화살표가 기록과 반대를 말했기 때문에 고친 것이고, 나머지 30건은 grammar 가 generic 하다는 이유로 건드리지 않았다.

6. SVG 좌표 직렬화

설명용 SVG 40개의 좌표 340개가 소수점 둘 이상을 갖고 있었다. 소수점 한 자리로 정규화했고 (기하 변화 최대 0.05px), 생성기와 validate_svg.py(COORDINATE_PRECISION) 양쪽에 규칙을 넣었다. 터미널 SVG 는 대상이 아니다 — 원래 정수 좌표만 쓴다.

7. cross-scope metadata

document-detail/.../state.jsoncrossScopeAnalysis 가 재생성 이전 값을 들고 있었다.

sha256  481b3728…  →  538e4e72…
lines   428        →  552

이것을 놓친 이유는 어떤 verifier 도 기록된 수치를 파일과 대조하지 않았기 때문이다. verify_pipeline.py_verify_upstream_document_metadata 를 추가했다 — state.json 안에서 pathsha256 을 함께 가진 모든 블록(crossScopeAnalysis · finalDocument · rootTree · candidateLedger · sourceManifest)을 실제 파일과 대조한다. regression test 5건.

8. LONG_TITLE 60건

길이만 보고 줄이지 않았다. 네 조건(독립 사건 둘 혼재 · 본문에 내려도 되는 설명 · 같은 뜻 반복 · 분석 과정 문장)으로 60건을 다시 훑었고 해당하는 것이 없었다. 남은 길이는 보호 대상 식별자 (MessagingPublicSurfaceContractTest · GrpcSerializedStreamWriter), 사건 자체가 두 사실의 대조인 경우(문서 X · 코드 Y), 열거가 실질인 경우에서 온다.

9. 최종 검증 (fresh)

항목 결과
records 총수 949 (CASE 402 · CONCEPT 386 · REFERENCE 105 · QUESTION 31 · DECISION 25)
record hash mismatch 0
body hash mismatch 0
diagram svg hash mismatch 0
raw evidence hash mismatch 0
line count mismatch 0
invalid source reference 0
repeated main-record prose 0
unittest discover -s tools/tests Ran 80 tests — OK
verify_pipeline.py /shared PASS (required paths 67 · upstream document metadata matches files)
audit_korean_tech_writing.py (5개 디렉터리 1,737 파일) findings 60 — 전부 LONG_TITLE
audit_corpus_structure.py concept bodies 386 · records 386 · findings 0
audit_corpus_structure.py case bodies 402 · records 402 · findings 0
audit_corpus_structure.py reference / openquestion / decision records 105 / 31 / 25 · findings 0
validate_svg.py assets/svg --kind diagram PASS (181개)
validate_svg.py assets/terminal --kind terminal PASS (788개)
validate_source_references.py (신규) findings 0
crossScope metadata 실제 파일과 일치

남은 editorial warning 은 CASE LONG_TITLE 60건뿐이며, §8 의 판정대로 유지한다.