Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/112-pool-lane-claim-registry-reachability.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

114 lines
6.4 KiB
Plaintext

Sub-scope 12 negative-space probes: lane claims, release-gate membership, reachability
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
executedAt=2026-08-29T14:41:21+00:00
cwd=/shared/codebase/clean-architecture-backend-template/src
observation boundary: tracked build/registry/workflow/doc files at this revision.
=== A. release registry gate names and tasks ===
$ python3 -c "import json;d=json.load(open(\"config/jpa/release-registry.json\"));print(len(d[\"gates\"]));[print(g[\"name\"],g[\"task\"],g[\"blocking\"]) for g in d[\"gates\"]]"
6
postgresql-contract :adapter:outbound:persistence-jpa:jpaPlatformContractTest True
completion-unknown-no-retry :adapter:outbound:persistence-jpa:jpaPlatformFailureTest True
osiv-disabled :app-bootstrap:test True
flyway-validate :adapter:outbound:persistence-jpa:jpaPlatformMigrationTest True
runtime-role-no-ddl :adapter:outbound:persistence-jpa:jpaPlatformSecurityTest True
collection-fetch-pagination :adapter:outbound:persistence-jpa:jpaPlatformQueryPlanTest True
exit=0
=== B. is the pool lane a registered gate? ===
$ grep -n -i pool config/jpa/release-registry.json
exit=1
$ grep -n -i pool ../docs/jpa/support-matrix.md
exit=1
$ grep -n -i pool adapter/outbound/persistence-jpa/src/testkit/java/dev/caskeleton/adapter/outbound/persistence/testkit/release/JpaReleaseGate.java
exit=1
=== C. where the pool lane is wired ===
$ grep -n jpaPlatformPoolContractTest adapter/outbound/persistence-jpa/build.gradle
287:def jpaPlatformPoolContractTest = tasks.register('jpaPlatformPoolContractTest', Test) {
309: dependsOn jpaPlatformPoolContractTest
exit=0
$ grep -rn jpaPlatformPoolContractTest ../.github/workflows
../.github/workflows/jpa-nightly.yml:132: :adapter:outbound:persistence-jpa:jpaPlatformPoolContractTest
exit=0
$ grep -n -A10 "register..jpaPlatformReleaseGate" adapter/outbound/persistence-jpa/build.gradle
300:tasks.register('jpaPlatformReleaseGate') {
301- group = 'verification'
302- description = 'Runs every JPA platform lane required for a release (design §41).'
303- dependsOn tasks.named('test')
304- dependsOn jpaPlatformContractTest
305- dependsOn jpaPlatformMigrationTest
306- dependsOn jpaPlatformFailureTest
307- dependsOn jpaPlatformQueryPlanTest
308- dependsOn jpaPlatformSecurityTest
309- dependsOn jpaPlatformPoolContractTest
310-}
exit=0
=== D. what the lane files actually assert ===
$ grep -n "assertThat\|assertThatThrownBy\|@DisplayName" adapter/outbound/persistence-jpa/src/jpaPlatformPerformanceTest/java/dev/caskeleton/adapter/outbound/persistence/platform/pool/PoolPressureContractTest.java
3:import static org.assertj.core.api.Assertions.assertThat;
27: @DisplayName("pending count and acquire latency are reported together")
31: assertThat(measurement.pending()).isEqualTo(3);
32: assertThat(measurement.acquireLatency()).isEqualTo(Duration.ofMillis(80));
33: assertThat(measurement.total()).isEqualTo(6);
34: assertThat(measurement.saturated()).isTrue();
38: @DisplayName("a REQUIRES_NEW depth of one needs two connections per concurrent thread")
45: assertThat(required)
exit=0
$ grep -n "assertThat\|assertThatThrownBy\|@DisplayName" adapter/outbound/persistence-jpa/src/jpaPlatformPerformanceTest/java/dev/caskeleton/adapter/outbound/persistence/platform/pool/HikariPoolSaturationContractTest.java
3:import static org.assertj.core.api.Assertions.assertThat;
4:import static org.assertj.core.api.Assertions.assertThatThrownBy;
51: @DisplayName("a saturated pool fails within its acquisition timeout")
61: assertThatThrownBy(pool::getConnection).isInstanceOf(SQLException.class);
64: assertThat(waited)
76: @DisplayName("releasing a connection lets the next caller through")
84: assertThat(third.isValid(1)).isTrue();
91: @DisplayName("the measurement reports what the pool is actually doing")
103: assertThat(measurement.active()).isEqualTo(1);
104: assertThat(measurement.total()).isGreaterThanOrEqualTo(1);
105: assertThat(held.isValid(1)).isTrue();
exit=0
$ grep -n "assertThat\|assertThatThrownBy\|@DisplayName" adapter/outbound/persistence-jpa/src/jpaPlatformPerformanceTest/java/dev/caskeleton/adapter/outbound/persistence/platform/pool/RequiresNewPoolPressureContractTest.java
3:import static org.assertj.core.api.Assertions.assertThat;
4:import static org.assertj.core.api.Assertions.assertThatThrownBy;
44: @DisplayName("a pool of one deadlocks the moment an inner transaction is needed")
50: assertThatThrownBy(pool::getConnection)
60: @DisplayName("a pool of two serves the same nesting")
68: assertThat(inner.isValid(1)).isTrue();
69: assertThat(inner).isNotSameAs(outer);
79: @DisplayName("the sizing rule matches the observed requirement")
86: assertThat(required)
exit=0
=== E. does any lane assertion read a non-zero pending count from a real pool? ===
$ grep -rn "getThreadsAwaitingConnection\|pending()\|saturated()" adapter/outbound/persistence-jpa/src/jpaPlatformPerformanceTest
adapter/outbound/persistence-jpa/src/jpaPlatformPerformanceTest/java/dev/caskeleton/adapter/outbound/persistence/platform/pool/HikariPoolSaturationContractTest.java:100: bean.getThreadsAwaitingConnection(),
adapter/outbound/persistence-jpa/src/jpaPlatformPerformanceTest/java/dev/caskeleton/adapter/outbound/persistence/platform/pool/PoolPressureContractTest.java:31: assertThat(measurement.pending()).isEqualTo(3);
adapter/outbound/persistence-jpa/src/jpaPlatformPerformanceTest/java/dev/caskeleton/adapter/outbound/persistence/platform/pool/PoolPressureContractTest.java:34: assertThat(measurement.saturated()).isTrue();
exit=0
=== F. nightly workflow claim text ===
$ sed -n 122,135p ../.github/workflows/jpa-nightly.yml
- name: Verify pool saturation and REQUIRES_NEW connection behaviour
working-directory: src
# A behaviour contract, not a measurement. This step used to switch assertions off with an
# explicit property and call the result a certification, so the only threshold it ever
# asserted was that thresholds were not being asserted. What
# it checks now — that REQUIRES_NEW needs two connections per concurrent thread, that a
# saturated pool reports its pending count, that a caller waits rather than proceeding
# without a connection — is true on any runner, so there is nothing to switch off.
run: >-
./gradlew
:adapter:outbound:persistence-jpa:jpaPlatformPoolContractTest
--no-daemon
--stacktrace
exit=0