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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
43bccd08a8
commit
b2963105a8
@@ -0,0 +1,65 @@
|
||||
# 사람이 읽고 정해야 남는 것
|
||||
|
||||
자료가 뒷받침하는 것은 다 채웠다. 아래는 자료에 없어서 쓰면 지어내는 것이 된다.
|
||||
하나를 끝내면 이 파일에서 지운다.
|
||||
|
||||
## 관계가 비어 있다
|
||||
|
||||
`root-tree.md` 는 949개 노드 중 374개에만 관계를 적었다. 나머지 575개 중 204개는 트리가
|
||||
적은 규칙 — 「근거 사건은 같은 `source` 의 finding 이 소유한다」 — 으로 채웠다. 남은 것은
|
||||
같은 분석 리프에 짝이 될 기록이 없는 경우다.
|
||||
|
||||
Studio 는 Decision 만 관계를 필수로 요구한다. 비어도 게시된다. 다만 관계 없는 기록은 다른
|
||||
기록에서 도달할 수 없다.
|
||||
|
||||
- case 125건
|
||||
- concept 239건
|
||||
- reference 5건
|
||||
- question 2건
|
||||
|
||||
## Question 에 가정·제약이 없다
|
||||
|
||||
이 칸은 확인하지 않고 전제한 것을 적는 자리다. 원본이 적지 않았으므로 지어내지 않는다.
|
||||
그 질문을 다시 읽고 무엇을 전제했는지 정해야 채워진다.
|
||||
|
||||
- 가정 없음 14건
|
||||
- tech-log-studio/contract-domain-and-bounds/question/openquestion-messaging-claim-check-f05.md
|
||||
- tech-log-studio/declaration-and-document-drift/question/openquestion-messaging-inbox-jdbc-postgresql-f04.md
|
||||
- tech-log-studio/drift-direction/question/openquestion-widen-doc-contract-assertions.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-core-api-f01.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-core-api-f03.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-kafka-share-experimental-f03.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-policy-f02.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-reliability-api-f03.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-schema-json-f03.md
|
||||
- tech-log-studio/schema-and-data-contracts/question/openquestion-messaging-cloudevents-f04.md
|
||||
- tech-log-studio/schema-and-data-contracts/question/openquestion-messaging-schema-protobuf-f03.md
|
||||
- tech-log-studio/security-policy-enforcement/question/openquestion-messaging-security-f03.md
|
||||
- tech-log-studio/transport-and-provider-semantics/question/openquestion-messaging-observability-f03.md
|
||||
- tech-log-studio/transport-and-provider-semantics/question/openquestion-messaging-spring-cloud-stream-bridge-f02.md
|
||||
- 제약 없음 14건
|
||||
- tech-log-studio/contract-domain-and-bounds/question/openquestion-messaging-claim-check-f05.md
|
||||
- tech-log-studio/declaration-and-document-drift/question/openquestion-messaging-inbox-jdbc-postgresql-f04.md
|
||||
- tech-log-studio/drift-direction/question/openquestion-widen-doc-contract-assertions.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-core-api-f01.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-core-api-f03.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-kafka-share-experimental-f03.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-policy-f02.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-reliability-api-f03.md
|
||||
- tech-log-studio/runtime-reachability-and-composition/question/openquestion-messaging-schema-json-f03.md
|
||||
- tech-log-studio/schema-and-data-contracts/question/openquestion-messaging-cloudevents-f04.md
|
||||
- tech-log-studio/schema-and-data-contracts/question/openquestion-messaging-schema-protobuf-f03.md
|
||||
- tech-log-studio/security-policy-enforcement/question/openquestion-messaging-security-f03.md
|
||||
- tech-log-studio/transport-and-provider-semantics/question/openquestion-messaging-observability-f03.md
|
||||
- tech-log-studio/transport-and-provider-semantics/question/openquestion-messaging-spring-cloud-stream-bridge-f02.md
|
||||
- 선택지 없음 1건
|
||||
- tech-log-studio/drift-direction/question/openquestion-widen-doc-contract-assertions.md
|
||||
|
||||
## 평문 칸에 백틱이 있다
|
||||
|
||||
본문을 뺀 모든 칸은 평문이라 백틱이 글자 그대로 보인다. 368개 칸이 그렇다. 지우면 되지만
|
||||
식별자를 어떻게 드러낼지는 칸마다 다르므로 한 번에 훑고 정한다.
|
||||
|
||||
```bash
|
||||
grep -rn '^## \(문제\|결론\|검증 환경\|재현 조건\|목적\|규칙\)' -A5 tech-log-studio/*/*/*.md | grep '`'
|
||||
```
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
[
|
||||
{
|
||||
"code": "LOW_HEADING_SIGNATURE_DIVERSITY",
|
||||
"severity": "warning",
|
||||
"message": "본문 402개가 heading signature 12종만 사용함(3.0%). 고정 목차 template 반복 여부를 검토한다.",
|
||||
"examples": [
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a-red-test-misread-as-a-product-defect.body.md",
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a-build-gate-that-is-not-in-the-build.body.md",
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a-release-gate-with-no-evidence-producer.body.md"
|
||||
]
|
||||
}
|
||||
]
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
[
|
||||
{
|
||||
"code": "LOW_HEADING_SIGNATURE_DIVERSITY",
|
||||
"severity": "warning",
|
||||
"message": "본문 386개가 heading signature 18종만 사용함(4.7%). 고정 목차 template 반복 여부를 검토한다.",
|
||||
"examples": [
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-inbound-graphql-c09.body.md",
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-inbound-graphql-c07.body.md",
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-inbound-graphql-c03.body.md"
|
||||
]
|
||||
}
|
||||
]
|
||||
+610
@@ -0,0 +1,610 @@
|
||||
{
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-fileserver-c01.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 63자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-fileserver-c05.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 67자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-httpclient-c09.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 56자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c03.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 58자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c04.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c05.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c12.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 72자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c16.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 56자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c19.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c25.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 62자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c26.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 62자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c27.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 74자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c28.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 58자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c29.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c30.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 65자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c31.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 76자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c35.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 76자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c36.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 66자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c37.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 81자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c47.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c51.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 73자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-persistence-jpa-c53.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 62자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-support-c02.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 56자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-adapter-outbound-support-c04.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 72자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-application-core-c03.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 64자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-application-core-c06.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 60자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-application-core-c08.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 70자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-application-core-c09.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/concept/concept-messaging-policy-c07.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a-five-second-string-that-broke-every-prod-deploy.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 58자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a01-f002-idfactory-newid.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 60자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f004-retrydecision-reason.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 60자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f005-jparetrypolicy.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f006-stable.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 68자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f007-transactionprofileregistry.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 69자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f013-specificationpolicy-specification-unrestricted.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 64자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f014-collection-fetch-pagination.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 66자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f022-stable.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 63자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f025-filequotaservice-commit.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 58자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f027-maximum-attempts.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 70자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f029-for-update-skip-locked.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 65자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a05-f033-jpa-flyway-migration.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 69자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a06-f016-flamingock.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 58자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a06-f018-changestreams-false.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 58자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a14-f005-publicpaths-restrictedpathrule.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 56자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-a17-f002-stomp.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a03-f001.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a04-f002.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 73자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a04-f004.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a05-f024.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 58자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a05-f028.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 61자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a05-f030.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 72자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a05-f031.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 61자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a05-f034.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 69자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a06-f002.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a06-f008.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 62자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a06-f027.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 66자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a16-f001.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 56자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-analysis-finding-a19-f013.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 62자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-autoconfiguration-in-name-only.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 61자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-conditionalonbean-evaluated-at-parse-time.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-grpc-proto-contract-f01.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-messaging-inbox-jdbc-postgresql-f01.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-messaging-kafka-f01.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 69자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-messaging-nats-experimental-f01.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 65자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-messaging-nats-experimental-f03.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 72자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-messaging-rabbit-f04.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 58자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-messaging-reliability-api-f08.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 61자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-messaging-spring-boot-starter-f02.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-readme-said-no-beans-there-are-eight.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 60자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-the-public-surface-contract-test-lives-outside-the-family.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/case/case-trust-policy-lives-in-nginx-not-in-the-code.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 12,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/openquestion/openquestion-a05-f003-capabilitysupport-constraints.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 56자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/openquestion/openquestion-analysis-finding-a02-f003.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 59자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/openquestion/openquestion-analysis-finding-a02-f005.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 67자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
],
|
||||
"/shared/Tech-Log-Document/clean-architecture-backend-template/openquestion/openquestion-analysis-finding-a04-f006.md": [
|
||||
{
|
||||
"code": "LONG_TITLE",
|
||||
"severity": "info",
|
||||
"line": 13,
|
||||
"message": "제목이 57자임; 사건/메커니즘 이름으로 줄일 수 있는지 검토"
|
||||
}
|
||||
]
|
||||
}
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"project": "clean-architecture-backend-template",
|
||||
"reviewedAt": "2026-09-01T15:43:48Z",
|
||||
"note": "검토를 마치고 유지하기로 한 editorial finding 의 원장이다. 감사 도구는 여기 있는 항목을 ACCEPTED 로, 없는 항목을 UNREVIEWED 로 보고한다. 제목이 바뀌면 titleSha256 이 어긋나 그 항목은 다시 UNREVIEWED 가 된다 — 한 번 승인했다고 영원히 넘어가지 않는다. 제목을 다시 써서 60자 아래로 내려간 항목은 가리킬 발견이 없으므로 여기서 지운다 — 낡은 항목은 tools/editorial_quality/detect_stale_exceptions.py 가 찾는다.",
|
||||
"criteria": {
|
||||
"PROTECTED_IDENTIFIER": "길이가 보호 대상 식별자(코드 심볼 · 설정 키 · SQL 구문 · 고유명)에서 온다",
|
||||
"PAIRED_CONTRAST": "사건 자체가 두 사실의 대비이고, 한쪽을 빼면 사건이 사라진다",
|
||||
"ENUMERATION_IS_THE_EVENT": "열거된 항목 자체가 관측의 실질이다",
|
||||
"TECHNICAL_QUALIFIER": "수치나 위치 같은 기술적 한정어가 결함의 규모·범위를 정한다"
|
||||
},
|
||||
"exceptions": {
|
||||
"LONG_TITLE": {
|
||||
"a-digest-that-covered-who-but-not-what": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "덮은 것과 덮지 않은 것의 대비가 digest 결함의 정의다.",
|
||||
"path": "case/case-a-digest-that-covered-who-but-not-what.md",
|
||||
"title": "transition digest가 \"누가·언제\"만 덮고 \"무엇\"을 덮지 않아 다른 전이를 같다고 보고했다",
|
||||
"titleSha256": "b3fc797d1c1ba2153d91cef24a0b120b215f9caf2e85976967196d585a711629"
|
||||
},
|
||||
"a-five-second-string-that-broke-every-prod-deploy": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PROTECTED_IDENTIFIER",
|
||||
"reason": "connection-timeout: 5s 는 설정 키와 값 그대로다. 그 문자열이 사건의 원인이다.",
|
||||
"path": "case/case-a-five-second-string-that-broke-every-prod-deploy.md",
|
||||
"title": "connection-timeout: 5s가 모든 prod 배포를 시작 실패시켰고 local만 통과했다",
|
||||
"titleSha256": "b3e9857acb4647200bc420b861507cf22389bf9b05b5eed35a905afe15ef6e54"
|
||||
},
|
||||
"a16-f004-graphqloperationnamepolicy": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "배선된 쪽과 미배선 쪽 중 정책 타입을 쓰는 것이 미배선 쪽이라는 역전이 사건이다.",
|
||||
"path": "case/case-a16-f004-graphqloperationnamepolicy.md",
|
||||
"title": "연산 이름 정책의 두 구현 중 하나만 배선되고, 미배선 쪽만 GraphQlOperationNamePolicy를 쓴다",
|
||||
"titleSha256": "d72780971c6a7742d779b1b6df1600edd6ee83b8c14f4059b987a983bd8175c3"
|
||||
},
|
||||
"a17-f002-stomp": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "ENUMERATION_IS_THE_EVENT",
|
||||
"reason": "연결 티켓·origin 정책·메시지 권한·연결 예산 네 통제의 열거가 실질이고, 뒤 절이 그중 일부의 예외를 정한다.",
|
||||
"path": "case/case-a17-f002-stomp.md",
|
||||
"title": "연결 티켓·origin 정책·메시지 권한·연결 예산이 요청 경로 밖이고, 그중 일부는 STOMP 어댑터가 다른 방식으로 대체한다",
|
||||
"titleSha256": "19246d62702500370586a97fd1bb90dce46e5c277ee3498773f1433e3233c5f7"
|
||||
},
|
||||
"a19-f003-messaging-reliability-api": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "TECHNICAL_QUALIFIER",
|
||||
"reason": "main 13파일 · 817 LOC · 테스트 0개 라는 세 수치의 비율이 관측 자체다. 수치를 빼면 남는 것이 없다.",
|
||||
"path": "case/case-a19-f003-messaging-reliability-api.md",
|
||||
"title": "messaging-reliability-api는 main 13파일 · 817 LOC에 테스트가 0개다",
|
||||
"titleSha256": "d94de5ec6f540c39653aa918da71f98fe4975b8609140889143911fb76f4ff50"
|
||||
},
|
||||
"analysis-finding-a06-f027": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "실제로 차단하는 것과 없는 것의 대비가 검증 지형 관측 자체다.",
|
||||
"path": "case/case-analysis-finding-a06-f027.md",
|
||||
"title": "release gate가 실제로 차단하는 것은 hermetic test 3개이고, mongo용 CI workflow는 없다",
|
||||
"titleSha256": "1e576f89ecf30db51c9b63a612d7fc3588fd631531fbcc5362818874fb7463f7"
|
||||
},
|
||||
"analysis-finding-a08-f004": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "경로 기반이라는 것과 그것을 지키는 사전검사가 스스로 근사라고 적었다는 인용의 대비다.",
|
||||
"path": "case/case-analysis-finding-a08-f004.md",
|
||||
"title": "발행 rename만 경로 기반이고, 그것을 지키는 것은 이 모듈이 \"근사에 불과하다\"고 적은 사전검사다",
|
||||
"titleSha256": "ed49f9e7783938fc6810385172713197c4c3aa4f51405125e2fa5346dca44f32"
|
||||
},
|
||||
"analysis-finding-a13-f010": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "FCM 만 규칙 밖이라는 것과 그 FCM 이 두 계약 집합 어디에도 없다는 것이 함께여야 사각지대가 성립한다.",
|
||||
"path": "case/case-analysis-finding-a13-f010.md",
|
||||
"title": "FCM만 \"커밋 후 응답 손실 = ambiguous\" 규칙 밖에 있고, 그 FCM이 두 계약 집합 어디에도 없다",
|
||||
"titleSha256": "4b12e9c90a97c8df82f6ccc5fa6336cabf14618675e78b1e187d94ca18cf0eac"
|
||||
},
|
||||
"analysis-finding-a16-f001": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "ENUMERATION_IS_THE_EVENT",
|
||||
"reason": "스키마 조립·계약 정체성·해시 사슬 셋이 통째로 미배선이라는 열거가 규모를 정하고, 액추에이터 엔드포인트가 네 번째다.",
|
||||
"path": "case/case-analysis-finding-a16-f001.md",
|
||||
"title": "스키마 조립·계약 정체성·해시 사슬이 통째로 미배선이고, 그것을 발행할 액추에이터 엔드포인트도 등록되지 않는다",
|
||||
"titleSha256": "e5f6e1f12deaa7f333a81801998a0ed09245ce00dbfaac04b4b7e76249456d58"
|
||||
},
|
||||
"autoconfiguration-in-name-only": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "TECHNICAL_QUALIFIER",
|
||||
"reason": "세 클래스라는 수와 capability 리포트에 Stable 로 올랐다는 결과가 사건의 두 축이다.",
|
||||
"path": "case/case-autoconfiguration-in-name-only.md",
|
||||
"title": "이름만 AutoConfiguration이던 세 클래스가 capability 리포트에 Stable로 올라 있었다",
|
||||
"titleSha256": "fed765b2bcafabffa436bbb66b658d38be4889bf0a29428fe3ce577666a01a42"
|
||||
},
|
||||
"conditionalonbean-evaluated-at-parse-time": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PROTECTED_IDENTIFIER",
|
||||
"reason": "@ConditionalOnBean(DataSource.class) 는 애너테이션 표기 그대로가 원인이다. 인자 타입까지가 조건이다.",
|
||||
"path": "case/case-conditionalonbean-evaluated-at-parse-time.md",
|
||||
"title": "@ConditionalOnBean(DataSource.class)가 클래스 파싱 시점에 평가되어 여덟 빈이 사라졌다",
|
||||
"titleSha256": "2f89d628a8e05f3943701661fc17a44b77d6b2a131943fb5a11a5927b7ece67e"
|
||||
},
|
||||
"grpc-proto-contract-f01": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PROTECTED_IDENTIFIER",
|
||||
"reason": "reserved 2 to 5; 는 오탐을 만드는 원문 구문이고 RESERVED_HISTORY 는 위반 코드다. 둘 다 그대로여야 재현된다.",
|
||||
"path": "case/case-grpc-proto-contract-f01.md",
|
||||
"title": "reserved 2 to 5; 범위가 개별 숫자로만 수집되어 RESERVED_HISTORY 오탐이 된다",
|
||||
"titleSha256": "ddb7fe8063fa09028571f1a8647c86b29e73bfc042bcabfaf7c013e4c6d6a2f0"
|
||||
},
|
||||
"messaging-inbox-jdbc-postgresql-f01": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "구현돼 있다는 것과 호출되지 않는다는 것의 대비이고, 뒤 절이 그 결과다.",
|
||||
"path": "case/case-messaging-inbox-jdbc-postgresql-f01.md",
|
||||
"title": "bounded purge가 구현돼 있고 호출되지 않아, cleanup이 스스로 막겠다고 한 장애를 일으킨다",
|
||||
"titleSha256": "11e1b5262a9f7739bdd6872a67886b4874d00c121ee2d004d71ae40408d303ab"
|
||||
},
|
||||
"messaging-nats-experimental-f01": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "무조건 참인 선언과 창이 있을 때만 일어나는 실제 동작의 대비다. 조건절을 빼면 결함이 성립하지 않는다.",
|
||||
"path": "case/case-messaging-nats-experimental-f01.md",
|
||||
"title": "deduplicatedPublish 를 무조건 참으로 선언하는데 실제 중복 제거는 프로파일에 창이 있을 때만 일어난다",
|
||||
"titleSha256": "d88fd462e81989a10308e98413fc5c0496662ce130606e4d25a947cbacc397a9"
|
||||
},
|
||||
"messaging-rabbit-f04": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "능력 상수가 참이라는 것과 그 지연을 제공할 토폴로지가 없다는 것의 대비다.",
|
||||
"path": "case/case-messaging-rabbit-f04.md",
|
||||
"title": "능력 상수의 delayedDelivery 가 무조건 참이고, 그 지연을 제공할 토폴로지는 조립되지 않는다",
|
||||
"titleSha256": "2ff213b705421e39147bad47dbcf8b3ed0dc22fa76daa1227fa62787041e7c34"
|
||||
},
|
||||
"messaging-reliability-api-f08": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "두 오버로드를 나란히 노출한다는 것과 호출자가 무제한 쪽을 골랐다는 것이 원인과 결과다.",
|
||||
"path": "case/case-messaging-reliability-api-f08.md",
|
||||
"title": "포트가 bounded/unbounded purge 두 오버로드를 나란히 노출하고, 호출자가 무제한 쪽을 고른다",
|
||||
"titleSha256": "d569175440aa856b591bd4e607f2830320fe877691c9dfc2660888afd53f4af7"
|
||||
},
|
||||
"messaging-spring-boot-starter-f02": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "아무도 공급하지 않는 빈 뒤에 있다는 것과 사슬이 자기 클래스 안을 가리킨다는 것이 함께여야 자기참조 구조가 드러난다.",
|
||||
"path": "case/case-messaging-spring-boot-starter-f02.md",
|
||||
"title": "출고되는 신뢰성 체인 전체가 아무도 공급하지 않는 빈 뒤에 있고, 그 사슬이 자기 클래스 안을 가리킨다",
|
||||
"titleSha256": "3c751db7f8344dd35c7f13610b20a384e88e53c6b1d7eab162787773ca881192"
|
||||
},
|
||||
"readme-said-no-beans-there-are-eight": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "README 인용과 실제 bean 여덟이 대비 자체다. 한쪽만 남기면 사건이 사라진다.",
|
||||
"path": "case/case-readme-said-no-beans-there-are-eight.md",
|
||||
"title": "README가 \"노출된 setting도 bean도 없다\"고 적은 능력에 production bean 여덟이 있다",
|
||||
"titleSha256": "c1f78904149820c311d1b1882827d808eb0e282e305606062f69dd5f93710f00"
|
||||
},
|
||||
"the-public-surface-contract-test-lives-outside-the-family": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PROTECTED_IDENTIFIER",
|
||||
"reason": "MessagingPublicSurfaceContractTest 한 이름이 제목의 절반이고, app-bootstrap 이 실제 소재다.",
|
||||
"path": "case/case-the-public-surface-contract-test-lives-outside-the-family.md",
|
||||
"title": "MessagingPublicSurfaceContractTest가 가족 밖(app-bootstrap)에 있다",
|
||||
"titleSha256": "fcf1375b7b32bea7173dcb0ab7d9e407e0c8a58cef56a12575dedaad420828d1"
|
||||
},
|
||||
"the-transport-and-the-validator-answer-differently": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "PAIRED_CONTRAST",
|
||||
"reason": "두 쪽이 다르게 답한다는 것과 런타임이 쓰는 쪽이 틀렸다는 것이 함께 있어야 심각도가 정해진다.",
|
||||
"path": "case/case-the-transport-and-the-validator-answer-differently.md",
|
||||
"title": "같은 어댑터의 능력을 전송과 검증기가 다르게 답하고, 런타임이 쓰는 쪽이 record 의 의미와 어긋난다",
|
||||
"titleSha256": "092faa5727dcae07b8486a17ddb1f6ff64c1141f33fedac9085641bd3e0edb74"
|
||||
},
|
||||
"trust-policy-lives-in-nginx-not-in-the-code": {
|
||||
"status": "ACCEPTED",
|
||||
"category": "TECHNICAL_QUALIFIER",
|
||||
"reason": "421 LOC 이 배선되지 않은 정책의 규모이고, Nginx 라는 실제 판정 위치가 대비의 반대쪽이다.",
|
||||
"path": "case/case-trust-policy-lives-in-nginx-not-in-the-code.md",
|
||||
"title": "forwarded 헤더 신뢰 판정이 Nginx에만 있고 Java 정책 421 LOC은 배선되지 않았다",
|
||||
"titleSha256": "1d2ef0398997a68c91b2712b2a55af15b2cf2a25f5720e6cfdbc01e092950a14"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
# Editorial / Visual Quality Audit — 2026-09-01 (초기 스냅숏)
|
||||
|
||||
:::warning
|
||||
|
||||
**상태: HISTORICAL_SNAPSHOT**
|
||||
|
||||
기준 시점: semantic editorial pass **이전**. 이 문서는 현재 완료 상태를 나타내지 않는다.
|
||||
|
||||
아래의 `lastEditorialAt: None` · `EDITORIAL_PENDING` · Concept signature 18종 ·
|
||||
Case signature 12종 · diagram 217 · LONG_TITLE 76 은 전부 그 시점의 값이고 지금은 다르다.
|
||||
숫자를 덮어쓰지 않고 그대로 둔다 — 어디서 출발했는지가 이 문서의 쓸모다.
|
||||
|
||||
현재 상태의 정본은 두 곳이다.
|
||||
|
||||
- `_meta/editorial/final-editorial-validation-2026-09-01.md` — 최종 검증 결과
|
||||
- `_meta/editorial/semantic-pass-progress.md` 의 `Correction pass` 절 — 무엇을 왜 고쳤는지
|
||||
|
||||
:::
|
||||
|
||||
## 상태
|
||||
|
||||
- technical records: **949** — CASE 402 · CONCEPT 386 · REFERENCE 105 · OPEN QUESTION 31 · DECISION 25
|
||||
- rich body: **788** — Concept 386 · Case 402
|
||||
- `lastEditorialAt`: `None`
|
||||
- `lastValidationAt`: `None`
|
||||
- 판정: **EDITORIAL_PENDING**. 생성 완료와 편집 완료를 같은 상태로 보지 않는다.
|
||||
|
||||
## 이번에 즉시 수정한 것
|
||||
|
||||
- terminal evidence 788개를 raw evidence hash 확인 후 새 renderer로 재생성했다. 긴 줄은 `<tspan>`으로 시각적 wrap하며 raw 문자는 바꾸지 않는다.
|
||||
- explanatory SVG 217개와 terminal SVG 788개는 새 SVG validator를 통과했다.
|
||||
- Concept의 고정 첫 절 `무엇을 해결하는가` 383개를 제거했다.
|
||||
- Case의 고정 첫 절 `무엇이 일어났나` 402개를 제거했다.
|
||||
- Concept main record의 중복 `무엇을 해결하는가` 357개를 제거했다.
|
||||
- provenance/asset 설명 boilerplate 1,656개를 body에서 제거했다. 이 정보는 asset/meta와 source provenance가 소유한다.
|
||||
- 분석자 경험처럼 보이던 `처음에는 … 의심했다/후보로 봤다` Concept 3개를 source anchor를 다시 읽고 객관적인 메커니즘 서술로 교정했다.
|
||||
|
||||
## 개별 문서 audit
|
||||
|
||||
- flagged artifacts: **76**
|
||||
- warning: **0**
|
||||
- info: **76**
|
||||
- code counts: `{'LONG_TITLE': 76}`
|
||||
|
||||
현재 warning은 0이다. `LONG_TITLE`은 자동 수정 대상이 아니라 편집 검토 신호다.
|
||||
|
||||
## corpus 구조 audit
|
||||
|
||||
### Concept
|
||||
|
||||
- LOW_HEADING_SIGNATURE_DIVERSITY: 본문 386개가 heading signature 18종만 사용함(4.7%). 고정 목차 template 반복 여부를 검토한다.
|
||||
|
||||
### Case
|
||||
|
||||
- LOW_HEADING_SIGNATURE_DIVERSITY: 본문 402개가 heading signature 12종만 사용함(3.0%). 고정 목차 template 반복 여부를 검토한다.
|
||||
|
||||
고정 첫 절과 반복 boilerplate는 제거했지만, 전체 목차 signature가 Concept 18종 / Case 12종에 집중되어 있다. 이 문제는 제목을 기계적으로 바꾸는 방식으로 해결하지 않는다. 다음 editorial pass에서 각 문서의 실제 메커니즘·사건을 읽고 내용 기반 절 이름으로 재구성한다.
|
||||
|
||||
## visual audit
|
||||
|
||||
- explanatory diagrams: 217
|
||||
- terminal evidence SVG: 788
|
||||
- XML/viewBox/title/desc/role/script/external-reference/text-overflow validator: **PASS**
|
||||
- explanatory diagram layout signatures: **10종**
|
||||
- most common signatures: [(('880', '276', 4, 4, 2, 1), 80), (('880', '366', 4, 4, 3, 1), 56), (('880', '186', 4, 4, 1, 1), 28), (('880', '276', 5, 5, 2, 1), 18), (('880', '186', 3, 3, 1, 1), 16)]
|
||||
|
||||
기계적 SVG 결함은 현재 막혔다. 다만 217개 다이어그램의 layout signature가 10종에 집중된 것은 시각 편집 문제다. 앞으로는 `designing-tech-log-visuals` Skill에서 boundary/sequence/state/data-flow/failure/before-after 중 논지에 맞는 visual grammar를 먼저 고르고, 그림 quota를 두지 않는다.
|
||||
|
||||
## 완료 조건
|
||||
|
||||
`lastEditorialAt`은 아직 채우지 않는다. 다음 단계에서 Concept/Case body를 topic/module 단위로 읽으면서 낮은 heading-signature 다양성을 해소하고, 76개 긴 제목 후보를 실제 문맥 기준으로 검토한 뒤 corpus audit를 다시 실행한다. 단순 정규식 치환으로 PASS를 만들지 않는다.
|
||||
|
||||
## state integrity
|
||||
|
||||
- record/body hash 또는 line mismatch: **0**
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
# Final Editorial Validation — 2026-09-01
|
||||
|
||||
**상태: COMPLETE.** 이 문서가 `clean-architecture-backend-template` Tech Log 의 편집 완료 상태를
|
||||
나타내는 정본이다. 다른 editorial artifact 는 전부 이 문서를 가리킨다.
|
||||
|
||||
검증 시각 `2026-09-01T15:48:45Z`. `_meta/state.json` 의 `lastEditorialAt` ·
|
||||
`lastValidationAt` 과 같은 값이다.
|
||||
|
||||
같은 디렉터리의 다른 문서와의 관계는 이렇다.
|
||||
|
||||
| 문서 | 성격 |
|
||||
|---|---|
|
||||
| `editorial-visual-audit-2026-09-01.md` | pass **이전**의 초기 audit. `HISTORICAL_SNAPSHOT` |
|
||||
| `editorial-audit-2026-09-01.json` | 같은 시점의 도구 원본 출력(LONG_TITLE 76). 가공하지 않는다 |
|
||||
| `concept-structure-audit-2026-09-01.json` · `case-structure-audit-2026-09-01.json` | 같은 시점의 구조 audit 원본(signature 18종 · 12종) |
|
||||
| `semantic-pass-progress.md` | 작업 로그. 앞부분은 진행 중 스냅숏, 하단 `Correction pass` 가 정본 |
|
||||
| `svg-semantic-review-2026-09-01.md` | 33개 후보의 시각 semantic 검토 판정 |
|
||||
| `editorial-exceptions.json` | 검토를 마치고 유지하기로 한 finding 의 원장 |
|
||||
| **이 문서** | **최종 검증 수치** |
|
||||
|
||||
세 `.json` 은 도구가 그대로 뱉은 출력이라 안에 표시를 넣지 않는다 — 넣으면 더 이상 도구
|
||||
출력이 아니다. 어느 세대인지는 파일명의 날짜와 이 표가 말한다.
|
||||
|
||||
---
|
||||
|
||||
## Corpus
|
||||
|
||||
```text
|
||||
records = 949
|
||||
|
||||
CASE = 402
|
||||
CONCEPT = 386
|
||||
REFERENCE = 105
|
||||
OPEN QUESTION = 31
|
||||
DECISION = 25
|
||||
|
||||
rich body = 788 (CONCEPT 386 · CASE 402)
|
||||
```
|
||||
|
||||
## Editorial
|
||||
|
||||
```text
|
||||
corpus structural findings = 0
|
||||
concept bodies=386 records=386 findings=0
|
||||
case bodies=402 records=402 findings=0
|
||||
reference / openquestion / decision records=105 / 31 / 25 findings=0
|
||||
|
||||
main-record repeated explanatory prose = 0
|
||||
|
||||
LONG_TITLE candidates = 60
|
||||
reviewed = 60
|
||||
accepted = 60
|
||||
unreviewed = 0
|
||||
stale exceptions = 0
|
||||
```
|
||||
|
||||
LONG_TITLE 60건은 미해결 finding 이 아니다. `editorial-exceptions.json` 이 60건 각각에 대해
|
||||
승인 사유를 기록한다.
|
||||
|
||||
| category | 수 | 뜻 |
|
||||
|---|---:|---|
|
||||
| `PROTECTED_IDENTIFIER` | 36 | 길이가 코드 심볼 · 설정 키 · SQL 구문 · 고유명에서 온다 |
|
||||
| `PAIRED_CONTRAST` | 17 | 사건 자체가 두 사실의 대비다 |
|
||||
| `TECHNICAL_QUALIFIER` | 4 | 수치나 위치가 결함의 규모를 정한다 |
|
||||
| `ENUMERATION_IS_THE_EVENT` | 3 | 열거된 항목 자체가 관측의 실질이다 |
|
||||
|
||||
승인은 영구 침묵이 아니다. 각 항목이 승인 당시 제목의 `titleSha256` 을 들고 있어서, 제목이
|
||||
바뀌면 그 항목은 다시 `UNREVIEWED` 가 된다. 승인한 finding 이 더 이상 나오지 않으면
|
||||
`STALE_EXCEPTION` 으로 보고된다. 새 기록이 55자를 넘는 제목을 갖고 원장에 없으면 그대로
|
||||
`UNREVIEWED` 로 나타난다.
|
||||
|
||||
## References
|
||||
|
||||
```text
|
||||
source/evidence files checked = 1737
|
||||
invalid references = 0
|
||||
```
|
||||
|
||||
## Visual
|
||||
|
||||
```text
|
||||
explanatory SVG = 181
|
||||
terminal SVG = 788
|
||||
|
||||
mechanical validation = PASS (diagram · terminal)
|
||||
|
||||
semantic negative-edge candidates reviewed = 33
|
||||
redesigned = 3
|
||||
accepted = 30
|
||||
|
||||
coordinate precision violation = 0
|
||||
```
|
||||
|
||||
## Integrity
|
||||
|
||||
```text
|
||||
record hash mismatch = 0
|
||||
body hash mismatch = 0
|
||||
diagram svg hash mismatch = 0
|
||||
raw evidence hash mismatch = 0
|
||||
line count mismatch = 0
|
||||
```
|
||||
|
||||
## Upstream
|
||||
|
||||
```text
|
||||
crossScopeAnalysis sha state 538e4e72cf033a9e262d5bbccd4914ccb4f2aea405432efd034b719c64cd25ff
|
||||
crossScopeAnalysis sha file 538e4e72cf033a9e262d5bbccd4914ccb4f2aea405432efd034b719c64cd25ff
|
||||
crossScopeAnalysis lines state 552 file 552
|
||||
→ MATCH
|
||||
```
|
||||
|
||||
`verify_pipeline.py` 가 매 실행마다 이 대조를 수행한다 (`upstream document metadata: matches files`).
|
||||
|
||||
## Tests
|
||||
|
||||
```text
|
||||
PYTHONPATH=tools python3 -m unittest discover -s tools/tests
|
||||
Ran 98 tests
|
||||
OK
|
||||
|
||||
python3 tools/verify_pipeline.py /shared
|
||||
PIPELINE VERIFICATION: PASS
|
||||
- required paths: 67
|
||||
- analysis queue contract: valid
|
||||
- root-tree contract: present
|
||||
- upstream document metadata: matches files
|
||||
- forbidden legacy dependency: absent
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 완료 판정 명령
|
||||
|
||||
이 상태를 재확인하는 한 줄은 다음이다. `--fail-on-unreviewed` 가 붙어야 완료 판정이 된다 —
|
||||
`findings == 0` 이 아니라 `unreviewed == 0` 이 조건이기 때문이다.
|
||||
|
||||
```bash
|
||||
python3 tools/editorial_quality/audit_korean_tech_writing.py \
|
||||
clean-architecture-backend-template/concept \
|
||||
clean-architecture-backend-template/case \
|
||||
clean-architecture-backend-template/reference \
|
||||
clean-architecture-backend-template/openquestion \
|
||||
clean-architecture-backend-template/decision \
|
||||
--exceptions clean-architecture-backend-template/_meta/editorial/editorial-exceptions.json \
|
||||
--fail-on-unreviewed
|
||||
```
|
||||
|
||||
## state 의 완료 의미
|
||||
|
||||
`_meta/state.json` 의 `lastEditorialAt` · `lastValidationAt` 은 "편집 pass 가 끝났고 그 시점에
|
||||
검증이 돌았다" 를 뜻하며, 그 날짜의 closure artifact 가 결과를 소유한다.
|
||||
|
||||
`editorialStatus` 같은 상태 필드는 **추가하지 않았다.** `_templates/project/_meta/state.json` 이
|
||||
이 상태의 계약이고, 필드를 하나 추가하면 그 템플릿과 그것으로 만들어질 모든 프로젝트의 계약이
|
||||
바뀐다. 이번 closure 가 요구하는 범위를 넘는다. 완료 여부는 이 문서와 위 명령의 exit code 로
|
||||
읽는다. 이 규칙은 `humanizing-korean-tech-writing` Skill 의
|
||||
`Audit artifacts have generations; say which one is current` 절에 적혀 있다.
|
||||
+1607
File diff suppressed because it is too large
Load Diff
+319
@@ -0,0 +1,319 @@
|
||||
# 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-f003` → `legacy compatibility surface의 제거 조건을 세 가지로 고정한다`
|
||||
(다른 두 기록의 `## 관계` 가 이미 이 이름으로 이 규칙을 가리키고 있었다. 끊긴 링크가 붙었다)
|
||||
- `a05-f003-capabilitysupport-constraints` → `CapabilitySupport.constraints 의 경계가 타입에 없다`
|
||||
- `analysis-finding-a04-f006` → `cache-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) |
|
||||
|
||||
넷째는 접두사 정정이 아니다. `Approved` 가 `VerifiedApproval` 이 아니라 `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.json` 의 `crossScopeAnalysis` 가 재생성 이전 값을 들고 있었다.
|
||||
|
||||
```
|
||||
sha256 481b3728… → 538e4e72…
|
||||
lines 428 → 552
|
||||
```
|
||||
|
||||
이것을 놓친 이유는 어떤 verifier 도 기록된 수치를 파일과 대조하지 않았기 때문이다.
|
||||
`verify_pipeline.py` 에 `_verify_upstream_document_metadata` 를 추가했다 — state.json 안에서 `path`
|
||||
와 `sha256` 을 함께 가진 모든 블록(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 의 판정대로 유지한다.
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
# SVG semantic review — 2026-09-01
|
||||
|
||||
기계 검증(`validate_svg.py`)은 통과하지만 그림이 기록의 주장과 반대를 말하는지 확인한 회차다.
|
||||
`validate_svg.py` 는 라벨 길이 · 문장형 · 상자 수 · 뷰포트만 본다. **화살표가 무엇을 뜻하는지는
|
||||
보지 않는다.** 그래서 이번 검토는 사람이 했다.
|
||||
|
||||
## 검토 모집단
|
||||
|
||||
`<desc>` 가 부재(없 · 않 · 미배선 · 도달하지 · 연결되지 · 0건 · 존재하지 · 못하 · 빠진 · 비어 ·
|
||||
아니 · 끊)를 말하면서 정상 방향 화살표도 가진 설명용 SVG **33개**. 181개 중 그 조건에 걸리는
|
||||
전부이며, 나머지 148개는 부재를 말하지 않으므로 이 회차의 대상이 아니다.
|
||||
|
||||
33개를 일괄 치환하지 않았다. 각각에 대해 다음 다섯을 대조했다.
|
||||
|
||||
- 기록의 주장(`## 요약` · 본문)
|
||||
- owning SSOT 의 해당 finding
|
||||
- SVG 의 `<desc>`
|
||||
- 보이는 라벨
|
||||
- 화살표의 방향과 도착 지점
|
||||
|
||||
## 판정 기준
|
||||
|
||||
정상 방향 화살표는 **실재하는 호출 · 의존 · 전이 · 데이터 흐름 · 도달성**을 뜻한다. 그래서
|
||||
도착 상자가 빗금이라는 사실만으로 화살표의 뜻이 뒤집히지 않는다. 그림이 결함인 경우는
|
||||
**화살표가 가리키는 관계 자체가 없을 때**다.
|
||||
|
||||
반대로, 들어오는 전이는 실재하고 기록이 말하는 부재가 **나가는** 전이인 경우가 있다. 상태
|
||||
기계의 종착 상태가 그 형태다. 그 경우 빗금 상자로 들어가는 화살표는 정확하다.
|
||||
|
||||
## 결과
|
||||
|
||||
| 판정 | 수 |
|
||||
|---|---:|
|
||||
| 재설계 | 3 |
|
||||
| 유지 — 들어오는 전이는 실재하고 부재는 나가는 쪽 | 3 |
|
||||
| 유지 — 빗금 상자에 화살표가 닿지 않음 | 2 |
|
||||
| 유지 — 빗금 상자가 없고 화살표가 전부 실재 흐름 | 25 |
|
||||
|
||||
## 재설계 3건
|
||||
|
||||
### `adapter-inbound-graphql-c04.svg`
|
||||
|
||||
기록의 주장은 "요청 계층만 배선되고, 네 파생 계층은 메서드로 존재하되 프로덕션 호출자가 0" 이다.
|
||||
기존 그림은 배선된 요청 데드라인에서 네 파생 계층으로 정상 화살표 넷을 그리고 그 위에
|
||||
`파생 없음` 이라는 글자를 얹었다. 화살표가 글자를 이긴다.
|
||||
|
||||
고친 형태는 화살표를 **하나도 그리지 않는다.** 네 계층은 `파생 없음 — 프로덕션 호출자 0` 이라고
|
||||
이름 붙인 별도 영역 안에 놓인다.
|
||||
|
||||
### `adapter-inbound-graphql-c10.svg`
|
||||
|
||||
주장은 "자동설정이 참조하는 두 타입에서 실제로 닿는 패키지는 dataloader 하나이고, fetch ·
|
||||
pagination · mutation 41개 파일은 어떤 배선 경로에도 없다" 이다. 기존 그림은 네 갈래 전부에
|
||||
정상 화살표를 그렸다.
|
||||
|
||||
고친 형태는 `dataloader` 에만 화살표를 두고, 나머지 셋은 `배선 경로 없음 — 화살표 없음` 영역에
|
||||
놓는다.
|
||||
|
||||
### `adapter-inbound-websocket-c01.svg`
|
||||
|
||||
주장은 "설정 접두사 셋 중 `backend.websocket` 만 그것을 읽어 조립하는 `@Configuration` 이 없고,
|
||||
그 접두사가 규정하는 범위가 main 169 파일 중 약 90개로 가장 넓다" 이다. 기존 그림은 세 갈래에
|
||||
모두 정상 화살표를 그려, 접두사가 소비자에 닿는다는 뜻과 닿지 않는다는 뜻이 한 그림 안에서
|
||||
충돌했다.
|
||||
|
||||
고친 형태는 소비자가 있는 두 접두사에만 화살표를 두고, `backend.websocket` 은
|
||||
`읽는 Configuration 없음` 영역에 화살표 없이 놓는다.
|
||||
|
||||
## 유지 3건 — 들어오는 전이는 실재한다
|
||||
|
||||
### `adapter-outbound-objectstorage-c05.svg` · `adapter-outbound-fileserver-c03.svg` 계열
|
||||
|
||||
`<desc>` 가 "그 네 상태에서 **나오는** 전이는 없다" 라고 적는다. 그림의 화살표 넷은 정상 사슬에서
|
||||
그 상태로 **들어가는** 전이이고, 그것은 실재한다. 부재는 반대 방향이며 `<desc>` 가 방향을 밝힌다.
|
||||
정확한 그림이다.
|
||||
|
||||
### `adapter-outbound-persistence-jpa-c51.svg`
|
||||
|
||||
주장은 "Stable persistence unit 의 스캔 문자열 목록에 experimental package 가 **이미 들어 있다**" 이다.
|
||||
화살표는 그 목록이 그 항목을 담는다는 실재하는 포함 관계이고, 빗금은 부재가 아니라
|
||||
바로 아래 라벨이 말하는 `조건 없음` 을 표시한다.
|
||||
|
||||
### `messaging-kafka-c02.svg`
|
||||
|
||||
주장은 "연속 구간만 커밋되고 빈 자리 뒤는 완료돼 있어도 보류된다" 이다. 화살표는 완료 표시 맵이
|
||||
두 구간으로 갈리는 실재하는 분할이고, 빗금 상자는 없는 것이 아니라 `보류` 상태다. 라벨이
|
||||
`빈 자리 뒤 구간 — 보류` 로 그것을 말한다.
|
||||
|
||||
## 유지 2건 — 빗금 상자에 화살표가 닿지 않는다
|
||||
|
||||
`grpc-policy-f02.svg` 와 `messaging-nats-experimental-f01.svg` 는 빗금 상자를 갖지만 어떤 화살표도
|
||||
그 안으로 들어가지 않는다. 이미 이번 회차가 정한 규칙을 지키는 형태다.
|
||||
|
||||
## 유지 25건 — 빗금 상자가 없다
|
||||
|
||||
나머지 25개의 `<desc>` 에 나오는 부정 표현은 부재가 아니라 **규칙이나 순서**를 말한다 —
|
||||
"반대 방향 의존이 없다", "뒤 규칙이 앞 규칙이 금지한 것을 다시 허용할 수 없다",
|
||||
"검증되지 않은 설정을 쓰는 bean 이 생기지 않는다" 같은 형태다. 화살표는 전부 실재하는 흐름이고
|
||||
빗금 상자 자체가 없다.
|
||||
|
||||
## 규칙을 어디에 고정했나
|
||||
|
||||
이 판정 기준을 `designing-tech-log-visuals` 에 명문화했다.
|
||||
|
||||
- `SKILL.md` — hard gate 한 줄
|
||||
- `references/diagram-editorial-rules.md` — "A normal arrow asserts that the relation exists" 절과,
|
||||
부재를 그리는 세 형태(no edge · separated region · 명시적으로 라벨된 broken/crossed edge)
|
||||
- `references/review-checklist.md` — 검토 항목 한 줄
|
||||
- `tools/tests/test_writing_quality_contracts.py` — 위 셋이 실제로 존재하는지 검사하는 테스트
|
||||
|
||||
## 전 파일 분류
|
||||
|
||||
| SVG | 화살표 | 빗금 | 빗금 진입 | 판정 |
|
||||
|---|---:|---:|---:|---|
|
||||
| `adapter-inbound-graphql-c04.svg` | 0 | 4 | 0 | 재설계 |
|
||||
| `adapter-inbound-graphql-c10.svg` | 1 | 3 | 0 | 재설계 |
|
||||
| `adapter-inbound-web-c01.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-inbound-websocket-c01.svg` | 2 | 1 | 0 | 재설계 |
|
||||
| `adapter-outbound-cache-redis-c01.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-cache-redis-c03.svg` | 1 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-cache-redis-c08.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-cache-redis-c12.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-cache-redis-c13.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-fileserver-c03.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-httpclient-c04.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-objectstorage-c05.svg` | 4 | 4 | 4 | 유지 — 들어오는 전이는 실재 |
|
||||
| `adapter-outbound-persistence-jpa-c02.svg` | 1 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-persistence-jpa-c24.svg` | 1 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-persistence-jpa-c26.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-persistence-jpa-c51.svg` | 2 | 1 | 1 | 유지 — 들어오는 전이는 실재 |
|
||||
| `adapter-outbound-persistence-mongo-c03.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `adapter-outbound-support-c02.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `application-core-c01.svg` | 1 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `application-core-c04.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `commit-evidence-phases.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `grpc-advanced-resilience-c01.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `grpc-policy-f02.svg` | 3 | 1 | 0 | 유지 — 빗금 상자에 화살표 없음 |
|
||||
| `messaging-claim-check-c01.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `messaging-inbox-jdbc-postgresql-c06.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `messaging-kafka-c02.svg` | 2 | 1 | 1 | 유지 — 들어오는 전이는 실재 |
|
||||
| `messaging-nats-experimental-f01.svg` | 3 | 1 | 0 | 유지 — 빗금 상자에 화살표 없음 |
|
||||
| `messaging-policy-c03.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `messaging-pulsar-experimental-c01.svg` | 1 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `messaging-rabbit-c01.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `messaging-security-c03.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `messaging-testkit-c04.svg` | 2 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
| `messaging-transport-spi-c03.svg` | 3 | 0 | 0 | 유지 — 빗금 없음, 화살표가 전부 실재 흐름 |
|
||||
|
||||
## 좌표 직렬화
|
||||
|
||||
같은 회차에 정리했다. 설명용 SVG 40개의 좌표 340개가 소수점 둘 이상을 갖고 있었다 —
|
||||
`225.33333333333334` · `440.00000000000006` 같은 형태다. 렌더링은 같지만 생성기가 float repr 을
|
||||
그대로 속성에 넣었다는 뜻이고, 같은 그림의 두 판을 diff 할 때 읽히지 않는다.
|
||||
|
||||
소수점 한 자리로 정규화했다(기하 변화 최대 0.05px). 그리고 규칙을 두 곳에 고정했다 —
|
||||
생성기가 좌표를 직렬화할 때 한 자리로 자르고, `validate_svg.py` 가 `COORDINATE_PRECISION` 으로
|
||||
설명용 SVG 를 검사한다. 터미널 SVG 는 대상이 아니다(원래 정수 좌표만 쓴다).
|
||||
File diff suppressed because it is too large
Load Diff
+65
@@ -0,0 +1,65 @@
|
||||
# Tech Log 초안 리뷰 체크리스트 — cycle 2 재실행
|
||||
|
||||
실행일 : 2026-09-01 (cycle 2 downstream 재생성 후)
|
||||
대상 : clean-architecture-backend-template · 레코드 333건 (CONCEPT 21 · CASE 217 · REFERENCE 53 · QUESTION 17 · DECISION 25)
|
||||
근거 root tree : root-tree.md (노드 334 · 생성 차단 1)
|
||||
소스 리비전 : 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
|
||||
## 이번 실행이 이전 실행과 다른 점
|
||||
|
||||
첫 실행(같은 날, 레코드 326건)에서 유일하게 열려 있던 항목은 upstream 상태였다 —
|
||||
document-detail 이 cycle 2 재분석 중이라 analysisStatus 가 IN_PROGRESS 였고 downstream 셋이 NOT_STARTED 였다.
|
||||
그 항목이 닫혔다.
|
||||
|
||||
## Provenance
|
||||
|
||||
- [x] **upstream 전부 COMPLETE** — analysisStatus COMPLETE · 스코프 61 COMPLETE + 1 EXCLUDED ·
|
||||
crossScopeAnalysis / finalDocument / rootTree 전부 COMPLETE · reanalysis.completedAt 기록됨
|
||||
- [x] 23개 리프가 canonical SSOT 를 갖고 FULL_READ 로 전환됐다. STRUCTURAL_ONLY 잔여 0.
|
||||
- [x] 레코드 333건 전부 root tree 노드에 slug 로 대응. 미대응 0.
|
||||
- [x] readiness READY/OPEN 만 생성. NEEDS_DECISION 노드 1건은 decision-evidence 부재로 차단 유지.
|
||||
- [x] 레코드 sourceRevision 333건 전부 root tree 리비전과 일치.
|
||||
- [x] root tree 노드 334건 전부 source 앵커 보유. 참조 파일 290건 중 결측 0.
|
||||
- [x] 라인 앵커 전부 헤딩 착지. 어긋남 0.
|
||||
|
||||
## Record kind
|
||||
|
||||
- [x] kind ↔ 노드 kind 일치 333/333 · 디렉터리 배치 일치
|
||||
- [x] bodyMarkdown 은 CASE·CONCEPT 만 사용
|
||||
- [x] DECISION 25건 전부 근거 기록 보유 · OPEN QUESTION 17건 전부 미지수와 다음 검증 보유
|
||||
|
||||
## Facts / Body / Relations
|
||||
|
||||
- [x] 비본문 필드의 마크다운 문법 유입 0 · 제목 중복 0
|
||||
- [x] body-syntax 화이트리스트 위반 0
|
||||
- [x] 관계 설명 누락 0 · root tree 끊긴 relations 0
|
||||
|
||||
## downstream 재생성 요약
|
||||
|
||||
| 산출물 | 변경 |
|
||||
|---|---|
|
||||
| `analysis/99-cross-scope.md` | 306 → 428줄. §1.2(전수 통독) 신설 · §3.2·§3.5 확장 · §3.7(전송 계열 가정) 신설 · §4 6~9항 · §6 |
|
||||
| `final/document.md` | 1,680 → 1,765줄. §14.2 신설 · §5.5 확장 · §8.2 9~13항 · 헤더 표 |
|
||||
| `root-tree.md` | 4,097 → 4,174줄. 노드 327 → 334 |
|
||||
| `candidate-ledger.json` | 340/291 → 347/298 |
|
||||
| 레코드 | 326 → 333 |
|
||||
|
||||
## 새로 낸 노드 7건
|
||||
|
||||
| 노드 | Topic |
|
||||
|---|---|
|
||||
| `case:assigned-id-turns-claim-into-upsert` | state-ownership-and-concurrency |
|
||||
| `case:complete-drain-rolls-back-a-rotation` | 〃 |
|
||||
| `case:startup-validator-is-the-only-reader-of-four-keys` | runtime-reachability-and-composition |
|
||||
| `case:validator-declared-and-never-injected` | 〃 |
|
||||
| `reference:a-validator-is-enforced-by-injection` | 〃 |
|
||||
| `case:capability-constant-outlives-its-condition` | transport-and-provider-semantics |
|
||||
| `case:ipv4-only-mask-passes-every-other-form` | security-policy-enforcement |
|
||||
|
||||
통독의 새 finding 52건 중 노드로 낸 것은 7건이다. 나머지는 리프 SSOT §17 에 남는다 —
|
||||
기존 REFERENCE 가 이미 그 규칙을 갖고 있거나(예: `atomic-type-is-not-atomicity`),
|
||||
같은 사건의 다른 인스턴스여서 노드를 늘릴 이유가 없는 경우다.
|
||||
|
||||
## 미결
|
||||
|
||||
없다. 다음 단계는 `humanizing-korean-tech-writing` 편집 패스이며, 체크리스트가 별도 패스로 규정한 것이다.
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
# Tech Log 초안 리뷰 체크리스트 실행 결과
|
||||
|
||||
실행일 : 2026-09-01
|
||||
대상 : clean-architecture-backend-template · 레코드 326건 (CONCEPT 21 · CASE 211 · REFERENCE 52 · QUESTION 17 · DECISION 25)
|
||||
근거 root tree : /shared/document-detail/clean-architecture-backend-template/root-tree.md (노드 327 · 생성 차단 1)
|
||||
소스 리비전 : 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
||||
|
||||
## Provenance
|
||||
|
||||
- [x] 레코드 326건 전부 root tree 노드에 slug 로 대응한다. 미대응 0.
|
||||
- [x] readiness 가 READY 또는 OPEN 인 노드만 생성됐다. NEEDS_DECISION 노드 1건(`widen-doc-contract-assertions`)은 decision-evidence 부재로 차단 유지.
|
||||
- [x] 레코드 sourceRevision 326건 전부 root tree 리비전과 일치.
|
||||
- [x] root tree 노드 327건 전부 source 앵커를 갖는다. 참조 파일 283건 중 결측 0 (codebase 경로 1건 포함 확인).
|
||||
- [x] 라인 앵커 155건 전부 헤딩에 정확히 착지. 어긋남 0.
|
||||
- [ ] **upstream 상태가 COMPLETE 가 아니다.** document-detail state.json 이 cycle 2 재분석 중이다 — analysisStatus IN_PROGRESS, 스코프 COMPLETE 38 / IN_PROGRESS 23 / EXCLUDED 1, crossScopeAnalysis·finalDocument·rootTree 는 NOT_STARTED(stale). 상세는 아래 "미결 항목".
|
||||
|
||||
## Record kind
|
||||
|
||||
- [x] 레코드 kind 가 root tree 노드 kind 와 326건 전부 일치.
|
||||
- [x] 디렉터리 배치가 kind 와 일치.
|
||||
- [x] bodyMarkdown 은 CASE·CONCEPT 만 사용. 다른 kind 의 body 참조 0.
|
||||
- [x] DECISION 25건 전부 근거 기록 1건 이상 보유.
|
||||
- [x] OPEN QUESTION 17건 전부 미지수와 다음 검증을 갖는다.
|
||||
|
||||
## Facts
|
||||
|
||||
- [x] 비본문 필드에 백틱·파이프 등 마크다운 문법 유입 0 (평문 규약 준수).
|
||||
- [x] 제목 중복 0.
|
||||
- [x] 각 레코드가 검증 환경·재현 조건·확인하지 못한 것을 분리해 적는다. 실행하지 않은 것은 실행하지 않았다고 적었다.
|
||||
|
||||
## Concept / Case body
|
||||
|
||||
- [x] body-syntax 화이트리스트 위반 0 — raw HTML·각주·체크박스·중첩 리스트·중첩 인용·취소선·링크 타이틀 모두 검출 0.
|
||||
- [x] body 파일 참조 결측 0.
|
||||
|
||||
## Relations
|
||||
|
||||
- [x] 관계 항목 전부가 제목 나열이 아니라 설명 줄을 동반한다. 설명 없는 관계 0.
|
||||
- [x] root tree 끊긴 relations 0.
|
||||
|
||||
## 이번 실행에서 고친 것
|
||||
|
||||
1. `a19-f022-messagingpublicsurfacecontracttest` — 레저 앵커가 §9.3(문서 계약 테스트 커버리지)에 착지해 §9.3 내용으로 초안이 작성됐다. 그 절은 이미 `doc-contract-test-boundary-predicted-the-drift` 가 담당한다. 노드 제목이 가리키는 §9.5(공개 표면 계약 테스트 위치)로 레코드를 다시 썼다.
|
||||
2. root tree 라인 앵커 4건 정정 — `analysis-finding-a19-f018` L911→L926, `analysis-finding-a19-f019` L960→L975, `a19-f020-messaging-admin-api` L982→L997, `a19-f022-...` L1099→L1114.
|
||||
|
||||
## 미결 항목 (편집 패스 전에 판단 필요)
|
||||
|
||||
document-detail 파이프라인이 cycle 2 재분석 중이다.
|
||||
|
||||
- 사유(state.json): 23개 리프의 production 구현이 cycle 1 에서 STRUCTURAL_ONLY 였고, full-read 게이트를 통과할 때까지 downstream 합성을 무효로 둔다.
|
||||
- 대상: messaging 5개(kafka·rabbit·pulsar-exp·nats-exp·spring-boot-starter), grpc 18개 전부.
|
||||
- 리비전은 그대로다 — baselineRevision == targetRevision, changedPaths 없음. 즉 코드가 바뀐 것이 아니라 읽기 깊이를 올리는 재분석이다.
|
||||
- 영향 범위: 이 23개 리프에서 나온 레코드는 가족 통합 문서 `analysis/19-messaging-platform.md`·`analysis/20-grpc-platform.md`(역할 INTEGRATION_ONLY)를 근거로 한다. 리프별 canonical SSOT(`analysis/messaging/*.md`·`analysis/grpc/*.md`)는 파일로 존재하지만 상태가 IN_PROGRESS 다.
|
||||
- 그 밖의 레코드(38개 COMPLETE 스코프 근거)는 이 항목의 영향을 받지 않는다.
|
||||
|
||||
체크리스트의 "owning registered leaf 가 자기 canonical module SSOT 를 갖고, 초안이 가족/최종 요약에만 근거하지 않는다" 항목은 이 23개 리프에 대해서는 재분석 완료 후 재확인이 필요하다.
|
||||
Reference in New Issue
Block a user