Skip to content

fix(streaming): v8.0.30 audit follow-ups + 8.0.32 bump (closes #498)#499

Merged
userFRM merged 1 commit into
mainfrom
fix/v8.0.30-audit-followup
May 6, 2026
Merged

fix(streaming): v8.0.30 audit follow-ups + 8.0.32 bump (closes #498)#499
userFRM merged 1 commit into
mainfrom
fix/v8.0.30-audit-followup

Conversation

@userFRM
Copy link
Copy Markdown
Owner

@userFRM userFRM commented May 6, 2026

Summary

Closes the seven hygiene gaps identified in the v8.0.30 streaming review (issue #498). One squashable commit; no dispatcher / FFI behavior change for users on the happy path, only on previously-undefined error paths.

  • Dispatcher resilience. Drain loop now wraps user-callback invocation in catch_unwind. A panic from user code (Rust closure / PyO3 callable / napi ThreadsafeFunction / C extern "C" fn) no longer kills the dispatcher thread; panics are counted on a new panic_count AtomicU64 (exposed via StreamingDispatcher::panic_count()) and logged at error level. SSOT: every binding inherits this behavior; no per-binding panic handling added.
  • FPSS C ABI state machine. TdxFpssHandle gets a permanent state: AtomicU8 field. tdx_fpss_set_callback / _set_inline_callback / _reconnect / _shutdown enforce the documented one-shot registration and terminal-shutdown rules. Post-shutdown ops return -1 with a clear tdx_last_error() string instead of silently re-using a torn-down handle.
  • Unified C ABI replacement contract. tdx_unified_set_callback after tdx_unified_stop_streaming is now documented (rustdoc + thetadx.h) as REPLACEMENT, not error. The high-level unified path supports stop+restart as a normal user flow (tdx_unified_reconnect is built on top of it). The contract divergence from FPSS one-shot is intentional and explicit in both header docs.
  • ctx lifetime + thread affinity documented in every tdx_*_set_callback / _set_inline_callback declaration in thetadx.h, mirrored in thetadx.hpp doxygen.
  • Python dropped_event_count() doc + test corrected to the actual reset-on-reconnect / zero-after-stop semantics. Counter lives on the live dispatcher; reconnect() rebuilds it. Matches the TypeScript binding's contract.
  • Dispatcher dropped counter is strictly queue-full. TrySendError::Disconnected (rare; shutdown race) feeds a new disconnected_count so the user-facing drop metric is not inflated by lifecycle noise.
  • TypeScript index.d.ts regenerated from the corrected napi-rs rustdoc so the JS-visible doc matches the Rust source.

Version 8.0.30 -> 8.0.31 via scripts/bump_version.py. Changelog mirrored to docs-site/docs/changelog.md.

Closes #498

Test plan

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace
  • cargo deny check
  • cargo run -p thetadatadx --bin generate_sdk_surfaces --features config-file -- --check
  • cargo check --manifest-path tools/mcp/Cargo.toml --locked
  • cargo clippy --manifest-path tools/mcp/Cargo.toml --all-targets -- -D warnings
  • cargo test --manifest-path tools/mcp/Cargo.toml --no-run
  • cargo check --manifest-path tools/server/Cargo.toml --locked
  • cargo check --manifest-path sdks/python/Cargo.toml --locked
  • cargo check --manifest-path sdks/typescript/Cargo.toml --locked
  • python3 scripts/check_version_sync.py
  • cmake -S sdks/cpp -B build/cpp && cmake --build build/cpp --target thetadatadx_cpp
  • cmake --build build/cpp --target thetadatadx_fpss_smoke
  • New unit test dispatcher_survives_panicking_callback in crates/thetadatadx/src/fpss/dispatcher.rs exercises three guaranteed-panic events followed by three successful ones, asserts panic_count == 3 and dropped_count == 0.
  • New unit test fpss_state_gate_rejects_after_shutdown in ffi/src/streaming.rs exercises every state-gate transition without needing a live FPSS connection.

…498)

Closes seven hygiene gaps surfaced by the v8.0.30 review:

- Dispatcher drain loop now wraps user-callback invocation in
  catch_unwind. A panic from user code (Rust closure / PyO3 callable
  / napi ThreadsafeFunction / C extern fn) no longer kills the
  dispatcher thread; panics are counted on a new panic_count
  AtomicU64 (exposed via StreamingDispatcher::panic_count) and logged
  at error level, then the loop continues. SSOT: every binding
  inherits this behavior, no per-binding panic handling.
- FPSS C ABI handle gains a permanent state field (Fresh / Active /
  Shutdown). tdx_fpss_set_callback / _set_inline_callback /
  _reconnect / _shutdown now enforce one-shot registration and
  terminal shutdown; post-shutdown calls return -1 with a clear
  tdx_last_error() string.
- Unified C ABI: tdx_unified_set_callback after stop is documented
  as REPLACEMENT (high-level path supports stop+restart). Contract
  divergence from FPSS one-shot is intentional and now explicit in
  rustdoc + thetadx.h.
- thetadx.h documents ctx lifetime + queued-vs-inline thread
  affinity on every set_callback / set_inline_callback declaration,
  mirrored in the thetadx.hpp doxygen blocks.
- Python dropped_event_count rustdoc, README, and test corrected
  to the actual reset-on-reconnect / zero-after-stop semantics.
  Counter lives on the live StreamingDispatcher; reconnect rebuilds
  it and resets to 0. Snapshot before reconnect for cross-session
  accumulation. Matches the TypeScript binding.
- Dispatcher dropped counter is now strictly queue-full
  (TrySendError::Full). TrySendError::Disconnected (rare; happens
  during shutdown races) feeds a separate disconnected_count so the
  user-facing drop metric is not inflated by lifecycle noise.
- TypeScript index.d.ts regenerated from the corrected napi-rs
  rustdoc so the JS-visible doc matches the Rust source.

Version 8.0.30 -> 8.0.31 via scripts/bump_version.py.

Closes #498

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@userFRM userFRM force-pushed the fix/v8.0.30-audit-followup branch from 3980546 to c72d6f6 Compare May 6, 2026 15:53
@userFRM userFRM changed the title fix(streaming): v8.0.30 audit follow-ups (closes #498) fix(streaming): v8.0.30 audit follow-ups + 8.0.32 bump (closes #498) May 6, 2026
@userFRM userFRM merged commit 5ee5d35 into main May 6, 2026
32 checks passed
@userFRM userFRM deleted the fix/v8.0.30-audit-followup branch May 6, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Post-release audit follow-ups for v8.0.30 streaming

1 participant