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
//! FVS: Kani bounded-model proofs for the unified verb surface (paiml/forjar#288).
//!
//! Gated behind `#[cfg(kani)]`; normal builds ignore them.
//! Run with: `cargo kani --harness proof_fvs_partition_is_total_and_disjoint`.
//!
//! ALLOCATION-FREE ON PURPOSE, like the nas_archive and backup_sync harnesses
//! beside it. That file records the measurement this one is shaped by: driving a
//! constructor instead of a predicate ran one CBMC process for 117 minutes at
//! 6.5 GB on an idle box — not because the input space was large, but because
//! CBMC had to model the allocator and `core::fmt` across it. These harnesses
//! never dereference a `&'static str` in the partition table; they read only the
//! bucket discriminant, so the model contains no string data and no allocation.
//!
//! WHAT THIS PROVES, AND WHAT IT DOES NOT. Kani proves the classification is
//! total and disjoint — every leaf carries exactly one bucket, over the whole
//! table rather than the entries a test happened to sample. It cannot prove the
//! table COVERS the shipped CLI, because that requires walking a `clap::Command`
//! tree built at runtime. That half is
//! `verb::partition::tests::the_partition_is_total`, which walks the live tree
//! and fails on an unbucketed leaf — verified by injection, and it caught
//! `rules serve` arriving from an unrelated merge. The two halves are
//! complementary and neither is sufficient alone.
// Gated with the harnesses: a bare `use` here is an unused import in every
// normal build, and this crate is clippy -D warnings.
use crateBucket;
/// Contract `KANI-FVS-003`: the CLI-leaf partition is total and disjoint —
/// every leaf is in exactly one of `{Unified, CliOnly, Pending}`.
///
/// Disjointness is the property worth proving mechanically. Totality at the
/// *type* level is enforced by the enum, but a future refactor that stores the
/// bucket as flags or a bitmask would lose it silently, and this harness fails
/// the moment two classifications can hold at once.
/// The table is not empty.
///
/// Stated separately because `proof_fvs_partition_is_total_and_disjoint`
/// assumes `i < len`, and on an empty table that assumption is unsatisfiable:
/// the harness would pass vacuously while classifying nothing. A proof that
/// holds because its premise cannot be met is the formal-methods form of a
/// green test over an empty set.
// ── FVS-4: the error taxonomy ───────────────────────────────────────────
//
// Both harnesses below target `ErrorClass`, never `ForjarError`. That is the
// allocation-free boundary: `ForjarError` carries a `String`, so a harness that
// CONSTRUCTS one drags the allocator and `core::fmt` into the model — the
// measurement recorded in kani_proofs_backup_sync is 117 minutes at 6.5 GB for
// exactly that mistake, on an input space of 216 cases.
//
// The split is the same one nas_archive documents. Kani proves the decision
// algebra; EXECUTION proves the delegation. `ForjarError::exit_code` is one line
// — `self.class.exit_code()` — and that it ignores `message` is proved by
// `error::tests`, which builds real errors with different messages and compares
// codes. Modelling a String to prove a one-line delegation would buy nothing.
/// Every `ErrorClass` variant, selected symbolically.
///
/// The `match` is EXHAUSTIVE over the enum rather than a `%`-wrapped index, so
/// adding a sixth variant fails to compile here. A harness that silently stops
/// covering a new variant is worse than no harness: it reports totality over a
/// set that has grown behind it.
/// Contract `KANI-FVS-001`: classification is TOTAL — every class maps into the
/// published exit-code set `{1, 2, 3, 4, 10}`.
///
/// These values are a public contract: CI scripts branch on them. A class that
/// mapped to some sixth code would be a silent change to that contract, and
/// nothing else in the build would notice.
/// Contract `KANI-FVS-002`: the exit code is a function of the VARIANT alone,
/// and distinct classes never collapse onto one code.
///
/// Injectivity is the half worth proving mechanically, because losing it is
/// precisely the defect this taxonomy replaced. The old classifier chose the
/// code by substring-matching the error PROSE, so every failure whose message
/// happened to contain "transport" collapsed onto 4 — the connection code CI
/// retries — including a deterministic bashrs rejection that fails identically
/// on every retry. A non-injective classifier cannot be acted on: the caller
/// cannot tell which failure it has.
///
/// `exit_code` takes `self: ErrorClass` by value, so it is structurally
/// incapable of reading a message. Injectivity plus that signature is the
/// allocation-free statement of "never of message length or content".