Files
clean-architecture-backend-…/docs/adr/ADR-MONGO-ADV-001-capability-promotion.md
T
DongHyeonkaandClaude Opus 5 d57d2f62a0 feat(mongodb): implement the MongoDB document persistence platform
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>
2026-08-14 13:41:00 +09:00

4.1 KiB

ADR-MONGO-ADV-001 — Advanced capability promotion

  • Status: Accepted
  • Date: 2026-08-13
  • Design source: design §2 (D-15), §3.2–§3.3; Advanced expansion plan Task 15

Context

Sharding, time series, CSFLE, Queryable Encryption, search, vector search and multi-tenancy each work in a demo within an afternoon. What they do not do is behave the same way in production, and the differences are not discovered by functional tests:

  • Sharding changes which queries are efficient. A query that misses the shard key becomes scatter-gather, which passes every test on a one-shard cluster.
  • Encryption's failure modes are KMS failure modes — wrong key, revoked permission, mid-rotation — none of which occur against a local key provider.
  • Search and vector search can be functionally correct and useless: the index returns results, and the results are not relevant. Recall is not visible in a pass/fail assertion.
  • Database-per-tenant works until the tenant count crosses what the connection and file-handle budget supports, which is an operational property, not a code property.

The failure mode this ADR prevents is a capability marked "done" on the strength of a green test that never touched the environment where it will run.

Decision

Every Advanced and Experimental capability is an opt-in module behind its own flag, and promotion requires evidence, not confidence.

Enablement

MongoAdvancedCapabilityFlags gates construction of every Advanced entry point. A disabled capability does not produce a runtime warning — the type refuses to be constructed, naming the property that enables it (MongoAdvancedCapabilityFlags.propertyFor(capability)). Being on the classpath is not being enabled, and stableNeverDependsOnAdvanced (ArchUnit) keeps the Stable surface free of them.

Promotion evidence

MongoAdvancedPromotionGate.verify(evidence) requires every category:

Category Means
stable-platform The Stable release gate passed on the same revision.
actual-topology The capability ran on the real topology — a real sharded cluster, the real KMS, the actual target deployment. Atlas Local is a pull-request convenience and explicitly not release evidence (MongoAtlasCapabilityContractSuite.Environment.ATLAS_LOCAL).
security Privileges reviewed; the capability's admin role is separate from the application role.
migration A documented path in and, where the capability is irreversible, an explicit statement that there is no path back.
failure Negative cases fail closed: wrong key, missing permission, rotation, non-ready index, unrouted query.
runbook A runbook exists for the capability's characteristic incident.

Additional per-capability requirements

  • Search / vector search: relevance and performance evidence, not functional success alone. MongoVectorSearchBenchmarkGate requires recall alongside latency and index size; a gate that measures only latency certifies a fast wrong answer.
  • Database-per-tenant and reshard orchestration remain Experimental until operational scale evidence exists. Both are correct in the small and unbounded in the large.
  • Reshard requires an explicit ReshardApproval — a named approver and a stated window. It rewrites the collection.

Promotion does not change the dependency boundary

A capability promoted to Stable remains an opt-in module unless a later starter ADR changes the dependency boundary. Promotion is a statement about evidence, not an invitation to add a transitive dependency to every service.

Consequences

Positive. No capability reaches production on the strength of a container-only test. The evidence list is the same for every capability, so promotion is reviewable rather than negotiated.

Negative. Promotion requires access to real infrastructure — a sharded cluster, a real KMS, the target deployment. That is the cost of the guarantee: the alternative is finding out in production, where encryption and sharding are both expensive to reverse.

Verification

bash scripts/verify-mongodb-advanced.sh