Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ All notable changes to this project are documented in this file.
## [Unreleased]

### Added
- Added `listCollections`, `drop`, and `dropDatabase` command handlers for metadata lookup and fixture cleanup flows.
- Added UTF `runCommand` importer support for `listCollections`, `distinct`, `drop`, and `dropDatabase`.
- Added tier-0 TTL runtime pruning for single-field `expireAfterSeconds` indexes using deterministic lazy cleanup.
- Added regression coverage for `findOneAndUpdate`/upsert duplicate-key behavior when `_id` matches an existing document but other predicates do not, including `$and`-wrapped filters.
- Added declarative fixture manifest schema (`fixture-manifest.v1`) with standardized `dev`/`smoke`/`full` profile model.
- Added fixture manifest loader/validator with path-aware aggregated validation errors.
Expand Down Expand Up @@ -44,8 +47,12 @@ All notable changes to this project are documented in this file.
- Added structured runtime logging contract (`onLog`, `logFormat`) with expanded log levels (`error`/`warn`/`info`/`debug`).

### Fixed
- Fixed deterministic R3 parity mismatches for dollar-prefixed `_id` subfields, replacement-style `updateMany`, and `createIndexes` inside transactions.
- Fixed upsert seed extraction to honor equality clauses nested inside `$and`, restoring duplicate-key behavior for `findOneAndUpdate` lock-style filters.

### Changed
- Default local project version moved to `0.1.6-SNAPSHOT`.

## [0.1.3] - 2026-02-24

### Added
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ This project targets integration-test compatibility for common Spring data paths

| Area | Current level | Notes |
| --- | --- | --- |
| Command surface | 22 handlers | Mix of `Supported` and `Partial` |
| Command surface | 25 handlers | Mix of `Supported` and `Partial` |
| Query language | Core comparison/logical/array/regex + partial `$expr` (including `$add` subset) | Advanced parity incomplete |
| Aggregation | Core stages + selected Tier-2 stages + minimal `$graphLookup` subset | Full operator coverage not implemented |
| Transactions | Single-process session/transaction flow | Namespace-aware commit merge + snapshot reads (`find`/`aggregate`/`countDocuments`) + deterministic retry labels/contracts |
Expand All @@ -183,10 +183,10 @@ This project targets integration-test compatibility for common Spring data paths

Support manifest summary:
- `Supported`: 7
- `Partial`: 6
- `Partial`: 7
- `Unsupported`: 0

Latest certification evidence (2026-02-28):
Historical certification evidence (2026-02-28; refresh on the release-candidate commit before tagging):
- Official Suite Sharded: run `22516323868` (`total=508`, `mismatch=0`, `error=0`)
- R3 Failure Ledger: run `22516324202` (`failureCount=0`)
- Complex Query Certification: run `22516137734` (`packVersion=complex-query-pack-v3`, `mismatchCount=0`, `unsupportedByPolicyCount=0`)
Expand Down Expand Up @@ -224,15 +224,16 @@ static void mongoProps(DynamicPropertyRegistry registry) {
## Implemented Command Handlers

- `hello`, `isMaster`, `ping`, `buildInfo`, `getParameter`
- `insert`, `find`, `aggregate`, `getMore`, `killCursors`
- `createIndexes`, `listIndexes`, `update`, `delete`, `bulkWrite`
- `insert`, `find`, `distinct`, `aggregate`, `getMore`, `killCursors`
- `createIndexes`, `listIndexes`, `listCollections`, `drop`, `dropDatabase`
- `update`, `delete`, `bulkWrite`
- `findAndModify`, `countDocuments`, `replaceOne`, `findOneAndUpdate`, `findOneAndReplace`
- `commitTransaction`, `abortTransaction`

## Known Limitations

- partial query and aggregation parity
- collation/TTL are currently metadata-focused, not full runtime parity
- collation and TTL runtime semantics are subset-only, not full server parity
- limited update operator coverage
- no multi-node replica-set or sharded topology semantics

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {
}

group = providers.gradleProperty("publishGroup").orElse("io.github.midagedev").get()
version = providers.gradleProperty("publishVersion").orElse("0.1.3-SNAPSHOT").get()
version = providers.gradleProperty("publishVersion").orElse("0.1.6-SNAPSHOT").get()

repositories {
mavenCentral()
Expand Down
20 changes: 14 additions & 6 deletions docs/COMPATIBILITY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Compatibility Matrix

Status date: 2026-02-28
Status date: 2026-05-09

This page describes implemented behavior in this repository. It is a code-level matrix, not a MongoDB claim.

Expand All @@ -25,13 +25,16 @@ Certification context:
| `killCursors` | Supported | Cursor cancellation |
| `createIndexes` | Partial | Key metadata accepted; runtime semantics partial |
| `listIndexes` | Partial | Metadata round-trip |
| `listCollections` | Partial | Cursor-shaped collection metadata subset for fixture discovery |
| `drop` | Partial | Collection cleanup subset with deterministic `NamespaceNotFound` error |
| `dropDatabase` | Partial | Database-scoped cleanup subset |
| `update` | Partial | Operator set intentionally limited; update pipeline subset supports `$set`/`$unset` stages without expression evaluation |
| `delete` | Supported | `limit` 0/1 behavior |
| `bulkWrite` | Partial | Ordered mode only (`ordered=true`); supports `insertOne/updateOne/updateMany/deleteOne/deleteMany/replaceOne` and stops on first write error |
| `clientBulkWrite` | Partial | UTF importer subset rewrites ordered single-namespace models to `bulkWrite`; mixed namespaces, `ordered=false`, and `verboseResults=true` are deterministic unsupported paths |
| `count` | Partial | Alias path routed through `countDocuments` semantics in the test-backend profile |
| `countDocuments` | Partial | Filter + skip/limit + hint/readConcern; collation subset applied to filter comparison |
| `runCommand` | Partial | UTF importer subset supports `ping`, `buildInfo`, `listIndexes`, `count`; other command names fail with deterministic unsupported reasons |
| `runCommand` | Partial | UTF importer subset supports `ping`, `buildInfo`, `listIndexes`, `listCollections`, `count`, `distinct`, `drop`, `dropDatabase`; other command names fail with deterministic unsupported reasons |
| `replaceOne` | Partial | Rewrites to single replacement `update` path (`multi=false`) |
| `findOneAndUpdate` | Partial | Rewrites to `findAndModify`; supports operator updates plus update-pipeline subset (`$set`/`$unset`, no expression evaluation), `arrayFilters` subset, and projection include/exclude subset (including `_id` override) |
| `findOneAndReplace` | Partial | Rewrites to `findAndModify`; replacement updates only; supports projection include/exclude subset (including `_id` override) |
Expand Down Expand Up @@ -80,13 +83,14 @@ Implemented stages:
- `$unionWith`
- `$graphLookup` (minimal subset: `from`, `startWith`, `connectFromField`, `connectToField`, `as`, optional `maxDepth`)
- `$out` (terminal string-target subset: replaces target collection contents and returns empty result set)
- `$merge` (terminal string-target or `{into: <collection>}` subset; merges by `_id`)

Not implemented or partial:
- unsupported stages return deterministic fail-fast
- many advanced expression operators are still missing
- `$group` accumulators other than `$sum` are not available
- `$unwind.includeArrayIndex` is not available
- `$merge` stage is excluded from current differential corpus
- `$merge` options beyond the terminal string / `{into: <collection>}` subset are deterministic unsupported paths
- `$graphLookup` options outside current subset (for example `depthField`, `restrictSearchWithMatch`) are deterministic unsupported paths
- `bypassDocumentValidation` for aggregate is excluded from current differential corpus

Expand Down Expand Up @@ -116,8 +120,8 @@ differential parity counts:
- unordered `insertMany` (`ordered=false`)
- unordered `bulkWrite` (`ordered=false`)
- `clientBulkWrite` with mixed namespaces, `ordered=false`, or `verboseResults=true`
- documents containing dot or dollar-prefixed field paths in insert payloads
- `runCommand` command names outside the imported subset (`ping`, `buildInfo`, `listIndexes`, `count`)
- dot/dollar insert payload forms outside the deterministic insert subset; dollar-prefixed subfields under `_id` fail with `code=52`
- `runCommand` command names outside the imported subset (`ping`, `buildInfo`, `listIndexes`, `listCollections`, `count`, `distinct`, `drop`, `dropDatabase`)
- update operations using unsupported `arrayFilters` forms (outside `$set`/`$unset` subset)
- update pipeline forms outside the supported subset (`$set`/`$unset` stages with literal values)
- replacement updates requested with `multi=true`
Expand All @@ -140,10 +144,11 @@ Supported metadata paths:
- `partialFilterExpression`
- `collation` metadata
- `expireAfterSeconds` metadata
- tier-0 TTL pruning for single-field non-partial TTL indexes

Current limitations:
- collation runtime semantics are subset-only (`locale`/`strength`/`caseLevel`)
- TTL expiration loop/clock behavior is not fully implemented
- TTL runtime behavior is lazy, in-process, and limited to date-like values on single-field non-partial indexes

## Transactions

Expand Down Expand Up @@ -183,6 +188,9 @@ Not in scope for this profile:
Known deterministic error classes:
- unknown command: `CommandNotFound` (`code=59`)
- validation failures: `BadValue` / `TypeMismatch` (`code=14`)
- parse parity failures: `FailedToParse` (`code=9`)
- invalid dollar-prefixed `_id` subfields: `DollarPrefixedFieldName` (`code=52`)
- missing namespace on cleanup commands: `NamespaceNotFound` (`code=26`)
- duplicate index/key: `DuplicateKey` (`code=11000`)
- cursor lifecycle: `CursorNotFound` (`code=43`)
- transaction state: `NoSuchTransaction` (`code=251`)
Expand Down
8 changes: 4 additions & 4 deletions docs/COMPATIBILITY_SCORECARD.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Compatibility Scorecard

Status date: 2026-02-28
Status date: 2026-05-09

This scorecard tracks MongoDB UTF compatibility progress with a focus on `runOnRequirements not satisfied` reduction while preserving differential stability (`mismatch=0`, `error=0`).
This scorecard tracks MongoDB UTF compatibility progress with a focus on `runOnRequirements not satisfied` reduction while preserving differential stability. Historical checkpoints below may not match the latest release-candidate artifacts; refresh this page from the RC workflow outputs before tagging.

## Lane model

Expand Down Expand Up @@ -57,8 +57,8 @@ Execution model:

Gates:

- strict lane stability: strict `mismatch=0` and `error=0`
- extended no-regression: extended mismatch/error cannot exceed strict
- strict lane mismatch/error deltas are reported as warnings during routine pilot runs
- extended mismatch/error deltas are reported as warnings during routine pilot runs
- runOn reduction: extended `runOnNotSatisfied` must be `<=` strict
- coverage non-regression: extended imported must be `>=` strict

Expand Down
20 changes: 16 additions & 4 deletions docs/NODE_COMPAT_SMOKE.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
# Node Compatibility Smoke

Status date: 2026-02-24
Status date: 2026-05-09

This suite validates practical Node ecosystem compatibility on top of `@jongodb/memory-server`:

- official `mongodb` Node driver
- Express route handler using the official driver
- Koa route handler using the official driver
- TypeORM MongoDB repository
- Prisma MongoDB provider
- `mongoose`

Current scenario set:
- CRUD baseline
- transaction commit
- transaction rollback
- `mongodb.crud`
- `express.mongodb.route`
- `koa.mongodb.route`
- `typeorm.mongodb.repository`
- `prisma.mongodb.provider`
- `mongodb.transaction.commit`
- `mongodb.transaction.rollback`
- `mongoose.crud`
- `mongoose.session.with-transaction`
- `mongoose.transaction.commit`
- `mongoose.transaction.rollback`

Execution:
- local command: `npm --prefix testkit/node-compat test`
Expand Down
10 changes: 5 additions & 5 deletions docs/RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Release Checklist

Status date: 2026-02-28
Status date: 2026-05-09

## R3 Certification Sign-Off

- [x] Official suite sharded run on `main` completed with zero mismatch/error.
- [ ] Official suite sharded run on the release-candidate commit completed with zero mismatch/error.
- run id: `22516323868` (commit `d2ba61b`)
- [x] R3 failure ledger run on `main` completed with `failureCount=0`.
- [ ] R3 failure ledger run on the release-candidate commit completed with `failureCount=0`.
- run id: `22516324202` (commit `d2ba61b`)
- [x] External canary certification completed for 3 projects with rollback success.
- latest success run id: `22378993613` (commit `868bbc7`)
Expand All @@ -20,14 +20,14 @@ Status date: 2026-02-28
- [x] Support boundary documents are updated.
- `docs/SUPPORT_MATRIX.md`
- `docs/COMPATIBILITY_SCORECARD.md`
- [x] README certification snapshot is updated and links current evidence docs.
- [ ] README certification snapshot is updated and links current release-candidate evidence docs.

## Current Release-Line Notes

- Latest Java release tag: `v0.1.5` (run `22379241855`, commit `868bbc7`).
- Latest Node adapter tag: `node-v0.1.4` (run `22379340586`, commit `868bbc7`).
- Latest compatibility certification snapshot: commit `d2ba61b` (runs `22516323868`, `22516324202`, `22516137734`).
- Next tag candidate should regenerate certification artifacts against the release-candidate commit, not reuse historical tag evidence.
- Next Java tag candidate: `v0.1.6`; regenerate certification artifacts against the release-candidate commit, not reuse historical tag evidence.

## Tagging Gate

Expand Down
11 changes: 7 additions & 4 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,29 @@ Completed in current wave:
- minimal `$graphLookup` certification subset implemented with deterministic option boundary
- listLocalSessions regression coverage normalized in UTF importer regression pack
- release-readiness streak artifacts added (`utf-shard-streak`, `r3-release-readiness-streak`)
- `listCollections`, `drop`, and `dropDatabase` command subsets added for fixture discovery/cleanup
- tier-0 TTL runtime pruning added for single-field non-partial TTL indexes
- deterministic R3 ledger mismatches reduced for `_id` dollar subfields, `updateMany` replacement validation, and transactional `createIndexes`

## Current Focus

### Pre-Release Hardening

Target outcomes:
- keep imported differential parity at zero mismatch/error while reducing unsupported categories
- keep imported differential parity moving toward zero mismatch/error while reducing unsupported categories
- close release-readiness streak gate (`minStreak=3`) on scheduled runs
- refresh certification evidence on release-candidate commit before tagging

Primary measures:
- preserve `mismatch=0`, `error=0` across Official Suite and R3 Ledger
- preserve or restore `mismatch=0`, `error=0` across release-candidate Official Suite and R3 Ledger runs
- increase zero-result streak counters (`officialZeroMismatchStreak`, `r3LedgerZeroFailureStreak`)
- maintain green canary certification for at least 3 external projects

## Planned Next

- close remaining aggregate-stage unsupported surface (`$merge` and advanced non-alias stages)
- close remaining aggregate-stage unsupported surface beyond the current `$merge` terminal subset
- expand collation semantics beyond current subset (`locale`/`strength`/`caseLevel`)
- implement TTL runtime behavior beyond index metadata registration
- expand TTL runtime behavior beyond the current single-field lazy-prune subset
- expand update/operator coverage beyond current `arrayFilters` subset (advanced positional/pipeline expressions)
- expand supported transaction operations in unified suites while preserving deterministic behavior

Expand Down
5 changes: 3 additions & 2 deletions docs/SUPPORT_MATRIX.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Support Matrix

Status date: 2026-02-28
Status date: 2026-05-09

This matrix is a versioned support boundary for integration-test usage.
Source artifact: `build/reports/r2-compatibility/r2-support-manifest.json`.
Expand All @@ -10,7 +10,7 @@ Source artifact: `build/reports/r2-compatibility/r2-support-manifest.json`.
| Status | Count |
| --- | --- |
| Supported | 7 |
| Partial | 6 |
| Partial | 7 |
| Unsupported | 0 |

## Feature-Level Matrix
Expand All @@ -26,6 +26,7 @@ Source artifact: `build/reports/r2-compatibility/r2-support-manifest.json`.
| `index.unique-sparse-partial` | index | Supported | Unique/sparse/partial |
| `index.collation-metadata` | index | Supported | Collation metadata round-trip |
| `index.collation-semantic` | index | Partial | Subset: locale/strength/caseLevel on query-sort-distinct and unique index checks |
| `index.ttl-runtime-tier0` | index | Partial | Lazy pruning for single-field non-partial TTL indexes with date-like values |
| `transactions-single-session` | transaction | Supported | Session + txn flow with namespace-aware commit merge and deterministic same-`_id` resolution |
| `transactions-retryable-advanced` | transaction | Partial | Deterministic retry contract for commit/abort replay and transaction error-label semantics (`TransientTransactionError`, `UnknownTransactionCommitResult`) within single-process scope |
| `deployment.single-node-replicaset-profile` | deployment | Partial | Optional single-node replica-set semantic profile (replica-set URI/hello shape, primary-only readPreference contract, constrained concern levels) |
Expand Down
4 changes: 2 additions & 2 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ OpMsg res = codec.decode(ingress.handle(codec.encode(req)));

## Verification and Evidence Tasks

Current certified reference runs (as of 2026-02-28):
Historical certified reference runs (as of 2026-02-28; refresh on the release-candidate commit before tagging):
- Official Suite Sharded: `22516323868` (`total=508`, `mismatch=0`, `error=0`)
- R3 Failure Ledger: `22516324202` (`failureCount=0`)
- Complex Query Certification: `22516137734` (`packVersion=complex-query-pack-v3`)
Expand Down Expand Up @@ -287,7 +287,7 @@ Manual fallback command:

```bash
gradle \
-PpublishVersion=0.1.5 \
-PpublishVersion=0.1.6 \
-PpublishGroup=io.github.midagedev \
-PpublishArtifactId=jongodb \
centralRelease
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/org/jongodb/command/CommandDispatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@ public CommandDispatcher(
configuredHandlers.put("insert", new InsertCommandHandler(routedStore));
configuredHandlers.put("find", new FindCommandHandler(routedStore, cursorRegistry));
configuredHandlers.put("distinct", new DistinctCommandHandler(routedStore));
configuredHandlers.put("listcollections", new ListCollectionsCommandHandler(routedStore, cursorRegistry));
configuredHandlers.put("aggregate", new AggregateCommandHandler(routedStore, cursorRegistry));
configuredHandlers.put("getmore", new GetMoreCommandHandler(cursorRegistry));
configuredHandlers.put("killcursors", new KillCursorsCommandHandler(cursorRegistry));
configuredHandlers.put("createindexes", new CreateIndexesCommandHandler(routedStore));
configuredHandlers.put("listindexes", new ListIndexesCommandHandler(routedStore, cursorRegistry));
configuredHandlers.put("drop", new DropCommandHandler(routedStore));
configuredHandlers.put("dropdatabase", new DropDatabaseCommandHandler(routedStore));
configuredHandlers.put("update", new UpdateCommandHandler(routedStore));
configuredHandlers.put("delete", new DeleteCommandHandler(routedStore));
configuredHandlers.put("bulkwrite", new BulkWriteCommandHandler(routedStore));
Expand Down Expand Up @@ -175,6 +178,21 @@ public int insert(final String database, final String collection, final java.uti
return delegate().insert(database, collection, documents);
}

@Override
public java.util.List<CollectionMetadata> listCollections(final String database) {
return delegate().listCollections(database);
}

@Override
public DropCollectionResult dropCollection(final String database, final String collection) {
return delegate().dropCollection(database, collection);
}

@Override
public int dropDatabase(final String database) {
return delegate().dropDatabase(database);
}

@Override
public java.util.List<BsonDocument> find(
final String database, final String collection, final BsonDocument filter) {
Expand Down
Loading
Loading