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>
4.5 KiB
Advanced — Search and Vector Search
Capabilities: MongoCapability.SEARCH, MongoCapability.VECTOR_SEARCH
Properties: ca-skeleton.persistence-mongo.advanced.search.enabled,
ca-skeleton.persistence-mongo.advanced.vector-search.enabled
Status: Experimental (design §3.3). Hybrid search likewise.
Requirements
| Topology | A deployment with the search service. Atlas Local in a container is a pull-request convenience and is not release evidence. |
| Privilege | MongoPrincipalRole.SEARCH_ADMIN for index management; the application role queries only. |
| Gate | MongoAtlasCapabilityContractSuite on the actual target deployment. |
1. Created is not ready
MongoSearchIndexState: CREATED → BUILDING → READY, plus FAILED and DELETING.
MongoSearchReadinessGate.requireReady(state) refuses anything but READY. A search index is built
asynchronously: the create call returns immediately and the index answers queries with partial
results while building. Not an error, not empty — partial. A deployment that creates an index and
starts querying serves incomplete results for as long as the build takes, and nothing reports it.
2. Search indexes are not application-owned
MongoSearchIndexDescriptor.metadataOwnership() is MongoMetadataOwnership.SEARCH_MANAGED, and
droppableByApplicationDrift() is false. The index reconciliation described in
ADR-MONGO-004 must not drop it.
3. Query guardrails
MongoSearchQuery binds an index, an allowlist of paths, the search text and a result limit.
requireAllowedPaths(allowed)raisesMongoOperationRejectedExceptionon a path outside the allowlist. Without it, a caller can search any indexed field, including ones indexed for a different purpose.- Search text length and result count are bounded at construction. An unbounded search text is a cost multiplier on someone else's service.
4. Vector search
MongoVectorIndexDescriptor.cosine(path, dimensions) declares the index.
MongoEmbedding.forIndex(index, values) binds an embedding to it and rejects a dimension
mismatch — a 1536-dimension embedding against a 768-dimension index is not a runtime degradation,
it is a category error, and catching it at construction beats catching it as a confusing server
message.
MongoEmbedding copies its backing array in and out. A vector that shares an array with its caller
can be mutated after the query is built, which produces a query nobody wrote.
MongoVectorQuery requires numCandidates > limit — searching 10 candidates to return 10 results is
an exhaustive scan wearing an ANN index's name. MongoVectorQuery.nearest(embedding, 10) uses the
standard 20× ratio (200 candidates for 10 results).
5. Relevance is the gate, not functionality
MongoVectorSearchBenchmarkGate.standard() requires recall alongside latency and index size.
requiredEvidence() names recall explicitly.
This is the difference between search and everything else in the platform. A vector index can be
functionally perfect — it accepts the index, accepts the query, returns k results, within the latency
budget — and return the wrong k. A gate that measures only latency certifies a fast wrong answer.
failures(recall, latencyMs, indexMb) reports which dimension failed so the finding is actionable.
6. Failure recovery
| Symptom | Cause | Action |
|---|---|---|
| Incomplete results after a deploy | Queried a BUILDING index |
Wait for READY. The gate prevents this; if it fired, something bypassed it. |
MongoOperationRejectedException on a path |
Path not in the allowlist | Add it deliberately, or fix the caller. |
| Dimension mismatch | Model changed | A new model means a new index. Build alongside, cut over, then retire. |
| Recall dropped without a code change | The index was rebuilt with different parameters, or the data distribution shifted | Re-run the benchmark gate; treat a recall regression like a failing test. |
Index FAILED |
Build error on the search service | Search-side diagnosis; the application must not fall back to a scan silently. |
7. Promotion evidence
Per ADR-MONGO-ADV-001: the actual target
deployment (not Atlas Local), security review of SEARCH_ADMIN, a rebuild path, failure cases
(non-ready index refused, disallowed path refused, dimension mismatch refused), this document as the
runbook, and relevance evidence. Search and vector search do not promote on functional success.