# monSQLize v3.0.0

> Release date: 2026-07-15
> Release status: Released
> Type: Major
> Stable predecessor: v2.0.6

## Summary

v3.0.0 consolidates the unpublished v2.0.7 work into a major release. It adds bounded production data tasks, Model-only write-path enforcement, runtime-scoped schema-dsl integration, stricter synchronization and optimistic-locking behavior, and production release controls. The major version is intentional because several defaults and failure contracts are stricter than v2.0.6.

## Public capability inventory

### Bounded production data tasks

- Added the named `dataTasks` facade with `preview()`, `apply()`, `previewRestore()`, and `restore()` for two independent source/target instances. CommonJS exposes the same root facade through destructuring; it is not an instance API.
- Added collection-level `indexes[]`, filtered `data`, explicit `fields` / `source-id` identity, deterministic `rename` / `set` / `unset` field adjustments, approval drift fingerprints, affected-scope BSON backup packages, verification, and reversible restore-safety packages.
- Consolidated data tasks on one `DataTaskJob` contract and the named `dataTasks.preview/apply/previewRestore/restore` service; the unpublished instance runner and step configuration were removed.
- Consolidated the CLI on `preview`, `apply`, `preview-restore`, and `restore`, with task files directly exporting the same Job configuration.
- Production apply requires explicit `targetEnvironment`, a durable `backup.dir`, and a non-expired preview approval bound to the job, source, target, and target indexes.
- Write-task environments are restricted to `development`, `test`, `staging`, `production`, `prod`, or `live`; unknown or misspelled names fail planning instead of silently bypassing production gates.
- Data task locks use a renewable lease in the target database, coordinate separate processes, and stop writes after ownership is lost.
- Data task planning uses a bounded stream independent of the public `findLimit`, exact write-time document CAS includes unexpected-field detection, and expired local leases fail closed before another write.

### Write-path policy

- Added `writePathPolicy` with permissive `allow-both` default behavior and optional `model-only` enforcement by namespace.
- Guards cover collection, database, legacy, raw client, management, batch, and aggregate `$out` / `$merge` write paths.
- Model writes and Model management methods remain available for namespaces assigned to `model-only`.

### Runtime-scoped schema DSL

- Upgraded `schema-dsl` to `2.1.6` and moved Model schema compilation to an isolated `schema-dsl/runtime` owned by each connected monSQLize runtime.
- Added `schemaDsl` options for runtime options, extension registration, external runtime injection, and explicit validation disablement.
- External runtimes remain application-owned and are not disposed by `MonSQLize.close()`.

### Model consistency and query bounds

- Versioned single-document writes now use optimistic concurrency control. Stale writes throw `WRITE_CONFLICT`.
- Added `updateMany()` / `updateBatch()` version modes: `counter`, `strict`, and `off` where supported.
- `find()` now defaults to `findLimit: 500`; positive `limit` and `skip` values are bounded by `findMaxLimit` and `findMaxSkip`. `limit(0)` keeps MongoDB's unlimited cursor semantics.
- Soft-delete filtering now covers the standard Model read surface, including `findPage`, ID reads, `distinct`, `aggregate`, `stream`, and `explain`.
- Populate has-many `skip` / `limit` is applied per parent and nested populate is capped by `maxDepth` (default `5`).

### Synchronization, cache, and operational safety

- Change Stream targets are processed in order; resume-token persistence is atomic and strict by default.
- Added optional per-target sync idempotency gates and explicit failure/restart state handling.
- Transaction cache invalidations are replayed after successful commit; query caches skip session-scoped reads and avoid refill during write-side invalidation barriers.
- `autoIndex: true` preflights with `listIndexes()`, skips matching indexes, creates only missing indexes, and reports conflicts without dropping or rebuilding indexes.
- `dropDatabase()` treats `production`, `prod`, and `live` as production-like environments requiring `allowProduction: true`.
- Data-task apply and restore use before/current-image compare-and-set filters, bounded source and backup sizes, ordered manifest checkpoint batches, and fsync-backed atomic backup files.
- Saga step timeouts use `OPERATION_TIMEOUT`, abort the cooperative context signal, and never trigger retries; failed runtime connection attempts await partial resource cleanup before returning.
- Runtime dependencies are pinned to `schema-dsl@2.1.6` and `ioredis@5.11.1`; Node 18-compatible test tooling uses `mongodb-memory-server@10.4.3`.
- The release server matrix now strictly requires MongoDB 7.0.37 and 8.0.26 across standalone, replica-set, Driver 6/7, and DataTask integration paths; unavailable combinations fail release preflight instead of being recorded as a successful skip.
- Release candidates must be clean, have a valid installed dependency graph, and already exist on `origin`; the same preflight also verifies the docs site and packaged `MIGRATION.md` / `SECURITY.md` consumer guidance.
- A manual pre-tag authentication workflow verifies the repository's current npm publish credential with `npm whoami` without creating a tag or publishing.
- Build and test artifact cleanup retries transient Windows filesystem contention, so repeated release-gate compilation does not fail on short-lived `ENOTEMPTY`, `EPERM`, or `EBUSY` races.
- GitHub workflows use `actions/setup-node@v6`, avoiding the retired Node 20 action runtime while preserving the explicit Node 18/20/22 package test matrix.
- Stable Pages deployment separates immutable release-tag content from current release tooling, so historical stable tags can rebuild their tagged docs with the current audited website toolchain and link gate without deploying unpublished branch content; current releases still require the complete website verification chain.

## Compatibility-impacting changes

Review these changes before upgrading from v2.0.6:

1. Versioned Model single-document writes can now throw `WRITE_CONFLICT` or `INVALID_ARGUMENT` where v2 behavior could write without a usable expected version.
2. Versioned `updateMany()` defaults to `counter`; choose `strict` for per-document conditional writes or `off` for compatibility behavior.
3. `find()` applies a default limit of 500 and validates positive limits/skips against configured caps.
4. Resume-token load/save failures stop Change Stream synchronization unless legacy best-effort options are selected explicitly.
5. `updateBatch({ upsert: true })` is rejected. Use `upsertOne()` or native `updateMany(..., { upsert: true })` according to the required insert semantics.
6. `dropDatabase()` has a broader production-like environment guard.
7. Soft-delete reads, has-many populate paging, nested populate depth, pool validation, and wildcard Change Stream collection filters now follow the documented stricter behavior.
8. Production Jobs require `preview -> approval -> apply`, a durable affected-scope backup directory, and a new preview after any source/target/index drift.

## Upgrade checklist

1. Run the complete release preflight on the exact commit to be tagged.
2. Audit versioned Model writes and select an explicit batch version mode where the default is not desired.
3. Review services that depend on unlimited `find()` results and configure bounded limits deliberately.
4. Decide whether Change Stream resume-token persistence should remain strict; document any best-effort override.
5. Inventory direct write paths before enabling `writePathPolicy: { default: 'model-only' }`.
6. Keep `autoIndex: false` in production rollout paths unless startup-time asynchronous creation is deliberately accepted; use data-task index plans for reviewed production changes.
7. For historical data changes, follow `preview -> review -> apply`; use `previewRestore -> restore` only when rollback is required, and retain the full database restore point until acceptance completes.

## Release acceptance

The release is publishable only when all of the following pass on the release commit:

- lint, docs-example coverage, TypeScript/tsd checks, strict file-size checks
- complete unit/integration suites and source coverage thresholds
- examples and MongoDB server matrix
- real dataTasks and CLI integration probes
- package dry-run plus temporary-install CJS, ESM, dataTasks, schema-dsl, types, MIGRATION/SECURITY, bin, help, and version smoke tests
- clean-install docs-site type, build, internal-link, and dependency-audit verification
- npm registry, dist-tag, Git tag, GitHub Release, and Pages post-publish acceptance

See the bilingual release preflight guides and production rollout guides for commands and recovery procedures.

> Contract correction (2026-07-15): the original GitHub Release text used the inaccurate phrase “pipeline/handler transforms.” The shipped and documented v3 contract supports only `rename`, `set`, and `unset`. This repository correction is the source for the next patch; editing the already-published GitHub Release remains a separate authorized release-maintenance action.
