Skip to content

feat(diagnostics): cargo/toolchain pre-flight family (DIAG-002)#34

Open
joshuaboys wants to merge 1 commit into
mainfrom
feat/diag-toolchain-preflight
Open

feat(diagnostics): cargo/toolchain pre-flight family (DIAG-002)#34
joshuaboys wants to merge 1 commit into
mainfrom
feat/diag-toolchain-preflight

Conversation

@joshuaboys

Copy link
Copy Markdown
Contributor

DIAG-002 — Cargo/toolchain pre-flight diagnostic family

The next DIAG slice after DIAG-001 (formatDiagnostic + doctor, already
merged). Built on top of the existing envelope — it does not rebuild it.
Routes cargo/rustup failures through the structured diagnostic so a missing
toolchain/target/cargo surfaces as an actionable nxrust error instead of a raw
shell failure.

What changed

  • src/utils/diagnostics.ts — slug-based diagnostic codes (DIAGNOSTIC_CODES,
    DiagnosticCode, D-D5), a code field on Diagnostic + a
    CataloguedDiagnostic type, and NxrustDiagnosticError carrying the code.
    Builder functions for the family (cargo-not-found, toolchain-not-installed,
    target-not-installed, nightly-required, invalid-toolchain-literal, plus
    generic spawn-failed). A runWithDiagnostic classifier maps spawn ENOENT
    on cargo/rustup → cargo-not-found and classifies rustup/cargo stderr; unknown
    cargo output passes through unchanged (no translation of arbitrary cargo
    output — module 14 Out-of-Scope). Secret redaction extended to --token-style
    flags (--token x and --token=x).
  • src/utils/run-process.ts — stderr is teed (live passthrough + 64 KB tail
    capture) so the single cargo-invocation chokepoint can classify failures;
    replaces the bare console.error (constraint: no console.* outside the
    envelope). Settles once across error/close; signal-kills (code === null)
    are not classified.
  • src/utils/rust-toolchain.tsvalidateChannelLiteral now throws a
    catalogued invalid-toolchain-literal diagnostic instead of a bare Error
    (legacy from <origin> wording preserved, so existing assertions still match).
  • docs/diagnostics.md — catalogue stub for the six codes (trigger + fix).
  • Plan — DIAG-002 work item added to module 14; codes open question resolved
    via D-D5; CHANGELOG Unreleased entry.

Tests / verification

  • diagnostics.spec.ts — builders, codes, NxrustDiagnosticError, classifier,
    redaction (incl. --token= form and the stable requires -Z non-misfire).
  • run-process.spec.ts — integration: ENOENT envelope, classified stderr,
    unknown pass-through, success path.
  • Full suite 225 passing (19 files), typecheck clean, oxfmt clean.
  • e2e smoke passes — cargo's live colourised output (Checking smoke …,
    Finished) still surfaces through the new teed-stderr path (no regression
    from the stdio change).

Review

An independent code review pass was run; its two MAJOR findings were fixed in
this branch (double-settle on ENOENT drifting setMaxListeners; an over-broad
requires -Z nightly matcher that could misfire on stable cargo output) plus
the MINOR items (defensive toolchain-quote matching, compile-time code
enforcement via CataloguedDiagnostic, explicit --token= redaction, redacted
spawn-failed detail). Regression tests added for the two behavioural fixes.

Notes

  • Branched from origin/main (the canonical trunk). Local main had diverged
    onto an unpushed planning fork; this PR is built on the published state where
    DIAG-001 and the cache-report/doctor work already live.

Route cargo/rustup failures through the DIAG-001 formatDiagnostic
envelope so a missing toolchain, target, or cargo surfaces as a
structured, actionable nxrust error instead of a raw shell failure.

- diagnostics.ts: slug-based codes (DIAGNOSTIC_CODES, D-D5),
  CataloguedDiagnostic + NxrustDiagnosticError, builders for the
  family, and runWithDiagnostic to classify ENOENT and rustup/cargo
  stderr. Unknown cargo output passes through unchanged. Secret
  redaction extended to --token flags.
- run-process.ts: tee stderr (live + 64KB tail) so the single cargo
  chokepoint can classify failures; replaces the bare console.error;
  settles once across error/close.
- rust-toolchain.ts: validateChannelLiteral throws a catalogued
  invalid-toolchain-literal diagnostic instead of a bare Error.
- docs/diagnostics.md: catalogue stub for the six codes.

Full suite 225 green; e2e confirms cargo's live colourised output
still surfaces through the teed-stderr path. Resolves the codes
open question via D-D5.
@joshuaboys
joshuaboys marked this pull request as ready for review July 18, 2026 13:04
@joshuaboys
joshuaboys requested a review from Copilot July 18, 2026 13:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the DIAG-002 “cargo/toolchain pre-flight” diagnostic family on top of the existing [nxrust] diagnostic envelope, so common cargo/rustup/toolchain failures become actionable, structured errors instead of raw spawn/stdio failures.

Changes:

  • Introduces stable slug-based diagnostic codes (nxrust:*) and a NxrustDiagnosticError wrapper to carry catalogued diagnostics programmatically.
  • Updates process execution to tee/capture stderr (bounded tail) and classify known cargo/rustup failure shapes into structured diagnostics while leaving unknown cargo output untouched.
  • Routes toolchain literal validation errors through the diagnostic catalogue and adds unit/integration test coverage plus docs/changelog/plan updates.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/utils/diagnostics.ts Adds diagnostic codes + builders and failure classifier (runWithDiagnostic), plus extended secret redaction.
src/utils/run-process.ts Tees stderr with a bounded tail and emits structured diagnostics on classified failures.
src/utils/rust-toolchain.ts Throws a catalogued diagnostic error for invalid toolchain literals.
src/utils/diagnostics.spec.ts Tests diagnostic builders, codes, error wrapper, classifier, and redaction behavior.
src/utils/run-process.spec.ts Integration tests for spawn failure classification and passthrough behavior.
docs/diagnostics.md Adds a diagnostics catalogue stub documenting the new codes, triggers, and fixes.
plans/modules/14-diagnostics.aps.md Records DIAG-002 work item status and design decisions in the plan.
CHANGELOG.md Adds an Unreleased entry describing the new DIAG-002 behavior and public contract notes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 148 to 150
- `src/utils/diagnostics.ts` — the shared `formatDiagnostic({ what, why,
command?, fix, severity? })` helper (spec §6.14 envelope) with secret
command?, fix, severity? })` helper (spec §6.14 envelope) with secret
redaction (`redactSecrets` strips `TOKEN`/`SECRET`/`KEY`/`PASSWORD` values
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.

2 participants