Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/a-soak-threshold-written-for-a-grade-that-does-not-exist.txt
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

67 lines
3.1 KiB
Plaintext

# 게이트 javadoc 의 등급 모형 — 둘
* <p>Two thresholds rather than one. Reaching Advanced Stable means the capability works and is
* documented; becoming a Stable default means every deployment gets it, which additionally puts its
* dependencies on every classpath and its failure modes in every on-call rotation. The second needs
* the first plus a longer soak, because a capability that has run in one deployment for a week is
* not the same claim as one that ships to all of them.
*/
# 그리고 상수 둘
/** The soak a promotion to Advanced Stable requires. */
public static final Duration ADVANCED_STABLE_SOAK = Duration.ofDays(7);
/** The soak a promotion to a Stable default requires. */
public static final Duration STABLE_DEFAULT_SOAK = Duration.ofDays(30);
# 그런데 등급 열거형의 값은 넷이다
13: ADVANCED_STABLE(true, false),
15: EXPERIMENTAL(true, true),
17: WATCH(false, false),
19: DISABLED(false, false);
# 그중 'Stable default' 에 해당하는 값: 0
# 증거 검사와 담금 선택 — 증거 쪽에는 목표 등급 조건이 없다
evidence.missing().stream()
.sorted()
.forEach(missing -> blockers.add(capability.flagName() + " has no " + missing));
Duration requiredSoak =
to == GrpcCapabilityGrade.ADVANCED_STABLE ? ADVANCED_STABLE_SOAK : STABLE_DEFAULT_SOAK;
# 증거 항목 수: 7
"compatibility evidence" "security review" "fault evidence" "performance evidence" "architecture decision record" "runbook" "real environment test"
# 추적 등급은 중간 등급을 먼저 밟아야 한다
if (from == GrpcCapabilityGrade.WATCH && to != GrpcCapabilityGrade.EXPERIMENTAL) {
blockers.add(
capability.flagName()
+ " is WATCH, which is tracked rather than implemented; it becomes EXPERIMENTAL "
+ "before anything else");
}
# 긴 갈래를 실행하는 테스트가 고른 전이
@DisplayName("becoming a Stable default needs a longer soak than becoming Advanced Stable")
void theStableDefaultThresholdIsHigher() {
GrpcAdvancedPromotionEvidence weekLongSoak =
GrpcAdvancedPromotionEvidence.complete(GrpcAdvancedCapability.GRPC_WEB, Duration.ofDays(7));
.isTrue();
assertThat(
GrpcAdvancedPromotionGate.evaluate(
weekLongSoak, GrpcCapabilityGrade.ADVANCED_STABLE, GrpcCapabilityGrade.DISABLED)
.blockers())
.anySatisfy(blocker -> assertThat(blocker).contains("requires 30"));
# 중간 등급으로 올라가는 테스트가 준 담금
@DisplayName("a WATCH capability becomes EXPERIMENTAL before anything else")
void watchPromotesOnlyToExperimental() {
GrpcAdvancedPromotionGate.evaluate(
GrpcAdvancedPromotionEvidence.complete(
GrpcAdvancedCapability.EDITION_2026, Duration.ofDays(60)),
GrpcCapabilityGrade.WATCH,
GrpcCapabilityGrade.EXPERIMENTAL)
.promoted())
.isTrue();
}
# 그 테스트들을 실제로 돌린 결과
BUILD SUCCESSFUL in 984ms
tests="8" skipped="0" failures="0" errors="0"