Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/179-outbound-messaging-contract-destination-probes.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

122 lines
11 KiB
Plaintext

Sub-scope 03 (outbound-messaging) contract/** + destination/** + qualification test — manifest and probes
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
generatedAt=2026-08-30T06:29:35+00:00
=== OWNED FILES ===
a4b9608deef1faa6107fea013e269595e0e999e0 main/java/dev/caskeleton/adapter/outbound/messaging/contract/CompiledIntegrationEventContract.java 263
66d6ab3cea648b0a8e5a3eb12596bd5a9256e161 main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogCompiler.java 274
57cf07bc4dfbe53912395e57536dda74735359d5 main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java 91
43cdeb88515f9174b1326b8cfb682d9255f7885f main/java/dev/caskeleton/adapter/outbound/messaging/destination/CompiledPublicationBinding.java 105
9759d0fb0d0942faf22420620b04ebc6efae0bac main/java/dev/caskeleton/adapter/outbound/messaging/destination/DestinationBindingCompiler.java 248
8fb7ffb59ef243ed8ed423bb7981d8cb0b48865a main/java/dev/caskeleton/adapter/outbound/messaging/destination/DestinationBindingSettings.java 238
a6c74dbdbb5bb02572303c4b8a3450740b301f49 main/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1.java 132
9d9274390e5314887d03334e370f1bda95989421 test/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogCompilerTest.java 566
1f541d4d217a8af44deb2bd67d7901fe40766305 test/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigestTest.java 112
500efc002b2ccb3fe73506a8bf1a0a513f1eb5a0 test/java/dev/caskeleton/adapter/outbound/messaging/destination/DestinationBindingCompilerTest.java 648
b9c9d3d7df0962f27718e717b6a9ad79d644160b test/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1Test.java 104
1a3fc898cab1fa38bd66707af0c39d9a53651d17 test/java/dev/caskeleton/adapter/outbound/messaging/qualification/MessagingEvidenceManifestSchemaValidator.java 68
2c0967e3c4d2e4ea81b035b9c649bfcb02e9b1f4 test/java/dev/caskeleton/adapter/outbound/messaging/qualification/MessagingEvidenceManifestSchemaValidatorTest.java 81
main: 7 test: 6
=== 8.1 도메인 분리 상수 전수 ===
$ git grep -rn 'ca-skeleton.messaging' -- adapter/outbound/messaging/src/main | sed 's|.*/messaging/||'
contract/ContractCatalogDigest.java:16: "ca-skeleton.messaging.contract-catalog-digest.v1".getBytes(StandardCharsets.UTF_8);
destination/DestinationBindingCompiler.java:95: MessageDigest digest = digest("ca-skeleton.messaging.destination-settings-digest.v1");
destination/DestinationBindingCompiler.java:121: MessageDigest digest = digest("ca-skeleton.messaging.schema-set-digest.v1");
destination/PartitionKeyV1.java:22: "ca-skeleton.messaging.partition-key.v1".getBytes(StandardCharsets.UTF_8);
envelope/EnvelopeHashV1.java:13: "ca-skeleton.messaging.envelope.v1".getBytes(StandardCharsets.UTF_8);
envelope/JsonSchemaIntegrationEventEncoder.java:25: "ca-skeleton.messaging.schema-set.v1".getBytes(StandardCharsets.UTF_8);
envelope/LocalJsonSchemaRegistry.java:64: "ca-skeleton.messaging.draft-2020-12-authority.v1".getBytes(StandardCharsets.UTF_8);
exit=0
=== 8.2 길이 프레이밍 다이제스트 일관성 ===
$ git grep -n 'unsignedLength\|rawField\|digest.update' -- adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1.java | head -20
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:25: digest.update(DOMAIN);
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:26: digest.update((byte) 0);
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:48: rawField(digest, "schemaHash", contract.payloadSchemaHash().bytes());
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:69: rawField(digest, tag, value.getBytes(StandardCharsets.UTF_8));
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:72: private static void rawField(MessageDigest digest, String tag, byte[] value) {
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:74: digest.update(unsignedLength(tagBytes.length));
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:75: digest.update(tagBytes);
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:76: digest.update(unsignedLength(value.length));
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:77: digest.update(value);
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java:80: private static byte[] unsignedLength(int length) {
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1.java:55: digest.update(DOMAIN);
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1.java:56: digest.update((byte) 0);
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1.java:66: digest.update(ByteBuffer.allocate(Integer.BYTES).putInt(bytes.length).array());
adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1.java:67: digest.update(bytes);
exit=0
=== 8.3 교차 언어 벡터 test ===
$ git grep -n 'vector\|Vector\|golden\|Golden' -- adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging | head -20
adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1Test.java:17: void freezesTenantScopedGoldenVectorAsLowercaseHexAndExactAsciiBytes() {
adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1Test.java:54: void nonAsciiAggregateIdGoldenVectorUsesUtf8ByteLengthNotCharacterCount() {
adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/envelope/JsonSchemaIntegrationEventEncoderTest.java:161: void exactEnvelopeHashHasDomainSeparatedGoldenVectorAndDefensiveShaValue() {
adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/envelope/LocalJsonSchemaRegistryTest.java:27: void precompilesOnlyCheckedDraft202012ResourcesAndValidatesGoldenVectors() {
exit=0
=== 8.4 qualification test 클래스가 build.gradle 필수 목록과 일치하는가 ===
$ sed -n '69,104p' adapter/outbound/messaging/build.gradle | grep -oE "'dev\.caskeleton[^']*'" | tr -d \"'\"
main: eval: line 8: unexpected EOF while looking for matching `''
exit=2
$ git ls-files 'adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging' | grep '\.java$' | sed 's|.*/java/||;s|/|.|g;s|\.java$||'
dev.caskeleton.adapter.outbound.messaging.MessagingConfigTest
dev.caskeleton.adapter.outbound.messaging.config.MessagingCapabilityCardRegistryTest
dev.caskeleton.adapter.outbound.messaging.contract.ContractCatalogCompilerTest
dev.caskeleton.adapter.outbound.messaging.contract.ContractCatalogDigestTest
dev.caskeleton.adapter.outbound.messaging.core.OutboundMessagePublisherTest
dev.caskeleton.adapter.outbound.messaging.destination.DestinationBindingCompilerTest
dev.caskeleton.adapter.outbound.messaging.destination.PartitionKeyV1Test
dev.caskeleton.adapter.outbound.messaging.envelope.EnvelopeAdversarialCorpusTest
dev.caskeleton.adapter.outbound.messaging.envelope.JsonSchemaIntegrationEventEncoderTest
dev.caskeleton.adapter.outbound.messaging.envelope.LocalJsonSchemaRegistryTest
dev.caskeleton.adapter.outbound.messaging.kafka.BrokerAddressTest
dev.caskeleton.adapter.outbound.messaging.kafka.KafkaAdapterSettingsTest
dev.caskeleton.adapter.outbound.messaging.outbox.OutboxMessagePublishAdapterTest
dev.caskeleton.adapter.outbound.messaging.outbox.Slf4jOutboxRelayFailureReportAdapterTest
dev.caskeleton.adapter.outbound.messaging.qualification.MessagingEvidenceManifestSchemaValidator
dev.caskeleton.adapter.outbound.messaging.qualification.MessagingEvidenceManifestSchemaValidatorTest
exit=0
=== 8.5 test 이름 ===
$ grep -h 'void [a-z]' adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/contract/*.java adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/destination/*.java adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/qualification/*.java | sed 's/^ *//'
void compilesAnImmutableClosedCatalogFromExactRecordTypeTokens() {
void rejectsNullInputsDuplicateStableSchemaAndExactPayloadIdentities() {
void rejectsNonPositiveVersionAndInvalidExactPayloadKinds() {
void rejectsNullBlankDuplicateAndReflectionMismatchedComponentOrders() {
void rejectsMissingDescriptorsAndLogicalDestinationDriftAcrossPayloadVersions() {
void compiledContractCannotBeConstructedWithAnInvalidExactTypeOrComponentOrder() {
void compiledContractUsesOnlyAStaticPublicCompositionBridgeWithoutReflectionLeak()
void snapshotsEveryContributionAccessorExactlyOnceIncludingAStatefulSchemaHash() {
void statefulDescriptorCannotBypassCrossVersionLogicalDestinationDrift() {
void recursivelyFreezesOnlyTheClosedDeclaredGenericPayloadGraph() {
void rejectsOpenRawWildcardMapJsonTreeInterfaceAndGenericRecordGraphs() {
private static void assertInvalidOrder(List<String> order) {
private static void assertUnsupportedGraph(
void digestIsDeterministicForEmptyAndInputOrderIndependentForNonEmptyCatalogs() {
void digestChangesForSchemaHashDescriptorAndCanonicalComponentOrderSemantics() {
void compilesExactContractBindingWithCodeDeploymentByteIntersectionAndStableDigests() {
void deploymentMaximumBelowCodeMaximumWinsAndMustRemainPositive() {
void settingsRejectDuplicateLogicalDestinationsInvalidPortsAndSecretShapedLegacyAliases() {
void settingsRejectNullDestinationAndDuplicatePhysicalTopicAcrossLogicalDestinations() {
void rejectsMissingDuplicateExtraAndContractDestinationMismatchedBindings() {
void rejectsUnknownCardsRoleMismatchLegacyConflictAndRelaxedRequirements() {
void disabledEmptyCatalogIsZeroResourceWhileActiveRequiresExactCatalogAndBindings() {
void compiledArtifactsExposeOnlyNarrowStaticImmutableCompositionBridges()
private static void assertPackagePrivateInstanceMethod(
private static void assertPublicStaticMethod(
private static void assertRejected(
void freezesTenantScopedGoldenVectorAsLowercaseHexAndExactAsciiBytes() {
void tenantDisabledCallerMustSupplyTheCanonicalNonNullSystemScope() {
void nonAsciiAggregateIdGoldenVectorUsesUtf8ByteLengthNotCharacterCount() {
void malformedUtf8SurrogatesAreRejectedInsteadOfCollidingWithLiteralQuestionMark() {
void canonicalComponentsApplyTask3BoundsBeforeEncoding() {
public static void main(String[] arguments) {
static void validate(byte[] exactSchemaBytes, byte[] exactManifestBytes) {
void validatesAConformingManifestAgainstTheExactCommonSchema() throws IOException {
void rejectsManifestDriftThatTheCommonSchemaForbids() throws IOException {
void rejectsCommonSchemaDriftThatFailsDraft202012MetaValidation() throws IOException {
exit=0