Expand description
btctax-core: domain model + pure deterministic event-sourced projection for the bitcoin_tax ledger.
The projection (project) is total and never panics (spec §7.1); only persistence performs I/O.
Re-exports§
pub use conventions::Sat;pub use conventions::TaxDate;pub use conventions::Usd;pub use donation::DonationDetails;pub use forms::form_8283;pub use forms::form_8949;pub use forms::schedule_d;pub use forms::year_donation_deduction;pub use forms::Form8283HowAcquired;pub use forms::Form8283Row;pub use forms::Form8283Section;pub use forms::Form8949Box;pub use forms::Form8949Part;pub use forms::Form8949Row;pub use forms::ScheduleDPart;pub use forms::ScheduleDTotals;pub use forms::DIGITAL_ASSET_8949_FIRST_YEAR;pub use identity::EventId;pub use identity::Fingerprint;pub use identity::LotId;pub use identity::Source;pub use identity::SourceRef;pub use identity::WalletId;pub use optimize::consult_sale;pub use optimize::optimize_year;pub use optimize::score_assignment;pub use optimize::ApproxReason;pub use optimize::ConsultReport;pub use optimize::ConsultRequest;pub use optimize::DisposalProposal;pub use optimize::OptimizeError;pub use optimize::OptimizeProposal;pub use optimize::Persistability;pub use optimize::TimingInsight;pub use price::PriceProvider;pub use project::conservation_report;pub use project::disposal_compliance;pub use project::evaluate_disposal;pub use project::in_force_methods;pub use project::project;pub use project::pseudo_plan;pub use project::would_conflict;pub use project::CandidateDisposal;pub use project::ComplianceStatus;pub use project::ConservationReport;pub use project::DisposalCompliance;pub use project::EvaluateError;pub use project::EvaluateOutcome;pub use project::FeeTreatment;pub use project::InForceMethod;pub use project::LotMethod;pub use project::ProjectionConfig;pub use project::PseudoDefault;pub use project::PseudoKind;pub use tax::apply_carryover_writeback;pub use tax::assemble_absolute;pub use tax::carryforward_consistency;pub use tax::compute_se_tax;pub use tax::compute_tax_year;pub use tax::loss_limit;pub use tax::niit_threshold;pub use tax::screen_absolute;pub use tax::se_addl_medicare_threshold;pub use tax::se_net_income;pub use tax::AbsoluteReturn;pub use tax::Carryforward;pub use tax::FilingStatus;pub use tax::LtcgBreakpoints;pub use tax::MarginalRates;pub use tax::OrdinaryBracket;pub use tax::OrdinarySchedule;pub use tax::PrefSplit;pub use tax::SeTaxResult;pub use tax::TaxOutcome;pub use tax::TaxProfile;pub use tax::TaxResult;pub use tax::TaxTable;pub use tax::TaxTables;pub use tax::NIIT_RATE;pub use tax::QUALIFIED_APPRAISAL_THRESHOLD;pub use tax::SE_NET_EARNINGS_FACTOR;pub use tax::SE_RATE_ADDL_MEDICARE;pub use tax::SE_RATE_MEDICARE;pub use tax::SE_RATE_SS;pub use void::is_revocable_payload;pub use void::voidable_decisions;pub use whatif::CarryforwardDelta;pub use whatif::ConsumedLot;pub use whatif::HarvestReport;pub use whatif::HarvestRequest;pub use whatif::HarvestStatus;pub use whatif::HarvestTarget;pub use whatif::LtcgBracket;pub use whatif::SellMethod;pub use whatif::SellReport;pub use whatif::SellRequest;pub use whatif::SellStatus;pub use whatif::WhatIfError;pub use whatif::HARVEST_TAU_SAT;pub use event::*;pub use state::*;
Modules§
- conservative
- Conservative-filing advisories (Phase 3 / D-9). PURE builders over already-projected state — no folding, no I/O. They are provenance-neutral (never assert “purchase”/“bought”; a tranche is undocumented BTC filed at its AS-FILED basis) and never instruct a tax-understating action.
- conservative_
promote - Approach-B / BG-D3: the
filed_basiscompute for promoting a$0conservative-filing tranche to a filed>$0basis FLOOR, gated hard onCoverage::Full(aPartial-covered window min can EXCEED the true window min —conservative::window_reference’s doc — so filing on it could UNDERSTATE the true floor; refused rather than silently downgraded). Also definesPromoteEntry/PromoteSet— the ★ shared decomposition-key types every leg-builder task (T4/T5/T6) consumes, given ONE owner here (arch r1 I-1) rather than each leg builder inventing its own shape. - conventions
- Exact money/time conventions (NFR5, §6.1). No floats anywhere.
- defensive
- Defensive Filing Wizard: derived, read-only signals over the projected
LedgerState— never new tax logic, never a second source of truth.discoveryis the DFW-D4 structured-shortfall/triage layer (Task 5); Task 6 addsjourney_view(the guided-dashboard read alongside it) — the composed, pure/read-only view a dashboard renders from: candidates to declare, shortfalls to resolve first, per-tranche status + derived advisories + clamped saving figures, the pool-level “still short” state, the BG-D9 fold-diff export year-set, and the safe-harbor mutual-exclusion flag. - donation
DonationDetails— Form 8283 Section-B appraiser + structured-donee metadata for a donation event. Pure type + completeness logic (no fold/projection coupling — this never entersLedgerState). Storage lives inbtctax-cli::donation_details(side-table, mirrors theTaxProfiletype-in-core / storage-in-cli pattern).- event
- The canonical event taxonomy (§6.4). One
EventPayloadenum; imported, system, and decision variants. - experimental
- The Approach-B (“Defensive Filing” — declare/promote tranche, Form 8275, estimated basis) experimental notice: a single, presentation-neutral source of truth for telling a filer that this part of btctax is newer and less proven than the rest of the tool, was developed with heavy AI assistance, and has shipped filing-affecting defects found only by later review (all known ones fixed).
- forms
- IRS Form 8949 (per-disposition rows) + Schedule D (aggregated part totals) generation
(Phase-2 sub-project 2). Both are pure, year-scoped projections over
state.disposals— no tax math, no rounding, no float (NFR5: the BTC-amount description is EXACTDecimal). Federal-only. - identity
- Stable identity & canonical ordering (§6.2). EventId is a STRUCTURED (injective) function of its components — no hashing needed for identity; only the content fingerprint (conflict detection) hashes.
- optimize
- Sub-project C — rate-aware optimizer. ASSIGNS lots to disposals (specific identification);
it does NOT advise whether to sell/hold (no investment advice — §C scope). Minimizes B’s
federal
total_federal_tax_attributableover feasible per-disposalLotSelections, within the §1.1012-1(j) identification boundary (adequate ID by the time of sale; no compliant post-hoc). Deterministic (NFR4) + exact (NFR5): BTreeMap/sorted iteration, Decimal/i64 only, no float. - persistence
- THE ONLY I/O in btctax-core. Reads/appends canonical event rows over a borrowed rusqlite handle (the live in-memory DB from btctax-store::Vault::conn(), wired by the CLI). Owns the events-table DDL, event (de)serialization, decision_seq allocation, and FR1 fingerprint-based conflict detection.
- price
- project
- state
- tax
- Tax-rate engine types and computation (Sub-project B). Federal-only (NFR5 exact Decimal;
NFR4 determinism). No float anywhere — all rates are
Decimalliterals. Tables and compute modules are added in Tasks 2–5. - tranche_
guard - Pure event-scan predicates for the tranche⇄allocation mutual-exclusion guard (D-8).
- void
- The voidable-candidate predicate — the SINGLE shared source of truth for “which reconcile
decisions may be swept-voided” (SPEC_bulk_void §Candidate set). Pure: it reads only the events +
the projected blockers, so it is reachable by the CLI (
Session::bulk_void_planviaproject()) AND the TUI (open_void_flow/open_bulk_void_flowvia the snapshot). There is NO second copy — any drift between the single-void filter and the bulk sweep is a tax-safety bug (the #7 exclusion). - whatif
- btctax-core::whatif — READ-ONLY hypothetical-transaction tax planning (task #43, phase P1).