Repository navigation
ci: run and schedule the wasm probe on main - #367
Conversation
… main nightly `wasm32-unknown-unknown` has no std clock: `SystemTime::now()` panics with "time not implemented on this platform". Four sites in this crate read it directly — the wire timestamp, both HLC variants, and `Timestamp::now` — so any of them panics the moment a wasm build calls it. `clock::since_epoch()` now owns the split: `js_sys` on `wasm32-unknown-unknown`, std everywhere else (`wasm32-wasip1` included). Callers keep their own conversion, saturation, and pre-epoch fallback, so native behaviour is unchanged. The site list in the TODO at `wire_time.rs` shrinks by four; the remaining callers are routed as they move to the helper. The CI workflow gains a nightly schedule: the `run-ci` label gate keeps upstream churn out of PR runs, but nothing then reports a red `main`, so the first run to notice it is the next labelled PR. Evidence: `cargo check -p nodedb-types --profile ci` and the same for `--target wasm32-wasip1` pass. The `wasm32-unknown-unknown` check does NOT run — `getrandom` needs a backend there (pre-existing, why the wiki uses wasip1 for wasm compile checks), so the `js-sys` arm is not compile-verified in this commit.
…he helper Fourteen more `SystemTime::now()` reads across the wasm-compiled crates now go through `nodedb_types::clock::since_epoch()`: the CRDT validator's auth-expiry check and HLC stamp, its four CascadeDefer/retry stamps, the DLQ enqueue stamp, the `DEFAULT NOW()` renderer, the `NOW()` preprocessor, and the array HLC. Each keeps its own conversion, fallback and error mapping, so native behaviour is unchanged; none of them panics on `wasm32-unknown-unknown` any more. `nodedb-vector`'s HNSW build timer is a log field, not a correctness stamp: it is gated off on `wasm32-unknown-unknown` and the log reports 0. The DLQ field's doc comment names the helper instead of `SystemTime::now`. Evidence: `cargo check -p nodedb-crdt -p nodedb-sql -p nodedb-array -p nodedb-vector --profile ci` passes, and the same for `--target wasm32-wasip1`; rustfmt is clean on all seven files. The `wasm32-unknown-unknown` target still cannot be checked: `getrandom` needs a backend there (pre-existing, why the wiki uses wasip1).
…es for wasm `clock::since_epoch()` is the one place a clock read happens on a wasm target, so it gets the two assertions callers rely on: the clock answers, and two reads do not go backwards (HLC monotonicity, retry stamps, auth expiry all assume it). CI gains a wasm compile job over the sixteen shared crates. The server, cluster and raft crates are not wasm targets; these are the ones NodeDB-Lite compiles into its wasm build, so a wasm-incompatible dependency or a target-specific cfg mistake fails here rather than in the Lite repo — which is how the array HLC's `SystemTime::now()` reached a consumer at all. `wasm32-wasip1` on purpose: `wasm32-unknown-unknown` needs a getrandom backend the workspace does not select, so that check would fail on the random source instead of the code under change. Evidence: `cargo test -p nodedb-types --profile ci --lib clock::` → 2 passed; `cargo check --profile ci --target wasm32-wasip1` over the same sixteen crates → clean.
`clone.rs` carried a private `current_wall_ms()` that read `SystemTime::now()` directly — the duplicate the `wire_time` TODO pointed at. It keeps its own contract (a pre-epoch clock is an `Err`, never a silent sentinel) but now reads through `clock::since_epoch()`, so the target split applies on every path. The TODO is replaced by the decision it was asking for: the funnel is the clock module, not that one helper, because callers legitimately differ on what a pre-epoch clock means — `0` plus a one-time log here, an error there. Evidence: `cargo check -p nodedb --profile ci` → finished clean.
…rt the resource limit An element count read from a frame is multiplied by its element size before the 64 MiB ceiling is compared. On a 32-bit target that multiplication overflows `usize` for counts the 64-bit path rejects cleanly, so the same hostile frame came back as `Corrupt` there and `ResourceLimit` here. `checked_capacity` now does the scaling in 64-bit arithmetic, which fixes every caller at once; `validate_value_count` in delta and double-delta and the FastLanes header parse route through it rather than repeating the multiplication.
…oder Zstd encoding is deliberately absent on wasm32: `compress_native` returns `CompressFailed` there, because the target decodes with ruzstd and encodes with LZ4. Eight tests roundtrip through `encode` or drive `ZstdEncoder`, so they assert a property this target does not have and unwrap on it. They are ignored by name and reason on wasm32 rather than weakened. The decoder-only tests -- the hostile-frame and truncation checks -- carry no such attribute and still run there, because decoding is the half the target does implement.
Four sites added a length read from the input to a header width in plain `usize`: the STR32/BIN32/EXT32 arms of `skip_value`, and `start + len` in the string read path. `5 + 0xffff_ffff` panics on a 32-bit target instead of returning `None`, which the module's own contract forbids -- it documents "Returns None on truncated/invalid data -- never panics". `checked_advance_len` performs both additions checked, and `checked_advance`, `read_u16_be`, `read_u32_be`, `read_u64_be`, `read_str`, `read_str_advance`, `read_bin_advance`, the field index and the field lookup all route through it.
Two test targets imported items that `src/lib.rs` gates off on wasm32, so the whole target failed to compile there rather than skipping anything: the `segment_backing` test in the index state module, and the entire `tests/vector_suite` integration target, which drives `VectorCollection`, `mmap_segment` and their `libc::madvise` path. Both are native-only for a real reason -- mmap is the only backing implementation -- so they are gated rather than rewritten, and they still run in full natively.
…silently regress The wasm job compiled the sixteen shared crates and stopped there. A check cannot observe a runtime panic, and without --all-targets it never builds a test target at all, so dev-dependency and test-only wasm breakage stayed invisible -- which is how a #[cfg(unix)] write guard that is false on wasi, and a header + len addition that overflows a 32-bit usize, both reached the tree with a green job. The job now executes the suites under wasmtime for all sixteen crates. Two nodedb-codec tests cannot hold on the target and are handled where the reason lives: the eight zstd encoder tests are ignored in-source by target cfg, and the one approximate-recall floor is skipped by name with its measurement recorded. scripts/ci/check_wasm_probe.py guards the shape rather than the prose: ci.yml must carry a schedule, the wasm job must execute tests rather than check, name a runtime with a raised stack, and cover exactly the sixteen crates. Its --self-test feeds each check a configuration built to violate it, so the gate cannot silently rot. Wired into both the static gates and the reusable suite.
`flush_buffer`'s only write sat behind `#[cfg(unix)]`, and wasm32-wasip1 is `target_family = "wasm"`, not unix — so on wasm the block compiled out while the lines after it still advanced `file_offset`, cleared the buffer and recorded the flush. `append()`/`sync()` returned `Ok` with `metadata(path).len() == 0`: every record was silently dropped. - Gate the pwrite loop on `all(unix, not(target_arch = "wasm32"))` and add a wasi arm that seeks to `file_offset` and `write_all`s (wasi preview1 has no positional write, and the file is only ever appended to). The shared `file_offset` advance below already accounts for the bytes. - `write_error` must exist for the wasm arm too, so widen it to `any(unix, target_arch = "wasm32")`; the ENOSPC branch stays unix-only (on wasi `raw_os_error()` is None, so the generic `WalError::Io` branch is taken). - `fsync_directory` has the same shape: wasi has no directory fsync and `File::sync_all()` on one returns EBADF, so on wasm it is a documented no-op. The rename still succeeds; the directory-entry crash guarantee is what the target cannot provide. - Pin the write path with an assertion: `metadata(path).len()` must equal `file_offset()` after `sync()`. The test previously only checked `file_offset() > 0`, which the no-op satisfied.
The shared crates are now compiled and executed for wasm32-wasip1 in CI, so the limitations are measured rather than assumed. Three are worth stating plainly because each is a guarantee the native WAL provides and this target cannot: there is no directory fsync in WASI preview 1 (so a rename is not crash-durable), no positional write (so the writer seeks and writes sequentially, which is equivalent for an append-only log), and no double-write buffer (so DWB Direct mode reports Unsupported rather than silently weakening).
The four crates' dev-dependencies inherited `tokio = { features = ["full"] }`
from the workspace entry, and tokio's wasm guard rejects
fs/io-std/net/process/rt-multi-thread/signal there, so their test targets
could not compile for wasm32-wasip1.
A narrower workspace alias cannot fix this: `fluxbench` (a dev-dependency of
wal and mem) declares its own normal `tokio = { features = ["full"] }`, and
Cargo unifies features across the whole invocation, so no member-level
feature list can subtract `full`. The suggested alias would also have tripped
the guard itself, since `rt-multi-thread` is one of the rejected features.
- wal/mem: move `tokio` and `fluxbench` to
`[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]`. Neither is
reachable from a wasm test — the crates have no tokio call sites, and
fluxbench is used only by a bench, which `cargo test` does not build.
- crdt: same move for its unused tokio dev-dependency.
- client: `#[tokio::test]` in src/traits/core/trait_def.rs needs only
`macros` + `rt`, so the dev-dependency becomes a direct narrow spec, and a
native-only `tokio = { workspace = true }` restores the exact pre-split
`full` resolution off wasm.
`std::env::temp_dir()` is `unimplemented!("not supported by WASI yet")` in
std's wasi backend, so `tempfile::tempdir()` aborts before it reaches the
filesystem — no preopen and no `TMPDIR` can help. With the write path fixed,
this was the next thing that stopped the wal test targets from running.
- Add a wasi-safe helper (`tempdir_in(".")` on wasm32, `tempfile::tempdir()`
otherwise — native unchanged) in src/lib.rs for the unit tests, and one in
tests/wal_suite/main.rs plus a small local one in tests/faultbox_single_emit.rs
for the two integration crates.
- Swap the 149 call sites (85 src, 64 tests) to the helpers. No assertion
changes; on native the helper is byte-for-byte the old call.
The wasm runner preopens the working directory (`wasmtime --dir=.`), so the
temp dirs land there on wasm.
Three wasi gaps remain after the write path and temp-dir helpers, and each one is a target limitation rather than a code defect, so the tests that need the missing capability are native-only while every assertion stays intact: - `std::thread::spawn`/`scope` fails with `Unsupported` on wasm32, and wasm targets abort on panic. Gates the shared-writer append test (wal), the DWB parallel-writer stress case (wal tests) and the two concurrent-reserve tests (mem). - `DoubleWriteBuffer::recover_record` is a deliberate `Ok(None)` stub on wasm32 (slot recovery needs `pread`/O_DIRECT), so the tests that assert a record comes back from it are native-only: the DWB unit tests in double_write/buffer.rs and double_write/recover.rs, and the DWB splice-back case in the wal crash-recovery suite. The non-recovery half of `batch_deferred_writes_and_flush` and the skip accounting in `oversized_record_is_reported_as_skipped` still run on wasm. - `nodedb_wal::mmap_reader` is gated off on wasm32, so encrypted_replay's mmap import and its one mmap test are gated together; the other four cases in that file stay in the wasm run. The mem suite drops from 86 to 83 on wasm and the wal lib from 218 to 195 plus the native-only suite cases; native test counts are unchanged.
…-free Follow-up to the previous gate commit, two fixes: - `reader_ciphertext_invariant` and `reader_preamble_and_continuity` both import `nodedb_wal::mmap_reader`, which is absent on wasm32, so the wasm test target did not compile. cases/mod.rs is held elsewhere and its `mod` gates were not in place, so each file carries `#![cfg(not(target_arch = "wasm32"))]` instead — same effect, the module never resolves the import. `durability_stress` is a single native-only thread case and is gated the same way, which also removes the imports it alone used. - Gating individual tests left items used only by them unreferenced on wasm: `double_write/recover.rs`'s whole test module is now `#[cfg(all(test, not(target_arch = "wasm32")))]` (every test in it asserts `recover_record`), and `governor/reserve.rs` gates `Arc`, `DatabaseId` and `TenantId` alongside the thread test that uses them. The wasm test build is now warning-free as well as green.
The two reader cases are gated inside their own files rather than on the `mod` line here, because every test in them drives the wasm-gated `mmap_reader` module. The comment now says that, and says why `encrypted_replay` is gated the other way -- four of its five tests are wasm-safe and keep running there.
The entry named O_DIRECT and positional reads as the reason. The stronger reason is that slot recovery needs the read side too, and recover_record is a stub on this target, so a slot written there could never be read back. A seek-and-write fallback would mirror the slot, let the writer report DwbProtection::Active, and deliver no protection — which is worse than the Degraded(WriteFailed) state the writer reports today while the append still succeeds.
The wasm arm is a deliberate refusal, not a gap: a seek-and-write fallback would let the writer mirror the slot and report DwbProtection::Active while recover_record remains a stub on that target, so the protection would be claimed and unusable. The comment now says that, and says what the target reports instead.
cargo clippy --workspace --all-targets --all-features --profile ci -- -D warnings aborted on this expression, so the lint job was red on the whole workspace and never reached the wasm job at all. Clippy's own suggested rewrite is exactly this one, and the predicate is unchanged: is_some_and over a negated match became is_none_or over the match. The file is otherwise untouched, and it is unrelated to the wasm work — it is here because a red lint job would have hidden everything else in this PR.
The workflow sets `RUSTFLAGS: -C link-arg=-fuse-ld=mold` for the native jobs,
where mold is a real speedup. The wasm job inherits it, and this target links
through the `wasm32-wasip1` spec with `rust-lld`, which rejects the argument:
error: linking with `rust-lld` failed: exit status: 1
= note: rust-lld: error: unknown argument: -fuse-ld=mold
Every test binary that has to link therefore failed. The compile-only job this
replaces never linked, so the flag was inert there and the failure only appeared
once this job started executing tests.
The job now clears `RUSTFLAGS` for itself. That has to be the un-prefixed
variable: cargo gives `RUSTFLAGS` precedence over
`CARGO_TARGET_WASM32_WASIP1_RUSTFLAGS`, verified by building a scratch crate with
both set and watching the mold argument still reach the linker, so a per-target
override does not work here. A job-level `env` shadows the workflow-level one,
so the native jobs keep mold.
There was a problem hiding this comment.
Removed from main. Resubmit the clock fix alone, in a new PR.
This PR merged, then main was reset to 1ff3551. A merged PR cannot reopen, so the next round needs a new PR.
Scope for the resubmit
Keep:
nodedb-types/src/clock.rs, and the 18 call sites routed throughsince_epoch()(#364). This part is correct and wanted.
Drop from this repo:
- The wasm test job in
test.yml, the probe gate instatic-gates.yml, andscripts/ci/check_wasm_probe.py. Lite is the only wasm consumer, so wasm CI belongs in the lite repo. - The nightly
scheduleinci.yml. NodeDB runs no scheduled CI. Gate on PR and push only. - The WASI changes in
nodedb-wal,nodedb-mem,nodedb-crdtandnodedb-client(test gating, tokio feature splits,docs/wasm.md). Lite targetswasm32-unknown-unknownand never runs these crates under WASI. - Unrelated fixes in
nodedb-codec,nodedb-query,nodedb-vectortests, andvector_primary.rs. Each is a separate change. Open its own PR with its own reproduction.
The 32-bit overflow in msgpack_scan/reader/skip.rs breaks a documented "never panics" contract. Open it as its own PR with a test.
Coverage for the js-sys arm
The clock.rs unit tests run only on std targets. Nothing in this repo runs the js_sys arm. Prove it in lite: nodedb-lite-wasm/tests/array.rs already reaches the array HLC that panicked.
Findings
Inline below. One blocker, two should-fix.
| /// has millisecond resolution. | ||
| #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] | ||
| pub fn since_epoch() -> Option<Duration> { | ||
| Some(Duration::from_millis(js_sys::Date::now() as u64)) |
There was a problem hiding this comment.
Blocker. The doc on line 17 says None when the clock reads before the epoch. This arm never returns None.
Date.now() returns a negative f64 for a pre-epoch clock. as u64 saturates it to 0, so the function returns Some(0). Callers that map None to an error then store a zero timestamp silently. nodedb-array's HLC now_ms() is one of them.
Return None when Date::now() is negative, matching the std arm.
| #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] | ||
| let elapsed_ms = start.elapsed().as_millis() as u64; | ||
| #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] | ||
| let elapsed_ms = 0u64; |
There was a problem hiding this comment.
Should-fix. This is dead code. nodedb-vector/src/lib.rs gates pub mod builder with #[cfg(not(target_arch = "wasm32"))], so this file never compiles on wasm32-unknown-unknown.
Remove the three cfg arms in this file and keep Instant::now() as it was.
| [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] | ||
| js-sys = "0.3" |
There was a problem hiding this comment.
Should-fix. Every other dependency in this crate uses { workspace = true }. Declare js-sys in the root [workspace.dependencies] and reference it from here. Add a blank line before the [target...] table.
ci: run and schedule the wasm probe on main
Why
ci.ymlwas label-gated with noschedule, so no run reported onmain— thelast one was a manual dispatch on 2026-05-07. The only wasm job compiled three
decoders with
cargo check, and a check can neither execute code nor, without--all-targets, build a test target. Both gaps were structural: atarget-specific failure could reach
mainwith every job green.That was not hypothetical. Changing the wasm job to execute the shared crates
turned up five failures on the first run, two of them in production code:
nodedb-wal/src/writer/flush.rs—flush_buffer's only write was guarded#[cfg(unix)], which is false onwasm32-wasip1(target_family = "wasm",target_os = "wasi"). On wasm the function advancedfile_offset, cleared thebuffer and returned
Okwith zero bytes written — silent data loss onappend()+sync(). The author's own comment at the site ("on other targets(wasm32) this would be dead code") is the assumption that hid it.
nodedb-query/src/msgpack_scan/reader/skip.rs—checked_advance(buf, offset, 5 + len)with
lenread from the input as au32. On 32-bit,5 + 0xffff_ffffpanicswith attempt to add with overflow instead of returning
None— against themodule's own documented contract, "Returns
Noneon truncated/invalid data —never panics". Four such sites in total.
nodedb-codec—checked_capacityscaled a decoded element count inusize,so on 32-bit a hostile count overflowed to
Corruptwhere 64-bit reportsResourceLimit.nodedb-vector— two test targets imported#[cfg(not(target_arch = "wasm32"))]modules, so they failed to compile rather than skipping.
nodedb-wal/nodedb-mem/nodedb-crdt/nodedb-client— the test targetscould not build at all, because
tokio = { features = ["full"] }is inheritedfrom the workspace and tokio rejects that feature set on wasm.
What changed
This closes two issues whose fixes travel together: (a) the wall-clock defect in the shared
crates (#364), and (b) the missing execution probe that is the only thing which verifies (a)
(#365). The sections below are split along that line so each can be reviewed on its own.
(a) The clock defect — #364
nodedb-types/src/clock.rs(in the branch's original commits) — one target-splitsince_epoch():js_sysonwasm32-unknown-unknown, std elsewhere. All eighteen productionreads route through it and no shared crate reads
SystemTime::now()directly any more.(b) The probe, and what executing it exposed — #365
.github/workflows/ci.yml— a nightlyscheduleonmain. Therun-cilabel gate still keeps upstream churn out of PR runs; this is the only thing
that reports on
mainitself..github/workflows/test.yml— thewasmjob now runscargo test --target wasm32-wasip1for all sixteen shared crates underwasmtime, with the runner's stack raised to match the native job'sRUST_MIN_STACK. Compile-only became execute..github/workflows/static-gates.ymlandtest.yml— the new probe gateruns in both, so it is checked on every PR as well as in the suite.
scripts/ci/check_wasm_probe.py— asserts the shape rather than the prose:ci.ymlcarries a schedule, the wasm job executes tests rather than checking,names a runtime with a raised stack, and covers exactly the sixteen crates.
--self-testfeeds each check a configuration built to violate it, so the gatecannot rot silently.
nodedb-wal/src/writer/flush.rs— a wasi arm that seeks tofile_offsetand
write_alls (wasi has no positional write; the segment is append-only, sothis is equivalent). The native path is byte-for-byte unchanged.
nodedb-wal/src/segment/atomic_io.rs—fsync_directoryis a documentedno-op on wasm; wasi preview 1 has no directory fsync. The file fsync and the
rename still happen; what is dropped is the directory-entry crash guarantee.
nodedb-query/.../msgpack_scan/reader/—checked_advance_lenperformsboth additions checked, and every length-prefixed tag routes through it.
nodedb-codec/src/bounds.rs— the element-size scaling moves to 64-bitarithmetic and reports
ResourceLimiton every target.nodedb-*/Cargo.toml— native-only dev-dependencies moved behind[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies], so the wasmtest builds no longer inherit
tokio/full. Native resolution is still exactlyfull.nodedb-waltest scaffolding — a wasi-safe temp dir helper replaces 149tempfile::tempdir()call sites (wasi'sstd::env::temp_dir()isunimplemented!()inside std,before any syscall), and the four crates' native-only dev-dependencies move behind
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]so the test builds stop inheritingtokio/full, which tokio refuses on wasm. Native resolution is still exactlyfull.nodedb/src/control/planner/sql_plan_convert/dml/vector_primary.rs— the unrelatednonminimal_boolrewrite, explained below.docs/wasm.md— records the three WAL guarantees a WASI target cannotgive, now that they are measured rather than assumed.
How it was verified
Executed locally against this branch head, because CI has not run yet.
python3 scripts/ci/check_wasm_probe.py --root <base workflow files>20260927T025538-wasm-probe-gate-base-base.logpython3 scripts/ci/check_wasm_probe.py --self-test && python3 scripts/ci/check_wasm_probe.py && cargo fmt --all -- --check20260927T035141-wasm-probe-gate-on-head-fix.logcargo test --profile ci --target wasm32-wasip1 -p <sixteen crates> -- --skip top1_recallcargo test --profile ci -p <sixteen crates>cargo fmt --check && probe gate --self-test && preflight20260927T033523-fmt-gate-preflight-final.logcargo clippy --workspace --all-targets --all-features --profile ci -- -D warningsThe red arm is the honest form of "the absence is the report": the gate run
against
origin/main's workflow files fails with noscheduletrigger andno
wasmjob.Side project
These are the exclusions the wasm job needs in order to be green at all. Each is a test or a guarantee the target genuinely cannot have, so they travel with the job as a side project rather than being folded silently into it — the reasons are the reviewable part.
top1_recall_on_training_setis skipped by name. It asserts an approximate-recall floor of 0.70 on a ten-vector synthetic set; it measures 0.60 on this target and passes natively. The training path is deliberately seeded, so the gap is float behaviour on a different codegen path, and the dataset is too small for the assertion to survive it. Skipped, not weakened.nodedb-codeczstd encoder tests are ignored on wasm in-source by#[cfg_attr(target_arch = "wasm32", ignore = ...)]. The target has no zstd encoder by design (compress_nativereturnsCompressFailed; it decodes withruzstdand encodes with LZ4), so they assert a property it does not have. The decoder-only tests — hostile frames, truncation — still run on wasm.std::thread::spawn, the DWBrecover_recordstub, or the mmap readers are gated#[cfg(not(target_arch = "wasm32"))]. No assertion was weakened or deleted: whole-crate#[test]counts are identical to the base (wal 294, mem 86, crdt 168, client 115).wasm32-unknown-unknownremains uncovered.cargo checkfor that target fails in a transitivegetrandom 0.3.4, which needs thewasm_jsfeature plus a--cfg getrandom_wasm_jsRUSTFLAGS entry before the target compiles at all. Thejs_sysclock arm this branch's clock fix adds is therefore still not compile-verified anywhere. A real hole, stated rather than papered over.use_direct_io: falseon wasm still reportsActiveand cannot be read back. Found by Review 2 and left alone, because fixing it is the same "write half without the read half" mistake this PR already reverted once:DwbMode::Directcorrectly reportsDegraded(WriteFailed)on wasm (pwrite_allreturnsUnsupported), but an explicitly Buffered-mode DWB takes a plain seek-and-write path, mirrors its slots, fsyncs them, and reportsDwbProtection::Active— whilerecover_recordis stillOk(None)on that target. The protection is claimed and unusable in exactly the way the Direct path is designed to avoid. It predates this branch (identical at the base), and it is not introduced here.recover_record's own rationale says slot recovery needspread, butscan_max_seqalready reads slot prefixes on wasm, so a seek-based read-back looks tractable — that is the follow-up, not this PR.Two items here deserve their own change rather than a corner of this one: the DWB read-back above, and the six byte-identical db-prefix strippers elsewhere in the tree. Neither is touched by this PR.
Unrelated lint carried in the diff
cargo clippy --workspace --all-targets --all-features --profile ci -- -D warningsaborted onclippy::nonminimal_boolatnodedb/src/control/planner/sql_plan_convert/dml/vector_primary.rs:161,base-identical and outside everything else here. It is fixed in this PR anyway, by the one-line
is_none_orrewrite clippy itself suggests: leaving it red would have failed the lint job and hiddenevery other change in the branch behind a failure that had nothing to do with them. The sibling PR
#368needs the same line, so it is deliberately the branch tip and lands first.Review
Review 2, fresh context, read-only: PASS, 0 blockers, on commit
434d5849d. It independently confirmed no test deleted or weakened (identicalper-crate
#[test]counts), the native paths byte-for-byte unchanged, that thewasm
flush_buffercannot returnOkwithout the bytes landing (write_allhandles short writes and errors before the offset advances), that the
Corrupt→ResourceLimitchange has no dependent matcher and keeps an accuraterequested, and that all fifteenchecked_advance_lenheader/len pairs matchtheir tag widths.
Closes
Closes #364 — the wall-clock defect: 18 guardless reads, one target-split helper, no shared crate
reads
SystemTime::now()directly.Closes #365 — the process gap: a scheduled probe on
main, and a wasm job that executes the sharedcrates instead of merely compiling them.