aprender_contrastive_data/lib.rs
1//! Deterministic, leakage-safe contrastive data construction.
2//!
3//! # Contract: contrastive-pair-protocol-v1.yaml
4//!
5//! This crate owns contrastive/Siamese **data construction** as a general capability —
6//! class buckets, balanced few-shot selection, bounded positive/negative pair sampling,
7//! typed split roles, dataset fingerprints, and the cross-split leakage checks that make
8//! all of the above trustworthy. SetFit is its first consumer, not its owner (D-01/D-03).
9//!
10//! # The bytes boundary (D-04)
11//!
12//! The public API is **bytes-in / bytes-out and typed values**. This crate performs no
13//! filesystem access, opens no sockets, and exposes no path-shaped parameters — not even
14//! in its tests. `apr-cli` owns every filesystem adapter.
15//!
16//! That is not stylistic. The destination for these artifacts is object storage behind a
17//! serverless consumer, where a manifest is an S3 object rather than a file; a crate
18//! whose API speaks in `&Path` forces such a consumer to be a rewrite instead of a
19//! wrapper. The boundary is **enforced**, not asserted: `make contrastive-data-boundary`
20//! compares the resolved dependency closure against a positive allowlist and bans
21//! `std::fs`/`std::net`/`std::path`/`Path`/`PathBuf` throughout `src/`, and
22//! `OBLIG-CPP-BYTES-BOUNDARY` in the contract names that check.
23//!
24//! # Determinism (D-20)
25//!
26//! Every random decision is a pure function of its draw ordinal, obtained from the
27//! counter-based Philox generator in `aprender-rand` (library name `trueno_rand`) rather
28//! than from a stateful stream. Worker-count independence is therefore *structural*: draw
29//! *i* cannot depend on how many draws preceded it, because nothing precedes it.
30//!
31//! ```
32//! use trueno_rand::Philox4x32;
33//!
34//! // The same (key, counter) always yields the same block ...
35//! let key = [0xdead_beef_u32, 0x0000_002a];
36//! let draw_7 = Philox4x32::generate_at(key, [7, 0, 0, 0]);
37//! assert_eq!(draw_7, Philox4x32::generate_at(key, [7, 0, 0, 0]));
38//!
39//! // ... and a different ordinal is an independent draw, with no carried state.
40//! assert_ne!(draw_7, Philox4x32::generate_at(key, [8, 0, 0, 0]));
41//! ```
42//!
43//! The RNG obligations (key derivation, counter mapping, the frozen domain-string table,
44//! and the bounded-draw derivation) are stated **inline** in
45//! `contracts/contrastive-pair-protocol-v1.yaml`. They deliberately do not cite an
46//! external RNG contract: no such file exists in this repository, and a dangling
47//! cross-reference is worse than an inline statement.
48//!
49//! # Why modules, not a flat re-export surface
50//!
51//! Consumers use module paths — `aprender_contrastive_data::split::Split`,
52//! `::pairs::CanonicalPair` — and this file re-exports exactly one name. That is
53//! deliberate. The complete module skeleton is declared here, once, so that each
54//! subsequent unit of work edits only its own module file and never contends on
55//! `lib.rs`. Without that, several independent workstreams would serialize behind a
56//! single re-export list for no engineering reason. The cost is one extra path segment
57//! at the call site; the benefit is that the module tree is also the ownership map.
58
59/// Typed failure surface shared by every boundary in this crate.
60pub mod error;
61
62/// Labeled-example schema and strict JSONL parse/encode over `&[u8]`.
63///
64/// Implemented by plan 02-03.
65pub mod schema;
66
67/// Exact and normalized content hashes plus the dataset fingerprint.
68///
69/// Implemented by plan 02-03.
70pub mod hash;
71
72/// Typestate split roles: `Split<Train>`, `Split<Validation>`, `Split<Test>`,
73/// `Split<CompatibilityTest>`.
74///
75/// Implemented by plan 02-03.
76pub mod split;
77
78/// The attested, profile-parameterized dataset a consumer must present before canonical
79/// splits are exposed.
80///
81/// Implemented by plan 02-06.
82pub mod prepared;
83
84/// Dataset identity attestation and its re-derivation from supplied buffers.
85///
86/// Implemented by plan 02-06.
87pub mod attestation;
88
89/// Cross-split duplicate coalescing and the deterministic exclusion record.
90///
91/// Implemented by plan 02-03.
92pub mod dedup;
93
94/// Append-only access ledger: which splits were touched, under which profile.
95///
96/// Implemented by plan 02-04.
97pub mod ledger;
98
99/// Domain-separated Philox key derivation and the bounded-draw primitive.
100///
101/// Implemented by plan 02-04.
102pub mod rng;
103
104/// Sorted per-class buckets over a selection pool.
105///
106/// Implemented by plan 02-05.
107pub mod buckets;
108
109/// Balanced few-shot selection and the ordered selected-ID manifest model.
110///
111/// Implemented by plan 02-05.
112pub mod select;
113
114/// Bounded pair sampling: canonical pairs, capacity math, budget resolution, and the
115/// singleton and degenerate-layout policies.
116///
117/// Implemented by plan 02-07.
118pub mod pairs;
119
120/// Canonical serialization and semantic hashing for every manifest in the protocol.
121///
122/// Implemented by plan 02-07.
123pub mod manifest;
124
125pub use error::ContrastiveDataError;