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
//! DFW-D9: era presets — confirm/edit STARTING POINTS for the Declare flow's window, never
//! authoritative windows. `era_window` maps each preset to a concrete `[start, end]` calendar window;
//! the Declare flow always applies the DFW-D5 before-the-short-op-date clamp ON TOP of whatever a
//! preset seeds ("the DFW-D5 before-the-short-op prefill governs over a preset's `window_end` where
//! they conflict" — SPEC.md DFW-D9).
//!
//! **What these buckets are (OWNER-RATIFIED).** Deliberate, CLAIM-FREE **round calendar spans** —
//! plain multi-year calendar blocks running from Bitcoin's genesis block (2009-01-03) to the newest tax
//! year this app can file. They make **no** historical, exchange, price, protocol or event claim (no
//! "Silk Road era", no named venue, no halving framing), which is exactly the point: there is nothing
//! in the table that can be factually WRONG. A bucket is one keystroke that seeds two dates the filer
//! then confirms or edits. This is a **UI convenience seeding a FILER ATTESTATION** — it is not
//! IRS-approved, not authoritative, and asserts nothing about when anyone actually acquired anything.
//!
//! **The filer's own window governs, and is validated downstream.** No preset value reaches a filed
//! number: the Declare flow requires an **EXPLICIT pick** (nothing is pre-selected — the tool never
//! answers "when did you acquire these coins?" for the filer, and `window_end` IS the lot's acquisition
//! date, `resolve.rs:~1310`, so the answer also sets short/long-term character); the DFW-D5
//! before-the-short-op clamp always governs `window_end`; `btctax_cli::plan_declare` re-validates
//! whatever window the filer confirms; and a later promotion's filed floor comes from
//! `conservative_promote::filed_basis_for`, which requires `Coverage::Full` over real price data.
//!
//! **No bucket STRADDLES the pooling cutover** (`conventions::TRANSITION_DATE`, 2025-01-01): every
//! window lies entirely before it or entirely on/after it, so a declared tranche's lot has an
//! unambiguous **acquisition-time** pool assignment (`project::pools::pool_key` — a single Universal
//! pool before the cutover, per-wallet from it on) — a pre-cutover lot is later drained into its
//! wallet's pool by `seed_transition` under Path A; the invariant here is about the initial assignment,
//! not lifetime residence. Pinned by
//! `defensive_era.rs::no_preset_window_straddles_the_pooling_cutover`.
use crate;
use date;
/// A named starting-point window for the Declare flow (DFW-D9). Presets are confirm/edit starting
/// points, NEVER authoritative windows — see the module doc.
/// Every preset, OLDEST first — the Declare flow's picker order (`1..=ALL_PRESETS.len()`) and KAT (a)'s
/// enumeration.
///
/// ★ A **slice**, not a fixed-length array: baking the count into the public type would make ADDING a
/// bucket a breaking change for every downstream matcher, and the census drift guard
/// (`btctax-forms/tests/census.rs::the_newest_era_preset_reaches_the_newest_filable_tax_year`) actively
/// schedules the next length change for whenever a new filing year is bundled. As a slice, that addition
/// is purely additive.
pub const ALL_PRESETS: & = &;
/// Map a preset to its concrete `[start, end]` calendar window (inclusive both ends).
// ★ whole-branch arch M-2: `next_preset` was DELETED here, with its two KATs — the same disposition
// `DeclareFlowState::clearance()` got. It lost its only production caller when the owner's explicit-pick
// decision replaced the Declare flow's Tab-cycling with a numbered picker (a "next" key would have put
// the first bucket one keystroke away from being the de-facto default again). It was briefly retained on
// the rationale "already-published accessor" — which was FALSE: `defensive::era` does not exist on `main`,
// so nothing here has ever been published, and narrowing the surface before the first release is far
// cheaper than after. A picker that needs "the bucket after this one" indexes `ALL_PRESETS` directly.