general review 004 (pre-release, whole workspace): one HIGH slot-poisoning fix, two contract-observable divergence fixes, robustness + doc corrections — all gates re-run green
- sqlite scheduler tick: a failed COMMIT (or ROLLBACK) left the connection released with a stuck-open transaction, wedging the writer slot forever — the one commit site missing the drop-+-reopen-replenish arm; tick now takes the conn by value with a poisoned disposition (drop + replenish), the commit-fault seam reaches the tick, and failed_tick_commit_replenishes_the_writer_slot pins the arm - pg save_offset_tx stored GREATEST($3,0) where the wave-8 gate's negative-seed fix (raw seed, ADR-023 §2 2026-10-11 annotation) covered only the auto-commit form; mem's merged in-tx read clamped a staged negative seed against a phantom zero; both fixed and the tx-form totality pinned by a new stamped suite leg (in_tx_reads_see_own_writes) green on all three columns vs the live harness server - pg: a failed forwarder register leaked the channel refcount forever (no receiver to drop it) — listen/spawn_bridge now unregister on the register error, mirroring the subscribe-failure arm; register doc corrected to put the failure disposition at the call site - pg forwarder: nine poisoned-mutex expect() panics converted to the mem crate's into_inner recovery idiom (no-expect-outside-tests rule) - core encode_payload: a deeply-nested Value aborted the process in serde_json's unguarded serializer recursion and the fuzz pin blessed storing bytes no decoder could read back; encode now rejects nesting past 127 containers (the empirically-verified decode limit) with typed Codec — decode-aligned boundary pins added to the fuzz invariant and value_type_tests, applied pre-publish within the open class-1 window - scheduler sleep deadlines: Instant + Duration overflow caps (MAX_SLEEP_S, tick-and-resleep) on all three engines for far-future boundaries; sqlite tick claim stamp now saturating_add - docs read true again: Error::Closed scope (stream try_recv arm), validation whitespace wording, sqlite lib.rs phantom durability knobs, pg lock.rs honest autocommit wording, mem tx/stream merge + wake- granularity wording; wakes.rs stale allow(dead_code) removed - tests: value_type_tests exercised its own map_err instead of the function under test (fixed); unwrap_or_default reference encodes panic with cause - docs/reviews/004-pre-release-general-review.md records nine fixed + sixteen parked findings (sqlite seam panic-safety armor, watcher post-death-subscribe hang + initial-stat self-kill, pg forwarder TOCTOU/hang/diagnosability, pg BIGINT server-side stamp overflow, mem growth/outbox notes, pg identifier-truncation doc note, smaller) and two false positives caught on verification; implementation.md review-rounds entry + core-contract backlog rows updated - gates: build, workspace tests (sqlite 194, core 27, suite legs new), full live pg column 127+25+9, clippy -D warnings, fmt, fuzz replay 6/6, wasm32 check, doc gate -D warnings — all green
This commit is contained in:
1 parent
5385f6bee3
commit
029f885aa1
24 files changed
+738
-103
No files matched your search
@@ -166,8 +166,11 @@ fn canonicalization_ulp(x: f64) -> f64 {
|
||||
|
||||
/// Deep inputs decode loud and typed: past serde_json's recursion
|
||||
/// limit, deserialization fails with `Error::Codec` — never a stack
|
||||
/// overflow, never an untyped panic. The encode side handles deep
|
||||
/// (but sub-limit) data as the normal round-trip.
|
||||
/// overflow, never an untyped panic. The encode side refuses the same
|
||||
/// depth region (typed `Codec`, never a serializer stack overflow): a
|
||||
/// `Value` nested past the decode limit could never be read back from
|
||||
/// the stored bytes, so storing it would be silent loss at read time.
|
||||
/// Data through the encode/decode boundary is the normal round-trip.
|
||||
fn assert_deep_input_loudness() {
|
||||
for depth in [RECURSION_LIMIT * 4, 4096] {
|
||||
let deep_bytes = nested_array_bytes(depth);
|
||||
@@ -185,20 +188,33 @@ fn assert_deep_input_loudness() {
|
||||
}
|
||||
Ok(_) => panic!("deep bytes must not decode to the typed target at depth {depth}"),
|
||||
}
|
||||
let deep_value = nest_value(Value::Null, RECURSION_LIMIT + 1);
|
||||
let deep_encoded =
|
||||
encode_payload(&deep_value).expect("a sub-limit-depth `Value` must encode");
|
||||
match payload_as::<Value>(&deep_encoded) {
|
||||
let deep_value = nest_value(Value::Null, RECURSION_LIMIT * 4);
|
||||
match encode_payload(&deep_value) {
|
||||
Err(Error::Codec(_)) => {}
|
||||
Err(other) => {
|
||||
panic!("the stored deep form must decode as typed `Codec`, got {other:?}")
|
||||
}
|
||||
Ok(_) => {
|
||||
panic!("stored bytes nested past the decode limit must decode loud, not silent")
|
||||
panic!("past-limit nesting must be a typed `Codec` encode failure, got {other:?}")
|
||||
}
|
||||
Ok(_) => panic!(
|
||||
"nesting past the decode limit must never encode (the stored bytes could \
|
||||
never be read back)"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// The encode/decode boundary (RECURSION_LIMIT - 1 containers read
|
||||
// back; RECURSION_LIMIT containers fail to decode): symmetry —
|
||||
// everything decodable encodes, nothing undecodable stores.
|
||||
let boundary_value = nest_value(Value::Null, RECURSION_LIMIT - 1);
|
||||
let boundary_encoded =
|
||||
encode_payload(&boundary_value).expect("a decodable `Value` must encode");
|
||||
let back: Value = payload_as(&boundary_encoded).unwrap_or_else(|e| {
|
||||
panic!("stored bytes at the encode/decode boundary must round-trip: {e:?}")
|
||||
});
|
||||
assert_eq!(
|
||||
back, boundary_value,
|
||||
"the boundary `Value` round-trip must hold"
|
||||
);
|
||||
|
||||
let shallow_bytes = nested_array_bytes(8);
|
||||
let shallow_value = nest_value(Value::from(0u8), 8);
|
||||
let shallow_encoded = encode_payload(&shallow_value).expect("a shallow `Value` must encode");
|
||||
|
||||
Reference in new issue
Block a user