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 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