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
// =============================================================================
// Copyright (c) 2025 - 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! # Qubit Redact
//!
//! Policy-driven, bounded redaction for fields, domain values, and diagnostic
//! formats. [`RedactedTextComposer`] builds one ordered text result, while
//! [`RedactionBatch`] builds independently resolvable results. Each object is
//! single-use and publishes only through its consuming `finish` method.
//!
//! ```
//! use qubit_redact::Redactor;
//!
//! let output = Redactor::strict()
//! .text_composer()
//! .literal("password=")
//! .field("password", "raw-secret")
//! .finish();
//! assert!(!output.text().as_str().contains("raw-secret"));
//! ```
//!
//! # Safety boundary
//!
//! `literal` accepts only `&'static str` program literals. Dynamic text must
//! be passed to a redaction operation. Derived fields that lack
//! `#[redact(...)]` are intentionally unredacted. Field sensitivity belongs to
//! the downstream domain: the framework cannot infer it reliably, and forcing
//! explicit "not sensitive" annotations onto the ordinary majority of fields
//! would add noise rather than knowledge. Downstream types must explicitly mark
//! sensitive fields and review that classification when their model changes.
//! Fields that explicitly use `skip` are neither accessed nor emitted.
//!
//! With redaction enabled, `Complete`, `Truncated`, and `Exhausted` output text
//! remains confidentiality-safe. Diagnostic formatters may publish that safe
//! text without interpreting an incompleteness reason; callers inspect
//! summaries only when completeness affects their own program contract.
//!
//! A disabled application-default policy is an intentional process-wide
//! debugging escape hatch. It restores raw values. The framework executes the
//! selected policy, while downstream code owns authorization, timing, and any
//! misuse. Generated `Debug`, `Display`, and `Serialize` implementations
//! intentionally obtain [`Redactor::application_default`] at the start of each
//! formatting or serialization call. Replacing the application default
//! therefore affects future generated calls, including installation of a
//! disabled policy. Existing explicit redactors, composers, and batches retain
//! the policy snapshots they already own.
//!
//! Transaction summaries are observations produced exclusively by a completed
//! transaction; callers cannot fabricate one outside the runtime.
//!
//! ```compile_fail
//! use qubit_redact::RedactionSummary;
//!
//! let _ = RedactionSummary::complete();
//! ```
//!
//! The removed pre-0.5 transaction API cannot be imported as a public
//! compatibility API.
//!
//! ```compile_fail
//! use qubit_redact::RedactionSession;
//! ```
//!
//! ```compile_fail
//! use qubit_redact::RedactionSessionOutput;
//! ```
//!
//! ```compile_fail
//! use qubit_redact::RedactionOutput;
//! ```
//!
//! ```compile_fail
//! use qubit_redact::RedactionHandle;
//! ```
//!
//! ```compile_fail
//! use qubit_redact::RedactionHandleError;
//! ```
//!
//! ```compile_fail
//! use qubit_redact::Redactor;
//!
//! let _ = Redactor::strict().session();
//! ```
//!
//! Composer and batch APIs deliberately do not overlap, and both publication
//! methods consume their owner.
//!
//! ```compile_fail
//! use qubit_redact::Redactor;
//!
//! let composer = Redactor::strict().text_composer();
//! let _ = composer.finish();
//! let _ = composer.literal("cannot reuse a finished composer");
//! ```
//!
//! ```compile_fail
//! use qubit_redact::Redactor;
//!
//! let mut batch = Redactor::strict().batch();
//! batch.literal("batch has no aggregate text API");
//! ```
//!
//! ```compile_fail
//! use qubit_redact::Redactor;
//!
//! let mut batch = Redactor::strict().batch();
//! let _ = batch.redact_field("password", "raw-secret");
//! let _ = batch.finish_for_diagnostics("<redaction incomplete>");
//! let _ = batch.redact_field("password", "cannot reuse a finished batch");
//! ```
//!
//! ```compile_fail
//! use qubit_redact::Redactor;
//!
//! let composer = Redactor::strict().text_composer();
//! let _ = composer.redact_field("password", "batch methods are unavailable");
//! ```
//!
//! ```compile_fail
//! use qubit_redact::Redactor;
//!
//! let mut batch = Redactor::strict().batch();
//! let handle = batch.redact_field("password", "raw-secret");
//! let output = batch.finish_for_diagnostics("<redaction incomplete>");
//! let _ = output.text(handle);
//! let _ = handle.to_string();
//! ```
//!
//! The domain-level rendering traits do not provide an alternate output path.
//! Domain values must be written through [`Redact`] and a
//! [`RedactedTextComposer`] or [`RedactionBatch`].
//!
//! ```compile_fail
//! use qubit_redact::policy::RedactionPolicy;
//! ```
extern crate self as qubit_redact;
pub use Redact;
pub
pub use Redact;
pub use RedactionWriter;
pub use DebugDisplay;
pub use RedactedText;
pub use RedactedTextComposer;
pub use RedactionBatch;
pub use RedactionBatchDiagnostics;
pub use RedactionBatchHandle;
pub use RedactionInspection;
pub use RedactionInspectionError;
pub use RedactionReason;
pub use RedactionReasons;
pub use RedactionSummary;
pub use RedactionTextOutput;
pub use RedactionUsage;
pub use Redactor;
pub use RedactionCompletion;
pub use AllowRule;
pub use FieldClassification;
pub use FieldMatchKind;
pub use FieldNameMatching;
pub use FieldsBuilder;
pub use HttpContextBuilderView;
pub use HttpPolicyBuilderView;
pub use MaskPolicy;
pub use MaskingPolicy;
pub use MaskingPolicyBuilder;
pub use PolicyError;
pub use PolicyLocation;
pub use RedactionFloor;
pub use RedactionFloorBuilder;
pub use RedactionLimits;
pub use RedactionLimitsBuilder;
pub use RedactionPolicy;
pub use RedactionPolicyBuilder;
pub use RedactionRules;
pub use SensitiveFieldPreset;
pub use SensitiveFieldRule;
pub use Sensitivity;
pub use UnkeyedJsonValuePolicy;
pub use UnknownFieldPolicy;
pub use UriPolicyBuilderView;
pub use RedactionHandle;
pub use RedactionHandleError;