ConvergenceOptions::default() takes max_iter from crate::ITERATIONS, which is 30. That is not close to enough for a history of even modest size, and the failure mode is the quiet kind.
Measured
ustat's joint hole-level fit is 1,991 nodes over 3,292 events. It needs:
76 sweeps to converge as built
161 unpooled
So the default stops at roughly a fifth to two fifths of the way there. It runs max_iter = 500 for that reason, and boot is tens of milliseconds either way — the default is not buying speed on anything but a toy.
Why it is worth more than a constant change
A fit that stops short is wrong by a little, which is the worst available failure: it converges enough to look plausible, the ratings are all finite and ordered sensibly, and nothing about the output says the numbers moved after the last sweep. The ConvergenceReport does carry the fact, so a careful consumer can detect it — but detection is opt-in and the default is the trap.
Three possible responses, roughly increasing in effort:
Document it. State on ITERATIONS and on ConvergenceOptions roughly what size of history 30 is adequate for, so the number reads as a floor rather than as a recommendation.
Scale the default with the graph — node or event count — rather than shipping one constant for every workload.
Make a non-converged fit hard to swallow. Whether that is a louder signal from converge() or a Result shape the caller must confront is a call for the crate; I only want it to be difficult to consume a short fit by accident.
(1) alone would be a real improvement, and #22 already tightened the neighbouring inconsistency, so this may be a small job.
Not urgent for ustat — it has set 500 since early on. Filing it because the default is what a new consumer gets, and the reason to change it is not discoverable from the output.
`ConvergenceOptions::default()` takes `max_iter` from `crate::ITERATIONS`, which is **30**. That is not close to enough for a history of even modest size, and the failure mode is the quiet kind.
## Measured
`ustat`'s joint hole-level fit is **1,991 nodes over 3,292 events**. It needs:
- **76** sweeps to converge as built
- **161** unpooled
So the default stops at roughly a fifth to two fifths of the way there. It runs `max_iter = 500` for that reason, and boot is tens of milliseconds either way — the default is not buying speed on anything but a toy.
## Why it is worth more than a constant change
A fit that stops short is **wrong by a little**, which is the worst available failure: it converges enough to look plausible, the ratings are all finite and ordered sensibly, and nothing about the output says the numbers moved after the last sweep. The `ConvergenceReport` does carry the fact, so a careful consumer can detect it — but detection is opt-in and the default is the trap.
Three possible responses, roughly increasing in effort:
1. **Document it.** State on `ITERATIONS` and on `ConvergenceOptions` roughly what size of history 30 is adequate for, so the number reads as a floor rather than as a recommendation.
2. **Scale the default** with the graph — node or event count — rather than shipping one constant for every workload.
3. **Make a non-converged fit hard to swallow.** Whether that is a louder signal from `converge()` or a `Result` shape the caller must confront is a call for the crate; I only want it to be difficult to consume a short fit by accident.
(1) alone would be a real improvement, and #22 already tightened the neighbouring inconsistency, so this may be a small job.
Not urgent for `ustat` — it has set 500 since early on. Filing it because the default is what a new consumer gets, and the reason to change it is not discoverable from the output.
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.
ConvergenceOptions::default()takesmax_iterfromcrate::ITERATIONS, which is 30. That is not close to enough for a history of even modest size, and the failure mode is the quiet kind.Measured
ustat's joint hole-level fit is 1,991 nodes over 3,292 events. It needs:So the default stops at roughly a fifth to two fifths of the way there. It runs
max_iter = 500for that reason, and boot is tens of milliseconds either way — the default is not buying speed on anything but a toy.Why it is worth more than a constant change
A fit that stops short is wrong by a little, which is the worst available failure: it converges enough to look plausible, the ratings are all finite and ordered sensibly, and nothing about the output says the numbers moved after the last sweep. The
ConvergenceReportdoes carry the fact, so a careful consumer can detect it — but detection is opt-in and the default is the trap.Three possible responses, roughly increasing in effort:
ITERATIONSand onConvergenceOptionsroughly what size of history 30 is adequate for, so the number reads as a floor rather than as a recommendation.converge()or aResultshape the caller must confront is a call for the crate; I only want it to be difficult to consume a short fit by accident.(1) alone would be a real improvement, and #22 already tightened the neighbouring inconsistency, so this may be a small job.
Not urgent for
ustat— it has set 500 since early on. Filing it because the default is what a new consumer gets, and the reason to change it is not discoverable from the output.