Member::prior is documented as a per-event override (src/event.rs):
weight defaults to 1.0; a per-event prior can override the competitor's current skill estimate for this event only.
Neither half of that sentence is true in the implementation.
What actually happens
History::add_events collects priors into a map keyed by Index (src/history.rs:719-721), then hands it to add_events_with_prior, which consults it in exactly one place (src/history.rs:512-527):
if!self.agents.contains(*agent){self.agents.insert(*agent,Competitor{rating: priors.remove(agent).unwrap_or_else(||Rating::new(/* history defaults */)),...});}
Two consequences:
Known competitor → the prior is dropped on the floor. If the competitor already exists in self.agents, the if is skipped, priors.remove is never called, and the supplied prior has no effect whatsoever. No error, no warning. Since a competitor is inserted the first time they appear, this means a prior only ever applies on a competitor's very first event and is silently discarded on every subsequent one.
Even when it is applied, it is not per-event. It sets Competitor.rating, which is the competitor's standing configuration for the whole history — not an override scoped to one event.
So the feature works only in the single case "brand-new competitor, first appearance", and even there it does something different from what the doc promises.
Why it matters
The natural use is seeding: import a competitor with a known rating from an external system, or pin a reference player's skill for one event. Both silently do nothing if the competitor has been seen before — the caller gets plausible output computed from the default prior instead.
Fix
Decide which of the two documented behaviours is actually wanted:
Per-competitor seeding (probably what the code was reaching for): apply the prior whenever supplied, replacing Competitor.rating even for known competitors. Cheap; but "last write wins" across a batch needs defining, and it makes ingestion order significant.
True per-event override (what the doc says): plumb the prior down to Item/Event so Item::within_prior (src/time_slice.rs:61-78) uses it in place of the skill-derived rating for that event only, leaving the competitor's own state untouched.
Whichever is chosen, the other should be either implemented under a distinct name or removed from the docs. If a supplied prior cannot be honoured, that should be an InferenceError, not a silent drop.
Acceptance
A test asserting a prior supplied for an already-known competitor changes the result.
A test asserting the scope of the override (whole-history vs single-event) matches the documented wording.
src/event.rs doc comment updated to describe what the code does.
`Member::prior` is documented as a per-event override (`src/event.rs`):
> `weight` defaults to 1.0; a per-event `prior` can override the competitor's current skill estimate **for this event only**.
Neither half of that sentence is true in the implementation.
## What actually happens
`History::add_events` collects priors into a map keyed by `Index` (`src/history.rs:719-721`), then hands it to `add_events_with_prior`, which consults it in exactly one place (`src/history.rs:512-527`):
```rust
if !self.agents.contains(*agent) {
self.agents.insert(*agent, Competitor {
rating: priors.remove(agent).unwrap_or_else(|| Rating::new(/* history defaults */)),
...
});
}
```
Two consequences:
1. **Known competitor → the prior is dropped on the floor.** If the competitor already exists in `self.agents`, the `if` is skipped, `priors.remove` is never called, and the supplied prior has no effect whatsoever. No error, no warning. Since a competitor is inserted the first time they appear, this means a prior only ever applies on a competitor's *very first* event and is silently discarded on every subsequent one.
2. **Even when it is applied, it is not per-event.** It sets `Competitor.rating`, which is the competitor's standing configuration for the whole history — not an override scoped to one event.
So the feature works only in the single case "brand-new competitor, first appearance", and even there it does something different from what the doc promises.
## Why it matters
The natural use is seeding: import a competitor with a known rating from an external system, or pin a reference player's skill for one event. Both silently do nothing if the competitor has been seen before — the caller gets plausible output computed from the default prior instead.
## Fix
Decide which of the two documented behaviours is actually wanted:
- **Per-competitor seeding** (probably what the code was reaching for): apply the prior whenever supplied, replacing `Competitor.rating` even for known competitors. Cheap; but "last write wins" across a batch needs defining, and it makes ingestion order significant.
- **True per-event override** (what the doc says): plumb the prior down to `Item`/`Event` so `Item::within_prior` (`src/time_slice.rs:61-78`) uses it in place of the skill-derived rating for that event only, leaving the competitor's own state untouched.
Whichever is chosen, the other should be either implemented under a distinct name or removed from the docs. If a supplied prior cannot be honoured, that should be an `InferenceError`, not a silent drop.
## Acceptance
- A test asserting a prior supplied for an already-known competitor changes the result.
- A test asserting the scope of the override (whole-history vs single-event) matches the documented wording.
- `src/event.rs` doc comment updated to describe what the code does.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Member::prioris documented as a per-event override (src/event.rs):Neither half of that sentence is true in the implementation.
What actually happens
History::add_eventscollects priors into a map keyed byIndex(src/history.rs:719-721), then hands it toadd_events_with_prior, which consults it in exactly one place (src/history.rs:512-527):Two consequences:
self.agents, theifis skipped,priors.removeis never called, and the supplied prior has no effect whatsoever. No error, no warning. Since a competitor is inserted the first time they appear, this means a prior only ever applies on a competitor's very first event and is silently discarded on every subsequent one.Competitor.rating, which is the competitor's standing configuration for the whole history — not an override scoped to one event.So the feature works only in the single case "brand-new competitor, first appearance", and even there it does something different from what the doc promises.
Why it matters
The natural use is seeding: import a competitor with a known rating from an external system, or pin a reference player's skill for one event. Both silently do nothing if the competitor has been seen before — the caller gets plausible output computed from the default prior instead.
Fix
Decide which of the two documented behaviours is actually wanted:
Competitor.ratingeven for known competitors. Cheap; but "last write wins" across a batch needs defining, and it makes ingestion order significant.Item/EventsoItem::within_prior(src/time_slice.rs:61-78) uses it in place of the skill-derived rating for that event only, leaving the competitor's own state untouched.Whichever is chosen, the other should be either implemented under a distinct name or removed from the docs. If a supplied prior cannot be honoured, that should be an
InferenceError, not a silent drop.Acceptance
src/event.rsdoc comment updated to describe what the code does.