Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/178-outbound-messaging-envelope-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

141 lines
9.5 KiB
Plaintext

Sub-scope 02 (outbound-messaging) envelope/** + JSON Schema meta 리소스 — manifest and probes
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
generatedAt=2026-08-30T06:27:52+00:00
=== OWNED FILES ===
758b7177a64804fe295e8be8b425f3808e91196e main/java/dev/caskeleton/adapter/outbound/messaging/envelope/DeterministicEnvelopeWriter.java 548
e0fd83434527d5a36b2a9810533b642c8f017787 main/java/dev/caskeleton/adapter/outbound/messaging/envelope/EnvelopeAdmissionLimits.java 56
63b3ba7a5de004c84241f54afd56198456522a70 main/java/dev/caskeleton/adapter/outbound/messaging/envelope/EnvelopeHashV1.java 36
5fa19d059d212146484fa2358a0105b182b08148 main/java/dev/caskeleton/adapter/outbound/messaging/envelope/JsonSchemaIntegrationEventEncoder.java 232
26eaddffcf160bb6a06c652e3943b576b627d518 main/java/dev/caskeleton/adapter/outbound/messaging/envelope/LocalJsonSchemaRegistry.java 701
3466e4660bd95fa55f817320609cef033f616445 main/resources/contracts/messaging/meta/draft-2020-12/authority.sha256 9
ca69923096f3a2e4fe5eb8152a92d87d146cf021 main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/applicator 48
2f6e056a9ac2399582eaf05985a26acf9161f213 main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/content 17
dfc092d9646e1ea89e4d771bfcf2a4ca87eeac75 main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/core 51
51ef7ea118c34e8ac3da66c973bae02b9e8325d8 main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/format-annotation 14
1a4f106cfe0b2df4784a39fae720762534a54cdf main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/format-assertion 11
05cbc22afde5ebe6ba84957ca412277bde1e4b08 main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/meta-data 37
5f62a3ffa20be07dc813d6b8a154fa8451d0dc61 main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/unevaluated 15
606b87ba2ec213d63b9e2035a6acc4edcb4b8357 main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/validation 98
d5e2d31c3c88e61f4c204cb6616887bba7e105dd main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/schema 58
e0ac636a898cf0a7143df39a0fca9c6105a3c9c7 test/java/dev/caskeleton/adapter/outbound/messaging/envelope/EnvelopeAdversarialCorpusTest.java 334
3d960a923d7dc4684e9b039782cf7eef900071f2 test/java/dev/caskeleton/adapter/outbound/messaging/envelope/JsonSchemaIntegrationEventEncoderTest.java 413
ff105bfaa862fd89f992367f6397cb5e858780f7 test/java/dev/caskeleton/adapter/outbound/messaging/envelope/LocalJsonSchemaRegistryTest.java 393
e127ca96edb86ab9fe30438da19b72367fbe5324 test/resources/contracts/messaging/test.event/v1.invalid.json 13
74a3d91ae00a7e82ee5c3893847e9abe0debac16 test/resources/contracts/messaging/test.event/v1.schema.json 70
52c2bce0490fa5845f14227347ec7498a5eb8ca0 test/resources/contracts/messaging/test.event/v1.valid.json 15
main: 5 test: 3 resources: 13
=== 8.1 레지스트리가 외부 해석을 실제로 닫는가 ===
$ grep -n 'SchemaRegistryConfig\|schemaLoader\|uriFetcher\|disable\|cacheRefs\|SpecificationVersion' adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/LocalJsonSchemaRegistry.java | head -20
7:import com.networknt.schema.SchemaRegistryConfig;
8:import com.networknt.schema.SpecificationVersion;
405: SchemaRegistryConfig config =
406: SchemaRegistryConfig.builder()
410: .cacheRefs(true)
414: SpecificationVersion.DRAFT_2020_12,
exit=0
$ grep -n 'UNSUPPORTED_CLOSED_SUBSET_KEYWORDS' -A 3 -B 1 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/LocalJsonSchemaRegistry.java | head -20
57- "https://json-schema.org/draft/2020-12/vocab/content");
58: private static final Set<String> UNSUPPORTED_CLOSED_SUBSET_KEYWORDS =
59- Set.of("$anchor", "$dynamicRef", "$dynamicAnchor", "$recursiveRef", "$recursiveAnchor");
60- private static final String PINNED_AUTHORITY_ROOT = "contracts/messaging/meta/draft-2020-12/";
61- private static final String PINNED_AUTHORITY_MANIFEST =
--
300- }
301: for (String keyword : UNSUPPORTED_CLOSED_SUBSET_KEYWORDS) {
302- if (node.has(keyword)) {
303- throw new IllegalArgumentException(
304- keyword + " is unsupported by the closed local schema subset");
exit=0
$ grep -n 'KNOWN_VOCABULARIES' adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/LocalJsonSchemaRegistry.java
48: private static final Set<String> KNOWN_VOCABULARIES =
286: if (!KNOWN_VOCABULARIES.contains(entry.getKey())) {
exit=0
=== 8.2 핀 고정된 메타스키마 권위 해시 ===
$ cat adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/authority.sha256
41da76f5afb7ce062d248f762463a92f7ca47e4e0f905b224ba6afeef91ded0f draft/2020-12/schema
c4a6e4147b91fef7fea6dc058cb1bf93402f7414b76578a8b16aaf1dad6aacef draft/2020-12/meta/applicator
08343747764e4a5814262793cf4d652057a7913863c5950d43297e8e1fdac5b6 draft/2020-12/meta/content
c2d12a8e4dd11d336dfc83a3f663aa4c69f0b49b3beb094ffeb25b5316f4803d draft/2020-12/meta/core
abc775adfefd89d22358170d9bf93f4ebd2349563bbbedd60f02bef7c812bcc0 draft/2020-12/meta/format-annotation
6a5a8e13c605e3eff51f9bf8da18078880d81ff1634e391760ccc2e16ee2146f draft/2020-12/meta/format-assertion
8f76d6e14f41b9b92ef933b708cdc5144c8b5268651ad11918485fb1754f1c76 draft/2020-12/meta/meta-data
2dbfbcb73994b670b0976492adee1fffb46c21682784d2f5a4ca561f9e2d0cb4 draft/2020-12/meta/unevaluated
7010a31e541f32d2be721e2de348df75c9b36876a3ed304877fc0abda1d37a58 draft/2020-12/meta/validation
exit=0
$ grep -n 'loadPinnedAuthority' -A 30 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/LocalJsonSchemaRegistry.java | head -45
105: loadPinnedAuthority(mapper, LocalJsonSchemaRegistry.class.getClassLoader());
106-
107- Map<String, ParsedSource> parsedById = new LinkedHashMap<>();
108- Map<String, ParsedSource> parsedByResource = new LinkedHashMap<>();
109- exactSources.entrySet().stream()
110- .sorted(Map.Entry.comparingByKey())
111- .forEach(
112- entry -> {
113- SchemaSource source = entry.getValue();
114- if (source == null || !entry.getKey().equals(source.resourcePath())) {
115- throw new IllegalArgumentException(
116- "schema resource map key must equal its non-null exact source path");
117- }
118- ParsedSource parsed = parseAndCheck(source);
119- if (parsedByResource.putIfAbsent(source.resourcePath(), parsed) != null) {
120- throw new IllegalArgumentException(
121- "duplicate schema resource " + source.resourcePath());
122- }
123- if (parsedById.putIfAbsent(parsed.schemaId(), parsed) != null) {
124- throw new IllegalArgumentException("duplicate schema $id " + parsed.schemaId());
125- }
126- });
127-
128- validateAllReferences(parsedById);
129- SchemaRegistry registry = compileRegistry(parsedById);
130- validatePinnedAuthorityAgainstRuntime(registry, pinnedAuthority);
131- validateAgainstBundledMetaSchema(registry, parsedById.values());
132-
133- Map<String, CompiledSchema> byId = new LinkedHashMap<>();
134- Map<String, CompiledSchema> byResource = new LinkedHashMap<>();
135- parsedById.values().stream()
--
440: private static PinnedAuthority loadPinnedAuthority(ObjectMapper mapper, ClassLoader classLoader) {
441- byte[] manifestBytes = readRequiredClasspathBytes(classLoader, PINNED_AUTHORITY_MANIFEST);
442- String manifest;
443- try {
444- manifest =
445- StandardCharsets.UTF_8
446- .newDecoder()
447- .onMalformedInput(CodingErrorAction.REPORT)
448- .onUnmappableCharacter(CodingErrorAction.REPORT)
449- .decode(ByteBuffer.wrap(manifestBytes))
450- .toString();
451- } catch (CharacterCodingException exception) {
452- throw new IllegalArgumentException(
exit=0
=== 8.3 실행 probe: 매니페스트 해시가 실제 파일과 일치하는가 ===
$ cd adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12 && for f in draft/2020-12/schema draft/2020-12/meta/*; do printf '%s %s\n' "$(sha256sum "$f" | cut -d' ' -f1)" "$f"; done
41da76f5afb7ce062d248f762463a92f7ca47e4e0f905b224ba6afeef91ded0f draft/2020-12/schema
c4a6e4147b91fef7fea6dc058cb1bf93402f7414b76578a8b16aaf1dad6aacef draft/2020-12/meta/applicator
08343747764e4a5814262793cf4d652057a7913863c5950d43297e8e1fdac5b6 draft/2020-12/meta/content
c2d12a8e4dd11d336dfc83a3f663aa4c69f0b49b3beb094ffeb25b5316f4803d draft/2020-12/meta/core
abc775adfefd89d22358170d9bf93f4ebd2349563bbbedd60f02bef7c812bcc0 draft/2020-12/meta/format-annotation
6a5a8e13c605e3eff51f9bf8da18078880d81ff1634e391760ccc2e16ee2146f draft/2020-12/meta/format-assertion
8f76d6e14f41b9b92ef933b708cdc5144c8b5268651ad11918485fb1754f1c76 draft/2020-12/meta/meta-data
2dbfbcb73994b670b0976492adee1fffb46c21682784d2f5a4ca561f9e2d0cb4 draft/2020-12/meta/unevaluated
7010a31e541f32d2be721e2de348df75c9b36876a3ed304877fc0abda1d37a58 draft/2020-12/meta/validation
exit=0
=== 8.4 test 이름 ===
$ git ls-files 'adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/envelope' | xargs -n1 basename
basename: missing operand
Try 'basename --help' for more information.
exit=123
$ git grep -h ' void [a-z]' -- 'adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/envelope' | sed 's/^ *//'
exit=0