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
//! [`DerivationRef`] — a typed upward edge to a second-life predecessor.
use ;
use PassportRef;
/// One of the four second-life operations named by Reg. (EU) 2023/1542
/// Art. 77(7).
///
/// ✅ COMPLIANCE-PIN: EU 2023/1542, Art. 77(7) and Art. 3(29)–(32)
/// (OJ L 191, 28.7.2023, pp. 73 and 27). Art. 77(7) transfers responsibility for
/// "a battery that has been subject to preparation for re-use, preparation for
/// repurposing, repurposing or remanufacturing"; the four are defined terms at
/// Art. 3(29) to (32).
///
/// The edge must say which one occurred because they are not interchangeable:
/// each has its own definition, and the boundary between the two repurposing
/// operations is the **waste status of the input** — Art. 3(30) operates on "a
/// waste battery, or parts thereof", Art. 3(31) on "a battery, that is not a
/// waste battery".
///
/// Mirrors the [`TransferReason`](crate::transfer::TransferReason) variants of
/// the same names. That correspondence is load-bearing rather than incidental:
/// the rule binding a derivation edge to the transfer of responsibility that
/// consents to it matches one against the other, so the two vocabularies must
/// not drift.
/// An upward edge to one predecessor a second-life unit derives from.
///
/// ✅ COMPLIANCE-PIN: EU 2023/1542, Art. 77(7) (OJ L 191, 28.7.2023, p. 73):
/// "Such battery shall have a new battery passport linked to the battery
/// passport **or passports** of the original battery **or batteries**."
///
/// Plural on both sides, which is why [`Passport::derived_from`](super::Passport::derived_from)
/// is a `Vec` and
/// not an `Option`. A stationary storage pack assembled from several retired EV
/// packs is the canonical second-life product, not a corner case, and the
/// single-predecessor shape this replaced could not represent it at all.
///
/// Wraps [`PassportRef`] rather than extending it: the reference stays a pure,
/// direction-neutral "where + pin" primitive, and the qualifier each direction
/// needs is added by the wrapper. Downward BOM edges wrap the same primitive
/// with their own qualifiers.
///
/// The edge is a *claim* until it is consented to. A hash-pin proves the target
/// has not been modified; it does not prove the target's operator agreed to the
/// relationship, and Art. 77(7) moves regulatory responsibility. The consent
/// artefact is the [`TransferRecord`](crate::transfer::TransferRecord), which
/// carries the **outgoing** operator's own authorisation — the predecessor's,
/// which is the half that matters here. Binding the two is a cross-field rule
/// (`dpp_rules::lineage::consent`), not a property of this type.