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
//! Does a passport's life status agree with the edges that produced it?
//!
//! # Why the status is stored and then checked, rather than derived
//!
//! Deriving the status from `derived_from` is tempting and does not survive the
//! plural case. Art. 77(7) permits several predecessors and nothing forces them
//! to share an operation, so a unit built from one repurposed and one
//! remanufactured predecessor has no unambiguous derived status. Storing it and
//! checking it recovers the one real advantage of deriving — a status that
//! cannot silently contradict the lineage — without inheriting that flaw. Same
//! shape as the derivation-consent rule next door.
//!
//! # What "agrees" means, and why it is *some* rather than *every*
//!
//! A claimed second-life status must be supported by **at least one** edge. It
//! deliberately does not require every edge to agree: that would make the plural
//! mixed-predecessor case above unrepresentable, and that case is lawful. What it
//! catches is the claim no edge supports at all — a passport claiming
//! `remanufactured` whose only derivation edge says `repurposing` is inconsistent
//! on its face.
//!
//! # `waste` is exempt, and that is not an oversight
//!
//! The four second-life values describe how a unit was *made*, and each of the
//! four operations produces a new passport under Art. 77(7), so a second-life
//! unit is born knowing its status. `waste` is the one value that is a transition
//! **on a record that continues**: Art. 77(7)'s second subparagraph moves
//! responsibility on a battery becoming waste and mandates no new passport.
//!
//! So a waste battery's derivation edges still describe its manufacture, and they
//! say nothing about whether it is now waste. A repurposed unit that later became
//! waste carries a `repurposing` edge and a `waste` status, and both are correct.
//! Checking `waste` against the edges would report that entirely ordinary record
//! as inconsistent.
//!
//! # What this rule cannot do
//!
//! It cannot tell whether an edge's operation is *truthful* — only whether the
//! status and the edges tell the same story. Whether the predecessor's operator
//! consented to the edge at all is [`super::consent`]'s question, and the two are
//! independent: an edge can be perfectly consented and still support a status the
//! passport does not claim.
use StatusDefect;
/// Operations that produce a unit with the given life status, in wire form.
///
/// `repurposed` has two, and the reason is the input rather than the outcome:
/// Art. 3(30) (`preparationForRepurposing`) operates on "a waste battery, or
/// parts thereof", Art. 3(31) (`repurposing`) on "a battery, that is not a waste
/// battery". Both yield a repurposed unit.
///
/// `None` means the status is not one Annex XIII point 4(c) enumerates.
/// Check a passport's life status against the operations its derivation edges
/// claim.
///
/// `life_status` and `operations` are wire forms — `"re-used"`,
/// `"preparationForReuse"` — because the two vocabularies are defined in a crate
/// this one must not depend on. They are pinned byte-identical on the core side.
///
/// Returns `None` when the record is consistent, including the two cases that
/// are consistent by construction: a passport with no life status at all (the
/// vocabulary is Reg. (EU) 2023/1542's, and a product group whose instrument does
/// not ask the question should not answer it), and a `waste` status, for the
/// reason in this module's documentation.