docs: document the whole public surface and deny(missing_docs)
80 undocumented public items, including three that are first contact:
`History::current_skill` — the method the crate's own first example calls
— `EventBuilder`, the type `h.event(t)` hands you, and `Gaussian::mu()`.
Now zero, and `#![deny(missing_docs)]` keeps it that way.
Several docs are measurements rather than readings of the code:
- `Outcome::Ranked` says ranks are used ordinally, so `[0, 1, 2]` and
`[0, 5, 90]` are the same observation. Measured: bit-identical
posteriors for both.
- `OwnedGame::log_evidence` says two identically-rated competitors give
exactly `ln(0.5)`. Written as a doctest, so it runs.
- `Member::weight` says zero and negative are accepted. Measured.
- `ConvergenceReport::final_step` is `(|Δmu|, |Δsigma|)` in skill units,
NOT natural parameters. That one had to be traced through
`Gaussian::delta` rather than assumed from the neighbouring vocabulary.
- `GameOptions::score_sigma` rejects non-positive and NaN but accepts
`+inf`, which is what the guard actually says.
README: it is the front door for a crate on a private registry, and it
opened with a link dump followed by 130 lines on drift. The first
`record_winner → converge → current_skill` block was at line 226 of 307.
It now leads with what the crate is, an install line, a quickstart, a
"which entry point?" table, and the `converge`-is-strict rationale that
was the crate's most opinionated recent decision and went unmentioned.
The two canonical examples disagreed on spelling (`History::default()`
vs `History::builder().build()`, `current_skill("a")` vs
`current_skill(&"a")`); they now agree. Five new README blocks are
doctested, taking the suite from 19 to 25.
`pub use smallvec;`. Four public items name `SmallVec` in their
signatures, and the only `Joint` example failed to compile from a
consumer crate with `unresolved import smallvec` — the dependency was in
the API but not reachable. Both worked examples now use the re-export,
so they teach the path that works downstream.
Vocabulary, from #75: "agent" was a fourth word for competitor, 200
occurrences, and it had reached public signatures before #73 un-exported
`TimeSlice`. Now zero.
Closes #77. Refs #75.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011hcFjNDmHXZF8URGLku5zZ
This commit is contained in:
@@ -18,9 +18,28 @@ use smallvec::SmallVec;
|
||||
#[non_exhaustive]
|
||||
#[must_use]
|
||||
pub enum Outcome {
|
||||
/// An ordinal finish: one rank per team, in the order the teams were given.
|
||||
///
|
||||
/// Lower is better, `0` is first, and equal values are a tie between those
|
||||
/// teams — which needs `p_draw > 0`, or ingestion rejects the event with
|
||||
/// [`InferenceError::TieWithoutDrawProbability`](crate::InferenceError::TieWithoutDrawProbability).
|
||||
///
|
||||
/// Only the ordering and the equalities are used. Ranks need not be dense
|
||||
/// or start at zero: inference sorts the teams and compares rank-adjacent
|
||||
/// pairs against a margin set by `p_draw`, so `[0, 1, 2]` and `[0, 5, 90]`
|
||||
/// are the same observation. A gap does not mean a bigger win — use
|
||||
/// `Scored` when the size of the difference is evidence.
|
||||
Ranked(SmallVec<[u32; 4]>),
|
||||
/// A continuous finish: one score per team, higher is better.
|
||||
///
|
||||
/// Unlike `Ranked`, the *sizes* of the differences are evidence. Teams are
|
||||
/// sorted by score and each adjacent pair's observed gap is fed to a
|
||||
/// `MarginFactor` as a measurement with standard deviation `sigma`, so
|
||||
/// beating a team by ten says more than beating them by one.
|
||||
#[non_exhaustive]
|
||||
Scored {
|
||||
/// Per-team scores, in the order the teams were given; higher is
|
||||
/// better. Must have one entry per team, and every entry finite.
|
||||
scores: SmallVec<[f64; 4]>,
|
||||
/// Per-event noise override. `None` means inherit
|
||||
/// `HistoryBuilder::score_sigma`. Must be `> 0.0` if `Some`.
|
||||
@@ -104,6 +123,12 @@ impl Outcome {
|
||||
}
|
||||
}
|
||||
|
||||
/// How many teams this outcome describes — the number of ranks, or of
|
||||
/// scores.
|
||||
///
|
||||
/// Ingestion checks it against the event's own team list and rejects a
|
||||
/// disagreement with `MismatchedShape`, so this is the cheap way to check
|
||||
/// an outcome built elsewhere before committing the event.
|
||||
#[must_use]
|
||||
pub fn team_count(&self) -> usize {
|
||||
match self {
|
||||
|
||||
Reference in New Issue
Block a user