Repository navigation
feat(diagnostics): add the diagnostics crate foundation - #803
Conversation
App-agnostic machinery for diagnostic support bundles, Unit 1 of the diagnostics spec (docs/specs/10-spec-diagnostics). BundleWriter is generic over a sealed BundleSink (default tokio::fs::File): create() writes an owner-only file with entries under a root directory and fsyncs on finish; stream() writes rootless through any blessed sink (DuplexStream for daemons) and half-closes on finish. Both modes append the same manifest.json last. Collected files open with O_NOFOLLOW plus a descriptor fstat check instead of a racy stat-then-open. The listing API returns a structured result so an unreadable root is an error rather than an empty listing, and the new capture module provides one timeout-bounded subprocess helper that kills timed-out children and returns their partial output inside a typed error. Refs: #801 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 15 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (8)
Comment |
Replaces the hand-rolled stack-recursive walk with walkdir (already a workspace dependency): a pathologically deep state dir can no longer blow the collector's stack, symlinks stay unfollowed, and sibling ordering stays sorted. Truncation is now exact — a listing that ends precisely at the cap is complete, not truncated. Refs: #801 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
Unit 1 of the diagnostics spec (#802, tracking #801): the app-agnostic machinery every later unit consumes.
bundle—BundleWriter<W: BundleSink = tokio::fs::File>, one writer, two modes (R1.2/R1.3):create()writes an owner-only (0600) file with entries under{root}/and flush+fsyncs on finish;stream()writes rootless through any blessed sink (DuplexStream— the daemon shape) and flush+half-closes. Both append the samemanifest.jsonas the final entry at the mode-specific path.BundleSinkis sealed; itsSyncsupertrait is load-bearing (async_tar::Builderrequires it).add_file_tailopens withO_NOFOLLOWplus a descriptorfstatregular-file check — no stat-then-open TOCTOU window — and bounds the read withtake(cap)against live-log growth.redact— the fail-closed key-based engine, unchanged from the reference implementation (compound public-key regressions included) (R1.5).listing— now returns a structuredListing { text, truncated }; an unreadable root is anErrthe caller records in its manifest instead of an empty-looking listing; the cap appends an explicit truncation marker (R1.6).capture(new) —command_capture(cmd, args, timeout): stdin closed,kill_on_drop, and a timed-out child is killed with its partial stdout/stderr returned inside a typedCaptureError::Timeout— partial evidence from a hung tool is still evidence (R1.7). Replaces three private near-duplicates in the reference tree.pub use,#[non_exhaustive]on the manifest types. Manifest field isversion(producer-agnostic — the daemon emits manifests too). The reference tree's unusedwalkdirdependency is dropped.Test plan
cargo clippy -p diagnostics --all-targets --all-features -- -D warningscleancargo fmtcleanSpec:
docs/specs/10-spec-diagnostics/(Unit 1, R1.1–R1.8).🤖 Generated with Claude Code