fix: validate bounded JSONRPC frames and envelopes (Fixes #532) - #560
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep LLVM_PROFILE_FILE in isolated PET subprocess environments so normal EOF shutdown writes profiles into the coverage collector instead of untracked default files. Preserve fixture overrides and minimal environment isolation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Read complete bounded multi-header frames without losing byte boundaries, and reject invalid request envelopes before dispatch while preserving supported IDs and legacy method errors. Exercise exact limits, fragmentation, recovery and native wire compatibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Test Coverage Report (Linux)Result: ✅ Within regression budget
|
Performance Report (Linux)Result: ✅ Within regression budgets
|
Performance Report (Windows)Result: ✅ Within regression budgets
|
Test Coverage Report (Windows)Result: ✅ Within regression budget
|
Performance Report (macOS)Result: ✅ Within regression budgets
|
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Cross-platform process ownership, concurrent output, and transport shutdown semantics warrant final human review.
Review effort: Balanced
Findings: None
What changed in this PR
Adds bounded JSONRPC framing and envelope validation while incorporating #559’s transport shutdown lifecycle.
Changes:
- Parses bounded multi-header frames and validates JSONRPC envelopes.
- Adds FIFO, size-limited output and supervised subprocess cancellation.
- Expands protocol, native-wire, fragmentation, and shutdown coverage.
| File | Description |
|---|---|
docs/JSONRPC.md |
Documents framing, validation, and shutdown contracts. |
crates/pet/tests/process_utils.rs |
Adds bounded fixture shutdown helpers. |
crates/pet/tests/jsonrpc_server_test.rs |
Adds native protocol and lifecycle regressions. |
crates/pet/tests/jsonrpc_client.rs |
Supports isolated startup and graceful shutdown. |
crates/pet/tests/fixtures/shutdown_probe.py |
Provides descendant-cleanup fixture. |
crates/pet/tests/e2e_performance.rs |
Gracefully closes performance fixtures. |
crates/pet/src/main.rs |
Returns failure for server errors. |
crates/pet/src/jsonrpc.rs |
Coordinates transport and probe cleanup. |
crates/pet-python-utils/src/process/supervisor.rs |
Supervises probe admission and cancellation. |
crates/pet-python-utils/src/process.rs |
Integrates cancellable subprocess execution. |
crates/pet-python-utils/src/env.rs |
Handles interpreter cancellation quietly. |
crates/pet-poetry/src/environment_locations_spawn.rs |
Handles Poetry cancellation. |
crates/pet-jsonrpc/src/server.rs |
Validates envelopes and dispatches framed input. |
crates/pet-jsonrpc/src/output.rs |
Adds bounded FIFO protocol output. |
crates/pet-jsonrpc/src/lib.rs |
Routes replies through the output subsystem. |
crates/pet-jsonrpc/src/framing.rs |
Implements bounded frame parsing. |
crates/pet-conda/src/conda_info.rs |
Handles Conda cancellation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Establish a bounded info exchange before closing the same stdout pipe, so startup is not charged to the unchanged one-second shutdown deadline. Explicitly terminate and bounded-join the readiness helper on setup failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Concurrent Unix fork/exec can retain another fixture pipe reader until exec, allowing the sole response write to succeed before the final reader disappears. Run the same real-pipe scenario in an isolated test subprocess; keep the one-second measured deadline and bounded cleanup unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Allow the outer test-process guard to cover readiness, both forced-shutdown waits, reader completion, and fallback cleanup without changing the one-second shutdown assertion. Record the verified subprocess testing pitfalls in the existing Rust skill. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merge the reviewed parent follow-ups, retaining the bounded readiness handshake, isolated real-pipe scenario, complete outer cleanup budget, and all native protocol cases without rewriting published history. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Merged the complete reviewed parent fixes from #559 through |
Poll the actual descendant lease using only the remainder of the existing four-second shutdown budget instead of requiring an instantaneous lock transition at server exit. Test held-lock timeout and success after release; preserve cancellation and elapsed-time assertions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Release the independent holder only after the same polling invocation observes WouldBlock, and assert exactly two real lock attempts. This removes scheduling assumptions and rejects an immediate-timeout mutation without changing shutdown semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merge the reviewed parent CI correction and deterministic contention-retry regression test without rewriting published history. Preserve all protocol cases and original shutdown deadlines. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Final review/CI update for The exact combined-protocol macOS control completed: https://github.com/microsoft/python-environment-tools/actions/runs/36194233841. Eight counterbalanced passes, verified exact base/head binaries and identical full inventories (10 environments, 1 manager). Medians of per-pass percentiles (not pooled percentiles):
Independent inspection found no avoidable decoder/wakeup delay. The roughly 10 ms first-notification increase and +23/+51 ms warm/cold RTT tails are explicitly recorded, not dismissed as noise; the matched macOS result is acceptable with its single-host/Rosetta/sample-size limits. Still holding draft/auto-merge:
|
Merge main after #559 landed. The resolved tree is identical to the reviewed protocol head; the final PR diff now contains only protocol framing, envelope validation, tests, and documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
#559 is merged and #529 is closed. |
Exercise valid requests and notifications after rejection checks, proving handler wiring and exact ID/parameter preservation without adding errors. Covers previously unexecuted negative-test callbacks without changing production behavior or coverage budgets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
The new exact-main coverage baseline exposed a small function-coverage regression (Linux -0.103pp; Windows -0.032pp), despite increased line coverage. LCOV traced it to the new rejection tests registering callbacks that were deliberately never invoked. |
|
The Windows matched control completed successfully: https://github.com/microsoft/python-environment-tools/actions/runs/36458287684. Independent quality review accepts the Windows performance prerequisite: no material regression reproduced in the matched control. Verified exact merged main Medians of four per-pass percentiles per revision, not pooled percentiles:
Limitations: one host, four passes per revision, ten samples per pass. The first-base cold RTT P95 outlier (2203 ms) is retained, not discarded; other base passes are 100-104 ms versus head 98-109 ms. This is not a claim of universal improvement. The ordinary exact-base macOS snapshot retains +14 ms warm RTT P95 and +22 ms startup-first-environment P95; Linux first-environment tails increase by 1-2 ms. Those small tails and the previously accepted macOS tradeoff remain explicitly recorded. Current-head Copilot has no code findings and all three CodeQL analyses report zero results/errors/warnings. Still draft until the refreshed hosted coverage and remaining CI checks complete. No budgets or exclusions were changed. |
|
Final-head (
Independent review finds no remaining code or quality blockers. Current-head Copilot reports no code findings; all three current-head CodeQL analyses have zero results/errors/warnings. Awaiting the final two native macOS jobs before marking ready and enabling protected auto-merge. |
|
All 35 automated checks now pass at |
Parse bounded multi-header JSONRPC frames and validate request envelopes before dispatch, while preserving request IDs, notifications, and legacy method-level error behavior.
Validation: 51 library and 19 native cases; workspace formatting/Clippy and independent code review pass. #559 is merged and main integrated; only the five protocol files remain in this PR. Exact-main Linux/Windows line and function coverage now improve, with no budget or exclusion changes. Current-head Copilot has no code findings and all CodeQL analyses are clean. The independently reviewed Windows matched-host control found no material regression; detailed platform snapshots, accepted tail outliers, and sampling limitations are recorded in the PR comments. All 35 automated checks now pass, including both native macOS jobs. Ready for required human approval and protected auto-merge.
Fixes #532