`spotbugsTest` and `spotbugsSampleOffTest` on :app-bootstrap fail on DM_GC in
NotificationObservationTest, which predates this branch — the file arrives from
701ba67 and this branch never touched it. The merge only surfaces it.
The call is intentional and cannot be removed without removing the assertion:
Micrometer holds gauge referents weakly, so a gauge whose source object is
collected reports NaN from then on, and provoking a collection is the only way
to show the notification metrics do not have that defect.
Scoped to the one method by class and method name, per the filter's own rule
that entries be narrow — a System.gc() anywhere else stays reportable.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Implements the Stable and Experimental JPA persistence platform designs
against real PostgreSQL, adapted to this repository's fail-closed 19-leaf
registry.
The design models the platform as 25 Gradle projects. `src/settings.gradle`
throws unless the registry holds exactly 19 leaves, so the plan's modules
become packages inside `:adapter:outbound:persistence-jpa` (starter in
`:app-bootstrap`, testkit in its own source set). The full mapping, the
renames this repository's naming gate required, and every deliberate
substitution are recorded in `docs/jpa/repository-adaptation.md`.
Seven Docker-backed lanes replace the plan's seven JVM test suites. Each
fails closed: a lane that discovers nothing, or a container that cannot
start, is an error rather than a skip.
Three defects the contracts found against a real server:
- `CommitFailureClassifier` treated only SQLSTATE 40003, class 08, and
transport breaks as completion-unknown. A backend terminated mid-commit
reports 57P01, and the commit record may already be in the WAL — so a
possibly-committed transaction could be re-run. 57P01/57P02/57P03 now
classify as completion-unknown.
- `SchemaTenantMigrationOrchestrator` recorded `MigrateResult`'s target
version, which is empty for a tenant already current, reporting migrated
tenants as unmigrated during a partial rollout. It now reads the applied
version back from the tenant's schema history.
- `JpaStreamExecutor` checked only the declared return type for reactive
publishers, and `RegisteredPostgreSqlCopyLoader` passed the COPY timeout
to `SET`, which is parsed before parameter binding.
`JpaModuleBoundaryTest` enforces the plan's module map as package rules;
`verifyCleanArchitectureDependencies` governs edges between leaves and
cannot see these. Its first assertion is that the import is non-empty,
because every rule under it is a `noClasses()` rule and would pass
vacuously on an empty import.
Verified: 128 container tests across all seven lanes, 1183 unit tests,
`:adapter:outbound:persistence-jpa:check`, `:app-bootstrap:check`,
`verifyCleanArchitectureDependencies`, `verifyOneTypePerFile`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Maps the 31-module plan onto the registry's 19 leaves as packages; the two
edges the registry forbids (provider->httpclient, inbox->messaging) are
replaced by application-owned ports. See docs/notification/module-mapping.md.
Acceptance is not delivery: ProviderSubmissionResult refuses to carry a
delivery outcome, and AMBIGUOUS is a first-class terminal state that blocks
automatic retry and fallback until reconciliation resolves it.
Providers: SES (SigV4 + SNS callback), Twilio (X-Twilio-Signature +
reconciliation), FCM (FID-primary batch), APNs, Web Push (RFC 8030/8291/8292),
SMTP and webhook. Contact points are AES-256-GCM encrypted with a separate
HMAC lookup fingerprint; nothing raw reaches a log, metric tag or exception.
Dispatch commits the attempt row, calls the provider with no transaction open,
then records the outcome; the durable queue uses FOR UPDATE SKIP LOCKED.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brings in the mongodb-superpowers-package implementation (Stable Tasks 1-50,
Advanced Tasks 1-15) as packages inside the registered leaf
:adapter:outbound:persistence-mongo, with the design's module dependency table
enforced by ArchUnit.
Shared build files are untouched by this branch: src/build.gradle,
src/settings.gradle, config/architecture/modules.json and
app-bootstrap/build.gradle are all unchanged, so this merge does not move the
19-leaf registry and does not collide with the other platform branches still in
flight.
Verified before merging: scripts/verify-mongodb-platform.sh reports 9 lanes,
0 skipped, 0 failed, every evidence category produced.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Implements the mongodb-superpowers-package design: Stable Tasks 1-50 and
Advanced Tasks 1-15.
The design assumes 19 Stable + 12 Advanced Gradle projects under
modules/mongodb*. This repository's fail-closed registry declares exactly 19
leaf identities, so those modules become package boundaries inside the
registered leaf :adapter:outbound:persistence-mongo, with the design's module
dependency table enforced by ten ArchUnit rules. The mapping and every
deviation are recorded in docs/mongodb/repository-adaptation.md.
Contract highlights, all enforced by tests rather than convention:
- Transaction body retry and commit retry are separate loops. A new session per
body attempt; commit-only retry on an unknown commit. The body is never
replayed after a commit ambiguity, so a failover cannot become a duplicate.
- MongoExecutionOutcome keeps both ambiguous outcomes distinct from success and
failure, and MongoFailureContext records only the design-permitted fields.
- Failure classification reads server error labels before numeric codes.
- BSON representations come from a pinned manifest, never a library default,
and a golden type-signature gate fails on any drift.
- Index and validator changes go through the manifest and the admin plane;
metadata ownership gates every drop.
- Every Advanced capability refuses construction unless its flag is enabled.
Verified against real servers, not only unit tests. Running the lanes for the
first time exposed four defects that a green `check` had hidden:
- Four release lanes passed while executing zero tests; the gate now counts
executed tests per lane and fails on zero.
- The "single replica set" fixture was a standalone, because Testcontainers 2.x
needs withReplicaSet(); its test only asserted a connection string.
- The three-node fixture was three independent clusters, so no election could
occur, and awaitNewPrimary() compared against the post-stop primary.
- The migration lease checked modifiedCount, so a same-millisecond refresh read
as a lost lease.
scripts/verify-mongodb-platform.sh now reports:
9 lanes, 0 skipped, 0 failed, every evidence category produced.
scripts/verify-mongodb-advanced.sh reports NOT PROMOTABLE: actual-topology
evidence (real sharded cluster, real KMS, real target deployment) is
unobtainable here, so it is named rather than assumed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The review found one defect shape repeated across the platform: surfaces
that were declared, bound, and documented, but that nothing read. An
operator configuring fullUrlRecording, bodyLogging, retry.policy,
validatedDnsPinning, timeout.dns, or any of ten declared metric names got a
guarantee the code never delivered. Every such surface is now in exactly one
of three states -- wired for real, rejected at startup, or registered in a
test-enforced gap list with its reason. No silent no-ops remain.
P0:
- Activate the platform from bootstrap behind app.httpclient.enabled, with a
single auto-configuration importing the nine child configurations.
- Give the platform a strict, repository-level ENV contract: 74 leaf fields
derived from the settings record tree, unknown APP_HTTPCLIENT_* rejected.
- Route typed HTTP service clients through the call kernel via
KernelHttpExchangeAdapter, so they stop bypassing platform policy.
- Pin dynamic-target DNS resolution to the socket for the life of a call,
closing the resolve-then-connect TOCTOU / rebinding window.
- Actually transmit the idempotency key, and make retry eligibility depend on
transmission rather than on merely holding one.
- Reject reactive authentication and reactive redirect at startup instead of
declaring support that does not function.
- Fix the Reactor-only Stable contract row so the lane stops failing.
- Stop advertising HTTP/3 on a transport that negotiates HTTP/1.
P1 covers execution and retry accounting, redirect security (per-hop target
guarding, sensitive-header stripping, 303 body handling), runtime rotation
and transport resource ownership keyed by generation, dynamic-target
hardening (subdomain matching, global-unicast classification, strict CIDR
parsing), protocol intent, pool and timeout wiring, streaming and body
limits, observability parity, and OAuth single-flight refresh on a bounded
pool with a bounded wait.
P2 covers configuration and documentation drift, the Gradle check wiring for
the four hermetic lanes, and the CI gate matrix.
Two test-quality defects surfaced while closing these: the HTTP/2 stream
saturation test ran against cleartext HTTP/1.1 while asserting nothing about
the protocol, and an OAuth contention test slept on a latch that could fire
before the callers it meant to observe. Both now assert what their names
claim.
Verification run: :adapter:outbound:httpclient:check and :app-bootstrap:check
(checkstyle, spotless, spotbugs, and the four hermetic lanes),
verifyCleanArchitectureDependencies, verifyEnvKeys, verifyOneTypePerFile,
verifyDependencyLocks, the documentation and gate-matrix verifiers, and the
performance lane against a real TLS+ALPN HTTP/2 server.
Not executed, and tracked rather than claimed: Docker/Toxiproxy fault
injection, JMH, a real QUIC/HTTP3 server, a real Spring Framework 6.2
distribution (now a delegated-pending gate), live OAuth/TLS/proxy/DNS
integration, and a whole-repository check.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Snapshot of the in-flight state that already existed, identically, in both
this worktree and the main checkout before this session began: the initial
HTTP Client platform implementation (previously untracked), the redis-lab
removal, and the JPA / object-storage / notification integration work.
Kept separate from this session's HTTP Client review response, which lands
in the following commit, so the two bodies of work stay reviewable apart.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>