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>
77 lines
4.8 KiB
Plaintext
77 lines
4.8 KiB
Plaintext
# 가족 지침이 이 계약의 주인으로 지목한 것
|
|
src/messaging/CLAUDE.md:36 - 반대로 **노출하지 않는 것은 `implementation`으로 낮춘다.** starter가 노출하지 않는 하위 모듈을
|
|
src/messaging/CLAUDE.md:37 `implementation`으로 내린 것이, JSON codec이 `ObjectMapper`를 private으로만 쓰고 Jackson을
|
|
src/messaging/CLAUDE.md:38 `implementation`으로 둔 것이 그 예다.
|
|
src/messaging/CLAUDE.md:39 - 이 규칙은 문서가 아니라 `MessagingPublicSurfaceContractTest`가 붙들고 있다. leaf의 production
|
|
src/messaging/CLAUDE.md:40 source에서 public/protected 시그니처에 등장하는 vendor 라이브러리를 뽑아 그 leaf의
|
|
src/messaging/CLAUDE.md:41 `build.gradle`이 `api`로 선언했는지 대조하고, starter의 `api` closure에 broker client 두 개가
|
|
src/messaging/CLAUDE.md:42 들어오지 않는 것도 함께 본다. Spring Framework/Boot는 대상이 아니다 — 조립 경계 안에서만
|
|
src/messaging/CLAUDE.md:43 등장하고 adopter가 이름 부를 일이 없다.
|
|
src/messaging/CLAUDE.md:44 - 새 public 타입은 그 모듈의 계약이다. 삭제·시그니처 변경은 breaking change로 취급한다.
|
|
|
|
# 그 시험 클래스가 놓인 트리
|
|
src/app-bootstrap/src/test/java/dev/caskeleton/bootstrap/contract/messaging/MessagingPublicSurfaceContractTest.java
|
|
src/messaging 아래 동명 파일 : 0 개
|
|
가족 test 트리 : 24 개 · 이 파일의 트리 : src/app-bootstrap/src/test
|
|
이 파일의 @Test 3 · @Tag 0 · @Disabled 0
|
|
:73 void vendorTypesInPublicSignaturesAreDeclaredApi() {
|
|
:94 void theScanIsNotVacuous() {
|
|
:114 void neitherBrokerSdkReachesAnAdoptersCompileClasspath() {
|
|
|
|
# 가족 경로에서 도는 워크플로의 트리거 전부와 실행 명령
|
|
messaging-certification.yml:15 on:
|
|
messaging-certification.yml:16 pull_request:
|
|
messaging-certification.yml:17 paths:
|
|
messaging-certification.yml:18 - "src/messaging/**"
|
|
messaging-certification.yml:19 - ".github/workflows/messaging-certification.yml"
|
|
messaging-certification.yml:20 schedule:
|
|
messaging-certification.yml:21 - cron: "41 4 * * 3"
|
|
messaging-certification.yml:22 workflow_dispatch:
|
|
messaging-certification.yml:52 run: ./gradlew :messaging:messaging-kafka:verifyMessagingCertificationEvidence --no-daemon --stacktrace
|
|
|
|
# 경로 필터가 없는 워크플로
|
|
ci-quality-gates.yml:1 name: ci-quality-gates
|
|
ci-quality-gates.yml:2
|
|
ci-quality-gates.yml:3 on:
|
|
ci-quality-gates.yml:4 pull_request:
|
|
ci-quality-gates.yml:5 push:
|
|
ci-quality-gates.yml:6 branches: ["main"]
|
|
ci-quality-gates.yml:7 workflow_dispatch:
|
|
ci-quality-gates.yml:8
|
|
ci-quality-gates.yml:9 permissions:
|
|
on 블록(1-9)의 paths 필터 : 0 건
|
|
ci-quality-gates.yml:19 jobs:
|
|
ci-quality-gates.yml:20 quality-gates:
|
|
ci-quality-gates.yml:21 runs-on: ubuntu-latest
|
|
ci-quality-gates.yml:22 steps:
|
|
ci-quality-gates.yml:48 - name: Check quality, public paths, and dependency locks
|
|
ci-quality-gates.yml:49 working-directory: src
|
|
ci-quality-gates.yml:50 run: ./gradlew check verifyPublicPathSnapshot verifyDependencyLocks --warning-mode=fail --no-daemon --stacktrace
|
|
ci-quality-gates.yml:51 # Named as its own step because nothing else runs it: `check` does not depend on
|
|
ci-quality-gates.yml:52 # graphqlStableTest, so the lane's required-class guard — the check that its module-boundary
|
|
ci-quality-gates.yml:53 # suite has not silently stopped being discovered — protected nothing in CI. A separate step
|
|
ci-quality-gates.yml:54 # keeps the aggregate invocation below byte-identical, which ConditionalTransportQualification
|
|
ci-quality-gates.yml:55 # ContractTest asserts on, and the two tasks do not overlap.
|
|
|
|
# check 가 정말 이 프로젝트의 test 를 포함하는가
|
|
$ ./gradlew :app-bootstrap:check --dry-run
|
|
:app-bootstrap:test SKIPPED
|
|
:app-bootstrap:functionalTest SKIPPED
|
|
:app-bootstrap:check SKIPPED
|
|
루트 test 규약이 거는 유일한 필터 :
|
|
src/build.gradle:549 tasks.named('test') {
|
|
src/build.gradle:550 useJUnitPlatform {
|
|
src/build.gradle:551 excludeTags 'quarantine'
|
|
src/build.gradle:552 }
|
|
src/build.gradle:553 }
|
|
|
|
# 이름으로 골라 실제로 돌리면
|
|
$ ./gradlew :app-bootstrap:test --tests '...MessagingPublicSurfaceContractTest'
|
|
BUILD SUCCESSFUL
|
|
결과 디렉터리 test/ · MessagingPublicSurfaceContractTest tests=3 failures=0 skipped=0
|
|
|
|
# 가족 태스크로 같은 이름을 고르면
|
|
$ ./gradlew :messaging:messaging-kafka:test --tests '...MessagingPublicSurfaceContractTest'
|
|
> No tests found for given includes: [dev.caskeleton.bootstrap.contract.messaging.MessagingPublicSurfaceContractTest](--tests filter)
|
|
BUILD FAILED
|