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>
132 lines
4.9 KiB
Plaintext
132 lines
4.9 KiB
Plaintext
# evidence 266 — grpc-family-claims-verification
|
|
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
|
# cwd: /shared/codebase/clean-architecture-backend-template
|
|
# command: bash /tmp/gclaims.sh
|
|
# ---- raw output ----
|
|
==== CLAIM 1: grpc-core-api names no io.grpc / Spring / protobuf / JPA type ====
|
|
-- io.grpc:
|
|
3
|
|
-- springframework:
|
|
0
|
|
-- protobuf:
|
|
0
|
|
-- jakarta.persistence:
|
|
0
|
|
-- same four, in grpc-core-api TEST sources:
|
|
io\.grpc 0
|
|
org\.springframework 0
|
|
com\.google\.protobuf 0
|
|
jakarta\.persistence 0
|
|
-- build.gradle of grpc-core-api:
|
|
apply plugin: 'java-library'
|
|
dependencies {
|
|
}
|
|
|
|
==== CLAIM 2: no Stable leaf references :grpc-advanced: ====
|
|
-- registry allowed_dependencies mentioning an advanced leaf, from a non-advanced leaf:
|
|
violations: none
|
|
grpc-spring-boot-starter allowed_dependencies: ['grpc-core-api', 'grpc-proto-contract', 'grpc-codegen', 'grpc-policy', 'grpc-server', 'grpc-client', 'grpc-discovery', 'grpc-admin', 'grpc-observability', 'grpc-operation-ledger-jpa']
|
|
-- source-level references from src/grpc to grpc.advanced packages:
|
|
0
|
|
-- GrpcStableBuildInvariant:
|
|
src/grpc/grpc-spring-boot-starter/src/main/java/dev/caskeleton/grpc/boot/GrpcPlatformStartupValidator.java
|
|
src/grpc/grpc-core-api/src/test/java/dev/caskeleton/grpc/core/GrpcStableModuleCatalogTest.java
|
|
src/grpc/grpc-core-api/src/main/java/dev/caskeleton/grpc/core/GrpcStableBuildInvariant.java
|
|
src/grpc-advanced/grpc-advanced-bootstrap/src/main/java/dev/caskeleton/grpc/advanced/bootstrap/GrpcAdvancedModuleGuard.java
|
|
|
|
==== CLAIM 3: every grpc leaf has empty runtime_memberships ====
|
|
grpc leaves: 18
|
|
with non-empty runtime_memberships: []
|
|
adapter-inbound-grpc allowed_dependencies: ['domain-core', 'application-core', 'shared-contract']
|
|
|
|
==== CLAIM 4: GrpcEvidenceGrade refuses a tls claim at CONTRACT grade ====
|
|
file: src/grpc/grpc-testkit/src/main/java/dev/caskeleton/grpc/testkit/GrpcEvidenceGrade.java
|
|
package dev.caskeleton.grpc.testkit;
|
|
|
|
|
|
/**
|
|
* What a lane's results are evidence about.
|
|
*
|
|
* <p>The Stable plan splits its testkit into four modules so that in-process results cannot be
|
|
* mistaken for network results. This repository expresses that with strict test lanes instead
|
|
* (adaptation design §2), and this enum is what keeps the distinction legible from inside the code:
|
|
* a claim about TLS backed by {@link #CONTRACT} evidence is refused, because in-process transport
|
|
* never negotiated one.
|
|
*/
|
|
public enum GrpcEvidenceGrade {
|
|
/**
|
|
* In-process. Proves adapter, interceptor, status and idempotency behaviour. Proves nothing about
|
|
* HTTP/2 framing, TLS, transport limits, keepalive or GOAWAY.
|
|
*/
|
|
CONTRACT,
|
|
/** Real Netty on a real socket. The only grade that certifies transport behaviour. */
|
|
TRANSPORT,
|
|
/** Real network faults at each evidence boundary. */
|
|
FAULT,
|
|
/** Latency, saturation and drain budget under load. */
|
|
PERFORMANCE;
|
|
|
|
/**
|
|
* What a result at this grade may be cited for.
|
|
*
|
|
* <p>Computed rather than held in a field: an enum with a collection field is a mutable enum as
|
|
* far as any static analysis can tell, and the alternative — a defensive copy per constant —
|
|
* would be the same set built at class-init time for no benefit.
|
|
*/
|
|
public Set<String> certifies() {
|
|
return switch (this) {
|
|
case CONTRACT ->
|
|
Set.of(
|
|
"service-adapter",
|
|
"interceptor-order",
|
|
"status-mapping",
|
|
"validation",
|
|
"idempotency-replay",
|
|
"context-propagation");
|
|
case TRANSPORT ->
|
|
Set.of(
|
|
"http2",
|
|
"tls",
|
|
"mutual-tls",
|
|
"metadata-limit",
|
|
"message-limit",
|
|
"goaway",
|
|
"keepalive",
|
|
"graceful-shutdown");
|
|
case FAULT ->
|
|
Set.of("connection-loss", "completion-unknown", "partial-stream", "evidence-classifier");
|
|
case PERFORMANCE ->
|
|
Set.of("latency", "stream-saturation", "executor-saturation", "drain-budget");
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Fails when {@code capability} is claimed on the strength of this grade.
|
|
*
|
|
* @throws IllegalStateException naming what this grade actually establishes
|
|
*/
|
|
public void requireCertifies(String capability) {
|
|
if (capability == null || capability.isBlank()) {
|
|
throw new IllegalArgumentException("a capability name is required");
|
|
}
|
|
Set<String> certified = certifies();
|
|
if (!certified.contains(capability)) {
|
|
throw new IllegalStateException(
|
|
this
|
|
+ " evidence does not certify '"
|
|
+ capability
|
|
+ "'; it establishes "
|
|
+ certified.stream().sorted().toList());
|
|
}
|
|
}
|
|
}
|
|
|
|
==== CLAIM 6: performance lane excluded from the default test task ====
|
|
14:strictTestLanes {
|
|
15: lane('grpcInProcessContractTest') {
|
|
20: lane('grpcNettyContractTest') {
|
|
25: lane('grpcFaultTest') {
|
|
30: lane('grpcPerformanceTest') {
|
|
31: tag = 'grpc-performance'
|
|
42: excludeTags 'grpc-performance'
|