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>
60 lines
5.2 KiB
Plaintext
60 lines
5.2 KiB
Plaintext
# 주제: 인증(certification) 증거 매니페스트의 실제 상태와,
|
|
# BrokerFailureMatrix 클래스 javadoc 이 선언한 "Stable 규칙" 이 강제되지 않는 사실
|
|
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
|
|
|
# command: find src -path "*messaging/broker-certification-evidence.jsonl"
|
|
# exit: 0
|
|
src/messaging/messaging-testkit/build/resources/main/messaging/broker-certification-evidence.jsonl
|
|
src/messaging/messaging-testkit/src/main/resources/messaging/broker-certification-evidence.jsonl
|
|
# command: diff <(sort src/.../src/main/resources/.../*.jsonl) <(sort src/.../build/resources/.../*.jsonl)
|
|
# exit: 0 -> IDENTICAL src vs build
|
|
|
|
# command: cat src/messaging/messaging-testkit/src/main/resources/messaging/broker-certification-evidence.jsonl
|
|
# exit: 0 (4줄)
|
|
{"adapter":"messaging-kafka","brokerImage":"apache/kafka:4.1.0","scenario":"confirm-timeout","testId":"KafkaBrokerCertificationIT#aConfirmThatNeverArrivesIsReportedAsAmbiguousAndTheRecordIsThere","outcome":"AMBIGUOUS","gitCommit":"e98b56eb03ecab588c21fd1e7dbcaa493c1d8645","observedAt":"2026-08-19T14:21:30.826332993Z"}
|
|
{"adapter":"messaging-kafka","brokerImage":"apache/kafka:4.1.0","scenario":"connection-cut-after-write","testId":"KafkaBrokerCertificationIT#aConnectionCutAfterTheWriteIsReportedAsAmbiguous","outcome":"AMBIGUOUS","gitCommit":"e98b56eb03ecab588c21fd1e7dbcaa493c1d8645","observedAt":"2026-08-19T14:21:34.906464945Z"}
|
|
{"adapter":"messaging-kafka","brokerImage":"apache/kafka:4.1.0","scenario":"high-latency","testId":"KafkaBrokerCertificationIT#latencyBeyondThePublishDeadlineIsReportedAsAmbiguous","outcome":"AMBIGUOUS","gitCommit":"e98b56eb03ecab588c21fd1e7dbcaa493c1d8645","observedAt":"2026-08-19T14:21:21.870705263Z"}
|
|
{"adapter":"messaging-kafka","brokerImage":"apache/kafka:4.1.0","scenario":"settlement-lost","testId":"KafkaBrokerCertificationIT#aDeliveryLostBeforeSettlementIsRedelivered","outcome":"REDELIVERED","gitCommit":"e98b56eb03ecab588c21fd1e7dbcaa493c1d8645","observedAt":"2026-08-19T14:21:42.058283607Z"}
|
|
|
|
# 시나리오 모집단 (NetworkFaultScenario.all(), NetworkFaultScenario.java:143-150) = 5개
|
|
# connection-refused / connection-cut-after-write / confirm-timeout / settlement-lost / high-latency
|
|
# 증거가 있는 조합 = messaging-kafka x 4 (connection-refused 없음)
|
|
# 증거가 있는 어댑터 = messaging-kafka 1개. messaging-rabbit 은 0줄.
|
|
|
|
# command: git rev-parse HEAD ; git log --oneline -1 e98b56eb03ecab588c21fd1e7dbcaa493c1d8645
|
|
# exit: 0
|
|
현재 HEAD : 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
|
증거가 기록한 gitCommit : e98b56eb "feat: jpa, messaging, notification, mongo, graphql 어댑터터 리펙토링"
|
|
# => 증거는 현재 트리가 아니라 과거 커밋에서 생산되었다. 히스토리에는 존재하는 커밋이다.
|
|
# => `verifyMessagingCertificationEvidence` 는 비교 시 gitCommit/observedAt 을 정규식으로 제거하고
|
|
# 비교하므로(messaging-kafka/build.gradle doLast 의 claims 클로저), 커밋 불일치는 게이트에 걸리지 않는다.
|
|
# 이는 설계된 선택이며 주석에 명시되어 있다("differ on every run by design").
|
|
|
|
# ---- 드리프트 ----
|
|
# BrokerFailureMatrix.java:19-20 클래스 javadoc:
|
|
# "A Stable adapter must cover every scenario. That rule is enforced by a test rather than
|
|
# documented, because a promotion to Stable is exactly the moment the gap would otherwise be
|
|
# overlooked."
|
|
#
|
|
# command: git grep -n "isComplete" -- src (messaging-testkit 범위만 발췌)
|
|
src/messaging/messaging-testkit/src/main/java/.../BrokerFailureMatrix.java:95: public boolean isComplete(String adapter) {
|
|
src/messaging/messaging-testkit/src/test/java/.../CrossBrokerContractSuite.java:110: assertThat(matrix.isComplete("messaging-pulsar-experimental"))
|
|
# => isComplete 의 호출부는 단 1곳이며, 그것은 *Experimental* 어댑터에 대해 false 를 단언한다.
|
|
# Stable 어댑터에 isComplete 를 거는 테스트는 존재하지 않는다.
|
|
#
|
|
# 실제로 Stable 어댑터인 messaging-kafka 는 gap 을 가진 상태로 통과한다:
|
|
# CertifiedEvidenceTest.java:52-55 aScenarioWithNoLineInTheManifestIsAGapRatherThanAnAbsence
|
|
# assertThat(CertifiedEvidence.knownGaps("messaging-kafka")).contains(CONNECTION_REFUSED)
|
|
# CrossBrokerContractSuite.java:43-54 everyStableAdapterCoversEveryFaultScenario
|
|
# -> 이름은 "covers every"이지만 본문은 gaps 를 *열거*할 뿐 비어 있음을 단언하지 않는다.
|
|
# 본문 주석이 그 선택을 명시한다: "The gaps are named rather than asserted empty."
|
|
#
|
|
# 판정: 코드는 의도적으로 "정직한 gap 열거"로 바뀌었고, 그 결정은 테스트 본문 주석에 남았다.
|
|
# 그러나 BrokerFailureMatrix 클래스 javadoc 은 바뀌기 전 규칙("must cover every scenario,
|
|
# enforced by a test")을 그대로 들고 있다. 규칙을 강제하는 테스트는 없다.
|
|
# 테스트 메서드 이름 everyStableAdapterCoversEveryFaultScenario 도 같은 잔재다.
|
|
|
|
# command: git grep -n "adapters()" -- src (messaging-testkit)
|
|
src/messaging/messaging-testkit/src/main/java/.../BrokerFailureMatrix.java:104: public List<String> adapters() {
|
|
# => 호출부 0건. public API 로 노출되어 있으나 아무도 쓰지 않는다.
|