sharpebench-core 0.28.0

Deterministic, luck-robust quantitative evaluation kernel for trading agents.
Documentation
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
//! What the digest actually covers, declared in machine-readable form.
//!
//! A signed evidence record is only as strong as the statement of *what it
//! signs*. The failure mode this module exists to prevent is the quiet one: a
//! digest is computed over most of a record, one field group is left out, and
//! nothing anywhere says so. A consumer holding the document cannot tell the
//! signed fields from the unsigned ones by inspection, so the whole record reads
//! as attested when part of it is not. Nobody has to be dishonest for this to
//! happen; a field added later that nobody remembers to include produces exactly
//! the same result.
//!
//! So coverage is declared, not implied:
//!
//! - Every field of an evidence document carries a [`Coverage`] entry naming the
//!   digest that binds it, or naming the reason it is deliberately unbound.
//! - [`EvidenceInventory::audit`] reports fields present in the document but
//!   missing from the inventory, and fields declared but no longer present. The
//!   schema tests in this module run that audit against the real structs, so a
//!   new field fails the build until somebody decides what it is.
//! - [`EvidenceInventory::preimage`] is the only supported way to build the bytes
//!   that get hashed. It emits covered fields, emits [`REDACTED`] in place of the
//!   value of a secret-bearing field, and refuses a value set that does not match
//!   the declaration.
//!
//! Secrets are redacted **before** hashing rather than omitted, so the field's
//! presence is still bound while its value never enters the preimage. Verifying
//! a document therefore never requires holding the secret.
//!
//! The preimage is a byte string, not a hash: this crate is pure and carries no
//! cryptographic dependency. Feed the output to a digest function such as
//! `sharpebench_attest::content_digest`.

use std::collections::BTreeSet;

use serde::Serialize;

/// The token substituted for a redacted value. Fixed and public, so a verifier
/// reconstructs the preimage without the secret.
pub const REDACTED: &str = "<redacted>";

/// Which digest binds a field.
///
/// Two digests exist because two different things are being attested. An agent's
/// own scored evidence is reproducible from its submission alone; the
/// field-relative figures are not, because they move whenever the field's
/// composition changes. Binding both under one digest would make a re-run with a
/// new entrant invalidate every previously published per-agent attestation.
#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "snake_case")]
pub enum DigestId {
    /// Fields determined by the agent's own runs and the score configuration.
    AgentScore,
    /// Fields determined by the composition of the field the agent was scored in.
    FieldContext,
    /// Fields describing how a run was produced: dataset, seeds, harness.
    RunProvenance,
}

/// The coverage status of one evidence field.
#[derive(Clone, Copy, Debug, Serialize, PartialEq, Eq)]
#[serde(tag = "coverage", rename_all = "snake_case")]
pub enum Coverage {
    /// The field's value enters the named digest's preimage verbatim.
    Covered { digest: DigestId },
    /// The field is bound by the named digest, but as [`REDACTED`] rather than
    /// as its value, because the value is secret. `reason` states why.
    Redacted {
        digest: DigestId,
        reason: &'static str,
    },
    /// The field enters no digest at all. `reason` states why, and a reason is
    /// mandatory: an exclusion nobody can justify is a bug, not a policy.
    Excluded { reason: &'static str },
}

impl Coverage {
    /// The digest binding this field, if any.
    pub fn digest(&self) -> Option<DigestId> {
        match self {
            Coverage::Covered { digest } | Coverage::Redacted { digest, .. } => Some(*digest),
            Coverage::Excluded { .. } => None,
        }
    }

    /// Whether the field's value (as opposed to its presence) is bound.
    pub fn binds_value(&self) -> bool {
        matches!(self, Coverage::Covered { .. })
    }
}

/// A declaration of what is and is not covered, for one evidence document.
#[derive(Clone, Copy, Debug)]
pub struct EvidenceInventory {
    /// The document this inventory describes, by type name.
    pub document: &'static str,
    /// Every field of the document, in serialization order.
    pub fields: &'static [(&'static str, Coverage)],
}

/// What an inventory audit found. Empty on both counts is the passing state.
#[derive(Clone, Debug, Default, Serialize, PartialEq)]
pub struct InventoryAudit {
    /// Fields present in the document but absent from the inventory. Each of
    /// these is a field a consumer cannot classify.
    pub undeclared: Vec<String>,
    /// Fields declared by the inventory but no longer present in the document.
    pub stale: Vec<String>,
}

impl InventoryAudit {
    /// Whether the inventory matches the document exactly.
    pub fn is_complete(&self) -> bool {
        self.undeclared.is_empty() && self.stale.is_empty()
    }
}

/// A value set that does not match the inventory.
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
#[serde(tag = "error", rename_all = "snake_case")]
pub enum PreimageError {
    /// A value was supplied for a field the inventory does not declare.
    UndeclaredField { field: String },
    /// A field bound by the requested digest had no value supplied.
    MissingField { field: String },
    /// The same field was supplied more than once.
    DuplicateField { field: String },
}

impl EvidenceInventory {
    /// The coverage declared for `field`, or `None` if it is undeclared.
    pub fn coverage(&self, field: &str) -> Option<Coverage> {
        self.fields
            .iter()
            .find(|(name, _)| *name == field)
            .map(|(_, c)| *c)
    }

    /// Field names bound by `digest`, in serialization order. Includes redacted
    /// fields, whose presence is bound even though their value is not.
    pub fn fields_for(&self, digest: DigestId) -> Vec<&'static str> {
        self.fields
            .iter()
            .filter(|(_, c)| c.digest() == Some(digest))
            .map(|(name, _)| *name)
            .collect()
    }

    /// Field names declared as covered by no digest, with their stated reasons.
    pub fn exclusions(&self) -> Vec<(&'static str, &'static str)> {
        self.fields
            .iter()
            .filter_map(|(name, c)| match c {
                Coverage::Excluded { reason } => Some((*name, *reason)),
                Coverage::Covered { .. } | Coverage::Redacted { .. } => None,
            })
            .collect()
    }

    /// Compare the inventory against the field names a document actually has.
    ///
    /// This is what keeps the declaration from drifting: run it in a test with
    /// the serialized field names of the real struct.
    pub fn audit<S: AsRef<str>>(&self, observed: &[S]) -> InventoryAudit {
        let declared: BTreeSet<&str> = self.fields.iter().map(|(n, _)| *n).collect();
        let present: BTreeSet<&str> = observed.iter().map(|s| s.as_ref()).collect();
        InventoryAudit {
            undeclared: present
                .difference(&declared)
                .map(|s| (*s).to_string())
                .collect(),
            stale: declared
                .difference(&present)
                .map(|s| (*s).to_string())
                .collect(),
        }
    }

    /// Build the canonical bytes to hash for one digest.
    ///
    /// `values` supplies every field of the document as an already-rendered
    /// string; the caller owns the rendering so that number formatting stays a
    /// decision of the producer rather than of this module. Fields bound by
    /// other digests, and excluded fields, are simply not consulted.
    ///
    /// The output is `name\x1fvalue\x1e` per field, in inventory order, with the
    /// document name and digest as the first record. The unit separators cannot
    /// appear in a field name, so no value can be crafted to look like a field
    /// boundary.
    ///
    /// Fails when a value is supplied for an undeclared field (the inventory is
    /// out of date), when a bound field has no value (the digest would silently
    /// cover less than it claims), or when a field is supplied twice.
    pub fn preimage(
        &self,
        digest: DigestId,
        values: &[(&str, &str)],
    ) -> Result<Vec<u8>, PreimageError> {
        let mut seen: BTreeSet<&str> = BTreeSet::new();
        for (name, _) in values {
            if self.coverage(name).is_none() {
                return Err(PreimageError::UndeclaredField {
                    field: (*name).to_string(),
                });
            }
            if !seen.insert(name) {
                return Err(PreimageError::DuplicateField {
                    field: (*name).to_string(),
                });
            }
        }

        let mut out = Vec::new();
        push_record(&mut out, "sharpebench.document", self.document);
        push_record(&mut out, "sharpebench.digest", digest_name(digest));

        for (name, coverage) in self.fields {
            if coverage.digest() != Some(digest) {
                continue;
            }
            let Some((_, value)) = values.iter().find(|(n, _)| n == name) else {
                return Err(PreimageError::MissingField {
                    field: (*name).to_string(),
                });
            };
            match coverage {
                Coverage::Covered { .. } => push_record(&mut out, name, value),
                Coverage::Redacted { .. } => push_record(&mut out, name, REDACTED),
                Coverage::Excluded { .. } => unreachable!("filtered by digest match"),
            }
        }
        Ok(out)
    }
}

fn push_record(out: &mut Vec<u8>, name: &str, value: &str) {
    out.extend_from_slice(name.as_bytes());
    out.push(0x1f);
    out.extend_from_slice(value.as_bytes());
    out.push(0x1e);
}

fn digest_name(d: DigestId) -> &'static str {
    match d {
        DigestId::AgentScore => "agent_score",
        DigestId::FieldContext => "field_context",
        DigestId::RunProvenance => "run_provenance",
    }
}

const COVERED_SCORE: Coverage = Coverage::Covered {
    digest: DigestId::AgentScore,
};
const COVERED_FIELD: Coverage = Coverage::Covered {
    digest: DigestId::FieldContext,
};

/// Coverage declaration for [`crate::composite::CompositeScore`], the per-agent
/// evidence record the leaderboard publishes.
///
/// Split by what determines the value. `AgentScore` fields come out of the
/// agent's own runs and the score configuration; `FieldContext` fields come out
/// of the composition of the field it was scored against and change when another
/// entrant is added. Four fields are bound by neither, each with its reason.
pub const COMPOSITE_SCORE_INVENTORY: EvidenceInventory = EvidenceInventory {
    document: "sharpebench_core::composite::CompositeScore",
    fields: &[
        ("agent_id", COVERED_SCORE),
        ("deflated_sharpe", COVERED_SCORE),
        ("psr", COVERED_SCORE),
        ("passed_k", COVERED_SCORE),
        ("process_ok", COVERED_SCORE),
        ("bootstrap_p", COVERED_SCORE),
        ("bootstrap_error", COVERED_SCORE),
        ("deflation_error", COVERED_SCORE),
        ("selection_error", COVERED_SCORE),
        ("raw_mean_return", COVERED_SCORE),
        ("rank_eligible", COVERED_SCORE),
        ("composite", COVERED_SCORE),
        ("alpha", COVERED_FIELD),
        ("beta", COVERED_FIELD),
        ("calibration_brier", COVERED_SCORE),
        ("calibration_observations", COVERED_SCORE),
        ("edge_half_life", COVERED_SCORE),
        ("field_reality_check_p", COVERED_FIELD),
        ("max_drawdown", COVERED_SCORE),
        ("mandate_ok", COVERED_SCORE),
        ("worst_run_drawdown", COVERED_SCORE),
        ("turnover", COVERED_SCORE),
        ("pareto_optimal", COVERED_FIELD),
        ("step_down_significant", COVERED_FIELD),
        ("confidence_weighted_return", COVERED_SCORE),
        ("cost", COVERED_SCORE),
        ("return_per_cost", COVERED_SCORE),
        ("field_spa_p", COVERED_FIELD),
        ("field_spa_consistent_p", COVERED_FIELD),
        ("field_significance_benchmark", COVERED_FIELD),
        ("field_crowdedness", COVERED_FIELD),
        ("field_crowdedness_peers", COVERED_FIELD),
        ("in_sample_trials", COVERED_SCORE),
        ("effective_n_trials", COVERED_SCORE),
        ("dsr_percentile", COVERED_FIELD),
        ("selection_median_dsr", COVERED_SCORE),
        ("selection_gap", COVERED_SCORE),
        ("rank_ordinal", COVERED_FIELD),
        ("rolling_min_sharpe", COVERED_SCORE),
        ("rolling_frac_positive", COVERED_SCORE),
        ("rolling_windows", COVERED_SCORE),
        ("sortino", COVERED_SCORE),
        ("downside_deviation", COVERED_SCORE),
        ("dsr_per_cost", COVERED_SCORE),
        ("process_floored", COVERED_SCORE),
        ("realized_floored_return", COVERED_SCORE),
        ("dsr_ci_low", COVERED_SCORE),
        ("dsr_ci_high", COVERED_SCORE),
        ("dsr_se", COVERED_SCORE),
        ("tie_group", COVERED_FIELD),
        ("dsr_tied", COVERED_FIELD),
        ("trials_sr_std", COVERED_SCORE),
        ("trials_sr_std_annualized", COVERED_SCORE),
        (
            "trials_sr_std_annualized_equivalent",
            Coverage::Excluded {
                reason: "presentation unit of trials_sr_std, which is covered by agent_score; \
                         a fixed conversion carries no evidence the covered value does not, \
                         and binding it would let a units edit break a digest over unchanged \
                         evidence",
            },
        ),
        ("deflation_bar_per_period", COVERED_SCORE),
        (
            "deflation_bar_annualized_equivalent",
            Coverage::Excluded {
                reason: "presentation unit of deflation_bar_per_period, which is covered by \
                         agent_score; excluded for the reason given on \
                         trials_sr_std_annualized_equivalent",
            },
        ),
        ("deflation_null_mean_per_period", COVERED_SCORE),
        ("pooled_observations", COVERED_SCORE),
        ("trials_sr_std_source", COVERED_SCORE),
        // A fixed-shape record like declared_mandate, and set by the field's
        // composition like pareto_optimal, so it binds under field_context.
        ("trials_sr_std_most_influential_vote", COVERED_FIELD),
        ("runs_submitted", COVERED_SCORE),
        ("runs_scored", COVERED_SCORE),
        ("process_score", COVERED_SCORE),
        ("process_warnings", COVERED_SCORE),
        ("econ_rationality_score", COVERED_SCORE),
        ("econ_dominance_violations", COVERED_SCORE),
        (
            "role_contributions",
            Coverage::Excluded {
                reason: "a variable-length nested structure whose element type carries its own \
                         fields; binding it through this flat inventory would go stale silently \
                         the moment RoleContribution gains a field, which is the exact failure \
                         this inventory exists to prevent. It needs its own inventory before it \
                         can be bound",
            },
        ),
        ("declared_mandate", COVERED_SCORE),
        ("verdict_applied", COVERED_SCORE),
        ("declared_passed_k", COVERED_SCORE),
        ("declared_mandate_eligible", COVERED_FIELD),
        ("declared_mandate_ordinal", COVERED_FIELD),
        (
            "certification",
            Coverage::Excluded {
                reason: "a nested record whose withheld list is variable-length and whose \
                         elements carry their own fields; binding it through this flat \
                         inventory would go stale silently the moment Certification or \
                         CertificationGap gains a field, the failure given on \
                         role_contributions. It is a second, labeled verdict filled only under \
                         an opt-in rank mode, and needs its own inventory before it can be \
                         bound",
            },
        ),
    ],
};

/// How one scored run was produced.
///
/// Distinct from the score itself: two identical scores produced from different
/// datasets, seeds or harness builds are not the same evidence, and a digest
/// over the score alone cannot tell them apart.
///
/// `dataset_canary` is the leak tripwire bound into a held-out set. It is the
/// one field here that must never be recoverable from a published preimage, and
/// it is declared [`Coverage::Redacted`] for that reason.
#[derive(Clone, Debug, Serialize, PartialEq, Eq)]
pub struct RunProvenance {
    pub agent_id: String,
    pub dataset_id: String,
    /// Content hash of the frozen dataset bytes.
    pub dataset_content_hash: String,
    /// The canary GUID embedded in the held-out set. Secret.
    pub dataset_canary: String,
    pub window_id: String,
    pub seed: u64,
    pub cost_profile: String,
    pub harness_version: String,
}

/// Coverage declaration for [`RunProvenance`].
pub const RUN_PROVENANCE_INVENTORY: EvidenceInventory = EvidenceInventory {
    document: "sharpebench_core::evidence_coverage::RunProvenance",
    fields: &[
        (
            "agent_id",
            Coverage::Covered {
                digest: DigestId::RunProvenance,
            },
        ),
        (
            "dataset_id",
            Coverage::Covered {
                digest: DigestId::RunProvenance,
            },
        ),
        (
            "dataset_content_hash",
            Coverage::Covered {
                digest: DigestId::RunProvenance,
            },
        ),
        (
            "dataset_canary",
            Coverage::Redacted {
                digest: DigestId::RunProvenance,
                reason: "the canary is a leak tripwire: publishing a preimage that contains it \
                         hands an agent the token whose appearance in training data is the \
                         evidence of contamination. Binding its presence is enough, and \
                         verification must not require holding it",
            },
        ),
        (
            "window_id",
            Coverage::Covered {
                digest: DigestId::RunProvenance,
            },
        ),
        (
            "seed",
            Coverage::Covered {
                digest: DigestId::RunProvenance,
            },
        ),
        (
            "cost_profile",
            Coverage::Covered {
                digest: DigestId::RunProvenance,
            },
        ),
        (
            "harness_version",
            Coverage::Covered {
                digest: DigestId::RunProvenance,
            },
        ),
    ],
};

#[cfg(test)]
mod tests {
    use super::*;
    use crate::composite::{
        rank_declared, AgentSubmission, CompositeScore, DeclaredMandate, MandateDeclarations, Run,
        ScoreConfig,
    };
    use crate::entrant_visibility::declared_struct_fields;
    use crate::process::Trace;

    /// Top-level field names of a serialized value.
    fn field_names<T: Serialize>(v: &T) -> Vec<String> {
        let json = serde_json::to_value(v).expect("value serializes");
        json.as_object()
            .expect("evidence documents serialize as objects")
            .keys()
            .cloned()
            .collect()
    }

    fn probe_submission(id: &str, mean: f64) -> AgentSubmission {
        let runs: Vec<Run> = (0..5)
            .map(|_| Run {
                returns: (0..60)
                    .map(|i| mean + 0.0005 * (i as f64 * 0.7).sin())
                    .collect(),
                trace: Trace::default(),
                confidences: Vec::new(),
                outcomes: Vec::new(),
                cost: 1.0,
            })
            .collect();
        AgentSubmission {
            agent_id: id.to_string(),
            runs,
            in_sample_trials: 0,
            candidates: Vec::new(),
        }
    }

    /// Every field name a `CompositeScore` can carry.
    ///
    /// The authority is the declared field list serde hands to
    /// `deserialize_struct`, which includes fields a `skip_serializing_if`
    /// hides. The serialized keys of the probes are added on top, so a field
    /// that serializes under a name the struct does not declare also fails. The
    /// probes alone missed `selection_error` and `certification`: no probe
    /// declared candidates or selected a rank mode, so both stayed `None` and
    /// were never serialized.
    fn observed_composite_score_fields() -> Vec<String> {
        let subs = vec![
            probe_submission("declared-probe", 0.002),
            probe_submission("undeclared-probe", 0.0018),
        ];
        let mut declarations = MandateDeclarations::new();
        declarations.insert(
            "declared-probe".to_string(),
            DeclaredMandate::AbsoluteReturn,
        );
        let mut scored = rank_declared(&subs, &declarations, &ScoreConfig::default());
        scored.extend(rank_declared(
            &subs,
            &declarations,
            &ScoreConfig {
                n_boot: 0,
                ..ScoreConfig::default()
            },
        ));

        let mut names: BTreeSet<String> = declared_struct_fields::<CompositeScore>()
            .iter()
            .map(|name| (*name).to_string())
            .collect();
        for s in &scored {
            names.extend(field_names(s));
        }
        names.into_iter().collect()
    }

    // -----------------------------------------------------------------------
    // The drift guards. These are the tests that fail on a new field.
    // -----------------------------------------------------------------------

    #[test]
    fn every_composite_score_field_is_declared_covered_or_excluded() {
        let names = observed_composite_score_fields();
        let audit = COMPOSITE_SCORE_INVENTORY.audit(&names);
        assert!(
            audit.is_complete(),
            "CompositeScore and its coverage inventory have diverged.\n\
             Fields present but undeclared: {:?}\n\
             Fields declared but absent: {:?}\n\
             Add each new field to COMPOSITE_SCORE_INVENTORY as Covered {{ digest }} \
             or Excluded {{ reason }}.",
            audit.undeclared,
            audit.stale
        );
    }

    #[test]
    fn every_run_provenance_field_is_declared_covered_or_excluded() {
        let p = RunProvenance {
            agent_id: "a".to_string(),
            dataset_id: "us-indices-1d".to_string(),
            dataset_content_hash: "abc".to_string(),
            dataset_canary: "canary-token".to_string(),
            window_id: "w3".to_string(),
            seed: 7,
            cost_profile: "retail".to_string(),
            harness_version: "0.11.0".to_string(),
        };
        let audit = RUN_PROVENANCE_INVENTORY.audit(&field_names(&p));
        assert!(audit.is_complete(), "{audit:?}");
    }

    #[test]
    fn a_new_undeclared_field_fails_the_audit() {
        // The guard above passes only because the inventory is current. Prove it
        // can actually fail: hand it a document with one extra field.
        let mut names = observed_composite_score_fields();
        names.push("newly_added_metric".to_string());
        let audit = COMPOSITE_SCORE_INVENTORY.audit(&names);
        assert!(!audit.is_complete());
        assert_eq!(audit.undeclared, vec!["newly_added_metric".to_string()]);
        assert!(audit.stale.is_empty());
    }

    /// `selection_error` and `certification` are absent from every serialized
    /// probe row, and the drift guard still classifies them.
    #[test]
    fn fields_a_skipped_none_hides_are_still_classified() {
        let subs = vec![probe_submission("probe", 0.002)];
        let serialized: BTreeSet<String> =
            rank_declared(&subs, &MandateDeclarations::new(), &ScoreConfig::default())
                .iter()
                .flat_map(field_names)
                .collect();
        for hidden in ["selection_error", "certification"] {
            assert!(!serialized.contains(hidden), "{hidden} was serialized");
            assert!(observed_composite_score_fields().contains(&hidden.to_string()));
        }
        assert_eq!(
            COMPOSITE_SCORE_INVENTORY.coverage("selection_error"),
            Some(COVERED_SCORE),
            "a diagnostic of the agent's own candidates, like bootstrap_error and \
             deflation_error"
        );
        assert!(matches!(
            COMPOSITE_SCORE_INVENTORY.coverage("certification"),
            Some(Coverage::Excluded { .. })
        ));

        // Covered means the preimage builder really emits it.
        let values: Vec<(&str, &str)> = COMPOSITE_SCORE_INVENTORY
            .fields
            .iter()
            .map(|(n, _)| (*n, "0"))
            .collect();
        let bytes = COMPOSITE_SCORE_INVENTORY
            .preimage(DigestId::AgentScore, &values)
            .unwrap();
        let record = b"selection_error\x1f0\x1e";
        assert!(bytes.windows(record.len()).any(|w| w == record));
    }

    #[test]
    fn a_removed_field_is_reported_as_stale() {
        let names: Vec<String> = observed_composite_score_fields()
            .into_iter()
            .filter(|n| n != "psr")
            .collect();
        let audit = COMPOSITE_SCORE_INVENTORY.audit(&names);
        assert_eq!(audit.stale, vec!["psr".to_string()]);
    }

    // -----------------------------------------------------------------------
    // The declaration itself.
    // -----------------------------------------------------------------------

    #[test]
    fn every_exclusion_carries_a_reason() {
        for inventory in [COMPOSITE_SCORE_INVENTORY, RUN_PROVENANCE_INVENTORY] {
            for (name, reason) in inventory.exclusions() {
                assert!(
                    reason.len() > 30,
                    "{}::{name} is excluded without a usable reason",
                    inventory.document
                );
            }
        }
    }

    #[test]
    fn every_redaction_carries_a_reason() {
        for inventory in [COMPOSITE_SCORE_INVENTORY, RUN_PROVENANCE_INVENTORY] {
            for (name, coverage) in inventory.fields {
                if let Coverage::Redacted { reason, .. } = coverage {
                    assert!(
                        reason.len() > 30,
                        "{}::{name} is redacted without a usable reason",
                        inventory.document
                    );
                }
            }
        }
    }

    #[test]
    fn the_two_digests_partition_the_covered_fields() {
        let score = COMPOSITE_SCORE_INVENTORY.fields_for(DigestId::AgentScore);
        let context = COMPOSITE_SCORE_INVENTORY.fields_for(DigestId::FieldContext);
        let excluded = COMPOSITE_SCORE_INVENTORY.exclusions();
        assert_eq!(
            score.len() + context.len() + excluded.len(),
            COMPOSITE_SCORE_INVENTORY.fields.len(),
            "every field lands in exactly one of the three buckets"
        );
        for f in &score {
            assert!(!context.contains(f), "{f} is claimed by both digests");
        }
        assert_eq!(excluded.len(), 4, "exactly four deliberate exclusions");
    }

    #[test]
    fn no_field_is_declared_twice() {
        for inventory in [COMPOSITE_SCORE_INVENTORY, RUN_PROVENANCE_INVENTORY] {
            let names: BTreeSet<&str> = inventory.fields.iter().map(|(n, _)| *n).collect();
            assert_eq!(
                names.len(),
                inventory.fields.len(),
                "{} declares a field twice",
                inventory.document
            );
        }
    }

    #[test]
    fn coverage_lookup_answers_the_consumer_question() {
        assert_eq!(
            COMPOSITE_SCORE_INVENTORY.coverage("deflated_sharpe"),
            Some(COVERED_SCORE)
        );
        assert_eq!(
            COMPOSITE_SCORE_INVENTORY
                .coverage("alpha")
                .unwrap()
                .digest(),
            Some(DigestId::FieldContext)
        );
        assert!(!COMPOSITE_SCORE_INVENTORY
            .coverage("role_contributions")
            .unwrap()
            .binds_value());
        assert_eq!(COMPOSITE_SCORE_INVENTORY.coverage("not_a_field"), None);
    }

    // -----------------------------------------------------------------------
    // Preimage construction and redaction.
    // -----------------------------------------------------------------------

    fn provenance_values() -> Vec<(&'static str, &'static str)> {
        vec![
            ("agent_id", "donchian-20-10"),
            ("dataset_id", "us-indices-1d"),
            ("dataset_content_hash", "9f86d081884c7d65"),
            ("dataset_canary", "SUPER-SECRET-CANARY-42"),
            ("window_id", "w3"),
            ("seed", "7"),
            ("cost_profile", "retail"),
            ("harness_version", "0.11.0"),
        ]
    }

    #[test]
    fn a_secret_never_reaches_the_preimage() {
        let bytes = RUN_PROVENANCE_INVENTORY
            .preimage(DigestId::RunProvenance, &provenance_values())
            .expect("complete value set");
        let text = String::from_utf8(bytes).unwrap();
        assert!(
            !text.contains("SUPER-SECRET-CANARY-42"),
            "the canary leaked into the bytes that get hashed"
        );
        assert!(
            text.contains(REDACTED),
            "the field's presence must still be bound"
        );
        assert!(text.contains("dataset_content_hash"));
    }

    #[test]
    fn changing_a_secret_does_not_change_the_preimage() {
        // The consequence of redacting rather than hashing the value: a verifier
        // who does not hold the canary still reproduces the digest exactly.
        let base = RUN_PROVENANCE_INVENTORY
            .preimage(DigestId::RunProvenance, &provenance_values())
            .unwrap();
        let mut rotated = provenance_values();
        rotated[3] = ("dataset_canary", "A-DIFFERENT-CANARY");
        let after = RUN_PROVENANCE_INVENTORY
            .preimage(DigestId::RunProvenance, &rotated)
            .unwrap();
        assert_eq!(base, after);
    }

    #[test]
    fn changing_a_covered_value_changes_the_preimage() {
        let base = RUN_PROVENANCE_INVENTORY
            .preimage(DigestId::RunProvenance, &provenance_values())
            .unwrap();
        let mut tampered = provenance_values();
        tampered[2] = ("dataset_content_hash", "0000000000000000");
        let after = RUN_PROVENANCE_INVENTORY
            .preimage(DigestId::RunProvenance, &tampered)
            .unwrap();
        assert_ne!(base, after);
    }

    #[test]
    fn the_preimage_is_deterministic_and_order_independent() {
        let mut shuffled = provenance_values();
        shuffled.reverse();
        assert_eq!(
            RUN_PROVENANCE_INVENTORY
                .preimage(DigestId::RunProvenance, &provenance_values())
                .unwrap(),
            RUN_PROVENANCE_INVENTORY
                .preimage(DigestId::RunProvenance, &shuffled)
                .unwrap(),
            "inventory order fixes the layout, not caller order"
        );
    }

    #[test]
    fn a_missing_bound_field_is_refused() {
        let mut incomplete = provenance_values();
        incomplete.retain(|(n, _)| *n != "seed");
        assert_eq!(
            RUN_PROVENANCE_INVENTORY.preimage(DigestId::RunProvenance, &incomplete),
            Err(PreimageError::MissingField {
                field: "seed".to_string()
            })
        );
    }

    #[test]
    fn an_undeclared_or_duplicated_value_is_refused() {
        let mut extra = provenance_values();
        extra.push(("newly_added_metric", "1.0"));
        assert_eq!(
            RUN_PROVENANCE_INVENTORY.preimage(DigestId::RunProvenance, &extra),
            Err(PreimageError::UndeclaredField {
                field: "newly_added_metric".to_string()
            })
        );

        let mut dup = provenance_values();
        dup.push(("seed", "8"));
        assert_eq!(
            RUN_PROVENANCE_INVENTORY.preimage(DigestId::RunProvenance, &dup),
            Err(PreimageError::DuplicateField {
                field: "seed".to_string()
            })
        );
    }

    #[test]
    fn an_excluded_field_never_appears_under_any_digest() {
        let values: Vec<(&str, &str)> = COMPOSITE_SCORE_INVENTORY
            .fields
            .iter()
            .map(|(n, _)| (*n, "0"))
            .collect();
        for digest in [DigestId::AgentScore, DigestId::FieldContext] {
            let bytes = COMPOSITE_SCORE_INVENTORY.preimage(digest, &values).unwrap();
            let text = String::from_utf8(bytes).unwrap();
            for (name, _) in COMPOSITE_SCORE_INVENTORY.exclusions() {
                assert!(
                    !text.contains(name),
                    "{name} is excluded but reached the {digest:?} preimage"
                );
            }
        }
    }

    #[test]
    fn the_two_digests_produce_different_preimages_over_the_same_values() {
        let values: Vec<(&str, &str)> = COMPOSITE_SCORE_INVENTORY
            .fields
            .iter()
            .map(|(n, _)| (*n, "0"))
            .collect();
        assert_ne!(
            COMPOSITE_SCORE_INVENTORY
                .preimage(DigestId::AgentScore, &values)
                .unwrap(),
            COMPOSITE_SCORE_INVENTORY
                .preimage(DigestId::FieldContext, &values)
                .unwrap(),
            "the digest tag and the field set both differ"
        );
    }
}