diagprint 0.8.1

A Rust diagnostics lifecycle framework for structured diagnostics, rendering, remediation, CI, editors, and telemetry.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
//! # diagprint
//!
//! `diagprint` is a Rust diagnostics lifecycle framework for carrying
//! structured diagnostics through creation, enrichment, rendering, editor and
//! CI integration, guarded remediation, verification, export, and telemetry.
//!
//! The crate deliberately separates diagnostic data from presentation and
//! mutation:
//!
//! - [`struct@Diagnostic`] describes what happened.
//! - [`CapturedDiagnostic`] pairs a diagnostic with its immutable source snapshot.
//! - [`Suggestion`] describes a possible resolution.
//! - [`Fixer`] validates and applies guarded structured edits.
//! - [`FixPlan`] coordinates transactional multi-file remediation.
//! - [`InteropDiagnostic`] is the dependency-free interoperability boundary.
//! - [`SourceCache`] supplies virtual and cached source text to renderers.
//! - [`DocumentationResolver`] resolves documentation without guessing package
//!   versions.
//! - [`DiagnosticMetadata`] lets typed errors supply semantic metadata.
//! - [`CompilerImporter`] consumes structured rustc diagnostics.
//! - [`CargoWorkspace`] models Cargo package/dependency metadata.
//! - [`CargoStreamImporter`] consumes Cargo build-message streams.
//!
//! Calling a renderer never modifies source files.
//!
//! ## Canonical identity
//!
//! `diagprint.canonical/v1` defines stable, schema-versioned identity for
//! diagnostics and reports without depending on JSON field ordering or volatile
//! runtime metadata. [`DiagnosticFingerprint`] identifies a logical diagnostic,
//! [`DiagnosticDigest`] identifies meaningful diagnostic content, and
//! [`ReportDigest`] identifies report content independently of insertion order.
//! [`DiagnosticDelta`] uses those identities to classify diagnostics across
//! reports as new, resolved, persisting, or changed while preserving duplicate
//! diagnostic instances.
//! [`DeltaPolicy`] evaluates those semantic differences for baseline-aware CI
//! without making existing diagnostic debt appear newly introduced.
//!
//! Canonical v1 is immutable: incompatible identity changes require a new
//! canonicalization version rather than silently changing existing digests.
//!
//! ## Diagnostic forensics
//!
//! [`DiagnosticCaseFile`] turns a verified [`DiagnosticHistory`] into a
//! privacy-light forensic explanation for one logical diagnostic fingerprint.
//!
//! Case-file v1 reports first/last observation, current lifecycle state,
//! contiguous active episodes, reappearances, canonical-content changes,
//! severity increases, supporting run/report/digest evidence, and the current
//! history-chain head.
//!
//! The forensic layer is deliberately evidence-based. It does not guess root
//! cause, source-control blame, or authorship.
//!
//! `DiagnosticHistory::case_file` requires an exact canonical fingerprint.
//! The `diagprint why` CLI additionally accepts a unique fingerprint prefix.
//!
//! ### Git provenance
//!
//! [`GitProvenanceRecord`] can bind one immutable diagnostic-history run to an
//! exact Git commit and tree without changing history-v2 semantics.
//!
//! [`GitProvenanceBinding::CapturedClean`] means diagprint observed a clean
//! worktree around the scan. [`GitProvenanceBinding::UserAsserted`] is an
//! explicit after-the-fact association and therefore carries weaker evidence.
//!
//! Git provenance establishes repository context and temporal association. It
//! does not establish that a commit caused a diagnostic transition.
//!
//! ## Diagnostic intelligence
//!
//! Structured suggestions can carry explanations, documentation links,
//! structured edits, advisory follow-up commands, and an [`Applicability`]
//! classification.
//!
//! Automatic editing requires [`Applicability::MachineApplicable`], valid
//! non-overlapping UTF-8 edit ranges, and verification of expected source
//! contents.
//!
//! Suggested shell commands are informational only and are never executed by
//! [`Fixer`] or [`FixPlan`].
//!
//! ## Transactional remediation
//!
//! [`FixPlan`] supports deterministic preconditions, multi-file preparation,
//! rollback-on-error writes, post-apply verification, verification rollback,
//! and optional backups.
//!
//! Verification is declarative and does not execute shell commands.
//!
//! ## Virtual and cached source text
//!
//! [`SourceCache`] stores named source text independently from diagnostics.
//! [`SourceProvider`] lets parsers, bridges, and other integrations populate
//! that cache without coupling the renderer to a specific ecosystem.
//! [`SourceSnapshot`] captures an immutable point-in-time source view so old
//! diagnostics can render against the exact text they were created from.
//! [`SourceRevision`] identifies successive versions of one named source and
//! allows snapshots to detect whether a diagnostic-time buffer is still current.
//! Terminal rendering can prefer cached source and fall back to filesystem
//! reads when no cached source exists.
//!
//! This supports editor buffers, generated files, parser inputs, compiler
//! virtual files, and other source text which may never exist on disk.
//!
//! Source contents are not serialized into [`struct@Diagnostic`] JSON output.
//!
//! ## Generic interoperability
//!
//! [`InteropDiagnostic`] is a dependency-free, owned diagnostic protocol for
//! compilers, linters, parsers, language tools, and third-party adapters.
//!
//! It preserves:
//!
//! - severity;
//! - diagnostic code;
//! - message and help;
//! - notes;
//! - primary and secondary source labels;
//! - cause chains;
//! - documentation links;
//! - related diagnostics.
//!
//! Custom producers can implement [`InteropDiagnosticSource`] and gain direct
//! conversion through [`InteropDiagnosticSourceExt`].
//!
//! Automatic edits and executable commands are deliberately excluded from the
//! generic protocol. Remediation requires stronger ecosystem-specific safety
//! guarantees.
//!
//! ## Cargo intelligence
//!
//! [`CargoWorkspace`] consumes `cargo metadata --format-version=1` output and
//! preserves package identity, versions, workspace membership, targets,
//! features, and resolved dependency context.
//!
//! [`CargoStreamImporter`] consumes Cargo `--message-format=json` output and
//! recognizes compiler diagnostics, compiler artifacts, build-script results,
//! and build completion.
//!
//! Unknown future Cargo message kinds are retained as [`CargoMessage::Unknown`]
//! rather than rejected.
//!
//! ## Documentation intelligence
//!
//! [`DocumentationResolver`] can build package/version catalogs from
//! `Cargo.lock` or [`CargoWorkspace`].
//!
//! Ambiguous package versions remain ambiguous rather than being guessed.
//!
//! ## Ecosystem interoperability
//!
//! The `miette` feature consumes miette's structured diagnostic protocol,
//! including source labels, causes, and related diagnostics.
//!
//! The `codespan-reporting` feature resolves codespan's file IDs and byte
//! ranges into [`InteropDiagnostic`] before conversion to diagprint.
//!
//! The `ariadne` feature provides a structured bridge which can emit both an
//! Ariadne report and a diagprint [`InteropDiagnostic`] from the same source
//! metadata without parsing rendered terminal output.
//!
//! The `annotate-snippets` feature provides the same dual-output model for
//! annotate-snippets reports while validating its byte-oriented source spans.
//!
//! The `anyhow` feature preserves Anyhow context/source chains.
//!
//! The `tracing` feature turns significant tracing events into structured
//! diagnostics.
//!
//! External adapters never need to parse another library's pretty terminal
//! rendering.
//!
//! ## Compiler diagnostics
//!
//! [`CompilerImporter`] consumes structured rustc JSON diagnostics directly.
//! It preserves compiler severity, Rust error codes, source spans, notes,
//! help, structured replacements, and applicability.
//!
//! Filesystem hydration is disabled by default.
//!
//! ## Typed errors
//!
//! Application error enums and structs can implement [`DiagnosticMetadata`]
//! to provide stable diagnostic codes, severity, help, notes, and structured
//! suggestions.
//!
//! ## Terminal documentation
//!
//! The optional `terminal-docs` feature can fetch documentation and display it
//! directly in a terminal with sanitized remote content and syntax-highlighted
//! examples.
//!
//! ## Themes
//!
//! [`Theme`], [`Style`], and [`SeverityTheme`] control terminal presentation.
//!
//! The optional `cybercore` feature maps the Cybercore semantic palette into
//! `diagprint` rather than copying Cybercore color values.
//!
//! ## Feature flags
//!
//! - `artifact-store` — append-only artifact generations with filesystem locking.
//! - `derive` — derive `DiagnosticMetadata` from typed errors.
//! - `anyhow` — Anyhow context-chain integration.
//! - `ariadne` — structured Ariadne/diagprint bridge.
//! - `annotate-snippets` — structured annotate-snippets/diagprint bridge.
//! - `miette` — miette diagnostic-protocol integration.
//! - `codespan-reporting` — codespan-reporting diagnostic integration.
//! - `tracing` — structured tracing-event integration.
//! - `compression` — gzip and Zstandard report compression.
//! - `html` — HTML diagnostic and report rendering.
//! - `cybercore` — Cybercore theme-schema integration.
//! - `terminal-docs` — terminal documentation retrieval and syntax
//!   highlighting.
//!
//! Generic interoperability, typed errors, compiler/Cargo ingestion,
//! documentation resolution, and `FixPlan` are core features.
//!
//! All optional features are disabled by default.

mod artifact;
mod artifact_writer;
mod attribute;
mod canonical;
mod capsule;
mod captured;
mod cargo;
mod compiler;
mod delta;
mod delta_artifact;
mod delta_policy;
mod diagnostic;
mod documentation;
mod export;
mod fingerprint;
mod fixer;
mod fixplan;
mod forensics;
mod git_provenance;
mod intelligence;
pub mod interop;
mod redaction;
mod relationship;
mod remediation;
mod remediation_evidence;
mod remediation_receipt;
mod remediation_replay;
mod report;
mod reporter;
mod result_ext;
mod rotation;
mod severity;
mod sink;
mod source;
mod suggestion;
mod typed;

#[cfg(any(
    feature = "anyhow",
    feature = "ariadne",
    feature = "annotate-snippets",
    feature = "codespan-reporting",
    feature = "miette",
    feature = "tracing"
))]
pub mod integrations;

#[cfg(feature = "terminal-docs")]
pub mod docs;

pub mod project_scan;

pub mod render;

pub use artifact::{
    ArtifactDigest, ArtifactEncoding, ArtifactVerificationError, DELTA_V1_MEDIA_TYPE,
    ExportPolicyDescriptor, ExportReceipt, ExportedArtifact, RECEIPT_V1_SCHEMA, ReceiptEvaluation,
};

pub use artifact_writer::{ArtifactWriteError, ArtifactWriter, PersistedArtifact};

pub use attribute::{DiagnosticAttribute, DiagnosticValue};

pub use canonical::{CANONICAL_V1_NAMESPACE, CanonicalizationError, CanonicalizationVersion};

pub use capsule::{
    CAPSULE_PROVENANCE_V1_SCHEMA, CAPSULE_SOURCE_INDEX_V1_SCHEMA, CapsuleEntryKind,
    CapsuleManifestEntry, CapsulePolicyDescriptor, CapsuleProvenance, CapsuleSourceEntry,
    CapsuleSourceIndex, DIAGNOSTIC_CAPSULE_V1_SCHEMA, DiagnosticCapsule, DiagnosticCapsuleError,
    DiagnosticCapsuleManifest, DiagnosticCapsulePolicy, DiagnosticCapsuleVerification,
    PersistedDiagnosticCapsule,
};

pub use captured::CapturedDiagnostic;

#[cfg(feature = "derive")]
pub use diagprint_derive::Diagnostic;

pub use cargo::{
    CargoArtifact, CargoBuildFinished, CargoBuildScript, CargoBuildSummary,
    CargoCompilerDiagnostic, CargoDependency, CargoDependencyKind, CargoImportError, CargoMessage,
    CargoPackage, CargoPackageIdentity, CargoProfile, CargoStreamImporter, CargoTarget,
    CargoUnknownMessage, CargoWorkspace,
};

pub use compiler::{CompilerImportError, CompilerImporter};

pub use diagnostic::{Cause, Diagnostic, Label, LabelKind, SourceLocation};

pub use delta::{DeltaCounts, DeltaKind, DiagnosticChange, DiagnosticDelta};

pub use delta_artifact::{
    DELTA_V1_SCHEMA, DeltaArtifact, DeltaArtifactCounts, DeltaArtifactEntry,
    DeltaArtifactEvaluation, DeltaArtifactFingerprintPolicy, DeltaArtifactPolicy,
    DeltaArtifactViolation,
};

pub use delta_policy::{DeltaEvaluation, DeltaPolicy, DeltaRule, DeltaViolation};

pub use documentation::{DocumentationError, DocumentationResolver};

pub use fingerprint::{
    DiagnosticDigest, DiagnosticFingerprint, DigestAlgorithm, FingerprintPolicy, FingerprintSource,
    IDENTITY_ATTRIBUTE, ReportDigest,
};

pub use forensics::{
    DIAGNOSTIC_CASE_FILE_V1_SCHEMA, DIAGNOSTIC_TIMELINE_V1_SCHEMA, DiagnosticCaseFile,
    DiagnosticCaseRun, DiagnosticCaseStatus, DiagnosticCleanWindow, DiagnosticCleanWindowKind,
    DiagnosticEpisode, DiagnosticTimeline, DiagnosticTimelineEvent, DiagnosticTimelinePhase,
    DiagnosticTimelineRun,
};

pub use git_provenance::{
    GIT_PROVENANCE_V1_SCHEMA, GitProvenanceBinding, GitProvenanceError, GitProvenanceRecord,
};

pub use fixer::{FixCheck, FixError, FixPreview, FixReport, Fixer, RollbackFailure};

pub use fixplan::{
    FIX_PLAN_DESCRIPTOR_V1_SCHEMA, FileCheck, FileCheckFailure, FixPlan, FixPlanCheck,
    FixPlanDescriptor, FixPlanError, FixPlanPreview, FixPlanReport,
};

pub use interop::{
    DiagnosticTree, InteropDiagnostic, InteropDiagnosticSource, InteropDiagnosticSourceExt,
    InteropLabel,
};

pub use render::{GithubActionsDeltaRenderer, ReportRenderer, SeverityTheme, Style, Theme};

pub use redaction::{
    REDACTED, RedactionPolicy, Sensitive, is_sensitive_key, sanitize_path, sanitize_url,
};

pub use relationship::{
    DIAGNOSTIC_RELATIONSHIP_GRAPH_V1_SCHEMA, DIAGNOSTIC_RELATIONSHIP_SNAPSHOT_V1_SCHEMA,
    DiagnosticRelationship, DiagnosticRelationshipDirection, DiagnosticRelationshipError,
    DiagnosticRelationshipEvidence, DiagnosticRelationshipEvidenceFilter,
    DiagnosticRelationshipGraph, DiagnosticRelationshipGraphBuilder, DiagnosticRelationshipKind,
    DiagnosticRelationshipNode, DiagnosticRelationshipSnapshot,
};

pub use export::{
    ExportAttributes, ExportDiagnostic, ExportDocumentationLink, ExportLabel, ExportPath,
    ExportPolicy, ExportRemediation, ExportSourceLocation, ExportSuggestion, ExportText, ExportUrl,
};

pub use remediation_evidence::{
    REMEDIATION_EVIDENCE_V1_SCHEMA, RemediationEvidenceEffect, RemediationEvidenceError,
    RemediationEvidenceRecord,
};

pub use remediation_receipt::{
    REMEDIATION_RECEIPT_V1_SCHEMA, RemediationEffect, RemediationOutcome, RemediationPlanReceipt,
    RemediationReceipt, RemediationReceiptError, RemediationStatus,
};

pub use remediation_replay::{
    DIAGNOSTIC_REMEDIATION_REPLAY_V1_SCHEMA, DiagnosticRemediationAssessment,
    DiagnosticRemediationReplay, DiagnosticRemediationReplayStep, DiagnosticRemediationState,
    RemediationReplayError,
};

pub use report::{DiagnosticReport, ReportStatus, SeverityCounts};

pub use result_ext::{CapturedDiagnosticResult, DiagnosticResult, ResultDiagnosticExt};

pub use reporter::{Compression, Reporter, ReporterBuilder};

pub use rotation::{RotationCadence, RotationPolicy, RotationState};

pub use severity::Severity;

pub use sink::{DiagnosticSink, JsonLinesSink, SinkError, SinkErrorKind, SinkResult, WriterSink};

pub use source::{SourceCache, SourceEntry, SourceProvider, SourceRevision, SourceSnapshot};

pub use suggestion::{
    Applicability, DocumentationLink, Edit, SuggestedCommand, Suggestion, TextRange,
};

pub use typed::{DiagnosticErrorExt, DiagnosticMetadata};

#[cfg(feature = "ariadne")]
pub use integrations::{
    AriadneBridge, AriadneBridgeError, AriadneBridgeLabel, AriadneOwnedSpan, AriadneSpan,
};

#[cfg(feature = "annotate-snippets")]
pub use integrations::{
    AnnotateSnippetsBridge, AnnotateSnippetsBridgeError, AnnotateSnippetsLabel,
};

#[cfg(feature = "anyhow")]
pub use integrations::AnyhowDiagnosticExt;

#[cfg(feature = "codespan-reporting")]
pub use integrations::CodespanDiagnosticExt;

#[cfg(feature = "miette")]
pub use integrations::{MietteDiagnosticExt, MietteDiagnosticTree, MietteReportExt};

#[cfg(feature = "tracing")]
pub use integrations::TracingLayer;

#[cfg(feature = "terminal-docs")]
pub use docs::{TerminalDocError, TerminalDocViewer};

pub type Result<T> = std::io::Result<T>;

mod history;

pub use history::{
    DIAGNOSTIC_HISTORY_RUN_V1_SCHEMA, DIAGNOSTIC_LINEAGE_V1_SCHEMA, DiagnosticHistory,
    DiagnosticHistoryError, DiagnosticHistoryRun, DiagnosticHistoryTransition, DiagnosticLineage,
    DiagnosticLineageStep, HistoryDeltaCounts, HistoryObservation, HistorySeverityCounts,
};

pub use history::{DIAGNOSTIC_HISTORY_HEAD_V1_SCHEMA, DIAGNOSTIC_HISTORY_RUN_V2_SCHEMA};