@push.rocks/smartdb 5.5.0 → 5.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_rust/rustdb_linux_amd64 +0 -0
- package/dist_rust/rustdb_linux_amd64.tsrust-build.json +4 -4
- package/dist_rust/rustdb_linux_arm64 +0 -0
- package/dist_rust/rustdb_linux_arm64.tsrust-build.json +4 -4
- package/dist_rust/rustdb_macos_amd64 +0 -0
- package/dist_rust/rustdb_macos_amd64.tsrust-build.json +4 -4
- package/dist_rust/rustdb_macos_arm64 +0 -0
- package/dist_rust/rustdb_macos_arm64.tsrust-build.json +4 -4
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/package.json +1 -1
- package/readme.md +7 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/readme.hints.md +0 -77
- package/readme.plan.md +0 -336
|
Binary file
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "tsrust.build-provenance.v2",
|
|
3
|
-
"binarySha256": "
|
|
3
|
+
"binarySha256": "00320ccbef2538dfa9fba1da65bb5db3b1874aef58eb85cdf40f8f29f4822578",
|
|
4
4
|
"buildInfo": {
|
|
5
5
|
"projectName": "@push.rocks/smartdb",
|
|
6
|
-
"projectVersion": "5.5.
|
|
7
|
-
"gitCommit": "
|
|
6
|
+
"projectVersion": "5.5.2",
|
|
7
|
+
"gitCommit": "389db71389a45d42b0f205736ae52f55d593aeb3",
|
|
8
8
|
"gitDirty": false,
|
|
9
|
-
"builtAt": "2026-09-
|
|
9
|
+
"builtAt": "2026-09-04T18:59:43.562Z",
|
|
10
10
|
"tsrustVersion": "1.10.4",
|
|
11
11
|
"binary": "rustdb",
|
|
12
12
|
"target": "linux_amd64"
|
|
Binary file
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "tsrust.build-provenance.v2",
|
|
3
|
-
"binarySha256": "
|
|
3
|
+
"binarySha256": "0efe48ad0d320b53e565e5ac16810bb8ca153b1d1c39cb86e971297e62931442",
|
|
4
4
|
"buildInfo": {
|
|
5
5
|
"projectName": "@push.rocks/smartdb",
|
|
6
|
-
"projectVersion": "5.5.
|
|
7
|
-
"gitCommit": "
|
|
6
|
+
"projectVersion": "5.5.2",
|
|
7
|
+
"gitCommit": "389db71389a45d42b0f205736ae52f55d593aeb3",
|
|
8
8
|
"gitDirty": false,
|
|
9
|
-
"builtAt": "2026-09-
|
|
9
|
+
"builtAt": "2026-09-04T19:00:17.487Z",
|
|
10
10
|
"tsrustVersion": "1.10.4",
|
|
11
11
|
"binary": "rustdb",
|
|
12
12
|
"target": "linux_arm64"
|
|
Binary file
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "tsrust.build-provenance.v2",
|
|
3
|
-
"binarySha256": "
|
|
3
|
+
"binarySha256": "f309ef5182f62bd147bab7bfd39be556d1ec0fce1dede84b9c424f607fe0a8b5",
|
|
4
4
|
"buildInfo": {
|
|
5
5
|
"projectName": "@push.rocks/smartdb",
|
|
6
|
-
"projectVersion": "5.5.
|
|
7
|
-
"gitCommit": "
|
|
6
|
+
"projectVersion": "5.5.2",
|
|
7
|
+
"gitCommit": "389db71389a45d42b0f205736ae52f55d593aeb3",
|
|
8
8
|
"gitDirty": false,
|
|
9
|
-
"builtAt": "2026-09-
|
|
9
|
+
"builtAt": "2026-09-04T19:01:23.168Z",
|
|
10
10
|
"tsrustVersion": "1.10.4",
|
|
11
11
|
"binary": "rustdb",
|
|
12
12
|
"target": "macos_amd64"
|
|
Binary file
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": "tsrust.build-provenance.v2",
|
|
3
|
-
"binarySha256": "
|
|
3
|
+
"binarySha256": "6935370ae83f20f3dfd5e8167b68c9a60c656c17f8839a9b16c05e4009c27797",
|
|
4
4
|
"buildInfo": {
|
|
5
5
|
"projectName": "@push.rocks/smartdb",
|
|
6
|
-
"projectVersion": "5.5.
|
|
7
|
-
"gitCommit": "
|
|
6
|
+
"projectVersion": "5.5.2",
|
|
7
|
+
"gitCommit": "389db71389a45d42b0f205736ae52f55d593aeb3",
|
|
8
8
|
"gitDirty": false,
|
|
9
|
-
"builtAt": "2026-09-
|
|
9
|
+
"builtAt": "2026-09-04T19:02:04.202Z",
|
|
10
10
|
"tsrustVersion": "1.10.4",
|
|
11
11
|
"binary": "rustdb",
|
|
12
12
|
"target": "macos_arm64"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartdb',
|
|
6
|
-
version: '5.5.
|
|
6
|
+
version: '5.5.2',
|
|
7
7
|
description: 'A MongoDB-compatible embedded database server with wire protocol support, backed by a high-performance Rust engine.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxxQkFBcUI7SUFDM0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHFIQUFxSDtDQUNuSSxDQUFBIn0=
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -840,6 +840,13 @@ Mixed `localField`/`foreignField` plus `pipeline` lookups and other inner stages
|
|
|
840
840
|
are rejected explicitly. Complete filter trees are validated before data is
|
|
841
841
|
read, and query nesting plus aggregation work are bounded.
|
|
842
842
|
|
|
843
|
+
A leading `$match` narrows the pipeline's source load instead of filtering
|
|
844
|
+
after it: only matching documents are materialized, using an equality index when
|
|
845
|
+
one serves the filter and a bounded scan otherwise. Filter shapes the query
|
|
846
|
+
matcher cannot pre-compile fall back to the unnarrowed load, so results are
|
|
847
|
+
unchanged. The materialization limit therefore applies to the matched set, which
|
|
848
|
+
is what lets `countDocuments(filter)` run against collections larger than it.
|
|
849
|
+
|
|
843
850
|
**Group accumulators:** `$sum`, `$avg`, `$min`, `$max`, `$first`, `$last`, `$push`, `$addToSet`, `$count`
|
|
844
851
|
|
|
845
852
|
### Indexes
|
package/ts/00_commitinfo_data.ts
CHANGED
package/readme.hints.md
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
# smartdb hints
|
|
2
|
-
|
|
3
|
-
## Single-Node Concern Profile, Namespace Clock, and Deadlines (5.5.0)
|
|
4
|
-
|
|
5
|
-
- `rustdb-commands/src/concerns.rs` is the sole owner of `readConcern`, `writeConcern`, and `maxTimeMS` validation. It runs in the router before authentication, sessions, permits, or gates. The profile is stated for one voting node: fsynced acknowledgement satisfies `w: 1`, `w: "majority"`, and `j: true`; `w: N > 1` is `UnsatisfiableWriteConcern` (100), tag sets are `UnknownReplWriteConcern` (79), cluster-time read concerns and misplaced fields are `InvalidOptions` (72), malformed deadlines are `BadValue` (2). `j: true` on `MemoryStorageAdapter` is `BadValue` through `StorageAdapter::journaled_writes()`. The driver sends a transaction's read concern on whichever statement starts the transaction, so a transaction-starting insert may carry one. Never accept a concern by widening an allowlist; every accepted value must map to a guarantee the engine actually provides.
|
|
6
|
-
- `rustdb-commands/src/clock.rs` (`CommandContext::namespace_clock`) is the publication clock. Every in-process publication that changes visible namespace contents records `publish_namespace` while it still holds the namespace write lock (point writes, transaction commit completion, `create`, `drop`, `renameCollection`, `$out`, `$merge`, oplog revert) or `publish_database` (`dropDatabase`, in-process durable replacement through `invalidate_database_runtime`, and cross-process publication observed through `invalidate_database_runtime_for_epoch`). `$out` publishes right after it drops the old contents and again after the refill, so a failed refill still invalidates pinned snapshots. Index DDL does not change documents and does not publish. Adding a new mutation path without a publication is a snapshot-consistency bug.
|
|
7
|
-
- Transactions pin `TransactionState::snapshot_sequence` when they materialize their first namespace. `transactions::load_transaction_docs_locked` requires the caller to hold the namespace write lock (insert/update/delete already do); `load_transaction_docs` acquires it for readers (`find`, `count`, `distinct`). A namespace whose `last_publication` exceeds the pinned sequence fails with `SnapshotUnavailable` (246); the router labels it `TransientTransactionError` so `withTransaction` restarts. This turns lazy per-namespace materialization into one database-wide snapshot without a second data copy; Storage VNext MVCC read timestamps replace the materialized copy itself.
|
|
8
|
-
- Sessions retain `last_outcome` (`TransactionOutcome::Committed`/`Aborted` per transaction number) through `SessionEngine::finish_transaction_if_bound`. `commitTransaction`/`abortTransaction` without an active binding replay that outcome: repeated commit is `ok`, abort-after-commit is `TransactionCommitted` (256), commit-after-abort is `NoSuchTransaction` (251), and an older `txnNumber` on start is `TransactionTooOld` (225). Outcomes are process-local; after a crash the outcome of an in-flight commit is discoverable only from the data, which is why callers must journal their own attempts inside the transaction.
|
|
9
|
-
- `rustdb-commands/src/deadline.rs` holds the `maxTimeMS` deadline in a tokio task-local set by `CommandRouter::route_with_response_policy`. Checks are cooperative: admission, `deadline::wait_bounded` inside `acquire_write_lock`/`acquire_maintenance_write_gate`, `wait_until_deadline` around the maintenance read lease, `check()` after materialization in readers, `check_every` in insert/delete loops, and one final `check()` before `apply_write_batch_with_completion` in commit. Handler futures are not cancellation-safe, so never wrap a handler in `tokio::time::timeout`; add a check at the next safe point instead. `SMARTDB_TEST_OPERATION_DELAY=<command>:<ms>` (test-support builds only) injects a pre-dispatch delay for deterministic expiry tests.
|
|
10
|
-
- Error labels are derived from the response code in `attach_error_labels` so pre-dispatch rejections and handler errors label identically: transaction statements with 112/246/251 carry `TransientTransactionError`; `commitTransaction` with 50 or 64 carries `UnknownTransactionCommitResult`.
|
|
11
|
-
|
|
12
|
-
## Storage VNext A0 Committed Log
|
|
13
|
-
|
|
14
|
-
- `rustdb-kernel` is a fixture-only, non-serving A0 durability slice. It is not linked into the released `rustdb` binary and provides no BSON, CRUD, MVCC, concern, deadline, migration, replication, or availability behavior.
|
|
15
|
-
- The immutable `kernel-manifest.sdb` stores format, group, timeline, and fixed segment identity only. It never stores a mutable commit frontier. Complete prepared/commit-marker pairs in `commit-0000000000000001.sdb` are the sole A0 commit authority.
|
|
16
|
-
- Each new command validates and prepares before append, receives the next contiguous nonzero LSN, and appends one `KPR1` prepared frame plus one `KCM1` marker binding the exact prepared bytes. Exact retries return the original LSN/response without appending; fingerprint conflicts, invalid commands, and segment exhaustion consume no LSN or state.
|
|
17
|
-
- Any append or sync error after write admission is ambiguous and permanently fences that handle, including reads and exact retries. Reopen is the only reconciliation path. Reopen syncs every complete recovered segment before exposing state or receipts.
|
|
18
|
-
- Recovery accepts only the declared timeline, contiguous LSNs, valid CRC frames, a matching marker position/hash, valid commands, and one durable record per receipt identity. It may truncate only an incomplete final frame of the expected kind or a complete valid prepared record without a complete marker. Complete corruption, wrong-kind tails, invalid prepared records, holes, duplicates, and marker mismatches fail without changing the segment.
|
|
19
|
-
- The descriptor-safe root/framing primitives are shared by `rustdb-kernel` and `rustdb-replication`. Their common parent-slot/in-root lock namespace is intentional: kernel and Raft roots must be exclusive and are never interchangeable.
|
|
20
|
-
|
|
21
|
-
## Authoritative File Recovery
|
|
22
|
-
|
|
23
|
-
- `data.rdb` is the sole runtime source for rebuilding KeyDir. The v1 `keydir.hint` format cannot prove completeness or data-generation identity, so existing regular hint files are tolerated for compatibility and diagnostics but their contents are never loaded as runtime state. New shutdowns, compactions, and v0-to-v1 migrations do not publish hints.
|
|
24
|
-
- Runtime WAL scanning is bounded and strict: exact current headers, strictly increasing record sequences, operation shapes, lengths, CRCs, and nonduplicated commit references to preceding records must validate. Only an incomplete final record-header or commit-marker prefix with the expected magic is truncated. A complete header with a short payload and every checksum, sequence, magic, or interior failure stop startup without repairing either `data.rdb` or the WAL.
|
|
25
|
-
- Recovery considers only the highest-sequence WAL record for each document key. If that final record is committed, no older markerless intent is replayed; if it is markerless, only that record is replayed. This prevents an older update or delete from overtaking a later acknowledged update or reinsert.
|
|
26
|
-
- A point mutation whose data record reached `data.rdb` and fsynced before its WAL commit marker failed is successful so command indexes and OpLog publish the same mutation. The collection is then sticky-fenced: later document/index access and every write, batch publication, cache invalidation, rename, drop, and database replacement touching it fail until restart; maintenance may skip the collection but must never evict its fence. Pre-publication WAL/data append failures may continue only after both files are durably rolled back to their previously validated lengths; an unverified rollback fences instead.
|
|
27
|
-
- `KeyDir::build_from_data_file()` streams every payload through CRC32 in fixed-size chunks before allocating its key and never allocates the declared value length. It may classify only a final prefix shorter than `RECORD_HEADER_SIZE` with matching record-magic bytes as an incomplete tail. A full header with a short payload and every checksum, magic, length, or UTF-8 key failure are corruption and must leave `data.rdb` unchanged.
|
|
28
|
-
- Compaction durably removes any legacy hint and syncs the collection directory before replacing `data.rdb`. This ordering forces SmartDB 5.2.1 and earlier to rebuild after downgrade even when the compacted file happens to have the hint's old recorded size.
|
|
29
|
-
- Startup maintenance may skip a publication-held database. Its first later storage access still performs the authoritative scan and fails unchanged on corruption; never infer validation of held data from listener startup alone.
|
|
30
|
-
- Every cancellation-unsafe maintenance, fencing, auth, or storage worker must own a clone of the retained storage-root capability through its final file/lock cleanup. Provider installation is a finite joined startup sweep; periodic maintenance starts only after listener setup has no remaining fallible step. `close()` joins maintenance, `RustDb::drop()` requests cooperative shutdown, and Unix socket cleanup is bound to the exact device/inode created by `bind()`.
|
|
31
|
-
|
|
32
|
-
## Stopped Storage-Root Relocation
|
|
33
|
-
|
|
34
|
-
- `LocalSmartDb.relocateStoppedStorageRoot()` is the only supported path-changing operation. It uses a dedicated serialized mutating sidecar runner; do not route it through the disposable offline-inspection helper. A bridge whose termination is unconfirmed remains in the static cleanup gate, and no later relocation may spawn until cleanup succeeds.
|
|
35
|
-
- Rust owns the descriptor-relative operation in `rust/crates/rustdb/src/storage_root_relocation.rs`. It never constructs `RustDb`. The fixed journal phases are `preparing`, `prepared`, `exchanged`, `providerPublished`, `sentinelPublished`, and `cleaned`; retries reconcile the exact source-root/destination-absent-or-receipt topology or source-receipt/destination-root topology before continuing.
|
|
36
|
-
- The destination receipt is published with an exclusive rename, then exchanged with the source root using an atomic swap (`RENAME_NOREPLACE`/`RENAME_EXCHANGE` on Linux and `RENAME_EXCL`/`RENAME_SWAP` on macOS). Provider and sentinel replacement also uses checked exchanges, retaining each previous object in the workspace until the replacement is durable and verified. The original root inode ends at the destination and the original receipt inode remains at the source indefinitely. Parent, root, internal, lock, provider, and sentinel identities are revalidated around publication.
|
|
37
|
-
- Eligibility is intentionally narrow: Linux on the existing supported local-filesystem set or macOS on qualified local APFS, exact current owner/provider/sentinel metadata, no auth path digest, and no active resource receipt, allocation, database-mutation workspace, unrelated marker, symlink, unknown entry, or unsafe ownership/mode/link profile. A transaction workspace is eligible only when `rustdb-storage` validates its exact `cleaned` internal journal and matching database transaction marker; workspace debris, unfinished phases, mismatches, and allocation bindings remain unsupported. Empty retired legacy locks are eligible only with the canonical resource-digest/inode name parsed by `resource_fencing`, within its existing bound, and tied to one of those terminal transaction resources. macOS additionally rejects case, Unicode, mount, and ancestry aliases by retained physical identity. Missing metadata is rejected and never initialized by relocation.
|
|
38
|
-
- Both TypeScript startup paths check for `.__rustdb_internal/storage-root-relocation` before `StorageMigrator`. Rust checks immediately after securely opening an existing root and repeats the descriptor-relative check after acquiring the owner lock, before storage initialization. This closes the interval where a relocation can create its workspace and release the lock after startup's first inspection. Occupancy or inspection ambiguity is a startup error; only an exact relocation retry performs recovery.
|
|
39
|
-
- Completed roots retain the SmartDB 5.0.1 provider/sentinel JSON shape, changing only their storage-root path digest. Interrupted Linux state requires 5.1.0 or newer; interrupted macOS state requires a macOS-capable release. Exact replay lasts only while the destination remains current; a later relocation supersedes the old source/destination tuple.
|
|
40
|
-
|
|
41
|
-
## Restricted Deny-All Views
|
|
42
|
-
|
|
43
|
-
- `rustdb-commands/src/views.rs` is the sole owner of `system.views` parsing, bounds, canonical `_id_` metadata validation, exact deny-all pipeline validation, and authoritative namespace classification. There is intentionally no mutable cross-command view cache; aggregate and transaction commit reuse one immutable authoritative catalog per database for that operation.
|
|
44
|
-
- The only accepted definition is `viewOn: <same-db collection name>` plus exact pipeline `[{ $match: { $expr: { $eq: [1, 0] } } }]`. A logical view has no physical collection and never reads `viewOn`.
|
|
45
|
-
- `system.views` is a physical reserved catalog. It is visible as a collection in wire `listCollections`, export, import, and content digest, but command-layer `IndexEngine` creation and direct wire access are forbidden. Internal view create/drop uses storage point insert/delete and preserves the storage adapter's canonical `_id` metadata.
|
|
46
|
-
- Catalog loading is bounded to 1,024 view records and 1 MiB of encoded view documents and never enumerates all physical collections. Runtime validation checks each bounded logical name with `collection_exists`; snapshot/import validation uses its already-provided physical-name set without adding a runtime collection ceiling. Exact document shape is `_id`, `viewOn`, and `pipeline`; malformed records, noncanonical indexes, duplicate/reserved names, and physical/view collisions fail closed.
|
|
47
|
-
- Publication permits validate once per newly observed publication state; databases without an epoch use an internal observed sentinel. Epoch refresh validates before recording the new observation. Startup validates databases whose publication lease can be acquired before listener bind; publication-held databases are validated on their first later permit. Snapshot/export explicitly revalidate. Import validates the source candidate, remaps only the exact source database prefix in catalog `_id` values, then validates the target candidate before mutation and clears its observed state after replacement.
|
|
48
|
-
- Content digest hashes the physical catalog but removes its already-validated deterministic database prefix from `_id` first, preserving the database-name-independent digest contract across cross-name imports.
|
|
49
|
-
- DDL and transaction commit take the maintenance write gate. View create/drop additionally lock the logical target and `${db}.system.views` in sorted order. View DDL validates the complete prospective catalog and performs cursor/index cleanup before its final point insert/delete, so cancellation cannot publish catalog state without cleanup. Commit locks every touched namespace in sorted order, loads one catalog per touched database, reclassifies each namespace, and transfers those guards into the storage completion closure.
|
|
50
|
-
- Mutation handlers reclassify after acquiring their target namespace lock and before existence, auto-create, or lazy-index work. Logical-view data/index/output/rename mutations and direct `system.views` operations return `CommandNotSupportedOnView` code 166; `dropCollection` removes a logical view, while direct catalog drop remains forbidden. Ordinary create collision with a logical view returns `NamespaceExists`.
|
|
51
|
-
- Find/count/distinct are empty outside a transaction, aggregate applies the client pipeline to an empty source, and lookup/union resolution is empty. A transaction first reading a current view snapshots an empty vector, while a populated snapshot captured before a rename-plus-view transition remains authoritative for find/count/distinct until commit revalidation. Do not infer view semantics from physical collection absence.
|
|
52
|
-
- Successful create/drop/rename/dropDatabase publication removes affected namespace cursors before releasing DDL guards. A subsequent `getMore` cannot continue against stale namespace contents.
|
|
53
|
-
- Management oplog revert rejects entries targeting `system.views` or a currently logical view. Logical-view `dropCollection` and whole-database drop are the catalog-removal exceptions; direct `system.views` drop is code 166. Database drop clears database indexes, cursors, oplog state, and observed publication state.
|
|
54
|
-
|
|
55
|
-
## Multikey Query Planning
|
|
56
|
-
|
|
57
|
-
- SmartDB detects when an indexed path resolves through an array and keeps that state on the in-memory index until a complete rebuild.
|
|
58
|
-
- Array-backed indexes are maintained for catalog and constraint compatibility but are not used to narrow queries; reads fall back to authoritative scans until full MongoDB multikey key expansion is implemented.
|
|
59
|
-
- A scalar-to-multikey transition invalidates an in-progress paged index read with a write conflict; retrying starts with the authoritative scan path instead of returning a partial result.
|
|
60
|
-
- Index data and multikey state are rebuilt from authoritative documents at startup, so this behavior requires no persisted-data migration.
|
|
61
|
-
|
|
62
|
-
## No-Op Write Detection (2.14.0)
|
|
63
|
-
|
|
64
|
-
- `update`/`findAndModify` post-images that equal the stored document skip storage, WAL, index staging, and oplog entirely; volatile-only rewrites (top-level `_updatedAt` differs, everything else equal) are skipped the same way and keep the stored `_updatedAt`. Both report `matched=1, modified=0`.
|
|
65
|
-
- Classification lives in `rustdb-commands/src/handlers/update_handler.rs` (`classify_document_rewrite`); the volatile field list is the `VOLATILE_METADATA_FIELDS` const. The comparison is key-order-insensitive (replacement paths re-append `_id`) and bails to "changed" on duplicate keys.
|
|
66
|
-
- Counters: `serverStatus.writes.{updatesWritten, noopSkipped.identical, noopSkipped.volatileOnly}` backed by `WriteMetrics` on `CommandContext`. Wire-level coverage in `test/test.noop-writes.ts`.
|
|
67
|
-
- Consequence for consumers: a save that changes nothing no longer bumps `_updatedAt` and emits no oplog event. To force a touch, change a non-volatile field.
|
|
68
|
-
|
|
69
|
-
## Static Rust Binaries
|
|
70
|
-
|
|
71
|
-
- The Linux Rust binaries in `dist_rust/` are statically linked (static-pie) via `"static": true` in the `@git.zone/tsrust` block of `.smartconfig.json` (tsrust >= 1.4.1). They run on both glibc (Debian/Ubuntu) and musl (Alpine) systems. The macOS amd64 and arm64 binaries use the normal Apple platform linkage.
|
|
72
|
-
- tsrust injects `RUSTFLAGS="-C target-feature=+crt-static"` only into its own per-target cargo invocations and verifies the result (no `PT_INTERP` ELF header). Keep `rust/.cargo/config.toml` free of `rustflags` entries: the injected env variable would replace them, and a repo-wide `rustflags` would also break plain `cargo test`/`cargo check` (proc-macros cannot build with `+crt-static` on linux-gnu without an explicit `--target`). The repo previously carried such `rustflags` lines; they were removed when the tsrust `static` option was adopted.
|
|
73
|
-
- `pnpm run test:rust` runs the Rust unit tests; plain `cargo test` in `rust/` works as well.
|
|
74
|
-
- Verify linkage manually with `ldd dist_rust/<binary>_linux_amd64` → "statically linked".
|
|
75
|
-
- Do NOT verify feature presence in release binaries with `strings`/`grep`: on x86_64 release builds LLVM embeds short string literals (≤16 bytes, e.g. BSON doc keys like `volatileOnly`) as instruction immediates, so they are invisible to byte scans while the aarch64 binary shows them in `.rodata`. This produces false "stale binary" alarms. Verify behavior by running the binary (the wire tests spawn the host-arch binary from `dist_rust/`), or disassemble: `objdump -d <bin> | grep <hex-of-literal-LE>`.
|
|
76
|
-
- Release builds use the tsrust 1.10 native matrix. The enabled gitzone test preflight checks the exact project-local tool, cross-execution, worker identities, toolchains, and remote root before versioning. The post-version build bundles TypeScript, transfers exact HEAD into isolated local and SSH workers, installs the frozen lockfile, executes all four target binaries, retrieves bounded artifact sets, and transactionally publishes the complete provenance matrix. Remote cleanup is limited to the unique owner-marked child below `SMARTDB_RELEASE_MACOS_TEMP_ROOT` and gates publication.
|
|
77
|
-
- Workspace release-age exclusion arrays replace operator-global exclusions, and matrix workers use synthetic homes with a separate age policy. For immediate dependency-chain releases, enumerate every required exact audited package version across all install contexts; do not disable the age gate or widen an exception to a scope.
|
package/readme.plan.md
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
# SmartDB advancement plan
|
|
2
|
-
|
|
3
|
-
Status: canonical direction, approved 2026-08-17. Reread before starting engine or
|
|
4
|
-
managed-service work.
|
|
5
|
-
|
|
6
|
-
Baseline: `@push.rocks/smartdb` 5.5.0. SmartDB is a Rust database engine with a
|
|
7
|
-
TypeScript lifecycle facade, a MongoDB wire-protocol command surface, file and
|
|
8
|
-
memory storage, authentication, transactions, resource fencing, and official
|
|
9
|
-
MongoDB Node.js driver integration.
|
|
10
|
-
|
|
11
|
-
Current execution status:
|
|
12
|
-
|
|
13
|
-
- the legal and provenance gate passed on 2026-08-22
|
|
14
|
-
- Phase 0 and the Phase 1 gate have not passed
|
|
15
|
-
- 5.x maintenance now treats `data.rdb` as authoritative, ignores unverifiable
|
|
16
|
-
legacy hint contents, streams CRC validation, and repairs only an incomplete
|
|
17
|
-
final record-header prefix
|
|
18
|
-
- strict latest-per-key runtime WAL recovery and post-publication point-write
|
|
19
|
-
fencing were released in 5.3.2; crash-safe ordinary DDL, debug-server security,
|
|
20
|
-
and general crash/soak qualification remain separate required 5.x slices
|
|
21
|
-
- 5.4.0 released the non-serving, fixture-only A0 committed-log kernel with one
|
|
22
|
-
static timeline, contiguous LSNs, exact retry receipts, bounded
|
|
23
|
-
change-proportional appends, strict pair recovery, and ambiguity fencing; the
|
|
24
|
-
follow-up A1/MVCC/rollover/checkpoint work is parked unreleased on the
|
|
25
|
-
`storage-vnext-a1-wip` branch
|
|
26
|
-
- A0 has no BSON document substrate, MVCC, checkpoint, segment rollover, OpenRaft
|
|
27
|
-
integration, wire serving, migration, or availability claim; Phase 3B and the
|
|
28
|
-
earlier Phase 0/1 gates have not passed
|
|
29
|
-
- 5.5.0 serves the truthful single-node concern profile on the legacy engine:
|
|
30
|
-
fsync-backed `w: 1`/`majority`/`j` acknowledgement, committed-state reads for
|
|
31
|
-
`local`/`available`/`majority`/`linearizable`, database-wide transaction
|
|
32
|
-
snapshots pinned by the namespace publication clock with fail-closed
|
|
33
|
-
`SnapshotUnavailable` retries, cooperative `maxTimeMS` deadlines, and
|
|
34
|
-
per-session idempotent commit/abort outcomes; unsatisfiable `w: N > 1`, tag
|
|
35
|
-
sets, cluster-time read concerns, and journaled writes on the memory backend
|
|
36
|
-
remain rejected
|
|
37
|
-
|
|
38
|
-
## Product objective
|
|
39
|
-
|
|
40
|
-
Build SmartDB into a commercially operated, MongoDB-driver-compatible managed
|
|
41
|
-
database service in this order:
|
|
42
|
-
|
|
43
|
-
1. truthful and provable single-node engine
|
|
44
|
-
2. certified compatibility profile
|
|
45
|
-
3. managed single-node service
|
|
46
|
-
4. replicated high-availability service
|
|
47
|
-
5. whole-database placement and migration
|
|
48
|
-
6. intra-database sharding only when customer scale requires it
|
|
49
|
-
|
|
50
|
-
Reimplementing MongoDB-compatible server behavior and its persistence engine is the
|
|
51
|
-
fixed strategy. SmartDB owns the wire, semantic, execution, storage, topology, and
|
|
52
|
-
service contracts. Storage VNext does not embed SQLite, redb, Fjall, LMDB, RocksDB,
|
|
53
|
-
or another database engine.
|
|
54
|
-
|
|
55
|
-
## Legal and provenance gate
|
|
56
|
-
|
|
57
|
-
The official MongoDB wire-protocol documentation and specifications carry terms
|
|
58
|
-
that expressly restrict commercial database and database-as-a-service adaptation.
|
|
59
|
-
This plan does not interpret those terms. Before expanding compatibility work:
|
|
60
|
-
|
|
61
|
-
- obtain written legal guidance for interoperability, clean-room implementation,
|
|
62
|
-
product claims, and trademarks
|
|
63
|
-
- audit the provenance of existing compatibility code and tests
|
|
64
|
-
- classify disputed material for retention, independent rewrite, or quarantine
|
|
65
|
-
- document which behavioral evidence and test sources implementation teams may use
|
|
66
|
-
- market the service under an approved SmartDB identity and compatibility claim
|
|
67
|
-
|
|
68
|
-
No compatibility feature enters a commercial release without passing this gate.
|
|
69
|
-
|
|
70
|
-
## Maintenance policy
|
|
71
|
-
|
|
72
|
-
SmartDB 5.x is the maintenance lane for existing consumers:
|
|
73
|
-
|
|
74
|
-
- accept security fixes, data-correctness fixes, explicit rejection of unsupported
|
|
75
|
-
behavior, and bounded operability improvements
|
|
76
|
-
- do not add broad MongoDB surface area or introduce a second durability model
|
|
77
|
-
- keep persisted 5.x behavior supported until a tested offline conversion or
|
|
78
|
-
snapshot/restore migration into Storage VNext exists
|
|
79
|
-
- release small fixes independently when their invariants and compatibility impact
|
|
80
|
-
can be verified in isolation
|
|
81
|
-
|
|
82
|
-
Storage VNext is developed behind explicit format and capability boundaries. It
|
|
83
|
-
must never dual-write through both the legacy and VNext commit paths.
|
|
84
|
-
|
|
85
|
-
## North-star architecture
|
|
86
|
-
|
|
87
|
-
### Wire gateway
|
|
88
|
-
|
|
89
|
-
- parse and encode the declared wire profile exactly
|
|
90
|
-
- validate complete command schemas before acquiring resources or mutating state
|
|
91
|
-
- advertise only capabilities and limits proven by target-driver handshake tests
|
|
92
|
-
- reject every unsupported command, concern, or option explicitly
|
|
93
|
-
|
|
94
|
-
### BSON semantic core
|
|
95
|
-
|
|
96
|
-
- own one implementation of BSON equality, ordering, hashing, numeric promotion,
|
|
97
|
-
null/missing behavior, array traversal, typed identifiers, projections,
|
|
98
|
-
expressions, and updates
|
|
99
|
-
- feed the same semantics into queries, indexes, transactions, aggregation,
|
|
100
|
-
uniqueness checks, and change streams
|
|
101
|
-
|
|
102
|
-
### Planner and executor
|
|
103
|
-
|
|
104
|
-
- use one planner for find, count, update, delete, aggregate, and explain
|
|
105
|
-
- stream storage-backed cursors instead of materializing complete result sets
|
|
106
|
-
- enforce deadlines, cancellation, admission, and work accounting at every loop
|
|
107
|
-
|
|
108
|
-
### Transactional storage kernel
|
|
109
|
-
|
|
110
|
-
- own one authoritative, checksummed, monotonically ordered commit log
|
|
111
|
-
- assign a stable timeline and LSN to every committed mutation
|
|
112
|
-
- commit documents, DDL, catalogs, index definitions, users, retryable-write
|
|
113
|
-
outcomes, and transaction outcomes through the same atomic boundary
|
|
114
|
-
- serve database-wide MVCC snapshots and deterministic checkpoint-plus-log recovery
|
|
115
|
-
|
|
116
|
-
### Replication
|
|
117
|
-
|
|
118
|
-
- replicate the committed Storage VNext log through a reviewed consensus design
|
|
119
|
-
- use consensus terms to fence leaders; allocation fencing controls placement and
|
|
120
|
-
publication but never substitutes for data-plane consensus
|
|
121
|
-
- derive majority acknowledgement, failover, snapshot installation, causal times,
|
|
122
|
-
and retry outcomes from the replicated commit history
|
|
123
|
-
|
|
124
|
-
### Administration and control plane
|
|
125
|
-
|
|
126
|
-
- keep RBAC-protected database administration such as `currentOp`, `killOp`,
|
|
127
|
-
`explain`, and user management available through the certified wire surface
|
|
128
|
-
- keep service administration such as provisioning, placement, billing, backup,
|
|
129
|
-
restore, upgrades, and incident actions on a separate privileged API
|
|
130
|
-
- start with one process per tenant or isolated replica group; shared-process
|
|
131
|
-
tenancy requires hard per-tenant admission and noisy-neighbor proof
|
|
132
|
-
|
|
133
|
-
## Phase 0: contract and measurement
|
|
134
|
-
|
|
135
|
-
- complete the legal and provenance gate
|
|
136
|
-
- select the first exact driver, ODM, topology, command, option, and error profile
|
|
137
|
-
- maintain raw-wire and target-driver handshake tests
|
|
138
|
-
- publish an out-of-band machine-readable compatibility manifest
|
|
139
|
-
- version engine build, wire profile, storage format, and service API independently
|
|
140
|
-
- establish baseline latency, memory, disk amplification, and restart benchmarks on
|
|
141
|
-
Linux amd64 and arm64
|
|
142
|
-
|
|
143
|
-
Gate: approved implementation sources and claims, an exact compatibility profile,
|
|
144
|
-
and reproducible baseline measurements.
|
|
145
|
-
|
|
146
|
-
## Phase 1: truthful single-node behavior
|
|
147
|
-
|
|
148
|
-
- stop over-advertising MongoDB version, wire behavior, and batch limits
|
|
149
|
-
- serve the single-node concern profile truthfully and reject every concern,
|
|
150
|
-
option, command, or administrative stub whose guarantee one node cannot
|
|
151
|
-
provide (completed 2026-09-02: concerns, deadlines, database-wide transaction
|
|
152
|
-
snapshots, idempotent transaction outcomes)
|
|
153
|
-
- completed slice (2026-08-25): validate OP_MSG required flags, CRC-32C
|
|
154
|
-
checksums, bounded framing, and exact no-response admission and execution
|
|
155
|
-
- preserve complete BSON type and value identity for document and index keys
|
|
156
|
-
- reconcile ambiguous point-write failures before returning control to callers
|
|
157
|
-
- journal DDL and sync every required file and parent directory
|
|
158
|
-
- distinguish incomplete final records from interior corruption and fail closed
|
|
159
|
-
- isolate or secure all debug and privileged management surfaces
|
|
160
|
-
- add an operation registry, deadlines, cancellation, real `currentOp`/`killOp`, and
|
|
161
|
-
truthful metrics
|
|
162
|
-
- write acknowledgement, recovery, corruption, and supported-filesystem contracts
|
|
163
|
-
|
|
164
|
-
Gate: deterministic failpoints and randomized crashes produce no acknowledged-write
|
|
165
|
-
loss, phantom documents, query/storage divergence, or unique-constraint violations
|
|
166
|
-
within the declared single-node fault model.
|
|
167
|
-
|
|
168
|
-
## Phase 2: conformance foundation
|
|
169
|
-
|
|
170
|
-
- build a legally approved behavioral comparison harness
|
|
171
|
-
- fuzz raw wire framing, flags, malformed BSON, and command boundaries
|
|
172
|
-
- validate commands into typed internal representations before execution
|
|
173
|
-
- add exact response, error-code, error-label, and side-effect contracts
|
|
174
|
-
- generate semantic corpora across BSON types, boundaries, arrays, null/missing,
|
|
175
|
-
NaN, Decimal128, projections, paths, expressions, and identifiers
|
|
176
|
-
- prevent any advertised capability from expanding without associated tests
|
|
177
|
-
|
|
178
|
-
Gate: no known P0/P1 mismatch in the certified profile, and every unsupported path
|
|
179
|
-
rejects before side effects.
|
|
180
|
-
|
|
181
|
-
## Phase 3A: storage-substrate decision
|
|
182
|
-
|
|
183
|
-
Decision accepted 2026-08-28: implement a fully SmartDB-owned transactional storage
|
|
184
|
-
kernel and persisted format. The legacy Bitcask engine remains only in the 5.x
|
|
185
|
-
maintenance and offline-conversion lane; it is not the VNext durability boundary.
|
|
186
|
-
Third-party database engines are excluded from the VNext runtime. Libraries for
|
|
187
|
-
bounded primitives such as checksums, compression, or cryptography remain subject
|
|
188
|
-
to ordinary evidence and license review without becoming an embedded database.
|
|
189
|
-
|
|
190
|
-
The custom kernel and every candidate primitive are evaluated against:
|
|
191
|
-
|
|
192
|
-
- crash and power-loss behavior
|
|
193
|
-
- atomic batch and MVCC support
|
|
194
|
-
- checkpoint, backup, and replication integration
|
|
195
|
-
- memory, latency, write amplification, and restart behavior
|
|
196
|
-
- format ownership, migration, licensing, and supply-chain risk
|
|
197
|
-
|
|
198
|
-
Gate: one architecture decision selects exactly one authoritative durability
|
|
199
|
-
boundary. Dual-WAL and dual-commit designs are prohibited.
|
|
200
|
-
|
|
201
|
-
## Phase 3B: Storage VNext
|
|
202
|
-
|
|
203
|
-
- add a segmented, checksummed global commit log with stable timelines and LSNs
|
|
204
|
-
- encode atomic data, DDL, catalog, index-metadata, and auth batches
|
|
205
|
-
- persist request deduplication, retryable-write results, and transaction outcomes
|
|
206
|
-
- add database-wide MVCC read timestamps and change-proportional transactions
|
|
207
|
-
- replace full index-engine clones with incremental deltas
|
|
208
|
-
- add immutable checkpoints, bounded replay, and a durable format manifest
|
|
209
|
-
- move compaction to a rate-limited background service
|
|
210
|
-
- add group commit and real batch publication
|
|
211
|
-
- define an offline 5.x migration and N-1 compatibility contract
|
|
212
|
-
|
|
213
|
-
Gates:
|
|
214
|
-
|
|
215
|
-
- one-document transaction cost is independent of database size
|
|
216
|
-
- repeated recovery is idempotent and produces the same content digest
|
|
217
|
-
- ENOSPC, EIO, short writes, and failed fsyncs yield success, explicit ambiguity, or
|
|
218
|
-
fail-closed state, never silent divergence
|
|
219
|
-
- 24-hour nightly and 72-hour release-candidate soaks meet declared memory, disk,
|
|
220
|
-
and restart ceilings on both Linux architectures
|
|
221
|
-
|
|
222
|
-
## Phase 4: query, index, and resource model
|
|
223
|
-
|
|
224
|
-
- implement one streaming planner/executor
|
|
225
|
-
- use canonical order-preserving BSON index keys
|
|
226
|
-
- add range, compound-prefix, and index-ordered top-k scans
|
|
227
|
-
- implement correct multikey expansion, uniqueness, and TTL execution
|
|
228
|
-
- compile predicates and regular expressions once per operation
|
|
229
|
-
- implement positional updates and array-filter semantics
|
|
230
|
-
- add process-wide and per-tenant admission for memory, scans, connections, I/O,
|
|
231
|
-
index builds, and maintenance
|
|
232
|
-
- add configurable service classes and fair scheduling
|
|
233
|
-
- add only features selected by the certified compatibility profile
|
|
234
|
-
|
|
235
|
-
Semantic work may proceed after Phase 2. Crash-durable retryable outcomes,
|
|
236
|
-
transaction publication, and durable index publication move onto Storage VNext.
|
|
237
|
-
The single-node concern profile is served today: every acknowledged write is
|
|
238
|
-
durable before the response, reads observe committed state, and transactions
|
|
239
|
-
observe one database-wide snapshot. Multi-voter majority acknowledgement and
|
|
240
|
-
cluster-time read concerns remain rejected until replication implements them.
|
|
241
|
-
|
|
242
|
-
Gate: bounded-memory scans at maximum declared scale, published p99 latency and
|
|
243
|
-
capacity curves, proven tenant isolation, and zero certified-profile mismatches.
|
|
244
|
-
|
|
245
|
-
## Phase 5: backup, PITR, and managed single-node service
|
|
246
|
-
|
|
247
|
-
- create online immutable checkpoints at exact LSNs
|
|
248
|
-
- archive subsequent commit-log segments continuously
|
|
249
|
-
- encrypt, checksum, and sign backup manifests with timeline, format, LSN range,
|
|
250
|
-
and key identity
|
|
251
|
-
- restore into a new root, replay to an exact LSN or timestamp, verify its content
|
|
252
|
-
digest, and promote atomically
|
|
253
|
-
- retain logical export/import as migration tools rather than backup primitives
|
|
254
|
-
- add versioned service classes, immutable node placement, node-bound grants,
|
|
255
|
-
TLS/mTLS endpoints, credential rotation/revocation, quotas, metering, backup
|
|
256
|
-
policy, maintenance windows, audit, and idempotent asynchronous operations
|
|
257
|
-
- operate one process per tenant initially
|
|
258
|
-
- qualify signed images, SBOM/provenance, canaries, rollback, alerts, runbooks, and
|
|
259
|
-
security before any general-availability claim
|
|
260
|
-
|
|
261
|
-
Launch order: internal alpha, private beta, then single-node GA with explicit
|
|
262
|
-
availability, RPO, RTO, capacity, and compatibility limits.
|
|
263
|
-
|
|
264
|
-
Gate: repeated maximum-size restore drills meet the published RPO/RTO; billing
|
|
265
|
-
reconciles; upgrades and rollback/restore pass; cross-tenant network, auth, quota,
|
|
266
|
-
backup, and restore isolation is proven; no plaintext secret reaches persisted or
|
|
267
|
-
logged state.
|
|
268
|
-
|
|
269
|
-
## Phase 6: replication and high availability
|
|
270
|
-
|
|
271
|
-
- replicate the Storage VNext log across three replicas in separate failure domains
|
|
272
|
-
- add terms, quorum commit, snapshot installation, log catch-up, and membership
|
|
273
|
-
changes
|
|
274
|
-
- extend the single-node concern profile to multi-voter majority acknowledgement
|
|
275
|
-
and cluster-time read concerns
|
|
276
|
-
- publish accurate `hello` topology and election metadata
|
|
277
|
-
- add causal times, retryable outcomes, idempotent transaction commits, and
|
|
278
|
-
failover-safe session behavior
|
|
279
|
-
- support mixed N/N-1 rolling upgrades
|
|
280
|
-
- keep one database assigned to one replica group
|
|
281
|
-
|
|
282
|
-
Majority RPO 0 means a majority-acknowledged write survives loss of any one replica
|
|
283
|
-
within the declared replica-group fault model.
|
|
284
|
-
|
|
285
|
-
Gate: no split-brain commits under partitions; accepted histories satisfy the
|
|
286
|
-
declared consistency model; leader failure meets the published RTO; and retries
|
|
287
|
-
return the original outcome exactly once.
|
|
288
|
-
|
|
289
|
-
## Phase 7: managed HA and compatibility expansion
|
|
290
|
-
|
|
291
|
-
- place complete databases across replica groups
|
|
292
|
-
- migrate a database through checkpoint transfer, log catch-up, and an atomic
|
|
293
|
-
routing-epoch change
|
|
294
|
-
- permanently fence stale owners
|
|
295
|
-
- add automated replica replacement and maintenance-aware failover
|
|
296
|
-
- derive durable change streams from the replicated commit log
|
|
297
|
-
- certify additional drivers and ODMs
|
|
298
|
-
- expand aggregation, views, indexes, and administrative behavior according to
|
|
299
|
-
measured workload demand
|
|
300
|
-
- publish machine-generated compatibility and SLO matrices
|
|
301
|
-
|
|
302
|
-
Gate: no open P0/P1 defect in the certified surface, regional and maintenance
|
|
303
|
-
exercises pass, and customer-visible incident/status processes are operational.
|
|
304
|
-
|
|
305
|
-
## Phase 8: horizontal scale
|
|
306
|
-
|
|
307
|
-
Scale complete databases across replica groups first. Add intra-database sharding
|
|
308
|
-
only after single-group limits become a measured customer constraint:
|
|
309
|
-
|
|
310
|
-
- separate router and replicated placement catalog
|
|
311
|
-
- range ownership and epochs
|
|
312
|
-
- snapshot-plus-log range migration
|
|
313
|
-
- stale-router rejection and permanent owner fencing
|
|
314
|
-
- per-shard replica groups, balancing, and range cleanup
|
|
315
|
-
- cross-shard transactions only as a separately justified program
|
|
316
|
-
|
|
317
|
-
Gate: migration crashes cannot create gaps, duplicates, or dual writers; stale
|
|
318
|
-
routing metadata cannot mutate old ownership; shard and region chaos meet the
|
|
319
|
-
published SLOs.
|
|
320
|
-
|
|
321
|
-
## Release qualification
|
|
322
|
-
|
|
323
|
-
Every applicable release must pass the narrowest relevant set of these gates:
|
|
324
|
-
|
|
325
|
-
- raw-wire and target-driver handshake tests
|
|
326
|
-
- generated semantic and certified compatibility suites
|
|
327
|
-
- deterministic persistence failpoints and randomized process-kill tests
|
|
328
|
-
- storage/index/content-digest reconciliation after recovery
|
|
329
|
-
- 24-hour nightly and 72-hour release-candidate resource soaks
|
|
330
|
-
- all published Linux and macOS architectures
|
|
331
|
-
- automated backup/restore drills once backup exists
|
|
332
|
-
- partition, failover, and history verification once replication exists
|
|
333
|
-
- supply-chain, provenance, security, upgrade, and rollback checks for managed tiers
|
|
334
|
-
|
|
335
|
-
No release may advertise a capability, durability level, topology, or operational
|
|
336
|
-
limit that its release qualification did not exercise.
|