# 카드 전체와 selected 카드의 태그 커버리지 카드 17 개 · implemented-candidate 6 · not-implemented 4 · selected 7 jpa-observability-lifecycle 태그 4 · 시나리오 2 · task-claim 0 · support-task 0 · 레지스트리가 덮지 않는 태그 ['no-skip'] jpa-security-baseline 태그 6 · 시나리오 3 · task-claim 1 · support-task 3 · 레지스트리가 덮지 않는 태그 ['no-skip'] jpa-flyway-migration 태그 4 · 시나리오 4 · task-claim 0 · support-task 0 · 레지스트리가 덮지 않는 태그 ['no-skip'] jpa-transaction-runtime 태그 4 · 시나리오 7 · task-claim 0 · support-task 0 · 레지스트리가 덮지 않는 태그 ['no-skip'] jpa-aggregate-store 태그 4 · 시나리오 1 · task-claim 0 · support-task 0 · 레지스트리가 덮지 않는 태그 ['no-skip'] jpa-query-model 태그 4 · 시나리오 1 · task-claim 0 · support-task 0 · 레지스트리가 덮지 않는 태그 ['no-skip'] jpa-primary-foundation 태그 4 · 시나리오 0 · task-claim 2 · support-task 5 · 레지스트리가 덮지 않는 태그 ['base-card-manifests', 'no-skip'] # 그 두 태그는 레지스트리가 덮을 수 없다 build.gradle 이 no-skip 을 필수로 요구하면서 클레임에서는 빼는 자리 : build.gradle:1672 if (!requiredEvidence.contains('no-skip')) { build.gradle:1673 violations << "${cardId}: required-evidence must include no-skip" build.gradle:1674 } build.gradle:1675 } build.gradle:1676 build.gradle:1677 Object migrationNode = card.migration build.gradle:1678 Set allowedEvidenceClaims = requiredEvidence build.gradle:1679 .findAll { String requirement -> requirement != 'no-skip' } build.gradle:1680 .toSet() 생성기가 JUnit XML 결과로 채우는 자리 : jpa-evidence.gradle:676 } as int jpa-evidence.gradle:677 int errorCount = testResults.sum { jpa-evidence.gradle:678 Map result -> result.errorCount as int jpa-evidence.gradle:679 } as int jpa-evidence.gradle:680 boolean noSkipResult = executedTestCount > 0 && jpa-evidence.gradle:681 skippedOrAbortedCount == 0 && jpa-evidence.gradle:682 failureCount == 0 && jpa-evidence.gradle:683 errorCount == 0 jpa-evidence.gradle:684 if (noSkipResult) { jpa-evidence.gradle:685 covered << 'no-skip' jpa-evidence.gradle:686 } jpa-evidence.gradle:687 if (cardId == 'jpa-primary-foundation' && jpa-evidence.gradle:688 (card.prerequisites as List).every { jpa-evidence.gradle:689 Object prerequisite -> manifestIds.containsKey(prerequisite as String) jpa-evidence.gradle:690 }) { jpa-evidence.gradle:691 covered << 'base-card-manifests' jpa-evidence.gradle:692 } # 시나리오가 가리키는 시험이 프로덕션을 지나는가 == jpa-aggregate-store 필수 태그 : ['real-postgresql', 'mapping', 'optimistic-conflict', 'no-skip'] 시나리오 : roundTripsUuidAndInstantAndDetectsExpectedVersionConflict 덮는 태그 : ['real-postgresql', 'mapping', 'optimistic-conflict'] == jpa-query-model 필수 태그 : ['real-postgresql', 'query-contract', 'query-plan', 'no-skip'] 시나리오 : boundedKeysetQueryUsesTheRepresentativeIndex 덮는 태그 : ['real-postgresql', 'query-contract', 'query-plan'] == jpa-observability-lifecycle 필수 태그 : ['real-postgresql', 'lifecycle', 'observability', 'no-skip'] 시나리오 : startsPostgreSql16WithUtcAndProvidesAValidConnection 덮는 태그 : ['real-postgresql', 'lifecycle'] 시나리오 : poolCapacityExhaustionAndShutdownAreBoundedAndObservable 덮는 태그 : ['observability'] # 그 세 시험의 본문 PostgreSqlAggregateIntegrationTest.java:19 @BeforeAll PostgreSqlAggregateIntegrationTest.java:20 static void startPostgreSql() throws Exception { PostgreSqlAggregateIntegrationTest.java:21 PostgreSqlReadinessSupport.assertDockerAvailable(); PostgreSqlAggregateIntegrationTest.java:22 postgres = PostgreSqlReadinessSupport.start(); PostgreSqlAggregateIntegrationTest.java:23 postgres.execute( PostgreSqlAggregateIntegrationTest.java:24 "create table readiness_aggregate(" PostgreSqlAggregateIntegrationTest.java:25 + "id uuid primary key, title varchar(100) not null, " PostgreSqlAggregateIntegrationTest.java:26 + "occurred_at timestamptz not null, version bigint not null)"); PostgreSqlAggregateIntegrationTest.java:27 } PostgreSqlAggregateIntegrationTest.java:28 PostgreSqlAggregateIntegrationTest.java:29 @AfterAll PostgreSqlAggregateIntegrationTest.java:30 static void stopPostgreSql() { PostgreSqlAggregateIntegrationTest.java:36 @Test PostgreSqlAggregateIntegrationTest.java:37 void roundTripsUuidAndInstantAndDetectsExpectedVersionConflict() throws Exception { PostgreSqlAggregateIntegrationTest.java:38 UUID id = UUID.randomUUID(); PostgreSqlAggregateIntegrationTest.java:39 Instant occurredAt = Instant.parse("2026-07-28T12:00:00.123456Z"); PostgreSqlAggregateIntegrationTest.java:40 try (Connection connection = postgres.connection(); PostgreSqlAggregateIntegrationTest.java:41 PreparedStatement insert = PostgreSqlAggregateIntegrationTest.java:42 connection.prepareStatement( PostgreSqlAggregateIntegrationTest.java:43 "insert into readiness_aggregate(id,title,occurred_at,version) " PostgreSqlAggregateIntegrationTest.java:44 + "values (?,?,?,0)")) { PostgreSqlAggregateIntegrationTest.java:45 insert.setObject(1, id); PostgreSqlAggregateIntegrationTest.java:46 insert.setString(2, "aggregate"); PostgreSqlAggregateIntegrationTest.java:47 insert.setObject(3, occurredAt.atOffset(ZoneOffset.UTC)); PostgreSqlAggregateIntegrationTest.java:48 assertThat(insert.executeUpdate()).isOne(); PostgreSqlAggregateIntegrationTest.java:49 } PostgreSqlAggregateIntegrationTest.java:50 PostgreSqlAggregateIntegrationTest.java:51 try (Connection connection = postgres.connection(); PostgreSqlAggregateIntegrationTest.java:52 PreparedStatement query = PostgreSqlAggregateIntegrationTest.java:53 connection.prepareStatement( PostgreSqlAggregateIntegrationTest.java:54 "select id,title,occurred_at,version from readiness_aggregate where id=?")) { PostgreSqlAggregateIntegrationTest.java:55 query.setObject(1, id); PostgreSqlAggregateIntegrationTest.java:56 try (ResultSet row = query.executeQuery()) { PostgreSqlAggregateIntegrationTest.java:57 assertThat(row.next()).isTrue(); PostgreSqlAggregateIntegrationTest.java:58 assertThat(row.getObject(1, UUID.class)).isEqualTo(id); PostgreSqlAggregateIntegrationTest.java:59 assertThat(row.getString(2)).isEqualTo("aggregate"); PostgreSqlAggregateIntegrationTest.java:60 assertThat(row.getObject(3, java.time.OffsetDateTime.class).toInstant()) PostgreSqlAggregateIntegrationTest.java:61 .isEqualTo(occurredAt); PostgreSqlAggregateIntegrationTest.java:62 assertThat(row.getLong(4)).isZero(); PostgreSqlAggregateIntegrationTest.java:63 } PostgreSqlAggregateIntegrationTest.java:64 } PostgreSqlAggregateIntegrationTest.java:65 PostgreSqlAggregateIntegrationTest.java:66 try (Connection first = postgres.connection(); PostgreSqlAggregateIntegrationTest.java:67 Connection second = postgres.connection(); PostgreSqlAggregateIntegrationTest.java:68 PreparedStatement firstUpdate = PostgreSqlAggregateIntegrationTest.java:69 first.prepareStatement( PostgreSqlAggregateIntegrationTest.java:70 "update readiness_aggregate set title=?,version=version+1 " PostgreSqlAggregateIntegrationTest.java:71 + "where id=? and version=?"); PostgreSqlAggregateIntegrationTest.java:72 PreparedStatement secondUpdate = PostgreSqlAggregateIntegrationTest.java:73 second.prepareStatement( PostgreSqlAggregateIntegrationTest.java:74 "update readiness_aggregate set title=?,version=version+1 " PostgreSqlAggregateIntegrationTest.java:75 + "where id=? and version=?")) { PostgreSqlAggregateIntegrationTest.java:76 first.setAutoCommit(false); PostgreSqlAggregateIntegrationTest.java:77 second.setAutoCommit(false); PostgreSqlAggregateIntegrationTest.java:78 bindUpdate(firstUpdate, "first", id, 0); PostgreSqlAggregateIntegrationTest.java:79 bindUpdate(secondUpdate, "second", id, 0); PostgreSqlAggregateIntegrationTest.java:80 assertThat(firstUpdate.executeUpdate()).isOne(); PostgreSqlAggregateIntegrationTest.java:81 first.commit(); PostgreSqlAggregateIntegrationTest.java:82 assertThat(secondUpdate.executeUpdate()).isZero(); PostgreSqlAggregateIntegrationTest.java:83 second.rollback(); PostgreSqlAggregateIntegrationTest.java:84 } PostgreSqlQueryIntegrationTest.java:22 @BeforeAll PostgreSqlQueryIntegrationTest.java:23 static void startPostgreSql() throws Exception { PostgreSqlQueryIntegrationTest.java:24 PostgreSqlReadinessSupport.assertDockerAvailable(); PostgreSqlQueryIntegrationTest.java:25 postgres = PostgreSqlReadinessSupport.start(); PostgreSqlQueryIntegrationTest.java:26 postgres.execute( PostgreSqlQueryIntegrationTest.java:27 "create table readiness_query(" PostgreSqlQueryIntegrationTest.java:28 + "id uuid primary key, occurred_at timestamptz not null, payload text not null)"); PostgreSqlQueryIntegrationTest.java:29 postgres.execute("create index ix_readiness_query_keyset on readiness_query(occurred_at,id)"); PostgreSqlQueryIntegrationTest.java:30 postgres.execute( PostgreSqlQueryIntegrationTest.java:31 "insert into readiness_query(id,occurred_at,payload) " PostgreSqlQueryIntegrationTest.java:32 + "select gen_random_uuid(), " PostgreSqlQueryIntegrationTest.java:33 + "timestamptz '2026-01-01T00:00:00Z' + (n || ' milliseconds')::interval, " PostgreSqlQueryIntegrationTest.java:34 + "'payload-' || n from generate_series(1,1000) n"); PostgreSqlQueryIntegrationTest.java:35 postgres.execute("analyze readiness_query"); PostgreSqlQueryIntegrationTest.java:45 @Test PostgreSqlQueryIntegrationTest.java:46 void boundedKeysetQueryUsesTheRepresentativeIndex() throws Exception { PostgreSqlQueryIntegrationTest.java:47 OffsetDateTime cursorTime = OffsetDateTime.of(2026, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC); PostgreSqlQueryIntegrationTest.java:48 UUID cursorId = new UUID(0, 0); PostgreSqlQueryIntegrationTest.java:49 List ids = new ArrayList<>(); PostgreSqlQueryIntegrationTest.java:50 String query = PostgreSqlQueryIntegrationTest.java:51 "select id from readiness_query " PostgreSqlQueryIntegrationTest.java:52 + "where (occurred_at,id) > (?,?) " PostgreSqlQueryIntegrationTest.java:53 + "order by occurred_at,id limit ?"; PostgreSqlQueryIntegrationTest.java:54 PostgreSqlQueryIntegrationTest.java:55 try (Connection connection = postgres.connection(); PostgreSqlQueryIntegrationTest.java:56 PreparedStatement statement = connection.prepareStatement(query)) { PostgreSqlQueryIntegrationTest.java:57 statement.setObject(1, cursorTime); PostgreSqlQueryIntegrationTest.java:58 statement.setObject(2, cursorId); PostgreSqlQueryIntegrationTest.java:59 statement.setInt(3, 25); PostgreSqlQueryIntegrationTest.java:60 try (ResultSet rows = statement.executeQuery()) { PostgreSqlQueryIntegrationTest.java:61 while (rows.next()) { PostgreSqlQueryIntegrationTest.java:62 ids.add(rows.getObject(1, UUID.class)); PostgreSqlQueryIntegrationTest.java:63 } PostgreSqlQueryIntegrationTest.java:64 } PostgreSqlQueryIntegrationTest.java:65 } PostgreSqlQueryIntegrationTest.java:66 assertThat(ids).hasSize(25).doesNotHaveDuplicates(); PostgreSqlQueryIntegrationTest.java:67 PostgreSqlQueryIntegrationTest.java:68 try (Connection connection = postgres.connection(); PostgreSqlQueryIntegrationTest.java:69 Statement setup = connection.createStatement()) { PostgreSqlQueryIntegrationTest.java:70 setup.execute("set enable_seqscan=off"); PostgreSqlQueryIntegrationTest.java:71 try (PreparedStatement explain = PostgreSqlQueryIntegrationTest.java:72 connection.prepareStatement("explain (format json) " + query)) { PostgreSqlQueryIntegrationTest.java:73 explain.setObject(1, cursorTime); PostgreSqlQueryIntegrationTest.java:74 explain.setObject(2, cursorId); PostgreSqlQueryIntegrationTest.java:75 explain.setInt(3, 25); PostgreSqlQueryIntegrationTest.java:76 try (ResultSet plan = explain.executeQuery()) { PostgreSqlQueryIntegrationTest.java:77 assertThat(plan.next()).isTrue(); PostgreSqlQueryIntegrationTest.java:78 assertThat(plan.getString(1)).contains("ix_readiness_query_keyset"); PostgreSqlQueryIntegrationTest.java:79 } PostgreSqlQueryIntegrationTest.java:80 } PostgreSqlLifecycleIntegrationTest.java:51 @Test PostgreSqlLifecycleIntegrationTest.java:52 @Timeout(10) PostgreSqlLifecycleIntegrationTest.java:53 void poolCapacityExhaustionAndShutdownAreBoundedAndObservable() throws Exception { PostgreSqlLifecycleIntegrationTest.java:54 PostgreSqlReadinessSupport bounded = PostgreSqlReadinessSupport.start(2, 300); PostgreSqlLifecycleIntegrationTest.java:55 HikariDataSource dataSource = bounded.dataSource(); PostgreSqlLifecycleIntegrationTest.java:56 try { PostgreSqlLifecycleIntegrationTest.java:57 try (Connection first = bounded.connection(); PostgreSqlLifecycleIntegrationTest.java:58 Connection second = bounded.connection()) { PostgreSqlLifecycleIntegrationTest.java:59 PoolSnapshot saturated = snapshot(dataSource); PostgreSqlLifecycleIntegrationTest.java:60 assertThat(saturated.state()).isEqualTo(PoolState.SATURATED); PostgreSqlLifecycleIntegrationTest.java:61 assertThat(saturated.activeConnections()).isEqualTo(2); PostgreSqlLifecycleIntegrationTest.java:62 assertThat(saturated.maximumConnections()).isEqualTo(2); PostgreSqlLifecycleIntegrationTest.java:63 assertThat(saturated.boundedTags()) PostgreSqlLifecycleIntegrationTest.java:64 .containsExactlyInAnyOrderEntriesOf( PostgreSqlLifecycleIntegrationTest.java:65 java.util.Map.of("component", "postgresql-primary", "state", "saturated")); PostgreSqlLifecycleIntegrationTest.java:66 PostgreSqlLifecycleIntegrationTest.java:107 private record PoolSnapshot( PostgreSqlLifecycleIntegrationTest.java:108 PoolState state, PostgreSqlLifecycleIntegrationTest.java:109 int activeConnections, PostgreSqlLifecycleIntegrationTest.java:110 int idleConnections, PostgreSqlLifecycleIntegrationTest.java:111 int totalConnections, PostgreSqlLifecycleIntegrationTest.java:112 int awaitingConnections, PostgreSqlLifecycleIntegrationTest.java:113 int maximumConnections) { PostgreSqlLifecycleIntegrationTest.java:114 PostgreSqlLifecycleIntegrationTest.java:115 private Map boundedTags() { PostgreSqlLifecycleIntegrationTest.java:116 return Map.of( PostgreSqlLifecycleIntegrationTest.java:117 "component", "postgresql-primary", "state", state.name().toLowerCase(Locale.ROOT)); PostgreSqlLifecycleIntegrationTest.java:118 } PostgreSqlLifecycleIntegrationTest.java:119 } # 그 시험들이 프로덕션 타입에 닿는가 PostgreSqlAggregateIntegrationTest.java dev.caskeleton 를 import 하는 줄 : 0 개 PostgreSqlQueryIntegrationTest.java dev.caskeleton 를 import 하는 줄 : 0 개 PostgreSqlLifecycleIntegrationTest.java dev.caskeleton 를 import 하는 줄 : 0 개 [대조] 같은 소스 세트가 훑은 파일 : 27 개 import 만이 아니라 이름 단위로 훑어도 : PostgreSqlAggregateIntegrationTest.java 프로덕션에 정의된 타입 이름 : 0 개 PostgreSqlQueryIntegrationTest.java 프로덕션에 정의된 타입 이름 : 0 개 PostgreSqlLifecycleIntegrationTest.java 프로덕션에 정의된 타입 이름 : 0 개 [대조] PostgreSqlTransactionIntegrationTest 에 같은 검사를 걸면 : 프로덕션에 정의된 타입 이름 : 15 개 두 시험이 쓰는 테이블 : readiness_aggregate readiness_query 그 이름이 프로덕션 소스나 마이그레이션에 나오는가 : 0 개 [대조] 그 검색이 훑은 main 파일 : 4714 개 postgresql-primary 가 프로덕션에 나오는 파일 : 0 개 # 대조 — 시나리오 일곱을 가진 카드 필수 태그 : ['real-postgresql', 'concurrency', 'fault', 'no-skip'] 시나리오 : appliesTransactionLocalTimeoutsBeforeWorkAndResetsThemAfterCommit -> ['real-postgresql'] 시나리오 : actionFailureProducesAConfirmedRollback -> ['fault'] 시나리오 : serializableConflictIsRetriedOnlyByTheReplaySafePolicy -> ['concurrency'] 시나리오 : deterministicDeadlockProducesExactlyOneTypedDeadlockFailure -> ['concurrency', 'fault'] 시나리오 : lockAndStatementTimeoutsRollbackWithinTheConfiguredBounds -> ['fault'] 시나리오 : poolExhaustionRejectsBeforeApplicationWorkStarts -> ['concurrency', 'fault'] 시나리오 : connectionLossDuringCommitIsIndeterminateAndNeverBlindlyRetried -> ['fault'] PostgreSqlTransactionIntegrationTest.java 가 dev.caskeleton 를 import 하는 줄 : 15 개 :6 import dev.caskeleton.adapter.outbound.persistence.failure.PersistenceExceptionTranslator; :7 import dev.caskeleton.adapter.outbound.persistence.failure.StandardSqlStateErrorMapping; :8 import dev.caskeleton.adapter.outbound.persistence.postgresql.PostgreSqlLocalTimeoutConfigurer; :9 import dev.caskeleton.adapter.outbound.persistence.postgresql.PostgreSqlSqlStateErrorMapping; :10 import dev.caskeleton.adapter.outbound.persistence.transaction.JpaTransactionSettings; :11 import dev.caskeleton.adapter.outbound.persistence.transaction.SpringTransactionPort; :12 import dev.caskeleton.application.outbound.CallBudget; :13 import dev.caskeleton.application.transaction.OperationId;